
    i                     \    d Z ddlmZ ddlmZmZmZ ddlZddlmZ ddl	m
Z
  G d d      Zy)	zmRuntime context for workflow graphs.

This module stores execution-time state and business logic for graphs.
    )datetime)AnyDictListN)Node)GraphConfigc                       e Zd ZdZdeddfdZedefd       Zed        Z	ede
eef   fd       Zej                  d	e
eef   ddfd
       Zde
eef   ddfdZdefdZdee   fdZdee   fdZde
eef   fdZy)GraphContexta	  Runtime context for a workflow graph (state + business logic).
    
    Differences from ``GraphConfig``:
    - ``GraphConfig`` is immutable configuration data.
    - ``GraphContext`` is mutable runtime state with dynamic execution data.
    
    Attributes:
        config: Graph configuration
        nodes: Mapping of ``node_id`` to ``Node``
        edges: List of edges
        layers: Topological layer layout
        outputs: Node outputs captured during execution
        topology: Topological ordering list
        subgraphs: Mapping of ``node_id`` to nested ``GraphContext``
        has_cycles: Whether the graph contains cycles
        cycle_execution_order: Execution order for cycles
        directory: Output directory for artifacts
        depth: Graph depth
    configreturnNc                 n   || _         t        |j                        | _        i | _        g | _        g | _        g | _        d| _        g | _        g | _	        i | _
        i | _        d| _        g | _        t        j                         j!                  d      }t#        |j$                  j'                  d            }|sd|j(                  v r|j*                  |j(                  z  | _        n#|j*                  |j(                   d| z  | _        | j,                  j/                  dd       |j0                  | _        y	)
zeInitialize the graph context.
        
        Args:
            config: Graph configuration
        r   Fz%Y%m%d%H%M%Sfixed_output_dirsession__T)parentsexist_okN)r   dictvarsnodesedgeslayerstopologydepthstart_nodesexplicit_start_nodesoutputs	subgraphs
has_cyclescycle_execution_orderr   nowstrftimeboolmetadatagetnameoutput_root	directorymkdiris_majority_voting)selfr   	timestampr   s       C/Users/bowang/.openclaw/workspace/ChatDev/workflow/graph_context.py__init__zGraphContext.__init__$   s    $($5	 ')
+-
')#%
&(/1! (*46 !&;=" LLN++N;	 3 34F GHzV[[8#//&++=DN#//V[[M9+2NNDNTD9(.(A(A    c                 .    | j                   j                  S )zReturn the project name.)r   r%   r*   s    r,   r%   zGraphContext.nameI   s     {{r.   c                 .    | j                   j                  S )z Return the configured log level.)r   	log_levelr0   s    r,   r2   zGraphContext.log_levelN   s     {{$$$r.   c                 .    | j                   j                  S )zReturn graph metadata.r   r#   r0   s    r,   r#   zGraphContext.metadataS   s     {{###r.   valuec                 &    || j                   _        y)zSet graph metadata.Nr4   )r*   r5   s     r,   r#   zGraphContext.metadataX   s      %r.   r   c                 <   || _         | j                  dz  }| j                   r?|j                  dd      5 }t        j                  | j                   |dd       ddd       | j
                  j                  | j
                  j                         | j
                  j                         | j
                  j                  d	}| j                  d
z  }|j                  dd      5 }t        j                  ||dd       ddd       y# 1 sw Y   xY w# 1 sw Y   yxY w)zoPersist execution results to disk.
        
        Args:
            outputs: Mapping of node outputs
        znode_outputs.yamlwzutf-8)encodingTF)allow_unicode	sort_keysN)projectorganizationdesign_pathr#   zworkflow_summary.yaml)
r   r'   openyamldumpr   r%   get_organizationget_source_pathr#   )r*   r   outputs_pathhandlesummarysummary_paths         r,   recordzGraphContext.record]   s      ~~(;;<<""3"9V		$,,deT :
 {{'' KK88:;;668,,	
 ~~(??sW5IIgvTUK 65 :9 65s   $D#DDDc                     | j                   sy| j                  j                         D cg c]  \  }}|j                  r| }}}dt	        | j                          dt	        |       dS c c}}w )ziBuild the final completion string.
        
        Returns:
            Completion message text
        z"Workflow finished with no outputs.zWorkflow finished with z node outputs (z terminal nodes).)r   r   items
successorslen)r*   node_idnode
sink_nodess       r,   final_messagezGraphContext.final_messagew   sn     ||737::3C3C3E]3E-'4T__g3E
]%c$,,&7%8 9Z!!24	
 ^s   A, A,c                 v    | j                   j                         D cg c]  }|j                  r| c}S c c}w )z1Return all leaf nodes (nodes without successors).)r   valuesrK   r*   rN   s     r,   get_sink_nodeszGraphContext.get_sink_nodes   s/    !%!2!2!4L!4DOO!4LLL   66c                 v    | j                   j                         D cg c]  }|j                  r| c}S c c}w )z5Return all source nodes (nodes without predecessors).)r   rR   predecessorsrS   s     r,   get_source_nodeszGraphContext.get_source_nodes   s1    !%!2!2!4N!4D<M<M!4NNNrU   c                    | j                   j                         | j                  j                         D ci c]  \  }}||j                          c}}t	        | j
                        t	        | j                        t	        | j                        | j                  | j                  t	        | j                        t	        | j                        t        | j                        d
S c c}}w )z*Convert the graph context to a dictionary.)
r   r   r   r   r   r   r   r   r   r   )r   to_dictr   rJ   listr   r   r   r   r   r   r   r   r   )r*   rM   rN   s      r,   rZ   zGraphContext.to_dict   s     kk))+CG::CSCSCUVCU-'4gt||~-CUV$**%4;;'T]]+ZZ// 0 01$()B)B$CDLL)
 	
Vs   C&)__name__
__module____qualname____doc__r   r-   propertystrr%   r2   r   r   r#   setterrH   rP   r   r   rT   rX   rZ    r.   r,   r
   r
      s    (#B{ #Bt #BJ  c     % % $$sCx. $ $ __%d38n % % %Ld38n L L4
s 
MT
 MO$t* O
c3h 
r.   r
   )r_   r   typingr   r   r   r@   entity.configsr   entity.graph_configr   r
   rc   r.   r,   <module>rg      s*   
  " "   +L
 L
r.   