
    iK:                         d Z ddlmZmZmZmZ ddlZddlmZ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d	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ  G d d      Zy)z@Graph management and construction utilities for workflow graphs.    )DictListSetAnyN)ConfigErrorSubgraphConfig)EdgeConditionConfig)extend_path)SubgraphFileConfigSubgraphInlineConfig)CycleManager)load_subgraph_config)GraphTopologyBuilder)build_env_var_map)resolve_mapping_with_varsGraphContextc                       e Zd ZdZddZddZddZdeddfdZdd	Z	de
ee      fd
Zde
e
e      fdZde
ee      de
e
e      fdZddZdeeef   fdZddZddZdefdZddZy)GraphManagerzOManages graph construction, cycle detection, and execution order determination.returnNc                 0    || _         t               | _        y)z5Initialize GraphManager with a GraphContext instance.N)graphr   cycle_manager)selfr   s     C/Users/bowang/.openclaw/workspace/ChatDev/workflow/graph_manager.py__init__zGraphManager.__init__   s    
)^    c                     | j                          | j                          | j                          | j                          | j	                          y)zFBuild the complete graph structure including nodes, edges, and layers.N)_instantiate_nodes_initiate_edges_determine_start_nodes_warn_on_untriggerable_nodes_build_topology_and_metadatar   s    r   build_graph_structurez"GraphManager.build_graph_structure   s>    !##%))+))+r   c                    | j                   j                  j                          | j                   j                  j	                         D ]  }|j
                  }|| j                   j                  v rt        d|        6t        j                  |      }g |_	        g |_
        g |_        t        | j                   j                        |_        || j                   j                  |<   |j                  dk(  s| j                  |        y)z)Instantiate all nodes from configuration.zDuplicated node id detected: subgraphN)r   nodesclearconfigget_node_definitionsidprintcopydeepcopypredecessors
successors_outgoing_edgesdictvars	node_type_build_subgraph)r   node_defnode_idnode_instances       r   r   zGraphManager._instantiate_nodes"   s    

 

))>>@HkkG$*****5gY?@ MM(3M)+M&')M$,.M)!%djjoo!6M(5DJJW%&&*4$$W- Ar   r8   c                    ddl m} ddlm} | j                  j
                  |   j                  t              }|sy| j                  j                  j                         }i }|j                  dk(  rS|j                  t              }|st        d| d|j                        t        j                  |j                        }|}	nv|j                  dk(  rM|j                  t               }
|
st        d	| d|j                        t#        |
j$                  |
      \  }}}	nt        d| d|j                        t'        | j                  j                  j(                        }|j+                  |       t-        |t/               |d| d       |j1                  dd      #| j                  j2                  j4                  |d<   |j7                  || j                  j8                   d| d| j                  j                  j:                  |	|      } ||      }t=        |      }|j?                          || j                  j@                  |<   y)z'Build a subgraph for the given node ID.r   )GraphConfigr   Nr*   z0Inline subgraph configuration missing for node ''filez.File subgraph configuration missing for node ')parent_sourcez,Unsupported subgraph configuration on node 'z	subgraph[])
env_lookupvars_mappath	log_level_	_subgraph)r*   nameoutput_rootsource_pathr4   )r*   )!entity.graph_configr;   workflow.graph_contextr   r   r(   	as_configr   r*   get_source_pathtyper   r   rB   r.   r/   r   r   	file_pathr3   r4   updater   r   getrC   value	from_dictrF   rG   r   r%   	subgraphs)r   r8   r;   r   subgraph_config_datar>   subgraph_vars
inline_cfgconfig_payloadrH   file_cfgcombined_varssubgraph_configr'   subgraph_managers                  r   r6   zGraphManager._build_subgraph4   s,   37#zz//8BB>R#

))99;(*$$0-778LMJ!FwiqQ(--  "]]:+;+;<N'K!&&&0+556HIH!DWIQO(--  :N""+:6NM;
 >wiqI$)) 
 TZZ..334]+!(*"WIQ'		
 k408*.***>*>*D*DN;'%//!JJOO$AgYi8

))55# 0 
  7'1..0(0

W%r   c                    | j                   j                  r\t        d       g | j                   _        t	        | j                   j
                  j                               }|g| j                   _        yg | j                   _        | j                   j                  j                         D ]7  }|j                  }|j                  }|| j                   j
                  vs|| j                   j
                  vrt        d| d|        ^|j                  }|+t        j                  dt        |j                   d            }|j#                         }|j$                  }|r|j#                         nd}|j&                  }	|j(                  |||j+                         |j,                  |j.                  |j0                  |j2                  |j4                  |||r|j,                  nd|	d}
