
    Jir!                       d dl mZ d dlZd dlZd dlZd dlmZmZmZm	Z	m
Z
mZmZmZmZ erd dlmZ 	 d dlmZ 	 d dlmZ d dlmZ dd	lmZ dd
lmZmZ ddlmZ dZ G d de      Z ddZ!ddZ"ddZ#ddZ$ddZ%ddZ&ddZ'ejP                  ejR                  z   Z*dddZ+y# e$ r	 d dlmZ Y vw xY w# e$ r	 d dlmZ Y w xY w)     )annotationsN)	TYPE_CHECKING	AnnotatedAnyCallableOptionalcastget_args
get_originget_type_hintsStepFunction)Union)	UnionType)	BaseModel   )WorkflowValidationError)Event	EventType)ResourceDefinitiong{Gz?c                  D    e Zd ZU dZded<   ded<   ded<   ded	<   ded
<   y)StepSignatureSpeczIA Pydantic model representing the signature of a step function or method.zdict[str, list[EventType]]accepted_events	list[Any]return_typesz
str | Nonecontext_parameterz
Any | Nonecontext_state_type	resourcesN)__name__
__module____qualname____doc____annotations__     a/var/www/html/BankruptcyAI-uat/bankruptcy-ai/venv/lib/python3.12/site-packages/workflows/utils.pyr   r   ,   s#    S//!!""r%   r   c                   t        |       s!t        dt        |       j                         t	        j
                  |       }t        | d      }i }d}d}g }|j                  j                         D ]  \  }}|dv r|j                  ||j                        }	t        |	      ;t        |	      }
t        |	      }t        |
d      r|
j                  dk(  r
|}|r|d   }mt        |	      t        u r+t        |	      \  }}|j                  t!        ||	             t        |	d      r|	j                  dk(  r|}t#        ||      }t%        d
 |D              s|||<    t'        |t)        |       |||      S )a  
    Given a function, ensure the signature is compatible with a workflow step.

    Args:
        fn (Callable): The function to inspect.

    Returns:
        StepSignatureSpec: A specification object containing:
            - accepted_events: Dictionary mapping parameter names to their event types
            - return_types: List of return type annotations
            - context_parameter: Name of the context parameter if present

    Raises:
        TypeError: If fn is not a callable object

    z Expected a callable object, got T)include_extrasN)selfclsr   Contextr   )nameresourcec              3     K   | ]6  }|t         k(  xs' t        j                  |      xr t        |t                8 y wN)r   inspectisclass
issubclass).0param_ts     r&   	<genexpr>z$inspect_signature.<locals>.<genexpr>t   sC      
  u I(GZ-GI
s   <>)r   r   r   r   r   )callable	TypeErrortyper   r0   	signaturer   
parametersitemsget
annotationr   r
   hasattrr   appendr   _get_param_typesallr   _get_return_types)fnsig
type_hintsr   r   r   r   r,   tr=   originargs_r-   param_typess                  r&   inspect_signaturerK   6   s   " B<:48;L;L:MNOO


B
C48J24OI >>'') 'a?"^^D!,,7
 j!-
+FJ'D vz*v)/K$(!)-a& j!Y.":.KAx/THMN :z*z/B/Bi/O $ 'q*5 
 '
 

 %0OD!O'R '&r*+- r%   c                    t        | j                        }|dk(  rd}t        |      |dkD  rd| d}t        |      | j                  sd}t        |      y)a	  
    Validate that a step signature specification meets workflow requirements.

    Args:
        spec (StepSignatureSpec): The signature specification to validate.

    Raises:
        WorkflowValidationError: If the signature is invalid for a workflow step.

    r   zGStep signature must have at least one parameter annotated as type Eventr   zJStep signature must contain exactly one parameter of type Event but found .zKReturn types of workflows step functions must be annotated with their type.N)lenr   r   r   )specnum_of_eventsmsgs      r&   validate_step_signaturerR      sn     ,,-MW%c**		Z[hZiijk%c**[%c** r%   c                    ddl m} i }t        j                  | t        j                        }|D ]!  \  }}t        |d      st        ||      ||<   # |S )a
  
    Given a class, return the list of its methods that were defined as steps.

    Args:
        _class (object): The class to inspect for step methods.

    Returns:
        dict[str, Callable]: A dictionary mapping step names to their corresponding methods.

    r   r   	predicate_step_config)workflows.decoratorsr   r0   
