
    g3fi6Z                       d Z ddlmZ ddlZddlmZ ddlmZmZ ddl	m
Z
 ddlmZmZmZmZmZmZ ddlmZmZ dd	lmZ dd
lmZmZ ddlmZmZ erddlmZmZ ddl m!Z! ddlmZ"  G d de      Z# G d de      Z$d(dZ% G d de      Z& G d de      Z' G d de      Z( G d de
      Z)e G d d             Z* G d de
      Z+	 	 	 	 	 	 d)d Z,d!d"	 	 	 	 	 d*d#Z-e G d$ d%             Z.d+d,d&Z/d+d,d'Z0y)-zGraph used in Runnables.    )annotationsN)defaultdict)	dataclassfield)Enum)TYPE_CHECKINGAny
NamedTupleProtocol	TypedDictoverload)UUIDuuid4)to_json_not_implemented)RunnableRunnableSerializable)_IgnoreUnserializableis_basemodel_subclass)CallableSequence)	BaseModel)r   c                      e Zd ZdZddZy)Stringifiablez7Protocol for objects that can be converted to a string.c                     y)zConvert the object to a string.N selfs    \/var/www/auto_recruiter/arenv/lib/python3.12/site-packages/langchain_core/runnables/graph.py__str__zStringifiable.__str__"   s        Nreturnstr)__name__
__module____qualname____doc__r   r   r    r   r   r      s
    A.r    r   c                  (    e Zd ZU dZded<   	 ded<   y)
LabelsDictz4Dictionary of labels for nodes and edges in a graph.zdict[str, str]nodesedgesNr$   r%   r&   r'   __annotations__r   r    r   r)   r)   &   s    >r    r)   c                :    	 t        |        y# t        $ r Y yw xY w)zCheck if a string is a valid UUID.

    Args:
        value: The string to check.

    Returns:
        `True` if the string is a valid UUID, `False` otherwise.
    FT)r   
ValueError)values    r   is_uuidr1   /   s'    U   s    	c                  Z    e Zd ZU dZded<   	 ded<   	 dZded<   	 dZd	ed
<   	 dddddZy)EdgezEdge in a graph.r#   sourcetargetNStringifiable | NonedataFboolconditionalr4   r5   c                   t        |xs | j                  |xs | j                  | j                  | j                        S )a  Return a copy of the edge with optional new source and target nodes.

        Args:
            source: The new source node id.
            target: The new target node id.

        Returns:
            A copy of the edge with the new source and target nodes.
        r4   r5   r7   r9   )r3   r4   r5   r7   r9   )r   r4   r5   s      r   copyz	Edge.copyK   s9     (T[[(T[[((	
 	
r    )r4   
str | Noner5   r>   r"   r3   )r$   r%   r&   r'   r-   r7   r9   r=   r   r    r   r3   r3   ?   s:    KK!%D
%2K*+/d 
r    r3   c                  \    e Zd ZU dZded<   	 ded<   	 ded<   	 ded<   	 d	d	d
	 	 	 	 	 ddZy	)NodezNode in a graph.r#   idname%type[BaseModel] | RunnableType | Noner7   dict[str, Any] | NonemetadataNrA   rB   c                   t        |xs | j                  |xs | j                  | j                  | j                        S )zReturn a copy of the node with optional new id and name.

        Args:
            id: The new node id.
            name: The new node name.

        Returns:
            A copy of the node with the new id and name.
        )rA   rB   r7   rE   )r@   rA   rB   r7   rE   )r   rA   rB   s      r   r=   z	Node.copyi   s6     }TWW"]]	
 	
r    )rA   r>   rB   r>   r"   r@   )r$   r%   r&   r'   r-   r=   r   r    r   r@   r@   ]   sR    G,
I
//##*
 	
 
 	

 

r    r@   c                  (    e Zd ZU dZded<   	 ded<   y)BranchzBranch in a graph.zCallable[..., str]	conditiondict[str, str] | NoneendsNr,   r   r    r   rI   rI      s    !!K
@r    rI   c                  @    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZy)
CurveStylez5Enum for different curve styles supported by Mermaid.basisbumpXbumpYcardinal
catmullRomlinear	monotoneX	monotoneYnaturalstep	stepAfter
stepBeforeN)r$   r%   r&   r'   BASISBUMP_XBUMP_YCARDINALCATMULL_ROMLINEAR
MONOTONE_X
MONOTONE_YNATURALSTEP
STEP_AFTERSTEP_BEFOREr   r    r   rN   rN      sA    ?EFFHKFJJGDJKr    rN   c                  <    e Zd ZU dZdZded<   dZded<   dZded<   y	)

