o
    i>                     @  s  d Z ddlmZ ddlZddlmZmZmZmZ ddl	m
Z
 ddlmZmZmZmZ ddlmZmZmZmZ ddlmZ dd	lmZmZmZmZ dd
lmZmZ ddlm Z  edddZ!edddZ"edddZ#edddZ$edZ%er~ddl&m'Z'm(Z(m)Z) G dd dee!e"e$e#f Z*e
G dd dZ+e
G dd dZ,e
G dd dZ-e
G dd dZ.e
G dd dZ/ed e+e,B e-B e.B e/B Z0	 e
G d!d" d"Z1e
G d#d$ d$ee!e"e#f Z2e
d%d&G d'd( d(ee!e"f Z3G d)d* d*ee!e"e#f Z4dS )+a  Path and edge definition for graph navigation.

This module provides the building blocks for defining paths through a graph,
including transformations, maps, broadcasts, and routing to destinations.
Paths enable complex data flow patterns in graph execution.
    )annotationsN)AsyncIterableCallableIterableSequence)	dataclass)TYPE_CHECKINGAnyGeneric
get_origin)ProtocolSelfTypeAliasTypeTypeVar)BaseNode)ForkIDJoinIDNodeIDgenerate_placeholder_node_id)NodeStepStepContext)GraphBuildingErrorStateTT)infer_varianceDepsTOutputTInputTT)AnyDestinationNodeDestinationNode
SourceNodec                   @  s   e Zd ZdZd	ddZdS )
TransformFunctiona$  Protocol for step functions that can be executed in the graph.

    Transform functions are sync callables that receive a step context and return
    a result. This protocol enables serialization and deserialization of step
    calls similar to how evaluators work.

    This is very similar to a StepFunction, but must be sync instead of async.

    Type Parameters:
        StateT: The type of the graph state
        DepsT: The type of the dependencies
        InputT: The type of the input data
        OutputT: The type of the output data
    ctx"StepContext[StateT, DepsT, InputT]returnr   c                 C  s   t )zExecute the step function with the given context.

        Args:
            ctx: The step context containing state, dependencies, and inputs

        Returns:
            An awaitable that resolves to the step's output
        )NotImplementedError)selfr"    r'   _/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/pydantic_graph/beta/paths.py__call__0   s   	zTransformFunction.__call__N)r"   r#   r$   r   )__name__
__module____qualname____doc__r)   r'   r'   r'   r(   r!       s    r!   c                   @     e Zd ZU dZded< dS )TransformMarkerzA marker indicating a data transformation step in a path.

    Transform markers wrap step functions that modify data as it flows
    through the graph path.
    z%TransformFunction[Any, Any, Any, Any]	transformNr*   r+   r,   r-   __annotations__r'   r'   r'   r(   r/   <      
 r/   c                   @  $   e Zd ZU dZded< 	 ded< dS )	MapMarkerzA marker indicating that iterable data should be map across parallel paths.

    Spread markers take iterable input and create parallel execution paths
    for each item in the iterable.
    r   fork_idJoinID | Nonedownstream_join_idNr1   r'   r'   r'   r(   r5   H   s   
 r5   c                   @  r4   )BroadcastMarkerzA marker indicating that data should be broadcast to multiple parallel paths.

    Broadcast markers create multiple parallel execution paths, sending the
    same input data to each path.
    Sequence[Path]pathsr   r6   Nr1   r'   r'   r'   r(   r9   V   s   
 r9   c                   @  r.   )LabelMarkerzA marker providing a human-readable label for a path segment.

    Label markers are used for debugging, visualization, and documentation
    purposes to provide meaningful names for path segments.
    strlabelNr1   r'   r'   r'   r(   r<   e   r3   r<   c                   @  r.   )DestinationMarkerzA marker indicating the target destination node for a path.

    Destination markers specify where data should be routed at the end
    of a path execution.
    r   destination_idNr1   r'   r'   r'   r(   r?   q   r3   r?   PathItemc                   @  s8   e Zd ZU dZded< 	 edddZeddd	Zd
S )PathzA sequence of path items defining data flow through the graph.

    Paths represent the route that data takes through the graph, including
    transformations, forks, and routing decisions.
    zlist[PathItem]itemsr$   "BroadcastMarker | MapMarker | Nonec                 C  s*   t | jD ]}t|ttB r|  S qdS )zGet the most recent fork or map marker in this path.

        Returns:
            The last BroadcastMarker or MapMarker in the path, or None if no forks exist
        N)reversedrC   
isinstancer9   r5   )r&   itemr'   r'   r(   	last_fork   s
   zPath.last_forkc                 C  s   t | jdd S )zCreate a new path with the first item removed.

        Returns:
            A new Path with all items except the first one
           N)rB   rC   r&   r'   r'   r(   	next_path   s   zPath.next_pathN)r$   rD   )r$   rB   )r*   r+   r,   r-   r2   propertyrH   rK   r'   r'   r'   r(   rB      s   
 rB   c                   @  sb   e Zd ZU dZded< 	 ddd#ddZddd$ddZd%ddZdddd&ddZd'd!d"Z	dS )(PathBuilderar  A builder for constructing paths with method chaining.

    PathBuilder provides a fluent interface for creating paths by chaining
    operations like transforms, maps, and routing to destinations.

    Type Parameters:
        StateT: The type of the graph state
        DepsT: The type of the dependencies
        OutputT: The type of the current data in the path
    zSequence[PathItem]working_itemsNr6   destination'DestinationNode[StateT, DepsT, OutputT]extra_destinationsr6   
