
    i!                         d Z ddlmZmZmZmZmZ ddlmZm	Z	 ddl
mZ e G d d             Z G d d      Z G d	 d
      Zy)z3Cycle detection and management for workflow graphs.    )DictListSetOptionalAny)	dataclassfield)Nodec                   d   e Zd ZU dZeed<   ee   ed<   ee   ed<   eeee	f      ed<   dZ
eed<   dZee   ed	<   d
Zeed<    ee      Zeee	f   ed<   dZee   ed<   dZee   ed<   dZeed<   deddfdZdeddfdZdeee	f   ddfdZddZdefdZdefdZddZdedefdZdedefdZy)	CycleInfoz9Information about a detected cycle in the workflow graph.cycle_idnodesentry_nodes
exit_edgesr   iteration_countNmax_iterationsF	is_active)default_factoryexecution_stateinitial_nodeconfigured_entry_noded   max_iterations_defaultnode_idreturnc                 :    | j                   j                  |       y)zAdd a node to the cycle.N)r   addselfr   s     C/Users/bowang/.openclaw/workspace/ChatDev/workflow/cycle_manager.pyadd_nodezCycleInfo.add_node   s    

w    c                 :    | j                   j                  |       y)zAdd an entry node to the cycle.N)r   r   r   s     r    add_entry_nodezCycleInfo.add_entry_node   s    W%r"   edge_configc                 :    | j                   j                  |       y)zAdd an exit edge configuration.N)r   append)r   r%   s     r    add_exit_edgezCycleInfo.add_exit_edge!   s    {+r"   c                 .    | xj                   dz  c_         y)z Increment the iteration counter.   Nr   r   s    r    increment_iterationzCycleInfo.increment_iteration%   s    !r"   c                 h    | j                   | j                   n| j                  }| j                  |k  S )z-Check if the cycle should continue executing.)r   r   r   )r   max_iters     r    is_within_iteration_limitz#CycleInfo.is_within_iteration_limit)   s1    *.*=*=*I4&&tOjOj##h..r"   c                 J    | j                   | j                   S | j                  S )z%Get the effective maximum iterations.)r   r   r,   s    r    get_max_iterationszCycleInfo.get_max_iterations.   s$    &*&9&9&Et""f4KfKffr"   c                     d| _         y)zReset the iteration counter.r   Nr+   r,   s    r    reset_iteration_countzCycleInfo.reset_iteration_count2   s
     r"   c                     || j                   v S )z&Check if a node is part of this cycle.)r   r   s     r    is_node_in_cyclezCycleInfo.is_node_in_cycle6   s    $**$$r"   c                     || j                   v S )z0Check if a node is an entry node for this cycle.)r   r   s     r    is_entry_nodezCycleInfo.is_entry_node:   s    $****r"   )r   N)__name__
__module____qualname____doc__str__annotations__r   r   r   r   r   intr   r   r   boolr	   dictr   r   r   r   r!   r$   r(   r-   r0   r2   r4   r6   r8    r"   r    r   r      s   CMs8OST#s(^$$OS$(NHSM(It&+D&AOT#s(^A #'L(3-&+/8C=/"%C%     &c &d &,c3h ,D ,"/4 /
gC g!% % %+S +T +r"   r   c                   x    e Zd ZdZd Zdeeef   dee	e      fdZ
dedeeef   defdZdedeeef   ddfd	Zy)
CycleDetectorz;Detects cycles in workflow graphs using Tarjan's algorithm.c                 h    d| _         i | _        i | _        g | _        t	               | _        g | _        y )Nr   )index_counterindexlow_linkstackseton_stackcyclesr,   s    r    __init__zCycleDetector.__init__B   s/    %'
(* "
"%%&(r"   r   r   c                 |   | j                   j                          d| _        | j                  j                          | j                  j                          | j
                  j                          | j                  j                          |D ]#  }|| j                  vs| j                  ||       % | j                   S )zWDetect all cycles in the graph using Tarjan's strongly connected components' algorithm.r   )rL   clearrF   rG   rH   rI   rK   _strong_connect)r   r   r   s      r    detect_cycleszCycleDetector.detect_cyclesJ   s    