NodeStyleszSchema for Hexadecimal color codes for different node types.

    Args:
        default: The default color code.
        first: The color code for the first node.
        last: The color code for the last node.
    zfill:#f2f0ff,line-height:1.2r#   defaultzfill-opacity:0firstzfill:#bfb6fclastN)r$   r%   r&   r'   ri   r-   rj   rk   r   r    r   rh   rh      s'     2GS1!E3!D#r    rh   c                      e Zd ZdZdZ	 dZy)MermaidDrawMethodz5Enum for different draw methods supported by Mermaid.	pyppeteerapiN)r$   r%   r&   r'   	PYPPETEERAPIr   r    r   rm   rm      s    ?I,
C2r    rm   c                    t        |       r|| S t        |t              r|j                         n|j                  }|j                  d      s|S |dd S )zConvert the data of a node to a string.

    Args:
        id: The node id.
        data: The node data.

    Returns:
        A string representation of the data.
    Nr      )r1   
isinstancer   get_namer$   
startswith)rA   r7   data_strs      r   node_data_strrx      sL     2;$,	",T8"<t}}$--H#..z:8LLr    Fwith_schemasc                  | j                   i }nPt        | j                   t              r?d| j                   j                         t	        | j
                  | j                         dd}nt        | j                   t              r=dt        | j                         d   t	        | j
                  | j                         dd}nt        j                  | j                         r^t        | j                         rI|r#d| j                   j                  t              dn"dt	        | j
                  | j                         d}n#dt	        | j
                  | j                         d}| j                  | j                  |d<   |S )	a'  Convert the data of a node to a JSON-serializable format.

    Args:
        node: The `Node` to convert.
        with_schemas: Whether to include the schema of the data if it is a Pydantic
            model.

    Returns:
        A dictionary with the type of the data and the data itself.
    runnablerF   )typer7   rA   schema)schema_generatorunknownrE   )r7   rt   r   lc_idrx   rA   r   r   inspectisclassr   model_json_schemar   rE   )noderz   jsons      r   node_data_jsonr      s8    yy!	DII3	4iioo'%dggtyy9
 
DIIx	(-dii8>%dggtyy9
 
	#(=dii(H  !		33%: 4  !%dggtyy9 	 !$''4995
 }} ==ZKr    c                  (   e Zd ZU dZ ee      Zded<    ee      Z	ded<   ddd(d	Z
d)d
Zd*dZ	 d+dd	 	 	 	 	 	 	 d,dZd-dZ	 	 d.	 	 	 	 	 	 	 	 	 d/dZdd	 	 	 	 	 d0dZd1dZd2dZd2dZd3dZd3dZd*dZd3dZe	 	 d4	 	 	 	 	 	 	 d5d       Ze	 	 d4	 	 	 	 	 	 	 d6d       Z	 	 	 d7	 	 	 	 	 	 	 d8dZdej6                  dddd 	 	 	 	 	 	 	 	 	 	 	 d9d!Zej6                  dddej<                  d"d#d$d%dddd&	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d:d'Zy);GraphzGraph of nodes and edges.

    Args:
        nodes: Dictionary of nodes in the graph. Defaults to an empty dictionary.
        edges: List of edges in the graph. Defaults to an empty list.
    )default_factoryzdict[str, Node]r*   z
