
    i                     L    d Z ddlmZmZmZmZ ddlmZ ddlm	Z	  G d d      Z
y)zGraph topology builder utility for cycle detection and topological sorting.

This module provides stateless utilities for building execution order of graphs,
supporting both global graphs and scoped subgraphs (e.g., within cycles).
    )DictListSetAny)Node)CycleDetectorc                   p   e Zd ZdZedeeef   dee	e      fd       Z
edeeef   deeeef      dee	e      deee	e   f   fd       Zedeee	e   f   dee	e      deeeeef         fd	       Zedeeef   deeeef      deeeeef         fd
       Zedeeef   deeeeef         fd       Zy)GraphTopologyBuildera]  
    Graph topology structure builder.

    Responsibilities:
    1. Detect cycles (based on CycleDetector)
    2. Build super-node graphs
    3. Perform topological sorting

    Features:
    - Stateless (pure static methods)
    - Can be used for both global graphs and local subgraphs
    - Does not depend on specific GraphContext instances
    nodesreturnc                 8    t               }|j                  |       S )z
        Detect cycles in the given node set.

        Args:
            nodes: Dictionary of nodes to analyze

        Returns:
            List of cycles, where each cycle is a set of node IDs
        )r   detect_cycles)r   detectors     F/Users/bowang/.openclaw/workspace/ChatDev/workflow/topology_builder.pyr   z"GraphTopologyBuilder.detect_cycles   s     !?%%e,,    edgescyclesc                 N   i }i }t        |      D ]#  \  }}d| }t               ||<   |D ]  }|||<   	 % | j                         D ]  }||vsd| }t               ||<   |||<     |D ]9  }	|	d   }
|	d   }|
| vs|| vr||
   }||   }||k7  s&||   j                  |       ; |S )ag  
        Create a super-node graph where each cycle is treated as a single node.

        Args:
            nodes: Node dictionary
            edges: Edge configuration list (only edges to consider)
            cycles: List of detected cycles

        Returns:
            Super-node dependency graph: {super_node_id: set(predecessor_super_node_ids)}
        super_cycle_node_fromto)	enumeratesetkeysadd)r   r   r   super_nodesnode_to_supericycle_nodessuper_node_idnode_idedge_config	from_nodeto_node
from_superto_supers                 r   create_super_node_graphz,GraphTopologyBuilder.create_super_node_graph)   s    "  (/NA{*1#.M),K&&)6g& ' 0 zz|Gm+"'y 1-0UM*)6g&	 $ !K#F+I!$'G %)=&y1J$W-H X%H%))*5 ! r   super_node_graphc           	         | j                         D ci c]  \  }}|t        |       }}}|j                         D cg c]  \  }}|dk(  s| }}}g }i }	t        |      D ]  \  }
}d|
 d| }||d|	d|
 <    |r|dd }|j                          g }|D ]  }|j	                  d      r*|	|   }|j                  d|d   t        |d	         d
       n7|j	                  d      r&|j                  dd      }|j                  d|d       | D ]E  }|| |   v s| |   j                  |       ||xx   dz  cc<   ||   dk(  s5|j                  |       G  |r|j                  |       |r|S c c}}w c c}}w )a  
        Perform topological sort on super-node graph to determine execution order.

        Args:
            super_node_graph: Super-node dependency graph
            cycles: List of cycles for mapping super-nodes to cycle info

        Returns:
            Execution layers, where each layer contains items that can be executed in parallel.
            Format: [
                [{"type": "node", "node_id": "A"}, {"type": "cycle", "cycle_id": "...", "nodes": [...]}],
                [...]
            ]
        r   cycle__)cycle_idr   r   Ncycler-   r   )typer-   r   r    noder/   r"      )	itemslenr   clear
startswithappendlistreplaceremove)r)   r   
super_nodepredecessors	in_degreer1   degreereadyexecution_layerscycle_lookupr   r    r-   current_layerlayer_items
cycle_datar"   	dependents                     r   topological_sort_super_nodesz1GraphTopologyBuilder.topological_sort_super_nodes]   s   , -=,B,B,D
,D(
L L)),D 	 
 +4//*;K*;,$v{*;K '/NA{s!K=1H$$0L<s+, 0 !!HMKKM K+
((8!-j!9J&& '$.z$:!%j&9!:( 
  **73(00"=G&& &#*(  "2I!%5i%@@(3:::F!),1,$Y/14!LL3 "2% ,2  ''4A D  i
 Ls   E3 E9E9c                     t         j                  |       }|st         j                  |       S t         j                  | ||      }t         j	                  ||      S )a  
        One-stop method to build execution order.

        Combines cycle detection, super-node construction, and topological sorting.

        Args:
            nodes: Node dictionary
            edges: Edge configuration list

        Returns:
            Execution layers
        )r
   r   build_dag_layersr(   rG   )r   r   r   super_graphs       r   build_execution_orderz*GraphTopologyBuilder.build_execution_order   sY    " &33E:'88??*BB5&
 $@@
 	
r   c                     | j                         D ci c]  \  }}|t        |j                         }}}|j                         D cg c]  \  }}|dk(  s| }}}g }|r|D cg c]  }d|d	 }}|j                  |       g }|D ][  }| |   j                  D ]G  }	||	j
                  xx   dz  cc<   ||	j
                     dk(  s-|j                  |	j
                         I ] |}|r|S c c}}w c c}}w c c}w )z
        Build topological layers for DAG (Directed Acyclic Graph).

        Args:
            nodes: Node dictionary

        Returns:
            Layers in execution item format
        r   r1   r2   r3   )r4   r5   r=   r8   
successorsid)
r   r"   r1   r>   degfrontierlayersrD   next_frontier	successors
             r   rI   z%GraphTopologyBuilder.build_dag_layers   s)    "'
!. S**++!. 	 
 )2(9
(9SAXG(9 	 
   ('G  G4'   MM+&M#!&w!:!:Iill+q0+ .!3%,,Y\\: "; $
 %H   5


s    C/
C5C5'C;N)__name__
__module____qualname____doc__staticmethodr   strr   r   r   r   r   r(   rG   rK   rI    r   r   r
   r
      s    -T#t)_ -c#h - - 1CI1DcN#1 SX1 
c3s8m		1 1f G sCH}-G SXG  
d4S>"	#G  G R 
CI
DcN#
 
d4S>"	#
 
< $S$Y $Dd38n9M4N $ $r   r
   N)rW   typingr   r   r   r   entity.configsr   workflow.cycle_managerr   r
   rZ   r   r   <module>r^      s$    ( '  0_ _r   