
    D_i6Z                       S r SSKJr  SSKrSSKJr  SSKJrJr  SSK	J
r
  SSKJrJrJrJrJrJr  SSKJrJr  SS	KJr  SS
KJrJr  SSKJrJr  \(       a  SSKJrJr  SSK J!r!  SSKJr"   " S S\5      r# " S S\5      r$S(S jr% " S S\5      r& " S S\5      r' " S S\5      r( " S S\
5      r)\ " S S5      5       r* " S S\
5      r+      S)S  jr,S!S".     S*S# jjr-\ " S$ S%5      5       r.S+S,S& jjr/S+S,S' jjr0g)-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                  "    \ rS rSrSrSS jrSrg)Stringifiable   z7Protocol for objects that can be converted to a string.c                    g)zConvert the object to a string.N selfs    X/home/james-whalen/.local/lib/python3.13/site-packages/langchain_core/runnables/graph.py__str__Stringifiable.__str__"   s        r   Nreturnstr)__name__
__module____qualname____firstlineno____doc__r    __static_attributes__r   r"   r   r   r      s
    A.r"   r   c                  0    \ rS rSr% SrS\S'    S\S'   Srg)
LabelsDict&   z4Dictionary of labels for nodes and edges in a graph.zdict[str, str]nodesedgesr   Nr&   r'   r(   r)   r*   __annotations__r+   r   r"   r   r-   r-   &   s    >r"   r-   c                <     [        U 5        g! [         a     gf = f)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_uuidr6   /   s'    U   s    
c                  f    \ rS rSr% SrS\S'    S\S'    SrS\S'    S	rS
\S'    SSS.SS jjrSr	g)Edge?   zEdge in a graph.r%   sourcetargetNStringifiable | NonedataFboolconditionalr:   r;   c                   [        U=(       d    U R                  U=(       d    U R                  U R                  U R                  S9$ )zReturn 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.
r:   r;   r=   r?   )r8   r:   r;   r=   r?   )r   r:   r;   s      r   copy	Edge.copyK   s9     (T[[(T[[((	
 	
r"   r   )r:   
str | Noner;   rE   r$   r8   )
r&   r'   r(   r)   r*   r2   r=   r?   rC   r+   r   r"   r   r8   r8   ?   s?    KK!%D
%2K*+/d 
 
r"   r8   c                  h    \ rS rSr% SrS\S'    S\S'    S\S'    S\S	'    S
S
S.     SS jjrSrg
)Node]   zNode in a graph.r%   idname%type[BaseModel] | RunnableType | Noner=   dict[str, Any] | NonemetadataNrI   rJ   c                   [        U=(       d    U R                  U=(       d    U R                  U R                  U R                  S9$ )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.
)rI   rJ   r=   rM   )rG   rI   rJ   r=   rM   )r   rI   rJ   s      r   rC   	Node.copyi   s6     }TWW"]]	
 	
r"   r   )rI   rE   rJ   rE   r$   rG   )r&   r'   r(   r)   r*   r2   rC   r+   r   r"   r   rG   rG   ]   sW    G,
I
//##*
 	
 
 	

 

 
r"   rG   c                  0    \ rS rSr% SrS\S'    S\S'   Srg)	Branch   zBranch in a graph.zCallable[..., str]	conditiondict[str, str] | Noneendsr   Nr1   r   r"   r   rR   rR      s    !!K
@r"   rR   c                  H    \ rS rSrSrSrSrSrSrSr	Sr
S	rS
rSrSrSrSrSrg)
CurveStyle   z5Enum for different curve styles supported by Mermaid.basisbumpXbumpYcardinal
catmullRomlinear	monotoneX	monotoneYnaturalstep	stepAfter
stepBeforer   N)r&   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"   r   rX   rX      sA    ?EFFHKFJJGDJKr"   rX   c                  D    \ rS rSr% SrSrS\S'   SrS\S'   SrS\S	'   S
r	g)
NodeStyles   zSchema 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lastr   N)
r&   r'   r(   r)   r*   ru   r2   rv   rw   r+   r   r"   r   rs   rs      s'     2GS1!E3!D#r"   rs   c                  "    \ rS rSrSrSr SrSrg)MermaidDrawMethod   z5Enum for different draw methods supported by Mermaid.	pyppeteerapir   N)r&   r'   r(   r)   r*   	PYPPETEERAPIr+   r   r"   r   ry   ry      s    ?I,
C2r"   ry   c                    [        U 5      (       a  Uc  U $ [        U[        5      (       a  UR                  5       OUR                  nUR                  S5      (       d  U$ US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      )r6   
isinstancer   get_namer&   
startswith)rI   r=   data_strs      r   node_data_strr      sT     2;;$,	",T8"<"<t}}$--H#..z::8LLr"   Fwith_schemasc               0   U R                   c  0 nGOh[        U R                   [        5      (       a@  SU R                   R                  5       [	        U R
                  U R                   5      S.S.nGO	[        U R                   [        5      (       a=  S[        U R                   5      S   [	        U R
                  U R                   5      S.S.nO[        R                  " U R                   5      (       ae  [        U R                   5      (       aK  U(       a   SU R                   R                  [        S9S.O"S[	        U R
                  U R                   5      S.nO#S[	        U R
                  U R                   5      S.nU R                  b  U R                  US'   U$ )	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.
runnablerN   )typer=   rI   schema)schema_generatorunknownrM   )r=   r   r   lc_idr   rI   r   r   inspectisclassr   model_json_schemar   rM   )noder   jsons      r   node_data_jsonr      sD    yy!	DII3	4	4iioo'%dggtyy9
 
DIIx	(	(-dii8>%dggtyy9
 
	#	#(=dii(H(H  !		33%: 4  !%dggtyy9 	 !$''4995
 }} ==ZKr"   c                  ^   \ rS rSr% Sr\" \S9rS\S'   \" \	S9r
S\S'   SS	.S*S
 jjrS+S jrS,S jr S-SS.       S.S jjjrS/S jr  S0         S1S jjrSS.     S2S jjrS3S jrS4S jrS4S jrS5S jrS5S jrS,S jrS5S jr\  S6       S7S jj5       r\  S6       S8S jj5       r   S9       S:S jjrS\R8                  SS SS!.           S;S" jjr\R8                  SS S\R>                  S#S$S%S&SSSS'.                         S<S( jjr S)r!g)=Graph   zGraph 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]r0   Fr   c          	     \   [        U R                  R                  5       5       VVs0 s H8  u  p#UR                  [	        UR                  5      (       a  UOUR                  _M:     nnn/ nU R
                   Hc  nXFR                     XFR                     S.nUR                  b  UR                  US'   UR                  (       a  SUS'   UR                  U5        Me     U R                  R                  5        Vs/ s H  nSXCR                     0[        X1S9EPM     snUS.$ s  snnf s  snf )zConvert 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@   r=   Tr?   rI   r   r/   r0   )	enumerater/   valuesrI   r6   r0   r:   r;   r=   r?   appendr   )r   r   ir   stable_node_idsr0   edge	edge_dicts           r   to_jsonGraph.to_json  s     %TZZ%6%6%89
9 GG'$''**Q79 	 
 ')JJD)++6)++6I yy$$(II	&!+/	-(LL# " !JJ--/
 0D /''2$TE 0 	
 		
!
"s   ?D#:#D)c                ,    [        U R                  5      $ )z'Return whether the graph has any nodes.)r>   r/   r   s    r   __bool__Graph.__bool__-  s    DJJr"   c                *    [        5       R                  $ )zVReturn a new unique node identifier.

It that can be used to add a node to the graph.
)r   hexr   s    r   next_idGraph.next_id1  s    
 w{{r"   N)rM   c          	         Ub   X R                   ;   a  SU S3n[        U5      eU=(       d    U R                  5       n[        XQU[	        XQ5      S9nX`R                   UR
                  '   U$ )a  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)rI   r=   rM   rJ   )r/   r4   r   rG   r   rI   )r   r=   rI   rM   msgid_r   s          r   add_nodeGraph.add_node8  sb    ( >bJJ.!"_5CS/!"DLLNs}S?WX"

477r"   c                    U R                   R                  UR                  5        U R                   Vs/ s H,  o!R                  UR                  UR
                  1;  d  M*  UPM.     snU l        gs  snf )zaRemove a node from the graph and all edges connected to it.

Args:
    node: The node to remove.
N)r/   poprI   r0   r:   r;   )r   r   r   s      r   remove_nodeGraph.remove_nodeT  sR     	

tww!ZZ
'T774;;:T+TDZ

 
s   )A0!A0c                N   UR                   U R                  ;  a  SUR                    S3n[        U5      eUR                   U R                  ;  a  SUR                    S3n[        U5      e[        UR                   UR                   X4S9nU R                  R                  U5        U$ )ad  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 rB   )rI   r/   r4   r8   r0   r   )r   r:   r;   r=   r?   r   r   s          r   add_edgeGraph.add_edge_  s    * 99DJJ& =9CS/!99DJJ& =9CS/!99VYYT
 	

$r"    )prefixc                 ^ [        S UR                  R                  5        5       5      (       a  SmSU4S jjnU R                  R                  UR                  R	                  5        VVs0 s H!  u  pEU" U5      UR                  U" U5      S9_M#     snn5        U R                  R                  UR                   Vs/ s H3  nUR                  U" UR                  5      U" UR                  5      S9PM5     sn5        UR                  5       UR                  5       pU(       a  UR                  U" UR                  5      S9OSU(       a   UR                  U" UR                  5      S94$ S4$ s  snnf s  snf )a  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  L   #    U  H  n[        UR                  5      v   M     g 7fN)r6   rI   ).0r   s     r   	<genexpr>Graph.extend.<locals>.<genexpr>  s     A,@Dwtww,@s   "$r   c                $   > T(       a  T SU  3$ U $ )N:r   )r   r   s    r   prefixedGraph.extend.<locals>.prefixed  s    (.fXQse$7C7r"   rI   r@   N)r   r%   r$   r%   )allr/   r   updateitemsrC   r0   extendr:   r;   
first_node	last_noderI   )	r   graphr   r   kvr   rv   rw   s	     `      r   r   Graph.extend  s?    AEKK,>,>,@AAAF	8 	

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

 "KK'D 		$++!6x?T	U'	
 &&(%//*;t16EJJ(588,J-D/3DII$''*I+
 	
9=
 	
 Rs   -(E1
 :E7c                  ^
 [        [        5      nU R                  R                  5        H*  nXR                     R                  UR                  5        M,     UR                  5        VVVVs0 s H6  u  p4[        U5        H!  u  pVU[        U5      S:X  a  UO	U SUS-    3_M#     M8     snnnnm
SU
4S jjn[        U R                  R                  5        VVs0 s H!  u  pU" U5      UR                  U" U5      S9_M#     snnU R                   V	s/ s H3  n	U	R                  U" U	R                  5      U" U	R                  5      S9PM5     sn	S9$ s  snnnnf s  snnf s  sn	f )zdReturn a new graph with all nodes re-identified.

Uses their unique, readable names where possible.
   _c                6   > TU    n[        U 5      (       a  U$ U $ r   )r6   )node_idlabelunique_labelss     r   _get_node_id Graph.reid.<locals>._get_node_id  s"    !'*EwNr"   r   r@   r   )r   r%   r$   r%   )r   listr/   r   rJ   r   rI   r   r   lenr   rC   r0   r:   r;   )r   node_name_to_idsr   	node_namenode_idsr   r   r   r   r   r   s             @r   reid
Graph.reid  sT   
 't,JJ%%'DYY'..tww7 (
 (8'='='?
'?#	'1
 #h-1"4YYKqQ:PP1 '?
	  "&!1!1!3!3IC S!499S0A9#BB!3 !JJ
 'D	 		'4'4   '
 	

s   .=E
(E
:E!
c                    [        U 5      $ )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   Graph.first_node  s     4  r"   c                    [        U 5      $ )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   Graph.last_node  s     $r"   c                    U R                  5       nU(       ar  [        XR                  /S9(       aX  [        U R                   Vs1 s H   o"R
                  UR                  :X  d  M  UiM"     sn5      S:X  a  U R                  U5        ggggs  snf )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   rI   r   r0   r:   r   )r   r   es      r   trim_first_nodeGraph.trim_first_node  so    
 __&
D==/:

H
1hh*--.GQ
HIQNZ( O ; H   B%Bc                    U R                  5       nU(       ar  [        XR                  /S9(       aX  [        U R                   Vs1 s H   o"R
                  UR                  :X  d  M  UiM"     sn5      S:X  a  U R                  U5        ggggs  snf )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   rI   r   r0   r;   r   )r   r   r   s      r   trim_last_nodeGraph.trim_last_node  so    
 NN$	4,,8

G
1hh),,.FQ
GHAMY' N 9 Gr   c                    SSK Jn  U" U R                  R                  5        Vs0 s H  o"R                  UR
                  _M     snU R                  5      $ s  snf )zKDraw the graph as an ASCII art string.

Returns:
    The ASCII art string.
r   )
draw_ascii)$langchain_core.runnables.graph_asciir   r/   r   rI   rJ   r0   )r   r   r   s      r   r   Graph.draw_ascii  sK     	D,0JJ,=,=,?@,?DWWdii,?@JJ
 	
@s    Ac                6    [        U R                  5       5        g)z'Print the graph as an ASCII art string.N)printr   r   s    r   print_asciiGraph.print_ascii	  s    doo r"   c                    g r   r   r   output_file_pathfontnamelabelss       r   draw_pngGraph.draw_png  s     r"   c                    g r   r   r   s       r   r   r     s     r"   c                    SSK Jn  U R                  R                  5        Vs0 s H  oUR                  UR
                  _M     nnU" U[        0 UEUb  US   O0 EUb  US   O0 S95      R                  X5      $ s  snf )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/   r0   r   )"langchain_core.runnables.graph_pngr   r/   r   rI   rJ   r-   draw)r   r   r   r   r   r   default_node_labelss          r   r   r     s    & 	A>Bjj>O>O>QR>Qdww		1>QR)*0*<vg" *0);fWo	
 $t
&		' Ss    A9T	   )with_stylescurve_stylenode_colorswrap_label_n_wordsfrontmatter_configc                   SSK Jn  U R                  5       nUR                  5       nUR	                  5       n	U" UR
                  UR                  U(       a  UR                  OSU	(       a  U	R                  OSUUUUUS9	$ )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/   r0   r   r   r  r  node_stylesr  r  )&langchain_core.runnables.graph_mermaidr
  r   r   r   r/   r0   rI   )
r   r  r  r  r  r  r
  r   r   r   s
             r   r
  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               N    SSK Jn  U R                  UUUU
S9nU" UUUUUUU	UUS9	$ )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  Graph.draw_mermaid_pngv  sU    j	
 **##11	 + 
  )-#-##

 
	
r"   )r0   )r   r>   r$   zdict[str, list[dict[str, Any]]])r$   r>   r#   r   )r=   rK   rI   rE   rM   rL   r$   rG   )r   rG   r$   None)NF)
r:   rG   r;   rG   r=   r<   r?   r>   r$   r8   )r   r   r   r%   r$   ztuple[Node | None, Node | None])r$   r   )r$   Node | None)r$   r  )NN)r   r%   r   rE   r   LabelsDict | Noner$   r  )r   r  r   rE   r   r  r$   bytes)NNN)r   rE   r   rE   r   r  r$   zbytes | None)r  r>   r  rX   r  NodeStyles | Noner  intr  rL   r$   r%   )r  rX   r  r  r  r   r   rE   r  ry   r  r%   r  r   r  r   r  floatr  rL   r  rE   r  rU   r$   r  )"r&   r'   r(   r)   r*   r   dictr/   r2   r   r0   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rX   rk   r
  ry   r~   r  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
 I
r"   r   c                L   U R                    Vs1 s H   o"R                  U;  d  M  UR                  iM"     nnU R                  R	                  5        Vs/ s H)  nUR
                  U;  d  M  UR
                  U;  d  M'  UPM+     nn[        U5      S:X  a  US   $ S$ s  snf s  snf )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)r0   r:   r;   r/   r   rI   r   )r   r   r   targetsr   founds         r   r   r          (-{{Q{tkk6P{t{{{GQ KK&&((D77'! 	&*ggW&< 	( 
 
 5zQ580D0 R   BBB!,B!>B!c                L   U R                    Vs1 s H   o"R                  U;  d  M  UR                  iM"     nnU R                  R	                  5        Vs/ s H)  nUR
                  U;  d  M  UR
                  U;  d  M'  UPM+     nn[        U5      S:X  a  US   $ S$ s  snf s  snf )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)r0   r;   r:   r/   r   rI   r   )r   r   r   sourcesr   r%  s         r   r   r     r&  r'  )r5   r%   r$   r>   )rI   r%   r=   rK   r$   r%   )r   rG   r   r>   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-   r6   r8   rG   rR   rX   rs   ry   r   r   r   r   r   r   r"   r   <module>r6     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"   