list[Edge]r+   Fry   c               F   t        | j                  j                               D ci c]3  \  }}|j                  t	        |j                        r|n|j                  5 }}}g }| j
                  D ]^  }||j                     ||j                     d}|j                  |j                  |d<   |j                  rd|d<   |j                  |       ` | j                  j                         D cg c]   }d||j                     it        ||      " c}|dS c c}}w c c}w )a  Convert the graph to a JSON-serializable format.

        Args:
            with_schemas: Whether to include the schemas of the nodes if they are
                Pydantic models.

        Returns:
            A dictionary with the nodes and edges of the graph.
        r:   r7   Tr9   rA   ry   r*   r+   )	enumerater*   valuesrA   r1   r+   r4   r5   r7   r9   appendr   )r   rz   ir   stable_node_idsr+   edge	edge_dicts           r   to_jsonzGraph.to_json  s"    %TZZ%6%6%89
4 GG'$''*Q7
 
 ')JJ 		$D)$++6)$++6I yy$$(II	&!+/	-(LL#		$" !JJ--/
  /$''2$TE 	
 		
!
"s   8D-%Dc                ,    t        | j                        S )z'Return whether the graph has any nodes.)r8   r*   r   s    r   __bool__zGraph.__bool__-  s    DJJr    c                *    t               j                  S )zfReturn a new unique node identifier.

        It that can be used to add a node to the graph.
        )r   hexr   s    r   next_idzGraph.next_id1  s    
 w{{r    N)rE   c          	         ||| j                   v rd| d}t        |      |xs | j                         }t        |||t	        ||            }|| j                   |j
                  <   |S )aX  Add a node to the graph and return it.

        Args:
            data: The data of the node.
            id: The id of the node.
            metadata: Optional metadata for the node.

        Returns:
            The node that was added to the graph.

        Raises:
            ValueError: If a node with the same id already exists.
        zNode with id z already exists)rA   r7   rE   rB   )r*   r/   r   r@   rx   rA   )r   r7   rA   rE   msgid_r   s          r   add_nodezGraph.add_node8  sk    ( >bDJJ.!"_5CS/!"DLLNs}SRV?WX"

477r    c                    | j                   j                  |j                         | j                  D cg c])  }|j                  |j                  |j
                  hvs(|+ c}| _        yc c}w )zyRemove a node from the graph and all edges connected to it.

        Args:
            node: The node to remove.
        N)r*   poprA   r+   r4   r5   )r   r   r   s      r   remove_nodezGraph.remove_nodeT  sP     	

tww!ZZ
4774;;:T+TD

 
s   )A+A+c                N   |j                   | j                  vrd|j                    d}t        |      |j                   | j                  vrd|j                    d}t        |      t        |j                   |j                   ||      }| j                  j                  |       |S )a  Add an edge to the graph and return it.

        Args:
            source: The source node of the edge.
            target: The target node of the edge.
            data: Optional data associated with the edge.
            conditional: Whether the edge is conditional.

        Returns:
            The edge that was added to the graph.

        Raises:
            ValueError: If the source or target node is not in the graph.
        zSource node z not in graphzTarget node r<   )rA   r*   r/   r3   r+   r   )r   r4   r5   r7   r9   r   r   s          r   add_edgezGraph.add_edge_  s    * 99DJJ& =9CS/!99DJJ& =9CS/!99VYYT{
 	

$r     )prefixc                  t        d |j                  j                         D              rddfd}| j                  j                  |j                  j	                         D ci c]$  \  }} ||      |j                   ||            & c}}       | j                  j                  |j                  D cg c]5  }|j                   ||j                         ||j                              7 c}       |j                         |j                         }}|r"|j                   ||j                              nd|r#|j                   ||j                              fS dfS c c}}w c c}w )aC  Add all nodes and edges from another graph.

        Note this doesn't check for duplicates, nor does it connect the graphs.

        Args:
            graph: The graph to add.
            prefix: The prefix to add to the node ids.

        Returns:
            A tuple of the first and last nodes of the subgraph.
        c              3  F   K   | ]  }t        |j                          y wN)r1   rA   ).0r   s     r   	<genexpr>zGraph.extend.<locals>.<genexpr>  s     ADwtwwAs   !r   c                    r d|  S | S )N:r   )r   r   s    r   prefixedzGraph.extend.<locals>.prefixed  s    (.fXQse$7C7r    rA   r:   N)r   r#   r"   r#   )allr*   r   updateitemsr=   r+   extendr4   r5   
first_node	last_noderA   )	r   graphr   r   kvr   rj   rk   s	     `      r   r   zGraph.extend  s5    AEKK,>,>,@AAF	8 	

