docs/user_guide/en/execution_logic.md
Version: 2025-12-16
This document explains how the DevAll backend parses and executes workflow graphs, with particular focus on handling complex graphs containing cyclic structures.
The DevAll workflow execution engine supports two types of graph structures:
| Graph Type | Characteristics | Execution Strategy |
|---|---|---|
| DAG (Directed Acyclic Graph) | No cyclic dependencies between nodes | Topological sort + parallel layer execution |
| Cyclic Directed Graph | Contains one or more loop structures | Recursive super-node scheduling |
The execution engine automatically detects the graph structure and selects the appropriate execution strategy.
For workflow graphs without cycles, the engine uses standard DAG scheduling:
predecessors and successors lists for each nodeflowchart LR
subgraph Layer1["Execution Layer 1"]
A["Node A"]
B["Node B"]
end
subgraph Layer2["Execution Layer 2"]
C["Node C"]
end
subgraph Layer3["Execution Layer 3"]
D["Node D"]
end
A --> C
B --> C
C --> D
When cyclic structures exist in the graph, the execution engine first uses Tarjan's algorithm to detect all Strongly Connected Components (SCCs). Tarjan's algorithm identifies all cycles in the graph in O(|V|+|E|) time complexity through depth-first search.
An SCC containing more than one node constitutes a cycle structure.
After detecting cycles, the execution engine abstracts each cycle into a "Super Node":
flowchart TB
subgraph Original["Original Graph"]
direction TB
A1["A"] --> B1["B"]
B1 --> C1["C"]
C1 --> B1
C1 --> D1["D"]
end
subgraph Abstracted["Super Node Graph"]
direction TB
A2["Node A"] --> S1["Super Node
(B, C cycle)"]
S1 --> D2["Node D"]
end
Original -.->|"Abstract"| Abstracted
For cycle super nodes, the system employs a recursive execution strategy:
Analyze the cycle boundary to identify the uniquely triggered entry node as the "initial node". This node must satisfy:
Using all nodes in the current cycle as the scope, logically remove all incoming edges to the initial node. This operation breaks the outer cycle boundary, ensuring subsequent cycle detection only targets nested structures within.
Apply Tarjan's algorithm again to the subgraph to detect nested cycles within the scope. Since the initial node's incoming edges are removed, detected SCCs represent only true inner nested cycles.
If nested cycles are detected:
If no nested cycles are detected, perform direct DAG topological sort.
Execute according to the topological order:
After completing each round of in-cycle execution, the system checks these exit conditions:
loop_timer node within the cycle reaches its configured time limit, exit the loopIf none of the conditions are met, return to Step 2 for the next iteration.
flowchart TB
A["Cycle super node scheduled"] --> B["Identify uniquely triggered initial node"]
B --> C{"Valid initial node?"}
C -->|"None"| D["Skip this cycle"]
C -->|"Multiple"| E["Report configuration error"]
C -->|"Unique"| F["Build scoped subgraph
Remove initial node's incoming edges"]
F --> G["Tarjan algorithm: detect nested cycles"]
G --> H{"Inner nested cycles exist?"}
H -->|"No"| I["DAG topological sort"]
H -->|"Yes"| J["Build inner super nodes
Topological sort"]
I --> K["Layered execution"]
J --> K
K --> L["Execute regular nodes"]
K --> M["Recursively execute inner cycles"]
L --> N{"Check exit conditions"}
M --> N
N -->|"Exit edge triggered"| O["Exit cycle"]
N -->|"Max iterations reached"| O
N -->|"Initial node not re-triggered"| O
N -->|"Continue iteration"| F
Each edge has a trigger attribute that determines whether it participates in execution order calculation:
| trigger value | Behavior |
|---|---|
true (default) | Edge participates in topological sort; target node waits for source completion |
false | Edge doesn't participate in topological sort; used only for data transfer |
Edge conditions determine whether data flows along the edge:
true (default): Always transferkeyword: Check if upstream output contains/excludes specific keywordsfunction: Invoke custom function for evaluationThe target node is triggered for execution only when the condition is satisfied.
nodes:
- id: Writer
type: agent
config:
name: gpt-4o
role: You are a professional technical writer
- id: Reviewer
type: human
config:
description: Please review the article, enter ACCEPT if satisfied
edges:
- from: Writer
to: Reviewer
- from: Reviewer
to: Writer
condition:
type: keyword
config:
none: [ACCEPT] # Continue loop when ACCEPT is not present
Execution flow:
The system supports arbitrarily deep nested loops. For example, an outer "review-revise" loop can contain an inner "generate-validate" loop:
Outer Loop (Writer -> Reviewer -> Writer)
└── Inner Loop (Generator -> Validator -> Generator)
The recursive execution strategy automatically handles such nested structures.
| Module | Function |
|---|---|
workflow/cycle_manager.py | Tarjan algorithm implementation, cycle info management |
workflow/topology_builder.py | Super node graph construction, topological sorting |
workflow/executor/cycle_executor.py | Recursive cycle executor |
workflow/graph.py | Main graph execution entry point |