str | Noner$   rB   c               G  sP   |rt dd |f| D tt|ptdd}nt|j}tg | j|dS )a  Route the path to one or more destination nodes.

        Args:
            destination: The primary destination node
            *extra_destinations: Additional destination nodes (creates a broadcast)
            fork_id: Optional ID for the fork created when multiple destinations are specified

        Returns:
            A complete Path ending at the specified destination(s)
        c                 S  s   g | ]}t t|jgd qS )rC   )rB   r?   id.0dr'   r'   r(   
<listcomp>   s    z"PathBuilder.to.<locals>.<listcomp>	broadcastr;   r6   rT   )r9   r   r   r   r?   rU   rB   rN   )r&   rP   r6   rR   	next_itemr'   r'   r(   to   s   
zPathBuilder.toforksr:   c               C  s0   t |tt|p	tdd}tg | j|dS )a8  Create a fork that broadcasts data to multiple parallel paths.

        Args:
            forks: The sequence of paths to run in parallel
            fork_id: Optional ID for the fork, defaults to a generated value

        Returns:
            A complete Path that forks to the specified parallel paths
        rZ   r[   rT   )r9   r   r   r   rB   rN   )r&   r^   r6   r\   r'   r'   r(   rZ      s   
zPathBuilder.broadcastfunc,TransformFunction[StateT, DepsT, OutputT, T]PathBuilder[StateT, DepsT, T]c                C  &   t |}ttttf g | j|dS )zAdd a transformation step to the path.

        Args:
            func: The step function that will transform the data

        Returns:
            A new PathBuilder with the transformation added
        rN   )r/   rM   r   r   r   rN   )r&   r_   r\   r'   r'   r(   r0         	zPathBuilder.transformr6   r8   r&   VPathBuilder[StateT, DepsT, Iterable[T]] | PathBuilder[StateT, DepsT, AsyncIterable[T]]r8   c                C  sJ   t tt|ptd|durt|ndd}ttttf g | j	|dS )a  Spread iterable data across parallel execution paths.

        This method can only be called when the current output type is iterable.
        It creates parallel paths for each item in the iterable.

        Args:
            fork_id: Optional ID for the fork, defaults to a generated value
            downstream_join_id: Optional ID of a downstream join node which is involved when mapping empty iterables

        Returns:
            A new PathBuilder that operates on individual items from the iterable
        mapNre   rc   )