=B[[=N=N=PQTQXa[!&&HQK&00Q	
 	

 "KK 		$++!6x?T	U	
 &&(%//*;t16EJJ(588,J-D/3DII$''*I+
 	
9=
 	
 Rs   &)E(
::E.c                  
 t        t              }| j                  j                         D ]*  }||j                     j                  |j                         , |j                         D ci c]3  \  }}t        |      D ]   \  }}|t        |      dk(  r|n	| d|dz    " 5 c}}}}
d
fd}t        | j                  j                         D ci c]$  \  }} ||      |j                   ||            & c}}| j                  D 	cg c]5  }	|	j                   ||	j                         ||	j                              7 c}	      S c c}}}}w c c}}w c c}	w )ztReturn a new graph with all nodes re-identified.

        Uses their unique, readable names where possible.
           _c                ,    |    }t        |       r|S | S r   )r1   )node_idlabelunique_labelss     r   _get_node_idz Graph.reid.<locals>._get_node_id  s    !'*EwNr    r   r:   r   )r   r#   r"   r#   )r   listr*   r   rB   r   rA   r   r   lenr   r=   r+   r4   r5   )r   node_name_to_idsr   	node_namenode_idsr   r   r   r   r   r   s             @r   reidz
Graph.reid  s\   
 't,JJ%%' 	8DTYY'..tww7	8
 (8'='='?
 
#	8'1
 7 #h-1"4YYKqQ:PP

	  "&!1!1!3C S!499S0A9#BB !JJ
 	 		'4'4  
 	

s   -8E
)E
:E
c                    t        |       S )a:  Find the single node that is not a target of any edge.

        If there is no such node, or there are multiple, return `None`.
        When drawing the graph, this node would be the origin.

        Returns:
            The first node, or None if there is no such node or multiple
            candidates.
        )_first_noder   s    r   r   zGraph.first_node  s     4  r    c                    t        |       S )a>  Find the single node that is not a source of any edge.

        If there is no such node, or there are multiple, return `None`.
        When drawing the graph, this node would be the destination.

        Returns:
            The last node, or None if there is no such node or multiple
            candidates.
        )
_last_noder   s    r   r   zGraph.last_node  s     $r    c                
   | j                         }|rlt        | |j                  g      rSt        | j                  D ch c]  }|j
                  |j                  k(  s|  c}      dk(  r| j                  |       yyyyc c}w )zRemove the first node if it exists and has a single outgoing edge.

        i.e., if removing it would not leave the graph without a "first" node.
        excluder   N)r   r   rA   r   r+   r4   r   )r   r   es      r   trim_first_nodezGraph.trim_first_node  so    
 __&
D:==/:

H1ahh*--.GQHIQNZ( O ; H   B B c                
   | j                         }|rlt        | |j                  g      rSt        | j                  D ch c]  }|j
                  |j                  k(  s|  c}      dk(  r| j                  |       yyyyc c}w )zRemove the last node if it exists and has a single incoming edge.

        i.e., if removing it would not leave the graph without a "last" node.
        r   r   N)r   r   rA   r   r+   r5   r   )r   r   r   s      r   trim_last_nodezGraph.trim_last_node  so    
 NN$	4),,8

G1ahh),,.FQGHAMY' N 9 Gr   c                    ddl m}  || j                  j                         D ci c]  }|j                  |j
                   c}| j                        S c c}w )zcDraw the graph as an ASCII art string.

        Returns:
            The ASCII art string.
        r   )