getmembers
isfunctionr>   r	   )_classr   step_methodsall_methodsr,   methods         r&   get_steps_from_classr^      sZ     2,.L$$Vw7I7IJK# <f6>*!%lF!;L< r%   c                    ddl m} i }t        j                  | t        j                        }|D ]!  \  }}t        |d      st        ||      ||<   # |S )a  
    Given a workflow instance, return the list of its methods that were defined as steps.

    Args:
        workflow (object): The workflow instance to inspect.

    Returns:
        dict[str, Callable]: A dictionary mapping step names to their corresponding methods.

    r   r   rT   rV   )rW   r   r0   rX   ismethodr>   r	   )workflowr   r[   r\   r,   r]   s         r&   get_steps_from_instancerb      sZ     2,.L$$X9I9IJK# <f6>*!%lF!;L< r%   c                *   |j                  | j                  | j                        }|t        j                  j
                  u rt        gS t        |      t        t        t        fv r't        |      D cg c]  }|t        d      us| c}S |gS c c}w )a  
    Extract and process the types of a parameter.

    This helper function handles Union and Optional types, returning a list of the actual types.
    For Union[A, None] (Optional[A]), it returns [A].

    Args:
        param (inspect.Parameter): The parameter to analyze.
        type_hints (dict): The resolved type hints for the function.

    Returns:
        list[Any]: A list of extracted types, excluding None from Unions/Optionals.

    N)r<   r,   r=   r0   	Parameteremptyr   r   r   r   r   r
   r8   )paramrE   typrF   s       r&   r@   r@      sy     ..U%5%5
6C
g%%%u#5(I66#C=@aAT$Z,?@@5L As   3BBc                    t        |       }|j                  d      }|g S t        |      }|t        t        fv r't        |      D cg c]  }|t        d      us| c}S |gS c c}w )zf
    Extract the return type hints from a function.

    Handles Union, Optional, and List types.
    returnN)r   r<   r   r   r   r
   r8   )funcrE   return_hintrG   rF   s        r&   rB   rB      sm      %J..*K	$F%###K0HaAT$Z4GHH} Is   A$A$c                z    | sd}t        |      | j                  d      }t        |      dk(  ryd|vry|d   dk(  S )a  
    Determines whether a certain qualified name points to a free function.

    A free function is either a module-level function or a nested function.
    This implementation follows PEP-3155 for handling nested function detection.

    Args:
        qualname (str): The qualified name to analyze.

    Returns:
        bool: True if the name represents a free function, False otherwise.

    Raises:
        ValueError: If the qualified name is empty.

    z"The qualified name cannot be emptyrM   r   Tz<locals>F)
ValueErrorsplitrN   )qualnamerQ   tokss      r&   is_free_functionrr      sL    " 2o>>#D
4yA~	4	Bx:%%r%   c                D    dj                  d t        |       D              S )z9Returns a unique identifier with the format 'kY2xP9hTnQ'. c              3  N   K   | ]  }t        j                  t                y wr/   )secretschoice	_alphabet)r3   rI   s     r&   r5   z_nanoid.<locals>.<genexpr>  s     B7>>),Bs   #%)joinrange)sizes    r&   _nanoidr|     s    77BeDkBBBr%   )rC   r   ri   r   )rO   r   ri   None)rZ   objectri   dict[str, StepFunction])ra   r~   ri   r   )rf   zinspect.ParameterrE   dictri   r   )rj   r   ri   r   )rp   strri   bool)
   )r{   intri   r   ),
__future__r   r0   rv   stringtypingr   r   r   r   r   r	   r
   r   r   rW   r   r   ImportErrortyping_extensionstypesr   pydanticr   errorsr   eventsr   r   r-   r   BUSY_WAIT_DELAYr   rK   rR   r^   rb   r@   rB   rr   ascii_lettersdigitsrx   r|   r$   r%   r&   <module>r      s    #   
 
 
 1(
*  + $ (	 L^+0...&&@   6==0	C}  ('(  *)*s"   B! B2 !B/.B/2C ?C 