Gdjj($$We4 
 {{r"   r   c                 p    |j                        }|syt        fd|j                         D              S )z Check if a node has a self-loop.Fc              3   P   K   | ]  }|j                   j                  k(    y wN)targetid).0	edge_linkr   s     r    	<genexpr>z/CycleDetector._has_self_loop.<locals>.<genexpr>_   s%     ^C]i9##&&'1C]s   #&)getanyiter_outgoing_edges)r   r   r   nodes    `  r    _has_self_loopzCycleDetector._has_self_loopZ   s1    yy!^4C[C[C]^^^r"   Nc                    | j                   | j                  |<   | j                   | j                  |<   | xj                   dz  c_         | j                  j	                  |       | j
                  j                  |       |j                  |      }|sy|j                         D ]  }|j                  j                  }|| j                  vrF| j                  ||       t        | j                  |   | j                  |         | j                  |<   m|| j
                  v s|t        | j                  |   | j                  |         | j                  |<    | j                  |   | j                  |   k(  rt               }	 | j                  j                         }| j
                  j                  |       |j                  |       ||k(  rnMt!        |      dkD  s| j#                  ||      r| j$                  j	                  |       yyy)z%Recursive part of Tarjan's algorithm.r*   N)rF   rG   rH   rI   r'   rK   r   rZ   r\   rU   rV   rP   minrJ   popremovelenr^   rL   )r   r   r   r]   rX   successor_idcyclews           r    rP   zCycleDetector._strong_connecta   s   "00

7!%!3!3ga

'"'"yy! 113I$++..L4::-$$\59),T]]7-CT]]S_E`)ag&.),T]]7-CTZZP\E])^g& 4 ==!TZZ%88EEJJNN$$$Q'		!<  5zA~!4!4We!D""5) "E 9r"   )r9   r:   r;   r<   rM   r   r=   r
   r   r   rQ   r@   r^   rP   rB   r"   r    rD   rD   ?   su    E)4T	? tCH~  _c _$sDy/ _d _!*s !*4T	? !*t !*r"   rD   c                   ~    e Zd ZdZd Zdeee      deee	f   ddfdZ
dedeee	f   ddfd	Zd
eddfdZd
eddfdZy)CycleManagerz2Manages execution of cycles in the workflow graph.c                 >    i | _         i | _        t               | _        y rT   )rL   node_to_cyclerJ   active_cyclesr,   s    r    rM   zCycleManager.__init__   s    ,.-/'*ur"   rL   r   r   Nc                 P   | j                   j                          | j                  j                          t        |      D ]d  \  }}d| d| }t	        |t        |      t               g       }| j                  ||       || j                   |<   |D ]  }|| j                  |<    f y)z2Initialize cycle information from detected cycles.cycle__)r   r   r   r   N)rL   rO   rj   	enumerater   rJ   _analyze_cycle_structure)r   rL   r   icycle_nodesr   
cycle_infor   s           r    initialize_cycleszCycleManager.initialize_cycles   s      "'/NA{s!K=1H"!+&E	J ))*e<$.DKK! '.6""7+ ' 0r"   re   c                 8  	 |j                   dt        dt        dt        f	fd}D ]M  	|j	                  	      }|s|j
                  D ](  } |||j                        s|j                  	        M O D ]  	|j	                  	      }|s|j                         D ]s  }|j                  j                  vs|j                  s)	|j                  j                  |j                  |j                  |j                  d}|j                  |       u  y)z;Analyze cycle structure to find entry nodes and exit edges._predecessor_predecessor_idr   c                     |v ry| j                         D ]+  }|j                  j                  k(  s|j                  r y y y)NFT)r\   rU   rV   trigger)rv   rw   
_edge_linkrr   r   s      r    judge_entry_predecessorzFCycleManager._analyze_cycle_structure.<locals>.judge_entry_predecessor   sJ    +-*>>@
$$''72!))#$ A r"   )fromto	conditionry   configN)r   r
   r=   r@   rZ   predecessorsrV   r$   r\   rU   ry   r~   r   r(   )
r   re   r   r{   r]   predecessorrX   	exit_edgerr   r   s
           @@r    rp   z%CycleManager._analyze_cycle_structure   s	   kk		$ 		 		QU 		 #G99W%D#00*;G((1  1 # #G99W%D!557	##&&k9i>O>O ''..11%.%8%8#,#4#4"+"2"2!I ''	2 8 #r"   r   c                     || j                   v r0d| j                   |   _        | j                  j                  |       yy)zActivate a cycle for execution.TN)rL   r   rk   r   r   r   s     r    activate_cyclezCycleManager.activate_cycle   s8    t{{".2DKK!+""8, #r"   c                     || j                   v rDd| j                   |   _        d| j                   |   _        | j                  j	                  |       yy)zDeactivate a cycle.Fr   N)rL   r   r   rk   discardr   s     r    deactivate_cyclezCycleManager.deactivate_cycle   sI    t{{".3DKK!+45DKK!1&&x0 #r"   )r9   r:   r;   r<   rM   r   r   r=   r   r
   rt   r   rp   r   r   rB   r"   r    rh   rh      s    <-
7SX 7tCI 7SW 7.)3i )3S$Y )3TX )3V-s -t -1 1 1r"   rh   N)r<   typingr   r   r   r   r   dataclassesr   r	   entity.configsr
   r   rD   rh   rB   r"   r    <module>r      sG    9 1 1 (  3+ 3+ 3+lC* C*LU1 U1r"   