draw_ascii)$langchain_core.runnables.graph_asciir   r*   r   rA   rB   r+   )r   r   r   s      r   r   zGraph.draw_ascii  sG     	D,0JJ,=,=,?@DTWWdii@JJ
 	
@s   Ac                6    t        | j                                y)z'Print the graph as an ASCII art string.N)printr   r   s    r   print_asciizGraph.print_ascii	  s    doo r    c                     y r   r   r   output_file_pathfontnamelabelss       r   draw_pngzGraph.draw_png  s     r    c                     y r   r   r   s       r   r   zGraph.draw_png  s     r    c                    ddl m} | j                  j                         D ci c]  }|j                  |j
                   }} ||t        i |||d   ni ||d   ni             j                  | |      S c c}w )a  Draw the graph as a PNG image.

        Args:
            output_file_path: The path to save the image to. If `None`, the image
                is not saved.
            fontname: The name of the font to use.
            labels: Optional labels for nodes and edges in the graph. Defaults to
                `None`.

        Returns:
            The PNG image as bytes if output_file_path is None, None otherwise.
        r   )	PngDrawerr*   r+   r   )"langchain_core.runnables.graph_pngr   r*   r   rA   rB   r)   draw)r   r   r   r   r   r   default_node_labelss          r   r   zGraph.draw_png  s    & 	A>Bjj>O>O>QRdtww		1RR)*0*<vg" *0);fWo	
 $t%
&		' Ss   A9T	   )with_stylescurve_stylenode_colorswrap_label_n_wordsfrontmatter_configc                   ddl m} | j                         }|j                         }|j	                         }	 ||j
                  |j                  |r|j                  nd|	r|	j                  nd|||||	      S )a  Draw the graph as a Mermaid syntax string.

        Args:
            with_styles: Whether to include styles in the syntax.
            curve_style: The style of the edges.
            node_colors: The colors of the nodes.
            wrap_label_n_words: The number of words to wrap the node labels at.
            frontmatter_config: Mermaid frontmatter config.
                Can be used to customize theme and styles. Will be converted to YAML and
                added to the beginning of the mermaid graph.

                See more here: https://mermaid.js.org/config/configuration.html.

                Example config:

                ```python
                {
                    "config": {
                        "theme": "neutral",
                        "look": "handDrawn",
                        "themeVariables": {"primaryColor": "#e2e2e2"},
                    }
                }
                ```
        Returns:
            The Mermaid syntax string.
        r   )draw_mermaidN)	r*   r+   r   r   r   r   node_stylesr   r   )&langchain_core.runnables.graph_mermaidr   r   r   r   r*   r+   rA   )
r   r   r   r   r   r   r   r   r   r   s
             r   r   zGraph.draw_mermaid?  sn    J 	H		%%'
OO%	++++(2z}}&/illT###11

 
	
r    white
   r   g      ?)r   r   r   r   draw_methodbackground_colorpaddingmax_retriesretry_delayr   base_urlproxiesc               Z    ddl m} | j                  ||||
      } ||||||||	||	      S )a  Draw the graph as a PNG image using Mermaid.

        Args:
            curve_style: The style of the edges.
            node_colors: The colors of the nodes.
            wrap_label_n_words: The number of words to wrap the node labels at.
            output_file_path: The path to save the image to. If `None`, the image
                is not saved.
            draw_method: The method to use to draw the graph.
            background_color: The color of the background.
            padding: The padding around the graph.
            max_retries: The maximum number of retries (`MermaidDrawMethod.API`).
            retry_delay: The delay between retries (`MermaidDrawMethod.API`).
            frontmatter_config: Mermaid frontmatter config.
                Can be used to customize theme and styles. Will be converted to YAML and
                added to the beginning of the mermaid graph.

                See more here: https://mermaid.js.org/config/configuration.html.

                Example config:

                ```python
                {
                    "config": {
                        "theme": "neutral",
                        "look": "handDrawn",
                        "themeVariables": {"primaryColor": "#e2e2e2"},
                    }
                }
                ```
            base_url: The base URL of the Mermaid server for rendering via API.
            proxies: HTTP/HTTPS proxies for requests (e.g. `{"http": "http://127.0.0.1:7890"}`).

        Returns:
            The PNG image as bytes.
        r   )draw_mermaid_png)r   r   r   r   )	mermaid_syntaxr   r   r   r   r   r   r   r   )r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   s                  r   r   zGraph.draw_mermaid_pngv  sU    j	
 **##11	 + 
  )-#-##

 
	