r5   r   r   r   r   rM   r   r   r   rN   )r&   r6   r8   r\   r'   r'   r(   rg      s
   zPathBuilder.mapr>   r=   #PathBuilder[StateT, DepsT, OutputT]c                C  rb   )zAdd a human-readable label to this point in the path.

        Args:
            label: The label to add for documentation/debugging purposes

        Returns:
            A new PathBuilder with the label added
        rc   )r<   rM   r   r   r   rN   )r&   r>   r\   r'   r'   r(   r>      rd   zPathBuilder.label)rP   rQ   rR   rQ   r6   rS   r$   rB   )r^   r:   r6   rS   r$   rB   )r_   r`   r$   ra   )r&   rf   r6   rS   r8   rS   r$   ra   )r>   r=   r$   rh   )
r*   r+   r,   r-   r2   r]   rZ   r0   rg   r>   r'   r'   r'   r(   rM      s   
 
rM   F)initc                   @  sH   e Zd ZU dZded< 	 ded< 	 ded< 	 dd	d
ZedddZdS )EdgePathzA complete edge connecting source nodes to destinations via a path.

    EdgePath represents a complete connection in the graph, specifying the
    source nodes, the path that data follows, and the destination nodes.
    (Sequence[SourceNode[StateT, DepsT, Any]]_sourcesrB   pathlist[AnyDestinationNode]destinationssourcesc                 C  s   || _ || _|| _d S N)rl   rm   ro   )r&   rp   rm   ro   r'   r'   r(   __init__  s   
zEdgePath.__init__r$   c                 C  s   | j S rq   )rl   rJ   r'   r'   r(   rp   "  s   zEdgePath.sourcesN)rp   rk   rm   rB   ro   rn   )r$   rk   )r*   r+   r,   r-   r2   rr   rL   rp   r'   r'   r'   r(   rj     s   
 
rj   c                   @  s`   e Zd ZdZd(ddZdd	d)ddZdd	d*ddZdddd+ddZd,d!d"Zd-d&d'Z	dS ).EdgePathBuildera  A builder for constructing complete edge paths with method chaining.

    EdgePathBuilder combines source nodes with path building capabilities
    to create complete edge definitions. It cannot use dataclass due to
    type variance issues.

    Type Parameters:
        StateT: The type of the graph state
        DepsT: The type of the dependencies
        OutputT: The type of the current data in the path
    rp   rk   path_builderrh   c                 C  s   || _ || _dS )zInitialize an edge path builder.

        Args:
            sources: The source nodes for this edge path
            path_builder: The path builder for defining the data flow
        N)rp   _path_builder)r&   rp   rt   r'   r'   r(   rr   4  s   	
zEdgePathBuilder.__init__NrO   rP   LDestinationNode[StateT, DepsT, OutputT] | type[BaseNode[StateT, DepsT, Any]]rR   r6   rS   r$   EdgePath[StateT, DepsT]c               G  sf   t |p|}tdd |D }dd |g|R D }t| j| jj|d g|dd R d|i|d	S )
a  Complete the edge path by routing to destination nodes.

        Args:
            destination: Either a destination node or a function that generates edge paths
            *extra_destinations: Additional destination nodes (creates a broadcast)
            fork_id: Optional ID for the fork created when multiple destinations are specified

        Returns:
            A complete EdgePath connecting sources to destinations
        c                 s  s    | ]	}t |p	|V  qd S rq   )r   rV   r'   r'   r(   	<genexpr>T  s    z%EdgePathBuilder.to.<locals>.<genexpr>c                 S  s"   g | ]}t |rt|n|qS r'   )inspectisclassr   rV   r'   r'   r(   rY   U  s   " z&EdgePathBuilder.to.<locals>.<listcomp>r   rI   Nr6   rp   rm   ro   )r   tuplerj   rp   ru   r]   )r&   rP   r6   rR   ro   r'   r'   r(   r]   @  s   $zEdgePathBuilder.to	get_forks3Callable[[Self], Sequence[EdgePath[StateT, DepsT]]]c               C  sX   || }dd |D }|st d| d| jj||d}dd |D }t| j||dS )aS  Broadcast this EdgePathBuilder into multiple destinations.

        Args:
            get_forks: The callback that will return a sequence of EdgePaths to broadcast to.
            fork_id: Optional node ID to use for the resulting broadcast fork.

        Returns:
            A completed EdgePath with the specified destinations.
        c                 S  s   g | ]}t |jjqS r'   )rB   rm   rC   )rW   xr'   r'   r(   rY   i  s    z-EdgePathBuilder.broadcast.<locals>.<listcomp>zThe call to z4 returned no branches, but must return at least one.rO   c                 S  s   g | ]
}|j D ]}|qqS r'   )ro   )rW   eprX   r'   r'   r(   rY   m  s    r{   )r   ru   rZ   rj   rp   )r&   r}   r6   new_edge_paths	new_pathsrm   ro   r'   r'   r(   rZ   \  s   zEdgePathBuilder.broadcastre   r&   ^EdgePathBuilder[StateT, DepsT, Iterable[T]] | EdgePathBuilder[StateT, DepsT, AsyncIterable[T]]r8   r7   !EdgePathBuilder[StateT, DepsT, T]c                C  s0   t | jdkrtdt| j| jj||ddS )aw  Spread iterable data across parallel execution paths.

        Args:
            fork_id: Optional ID for the fork, defaults to a generated value
            downstream_join_id: Optional ID of a downstream join node which is involved when mapping empty iterables

        Returns:
            A new EdgePathBuilder that operates on individual items from the iterable
        rI   zMap is not currently supported with multiple source nodes. You can work around this by just creating a separate edge for each source.re   rp   rt   )lenrp   r%   rs   ru   rg   )r&   r6   r8   r'   r'   r(   rg   t  s   zEdgePathBuilder.mapr_   r`   c                C     t | j| j|dS )zAdd a transformation step to the edge path.

        Args:
            func: The step function that will transform the data

        Returns:
            A new EdgePathBuilder with the transformation added
        r   )rs   rp   ru   r0   )r&   r_   r'   r'   r(   r0        	zEdgePathBuilder.transformr>   r=   'EdgePathBuilder[StateT, DepsT, OutputT]c                 C  r   )zAdd a human-readable label to this point in the edge path.

        Args:
            label: The label to add for documentation/debugging purposes

        Returns:
            A new EdgePathBuilder with the label added
        r   )rs   rp   ru   r>   )r&   r>   r'   r'   r(   r>     r   zEdgePathBuilder.label)rp   rk   rt   rh   )rP   rv   rR   rv   r6   rS   r$   rw   )r}   r~   r6   rS   r$   rw   )r&   r   r6   rS   r8   r7   r$   r   )r_   r`   r$   r   )r>   r=   r$   r   )
r*   r+   r,   r-   rr   r]   rZ   rg   r0   r>   r'   r'   r'   r(   rs   '  s    

rs   )5r-   
__future__r   ry   collections.abcr   r   r   r   dataclassesr   typingr   r	   r
   r   typing_extensionsr   r   r   r   pydantic_graphr   pydantic_graph.beta.id_typesr   r   r   r   pydantic_graph.beta.stepr   r   pydantic_graph.exceptionsr   r   r   r   r   r   pydantic_graph.beta.node_typesr   r   r    r!   r/   r5   r9   r<   r?   rA   rB   rM   rj   rs   r'   r'   r'   r(   <module>   sL     i