Node Types
AgentFlow provides eight node types that can be combined to build any workflow — from simple automation to complex multi-stage pipelines with loops, human oversight, and more.
AI Task
Executes Claude Code CLI with custom instructions. This is the primary node for AI-powered code generation, review, refactoring, and analysis.
| Property | Type | Description |
|---|---|---|
instructions* | string | The prompt sent to Claude. Supports variable substitution and {output.NODE_ID} references. |
agent | string | Agent name referencing .claude/agents/{name}.md for system instructions. |
model | string | Claude model override for this node: "opus", "sonnet", or "haiku". Defaults to pipeline/global setting. |
requires_tools | string[] | MCP tools that must be available for this task. |
retry | { max, delay } | Retry policy for failed invocations. |
timeout | number | Max execution time in seconds. |
# With agent:
claude --agent code-reviewer --print "Review changed files for security issues"
# Without agent:
claude --print "Generate unit tests for src/utils.ts"
# Cost is extracted from Claude CLI stderr:
# Looks for "Total cost: $X.XX" or "total_cost_usd: X.XX"Info
Shell Command
Executes any bash command. Use for running tests, building projects, linting, deploying, or any CLI operation.
| Property | Type | Description |
|---|---|---|
instructions* | string | The bash command to execute. |
retry | { max, delay } | Retry on non-zero exit code. |
timeout | number | Kill process after N seconds. |
# Commands run via:
bash -c "{instructions}"
# stdout and stderr are streamed to the live log viewer
# Exit code 0 = success, non-zero = failurenpm run test -- --coverage
cargo build --release
docker compose up -d
eslint src/ --fixGit Operation
Runs git commands as part of your pipeline. Functionally identical to Shell but semantically distinct for clarity on the canvas.
| Property | Type | Description |
|---|---|---|
instructions* | string | The git command to execute. |
retry | { max, delay } | Retry on failure. |
timeout | number | Max execution time. |
git checkout -b feature/auto-fixes
git add -A && git commit -m "feat: AI-generated changes"
git push origin HEAD
git merge origin/main --no-editParallel
A container node that runs all its children simultaneously and waits for every child to complete before continuing.
| Property | Type | Description |
|---|---|---|
children* | string[] | Array of child node IDs to run concurrently. |
instructions | string | Optional description (not executed). |
1. All child nodes are spawned concurrently via tokio::task::JoinSet
2. Results are processed in completion order (not spawn order)
3. Execution blocks until ALL children complete
4. Status = "success" only if ALL children succeed
5. Status = "failed" if ANY child fails
6. Individual child status is tracked separately{
"id": "node-parallel",
"name": "Run All Checks",
"type": "parallel",
"instructions": "Run lint, test, and type-check in parallel",
"children": ["node-lint", "node-test", "node-typecheck"],
"inputs": [],
"outputs": [],
"position": { "x": 250, "y": 150 }
}Loop
Iterates over a list of items, executing child steps for each one. Supports configurable separators (newline, comma, custom), max iteration caps, and injects per-item variables into child node instructions.
| Property | Type | Description |
|---|---|---|
instructions* | string | The list of items to iterate over, or an expression that produces a list. |
children* | string[] | Array of child node IDs to execute for each loop item. |
loop_config | LoopConfig | Configuration for loop behavior (separator, max iterations, timeout, model). |
retry | { max, delay } | Retry policy for the entire loop. |
timeout | number | Max execution time for the entire loop. |
{
"loop_config": {
"separator": "newline", // "newline" | "comma" | custom string
"max_iterations": 100, // Cap iterations (1-1000)
"timeout": 600, // Per-loop timeout in seconds
"model": "sonnet" // Model override for AI children
}
}$LOOP_ITEM — The current item from the list
$LOOP_INDEX — Zero-based index of the current iteration
$LOOP_COUNT — Total number of items in the list
# Example: if instructions = "file1.ts\nfile2.ts\nfile3.ts"
# Iteration 0: $LOOP_ITEM="file1.ts", $LOOP_INDEX=0, $LOOP_COUNT=3
# Iteration 1: $LOOP_ITEM="file2.ts", $LOOP_INDEX=1, $LOOP_COUNT=3
# Iteration 2: $LOOP_ITEM="file3.ts", $LOOP_INDEX=2, $LOOP_COUNT=3{
"id": "node-loop",
"name": "Review Each File",
"type": "loop",
"instructions": "src/auth.ts\nsrc/api.ts\nsrc/db.ts",
"children": ["node-review"],
"loop_config": {
"separator": "newline",
"max_iterations": 50
},
"inputs": [],
"outputs": [],
"position": { "x": 250, "y": 150 }
}Loop-aware cost estimation
max_iterations to cap both runtime and estimated cost.Info
Approval Gate
Pauses pipeline execution and waits for a human to approve or reject before continuing. Essential for production deployments and sensitive operations.
| Property | Type | Description |
|---|---|---|
instructions* | string | Message shown to the approver explaining what they're approving. |
timeout | number | Auto-fail if no response after N seconds. |
1. Node enters "running" state
2. Emits "approval-requested" event: { runId, nodeId, name }
3. UI shows approval dialog with the node instructions
4. Blocks until respond_to_approval(approved: bool) is called
5. If approved → status "success", approval_state "approved"
6. If rejected → status "failed", approval_state "rejected"
7. If timeout → status "failed" (no approval received)Resume behavior
Sub-pipeline
References and executes another saved pipeline. Enables composable, reusable workflow modules.
| Property | Type | Description |
|---|---|---|
pipeline_ref* | string | Name of the pipeline to execute (matches filename without .pipeline.json). |
instructions | string | Optional description. |
1. Loads {project}/.claude/pipelines/{pipeline_ref}.pipeline.json
2. Executes the full pipeline recursively (run_pipeline_loop)
3. Circular references are detected and blocked:
- Ancestor pipeline names are tracked through the chain
- If pipeline_ref appears in ancestors → error
4. Cost is aggregated from all nodes in the sub-pipeline
5. Sub-pipeline success/failure propagates to parent{
"id": "node-deploy",
"name": "Deploy to Staging",
"type": "sub-pipeline",
"instructions": "Execute the staging deployment pipeline",
"pipeline_ref": "deploy-staging",
"inputs": [],
"outputs": [],
"position": { "x": 250, "y": 300 }
}Validation
pipeline_ref set. The referenced pipeline must exist at execution time. Circular references (A calls B which calls A) are caught and result in a validation error.Comment
A non-executing annotation node for documenting pipeline sections, leaving notes for teammates, and organizing complex workflows visually. Comment nodes are completely ignored during execution.
| Property | Type | Description |
|---|---|---|
instructions* | string | The comment text displayed on the canvas. |
{
"id": "node-comment-1",
"name": "Deployment Notes",
"type": "comment",
"instructions": "This section handles the staging deployment. Requires VPN access and valid AWS credentials.",
"inputs": [],
"outputs": [],
"position": { "x": 50, "y": 600 }
}Info
Common Properties
All node types share these properties:
Retry Policy
{
"retry": {
"max": 3, // Maximum number of attempts (1 = no retries)
"delay": 10 // Seconds to wait between retries
}
}Each attempt is tracked in the database with its own attempt number, exit code, and log output.
Timeout
{
"timeout": 300 // Kill process after 300 seconds (5 minutes)
}When a timeout fires, the process receives SIGTERM. If it doesn't exit within a grace period, SIGKILL is sent.
Execution Status
| Status | Meaning |
|---|---|
pending | Not yet reached in execution order |
running | Currently executing |
success | Completed with exit code 0 (or approved) |
failed | Non-zero exit, timeout, rejection, or error |
skipped | Conditional edge not satisfied |
cancelled | Pipeline was cancelled by user |