Flow
DAG pipelines: flow.json, nodes, routing, and input templating.
Flow
A Flow is a fixed, repeatable DAG pipeline that runs a structured multi-agent process. Flows are the right tool when the same sequence of agent handoffs must run consistently, every time.
Directory Layout
flows/<name>/
├── flow.json # DAG definition (required)
└── agents/ # Flow-scoped agents
└── <short-name>/agent.json
flow.json
{
"name": "code-review",
"description": "Multi-dimensional code review pipeline.",
"entry": "scanner",
"maxLoop": 3,
"nodes": [
{
"id": "scanner",
"agent": "scanner",
"prompt": "Scan the changes and list all findings with severity.",
"onComplete": { "type": "goto", "target": "reviewer" }
},
{
"id": "reviewer",
"agent": "reviewer",
"prompt": "Classify each finding by severity.",
"onComplete": { "type": "switch", "cases": [["PASS", "fixer"], ["FAIL", "return"]] }
},
{
"id": "fixer",
"agent": "fixer",
"prompt": "Apply fixes for the accepted findings.",
"onComplete": { "type": "goto", "target": "reviewer" }
}
]
}
Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| name | string | Yes | Unique flow name |
| description | string | Yes | What the flow does (used for triggering) |
| entry | string | Yes | Id of the entry node |
| maxLoop | int | No | Maximum node executions per run (loop guard) |
| nodes | Node[] | Yes | Node definitions |
Node
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| id | string | Yes | Unique node id (referenced by routing) |
| agent | string | Yes | Flow-scoped agent directory name |
| prompt | string | No | Task template for this node |
| onComplete | Route | No | Where to go after success |
| onError | Route | No | Where to go after failure (default: abort) |
Routing
Node routing is declared per node in onComplete:
| Type | Meaning |
|------|---------|
| goto | Always go to target node |
| switch | Choose by the node's JSON output; cases is [pattern, target] pairs |
| return | Finish the flow and return the node output |
Example switch routing on a reviewer's verdict:
"onComplete": {
"type": "switch",
"cases": [
["PASS", "return"],
["FAIL", "fixer"]
]
}
Input Templating
Node prompts support variable substitution from the flow context:
| Variable | Meaning |
|----------|---------|
| $task | The flow's input task |
| $<nodeId>.output | The output of a previous node (e.g. $scanner.output) |
{
"id": "reviewer",
"agent": "reviewer",
"prompt": "Review these findings: $scanner.output"
}
Flow Agents
Flow-scoped agents live in flows/<name>/agents/<short-name>/. They have one important constraint:
Output must be JSON. The flow engine parses node output for routing — switch nodes inspect status / verdict fields, and return nodes deliver structured results.
{
"status": "FAIL",
"verdict": "blocker",
"summary": "Unhandled null pointer in line 42"
}
Keep flow agents single-purpose and deterministic: they run the same way every time, driven by the flow definition.
Execution Model
- Flow is triggered by name with a task string
- The entry node's agent runs with
$tasksubstituted into its prompt - On success,
onCompleteroutes to the next node - On error,
onErrorroutes (or the flow aborts) maxLoopcaps total node executions to prevent runaway loops
Team-invoked Flows
Teams list flows they may invoke in team.json. A team-triggered flow renders as an inline widget inside the team card — the flow runs in the team's context rather than as a separate global pipeline.