r    )rz   r8   r"   zdict[str, list[dict[str, Any]]])r"   r8   r!   r   )r7   rC   rA   r>   rE   rD   r"   r@   )r   r@   r"   None)NF)
r4   r@   r5   r@   r7   r6   r9   r8   r"   r3   )r   r   r   r#   r"   ztuple[Node | None, Node | None])r"   r   )r"   Node | None)r"   r   )NN)r   r#   r   r>   r   LabelsDict | Noner"   r   )r   r   r   r>   r   r   r"   bytes)NNN)r   r>   r   r>   r   r   r"   zbytes | None)r   r8   r   rN   r   NodeStyles | Noner   intr   rD   r"   r#   )r   rN   r   r   r   r   r   r>   r   rm   r   r#   r   r   r   r   r   floatr   rD   r   r>   r   rK   r"   r   ) r$   r%   r&   r'   r   dictr*   r-   r   r+   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rN   r`   r   rm   rq   r   r   r    r   r   r      s    #48E?8d3E:3.3 #
J  
 +/3 
 ( 
8	
 &*!  #	
  
D .0$
$
'*$
	($
L!
F
!
 )(
!   $$(	  "	
 
    $$(	  "	
 
  (,#$(	 '$ '  ' "	 '
 
 'J !","3"3)-"#485
 5
  	5

 '5
  5
 25
 
5
t #-"3"3)-"#'+):)>)> ' 48#)-I
  I
 '	I

  I
 %I
 'I
 I
 I
 I
 I
 2I
 I
 'I
 
I
r    r   c                *   | j                   D ch c]  }|j                  |vs|j                   }}| j                  j	                         D cg c]   }|j
                  |vr|j
                  |vr|" }}t        |      dk(  r|d   S dS c c}w c c}w )zFind the single node that is not a target of any edge.

    Exclude nodes/sources with IDs in the exclude list.

    If there is no such node, or there are multiple, return `None`.

    When drawing the graph, this node would be the origin.
    r   r   N)r+   r4   r5   r*   r   rA   r   )r   r   r   targetsr   founds         r   r   r          (-{{Qtdkk6Pt{{QGQ KK&&(77'!dggW&< 	E 
 5zQ580D0 R   BB%Bc                *   | j                   D ch c]  }|j                  |vs|j                   }}| j                  j	                         D cg c]   }|j
                  |vr|j
                  |vr|" }}t        |      dk(  r|d   S dS c c}w c c}w )zFind the single node that is not a source of any edge.

    Exclude nodes/targets with IDs in the exclude list.

    If there is no such node, or there are multiple, return `None`.

    When drawing the graph, this node would be the destination.
    r   r   N)r+   r5   r4   r*   r   rA   r   )r   r   r   sourcesr   r  s         r   r   r     r  r  )r0   r#   r"   r8   )rA   r#   r7   rC   r"   r#   )r   r@   rz   r8   r"   zdict[str, str | dict[str, Any]])r   )r   r   r   zSequence[str]r"   r   )1r'   
__future__r   r   collectionsr   dataclassesr   r   enumr   typingr   r	   r
   r   r   r   uuidr   r    langchain_core.load.serializabler   langchain_core.runnables.baser   r   langchain_core.utils.pydanticr   r   collections.abcr   r   pydanticr   RunnableTyper   r)   r1   r3   r@   rI   rN   rh   rm   rx   r   r   r   r   r   r    r   <module>r     s    "  # (    D H V2"F.H .  
: 
< 
:  
FAZ A "   3 3MM
/M 	M( ).4
4!%4$4n B
 B
 B
J1$1r    