| j                   j
                  |   j7                  | j                   j
                  |   |
       | j                   j
                  |   j9                  | j                   j
                  |          | j                   j                  j;                  |||j(                  ||j,                  |j.                  |j0                  |j2                  |j4                  ||r|j,                  nd|	dud	       : | j=                         }t?        |      d
kD  | j                   _         | j                   j@                  r9t        dt?        |       d       | jC                  |      | j                   _        y| jE                         | j                   _        y)z?Initialize edges and determine layers or cycle execution order.z<Majority voting mode detected - skipping edge initializationNzEdge references unknown node: z->true	condition)rB   )triggerr^   condition_configcondition_labelcondition_type
carry_datakeep_messageclear_contextclear_kept_contextprocess_configprocessprocess_typedynamic_config)fromtor_   r^   rb   rc   rd   re   rf   rh   ri   dynamicr   z	Detected z  cycle(s) in the workflow graph.)#r   is_majority_votingr-   edgeslistr(   keyslayersr*   get_edge_definitionssourcetargetr^   r	   rR   r
   rB   to_external_valuerh   rm   r_   display_labelrM   rc   rd   re   rf   add_successoradd_predecessorappend_detect_cycleslen
has_cycles_build_cycle_execution_order_build_dag_layers)r   all_node_idsedge_configsrcdstr`   condition_valuerg   process_valuerj   payloadcycless               r   r    zGraphManager._initiate_edgesv   s    ::((PQ!DJJ  

 0 0 5 5 78L!-DJJ

::,,AACK$$C$$C$*****c9I9I.I6se2cUCD*44'#6#@#@kZeZjZjlwNx#y .@@BO(00NBPN<<>VZM(00N&..,$4#3#A#A#C"2"7"7)44 + 8 8!,!:!:&1&D&D"0(7E 3 34"0G JJS!//

0@0@0EwOJJS!11$**2B2B32GHJJ##&..,"2"7"7)44 + 8 8!,!:!:&1&D&D(7E 3 34)5% ? D^ $$& #Fa

::  Ic&k]*JKL $ A A& IDJJ $ 6 6 8DJJr   c                 T    t        j                  | j                  j                        S )z6Detect cycles in the graph using GraphTopologyBuilder.)r   detect_cyclesr   r(   r$   s    r   r{   zGraphManager._detect_cycles   s    #11$**2B2BCCr   c           	      Z   t        j                  | j                  j                        }|D cg c]  }|D cg c]  }|d   	 c} }}}t	        d|        t        t        d |D                    t        | j                  j                        k7  rt	        d       |S c c}w c c}}w )zIBuild layers for DAG (Directed Acyclic Graph) using GraphTopologyBuilder.r8   zlayers: c              3   .   K   | ]  }|D ]  }|   y w)N ).0layerr8   s      r   	<genexpr>z1GraphManager._build_dag_layers.<locals>.<genexpr>   s     Due77e7s   z:Detected a cycle in the workflow graph; a DAG is required.)r   build_dag_layersr   r(   r-   r|   set)r   layers_with_itemsr   itemrr   s        r   r   zGraphManager._build_dag_layers   s    0AA$**BRBRS
 +
* *//T)_/* 	 

 	!"sDDDETZZM]M]I^^NO 0
s   	B'B"B'"B'r   c                    | j                   j                  || j                  j                         t	        j
                  | j                  j                  | j                  j                  |      }t	        j                  ||      }|D ]W  }|D ]P  }|d   dk(  s|d   }| j                   j                  |   }t        |j                        |d<   |j                  |d<   R Y || j                  _        dggS )zcBuild execution order for graphs with cycles using super-node abstraction and GraphTopologyBuilder.rM   cyclecycle_identry_nodes
exit_edges__CYCLE_AWARE__)r   initialize_cyclesr   r(   r   create_super_node_graphro   topological_sort_super_nodesr   rp   r   r   cycle_execution_order)r   r   super_node_graphexecution_orderr   r   r   
cycle_infos           r   r~   z)GraphManager._build_cycle_execution_order   s     	,,VTZZ5E5EF 0GGJJJJ
 /KK
 %E<7*#J/H!%!3!3!:!:8!DJ*.z/E/E*FD')3)>)>D&  % ,;

( ##$$r   c                 X   | j                   j                  D cg c]  }|D ]  }|  c}}| j                   _        | j                   j                  r"t        | j                   j                        dz
  nd| j                   _        | j                         | j                   _        yc c}}w )z*Build topology and metadata for the graph.   r   N)r   rr   topologyr|   depth_build_metadatametadata)r   r   r8   s      r   r#   z)GraphManager._build_topology_and_metadata   s}    48JJ4E4E[4E5UZ'wUZw4E[

9=9J9J3tzz001A5PQ

"224

 \s   B&c           	         | j                   j                  j                  }i }| j                   j                  j	                         D ]X  \  }}|j
                  |j                  |j                  |j                  |j                  |j                  |j                  d||<   Z |j                  t        | j                   j                        t        | j                   j                        t        | j                   j                         |j"                  || j                   j$                  | j                   j&                  dS )zBuild metadata for the graph.)rM   description
model_nameroletoolsmemoriesparams)	design_id
node_count
edge_countstartendcatalogr   rr   )r   r*   
definitionr(   itemsr5   r   r   r   r   r   r   r,   r|   ro   rp   start_nodes	end_nodesr   rr   )r   	graph_defr   r8   nodes        r   r   zGraphManager._build_metadata   s    JJ%%00	"$!ZZ--335MGT#//"oo		 MM++ GG 6 #djj../djj../$**001&&

++jj''	
 		
r   c                    | j                   j                  j                  }t        |j                        }t        |      }|rt        |j                  d      }|D ]  }|| j                   j                  vrt        d| d|      | j                  j                  j                  |      }|S| j                  j                  j                  |      }|t        d| d|      |j                  r,|j                  |k7  rt        d| d|j                   d|      ||_         |s t        d	t        |j                  d            || j                   _        || j                   _        y)
z;Determine the effective set of start nodes (explicit only).r   zstart node 'z' not defined in nodesNz#cycle data missing for start node 'r<   zcycle 'z' already has start node 'zUnable to determine a start node for this graph. Configure at least one Start Node via Configure Graph > Advanced Settings > Start Node > input node ID.)r   r*   r   rp   r   r   r
   rB   r(   r   r   node_to_cyclerP   r   configured_entry_nodeexplicit_start_nodes)r   r   explicit_orderedexplicit_set
cycle_pathr8   r   r   s           r   r!   z#GraphManager._determine_start_nodes  st   ZZ&&11

 6 67+, $Z__g>J+$**"2"22%&wi/EF" 
  --;;??H#!//66::8D
%%=gYaH" 
 33
8X8X\c8c%!(+EjFfFfEgghi" 
 4;
0/ ,2   kJOOW5 
 "2

*:

'r   c                    t        | j                  j                  xs g       }| j                  j                  j	                         D ]t  \  }}|j
                  s||v rd}|j
                  D ]:  }|j                         D ]!  }|j                  |u s|j                  sd} n |s: n |rft        d| d       v y)zDEmit warnings for nodes that cannot be triggered by any predecessor.FTzWarning: node 'z;' has no triggerable incoming edges and will never execute.N)
r   r   r   r(   r   r0   iter_outgoing_edgesru   r_   r-   )r   r   r8   r   has_triggerable_edgepredecessor	edge_links          r   r"   z)GraphManager._warn_on_untriggerable_nodesA  s    $**006B7!ZZ--335MGT$$+%#( #00!,!@!@!BI ''4/I4E4E/3, "C (  1 (%gY.ij! 6r   c                     | j                   S )zGet the cycle manager instance.)r   r$   s    r   get_cycle_managerzGraphManager.get_cycle_managerX  s    !!!r   c                 $    | j                          y)z?Build graph structure only (no memory/thinking initialization).N)r%   r$   s    r   build_graphzGraphManager.build_graph\  s    ""$r   )r   r   r   N)r   N)__name__
__module____qualname____doc__r   r%   r   strr6   r    r   r   r{   r   r~   r#   r   r   r   r!   r"   r   r   r   r   r   r   r   r      s    Y,
,.$@1s @1t @1DD9LDSX D4S	? "%4C> %d4PS9o %@5
c3h 
4.;`."< "%r   r   )r   typingr   r   r   r   r.   entity.configsr   r   "entity.configs.edge.edge_conditionr	   entity.configs.baser
   entity.configs.node.subgraphr   r   workflow.cycle_managerr   workflow.subgraph_loaderr   workflow.topology_builderr   utils.env_loaderr   utils.vars_resolverr   rJ   r   r   r   r   r   <module>r      s;    F ' '  6 B + Q / 9 : . 9 /L% L%r   