Declarative workflow orchestration for AI agents.
Define complex, multi-agent LLM workflows as readable .iter files β chain agents, judges, routers, human gates, parallel branches, bounded loops, and budget caps into a single, auditable execution graph.
β οΈ This project is highly experimental. APIs, DSL syntax, and storage formats may change without notice. Use at your own risk in production environments. Feedback and contributions are welcome!
- What is Iterion?
- Quickstart
- A Taste of the DSL
- Features
- Visual Editor
- The
.iterDSL - CLI Reference
- Delegation
- AI Agent Skill
- Recipes
- Examples
- Architecture
- Development
- License
Iterion is a workflow engine that turns .iter files into executable AI pipelines. You describe what your agents should do β review code, plan fixes, check compliance, ask a human β and Iterion handles how: scheduling branches in parallel, enforcing budgets, persisting state, and routing between nodes.
.iter file β Parse β Compile β Validate β Execute
β
ββββββββββββββββββββββββββ
β agents, judges, ββ
β routers, joins, ββ
β humans, tools ββ
β running in parallel ββ
β with budget tracking ββ
ββββββββββββββββββββββββββ
βΌ
results, artifacts, event log
Think of it as a DAG runner purpose-built for LLM workflows β with first-class support for things like structured I/O, conversation sessions, human-in-the-loop pauses, and cost control.
curl -fsSL https://socialgouv.github.io/iterion/install.sh | shOr install to a custom directory (no sudo needed):
INSTALL_DIR=. curl -fsSL https://socialgouv.github.io/iterion/install.sh | shWindows (PowerShell)
Invoke-WebRequest -Uri "https://github.com/socialgouv/iterion/releases/latest/download/iterion-windows-amd64.exe" -OutFile iterion.exeYou can also download binaries from the latest release. Builds are available for Linux, macOS (Intel + Apple Silicon), and Windows.
# Scaffold a new project
mkdir my-project && cd my-project
iterion init
# Configure your API key
cp .env.example .env
# Edit .env β set ANTHROPIC_API_KEY (or OPENAI_API_KEY)
source .env && export ANTHROPIC_API_KEY
# Validate the workflow
iterion validate pr_refine_single_model.iter
# Run it
iterion run pr_refine_single_model.iter \
--var pr_title="Fix auth middleware" \
--var review_rules="No SQL injection, no hardcoded secrets"iterion init creates a complete PR refinement workflow (review β plan β compliance check β act β verify) that you can run immediately.
# List all runs
iterion inspect
# View a specific run with events
iterion inspect --run-id <id> --events
# Generate a detailed report
iterion report --run-id <id>All run data (events, artifacts, interactions) is stored in .iterion/runs/.
Here's the simplest possible workflow β an agent reviews code and decides pass/fail:
prompt review_system:
You are a code reviewer. Evaluate the submission
and decide if it meets quality standards.
prompt review_user:
Review this code:
{{input.code}}
schema review_input:
code: string
schema review_output:
approved: bool
summary: string
agent reviewer:
model: "${MODEL}"
input: review_input
output: review_output
system: review_system
user: review_user
workflow minimal:
entry: reviewer
reviewer -> done when approved
reviewer -> fail when not approved
That's it β 28 lines. The agent gets a code input, produces a structured {approved, summary} output, and the workflow routes to done or fail based on the verdict.
From here you can add judges for multi-pass review, routers for parallel fan-out, human gates for approval, bounded loops for retry, budget caps for cost control, and more.
- π Declarative DSL β Human-readable
.iterfiles with indentation-based syntax - π€ Multi-agent orchestration β Chain agents, judges, routers, and joins into complex graphs
- π₯οΈ Visual editor β Browser-based workflow builder with drag-and-drop, live validation, and source view
- π Human-in-the-loop β Pause for human input, auto-answer via LLM, or let the LLM decide when to ask
- π Parallel branching β Fan-out via routers, converge with join nodes (
wait_all/best_effort) - π§ 4 routing modes β
fan_out_all,condition,round_robin, andllm-driven routing - π Bounded loops β Retry and refinement cycles with configurable iteration limits
- π° Budget enforcement β Caps on tokens, cost (USD), duration, and iterations
- π Delegation β Offload execution to external agents (Claude Code, Codex) with full tool access β works with Claude and ChatGPT/Codex subscriptions
- π² Structured I/O β Typed schemas for inputs and outputs with enum constraints
- π MCP support β Declare MCP servers directly in
.iterfiles (stdio,http) - π¦ Artifact versioning β Per-node, per-iteration versioned outputs persisted to disk
- π Event sourcing β Append-only JSONL event log for full observability and replay
- βΈοΈ Pause/resume β Checkpoint-based suspension and resumption of runs
- π Mermaid diagrams β Auto-generate visual workflow diagrams
- π§ͺ Recipe system β Bundle workflows with presets for comparison and benchmarking
- π‘οΈ Tool policies β Allowlist-based access control with exact, namespace, and wildcard matching
- π Provider-agnostic β Supports multiple LLM providers (Claude, OpenAI, etc.) via goai
- π§ AI agent skill β Install as a skill in Claude Code, Codex, Cursor, and other AI agents
Iterion includes a browser-based visual workflow editor built with React and XYFlow.
iterion editor # Launch on default port (4891)
iterion editor --port 8080 # Custom port
iterion editor --dir ./workflows # Custom working directory
iterion editor --no-browser # Don't auto-open browserWhat you get:
- Canvas β Drag-and-drop node graph with auto-layout, zoom, search, and keyboard shortcuts
- Node library β Drag pre-built node types (agent, judge, router, join, human, tool) onto the canvas
- Property editor β Edit node properties, schemas, prompts, and edge conditions in a side panel
- Source view β Split-pane view showing the raw
.itersource alongside the visual graph - Live diagnostics β Real-time validation errors and warnings as you edit (codes C001βC029)
- File watching β Detects external file changes via WebSocket and syncs automatically
- Undo/redo β Full edit history
Workflows are written in a declarative, indentation-significant language. The formal grammar is in grammar/iterion_v1.ebnf.
Define typed variables at the top level. These can be set at runtime with --var key=value:
vars:
pr_title: string
max_retries: int = 3
verbose: bool = false
config: json = { "key": "value" }
tags: string[] = ["security", "performance"]
Supported types: string, bool, int, float, json, string[].
Reusable prompt templates with {{...}} interpolation:
prompt review_system:
You are a code reviewer specializing in {{vars.language}}.
Focus on: {{vars.review_rules}}
prompt review_user:
Review this code:
{{input.code}}
Previous feedback: {{outputs.prior_review.summary}}
Typed data contracts for structured agent I/O:
schema review_result:
approved: bool
summary: string
issues: string[]
confidence: string [enum: "low", "medium", "high"]
score: float
metadata: json
Supported field types: string, bool, int, float, json, string[]. Strings support [enum: ...] constraints.
The primary execution unit. Calls an LLM with prompts, optionally uses tools, and returns structured output:
agent reviewer:
model: "claude-sonnet-4-20250514"
input: review_request
output: review_result
system: review_system
user: review_user
session: fresh
tools: [git_diff, read_file, search_codebase]
tool_max_steps: 10
publish: review_artifact
reasoning_effort: high
readonly: true
| Property | Description |
|---|---|
model |
LLM model identifier (supports ${ENV_VAR}) |
delegate |
Offload to external agent: claude_code or codex (see Delegation) |
input / output |
Schema references for structured I/O |
publish |
Persist output as a named artifact |
system / user |
Prompt references |
session |
Context mode: fresh (default), inherit, fork, or artifacts_only |
tools |
List of allowed tool names |
tool_max_steps |
Max tool-use iterations (0 = unlimited) |
reasoning_effort |
Extended thinking: low, medium, high, extra_high |
readonly |
If true, prevents tool side effects (workspace safety) |
Structurally identical to agents, but semantically intended for evaluation β typically no tools:
judge compliance_check:
model: "claude-sonnet-4-20250514"
input: plan_schema
output: verdict_schema
system: compliance_system
user: compliance_user
Branches execution into parallel or conditional paths. Four modes are available:
router dispatch:
mode: fan_out_all # Send to ALL outgoing edges in parallel
router branch:
mode: condition # Route based on `when` clauses on edges
router alternate:
mode: round_robin # Cycle through targets one per iteration
router smart:
mode: llm # LLM decides which target(s) to route to
model: "claude-sonnet-4-20250514"
system: routing_prompt
multi: true # Allow selecting multiple targets
For a deep dive on routing modes, edge rules, and convergence patterns, see
docs/routers.md.
Converges parallel branches back into a single path:
join merge:
strategy: wait_all # Wait for all branches (or: best_effort)
require: [branch_a, branch_b]
output: merged_result
wait_allβ waits for every incoming branchbest_effortβ proceeds when required branches finish, tolerates failures on others
Pauses the workflow for human input, or lets an LLM handle it:
## Always pause for human answers
human approval:
input: approval_request
output: approval_response
instructions: approval_prompt
mode: pause_until_answers
min_answers: 1
## LLM auto-answers (never pauses)
human auto_review:
mode: auto_answer
model: "claude-sonnet-4-20250514"
system: auto_review_prompt
output: review_decision
## LLM decides whether to pause or auto-answer
human conditional:
mode: auto_or_pause
model: "claude-sonnet-4-20250514"
system: decision_guidance
instructions: review_questions
output: review_decision
Resume a paused run with iterion resume --run-id <id> --file <file> --answer key=value.
Direct shell command execution β no LLM involved:
tool run_tests:
command: "make test"
output: test_result
Supports ${ENV_VAR} in the command string.
Every workflow must end at done (success) or fail (failure). These are built-in β you don't declare them.
A workflow ties nodes together with an entry point, optional budget, and edges:
workflow pr_review:
entry: context_builder
budget:
max_duration: "30m"
max_cost_usd: 10
max_tokens: 400000
context_builder -> reviewer
reviewer -> done when approved
reviewer -> context_builder when not approved as retry(3)
Edge syntax:
src -> dst # Unconditional
src -> dst when approved # Conditional (bool field from src output)
src -> dst when not approved # Negated condition
src -> dst as loop_name(5) # Bounded loop (max 5 iterations)
src -> dst with { # Data mapping
context: "{{outputs.src}}",
config: "{{vars.my_var}}"
}
Edge rules:
- Non-router nodes can have at most one unconditional edge
- Conditional edges must be exhaustive (
when X+when not X) or have an unconditional fallback - All cycles must be declared with
as name(N)β undeclared cycles are a compile error - Inside loops, you can access iteration history with
{{outputs.node_id.history}}
Templates use {{...}} interpolation:
| Reference | Description |
|---|---|
{{vars.name}} |
Workflow variable |
{{input.field}} |
Current node's input field |
{{outputs.node_id}} |
Full output of a previously executed node |
{{outputs.node_id.field}} |
Specific field from a node's output |
{{outputs.node_id.history}} |
Array of all outputs across loop iterations |
{{artifacts.name}} |
Published artifact by name |
Environment variables are supported with ${ENV_VAR} syntax (resolved at compile time).
You can declare MCP (Model Context Protocol) servers directly in your .iter files:
mcp_server code_tools:
transport: stdio
command: "npx"
args: ["-y", "@anthropic-ai/claude-code-mcp"]
mcp_server api_server:
transport: http
url: "http://localhost:3000/mcp"
Agents can then reference these servers:
agent worker:
model: "claude-sonnet-4-20250514"
mcp:
servers: [code_tools, api_server]
Supported transports: stdio (requires command), http (requires url).
Control costs and prevent runaway execution:
budget:
max_parallel_branches: 4 # Concurrent branch limit
max_duration: "30m" # Global timeout
max_cost_usd: 10.0 # Cost cap in USD
max_tokens: 500000 # Total token budget
max_iterations: 50 # Loop iteration limit
The budget is shared across all branches. When a limit is hit, the engine emits a budget_exceeded event and stops the run.
All commands support --json for machine-readable output and --help for usage details.
Scaffold a new project with an example workflow:
iterion init # Current directory
iterion init my-project # New directoryCreates pr_refine_single_model.iter, .env.example, and .gitignore. Idempotent β won't overwrite existing files.
Parse, compile, and validate a workflow without running it:
iterion validate workflow.iterReports errors and warnings with diagnostic codes (C001βC029), file positions, and descriptions.
Execute a workflow:
iterion run workflow.iter [flags]| Flag | Description |
|---|---|
--var key=value |
Set workflow variable (repeatable) |
--recipe <file> |
Apply a recipe preset (JSON) |
--run-id <id> |
Use a specific run ID (default: auto-generated) |
--store-dir <dir> |
Run store directory (default: .iterion) |
--timeout <duration> |
Global timeout (e.g. 30m, 1h) |
--log-level <level> |
Log verbosity: error, warn, info, debug, trace |
--no-interactive |
Don't prompt on TTY; exit on human pause |
View run state and history:
iterion inspect # List all runs
iterion inspect --run-id <id> # View a specific run
iterion inspect --run-id <id> --events # Include event log
iterion inspect --run-id <id> --full # Show full artifact contentsResume a paused workflow run with human answers:
iterion resume --run-id <id> --file workflow.iter --answer key=value
iterion resume --run-id <id> --file workflow.iter --answers-file answers.jsonGenerate a Mermaid diagram from a workflow:
iterion diagram workflow.iter # Compact view (default)
iterion diagram workflow.iter --detailed # Include node properties
iterion diagram workflow.iter --full # Include templates and loop detailsPaste the output into any Mermaid-compatible renderer (GitHub Markdown, Mermaid Live Editor, etc.).
Generate a chronological report for a completed run:
iterion report --run-id <id>
iterion report --run-id <id> --output report.mdThe report includes:
- Summary table β workflow name, status, duration, tokens, cost, model calls
- Artifacts table β all published artifacts with versions
- Timeline β chronological reconstruction of every node execution, edge selection, verdict, branch lifecycle, and budget warning
Launch the visual workflow editor:
iterion editor # Default port 4891
iterion editor --port 8080 # Custom port
iterion editor --dir ./workflows # Custom directory
iterion editor --no-browser # Don't auto-open browserPrint version and commit hash.
For tasks that need full tool access (file editing, shell commands, git operations), you can delegate agent execution to an external CLI agent instead of making direct LLM API calls:
agent implementer:
delegate: "claude_code" # or: "codex"
input: plan_schema
output: result_schema
system: implementation_prompt
tools: [read_file, write_file, run_command, git_diff]
| Backend | What it does |
|---|---|
claude_code |
Runs the claude CLI as a subprocess with full tool access |
codex |
Runs the codex CLI as a subprocess |
π‘ Both backends work with standard subscriptions β Claude Code with your Claude subscription (Pro/Max/Team/Enterprise), and Codex with your ChatGPT subscription (Plus/Pro/Team/Enterprise). No separate API key is required for delegation.
Delegation is useful for agents that need to act on the codebase (write files, run tests, execute commands). For agents that only need to think (review, judge, plan), use model: directly β it's lighter weight and faster.
You can mix both in the same workflow. A common pattern is using model: for reviewers and judges, and delegate: for implementers:
agent reviewer:
model: "claude-sonnet-4-20250514" # Direct API call β fast, read-only
readonly: true
agent implementer:
delegate: "claude_code" # Full agent β can edit files
tools: [read_file, write_file, patch, run_command]
Iterion ships as an Agent Skill compatible with Claude Code, Codex, Cursor, Windsurf, GitHub Copilot, Cline, Aider, and other AI coding agents. Once installed, your agent knows the full .iter DSL and can write correct workflows for you.
npx skills add https://github.com/SocialGouv/iterion --skill iterion-dsl| File | Content |
|---|---|
SKILL.md |
Complete DSL reference β node types, properties, edge syntax, templates, budget, MCP |
references/dsl-grammar.md |
Formal grammar specification (EBNF) |
references/patterns.md |
10 reusable workflow patterns with annotated snippets |
references/diagnostics.md |
All validation diagnostic codes (C001βC029) with causes and fixes |
examples/skill/ |
4 minimal, self-contained .iter examples |
Once installed, just ask your agent to write workflows:
- "Write an .iter workflow that reviews a PR with two parallel reviewers"
- "Create an iterion pipeline that fixes CI failures in a loop"
- "Add a human approval gate before the deployment step"
The agent will use the skill reference to produce valid .iter files that pass iterion validate.
Recipes let you run the same workflow with different configurations without editing the .iter file. They're useful for benchmarking models, comparing prompts, or creating reusable presets:
{
"name": "fast_review",
"workflow_ref": {
"name": "pr_refine_single_model",
"path": "examples/pr_refine_single_model.iter"
},
"preset_vars": {
"review_rules": "Focus on security only"
},
"prompt_pack": {
"review_system": "You are a security-focused reviewer."
},
"budget": {
"max_duration": "10m",
"max_cost_usd": 5.0
},
"evaluation_policy": {
"primary_metric": "approved",
"success_value": "true"
}
}iterion run workflow.iter --recipe fast_review.jsonRecipes can override variables, prompts, budgets, and define success criteria for automated evaluation.
The examples/ directory contains workflows of increasing complexity. Start simple and work your way up:
| File | Description |
|---|---|
skill/minimal_linear.iter |
28 lines β single agent with conditional pass/fail |
skill/human_gate.iter |
Human approval gate pattern |
skill/loop_with_judge.iter |
Simple bounded loop with judge evaluation |
skill/parallel_fan_out_join.iter |
Basic fan-out/join parallelism |
| File | Description |
|---|---|
pr_refine_single_model.iter |
PR refinement: review β plan β compliance β act β verify loop |
ci_fix_until_green.iter |
Automated CI fix loop: diagnose β plan β fix β rerun tests |
session_review_fix.iter |
Session continuity with inherit and fork modes |
llm_router_task_dispatch.iter |
LLM-driven routing decisions |
| File | Description |
|---|---|
pr_review.iter |
Parallel dual-reviewer PR analysis with judge synthesis |
pr_refine_dual_model_parallel.iter |
Dual-model parallel review with router/join |
dual_model_plan_implement_review.iter |
Enterprise dual-LLM orchestration with round-robin routing and delegation |
recipe_benchmark.iter |
Model/prompt benchmarking with recipe presets |
See examples/FIXTURES.md for detailed documentation on each example.
.iter file
β
βΌ
βββββββββββ βββββββββββ ββββββββββββ
β PARSE ββββββΆβ COMPILE ββββββΆβ VALIDATE β
β Lexer + β β ASTβIR β β Static β
β Parser β β Resolve β β Checks β
βββββββββββ βββββββββββ ββββββββββββ
β β β
βΌ βΌ βΌ
AST IR Diagnostics
- Parse (
parser/) β Indent-sensitive lexer + recursive-descent parser produces an AST - Compile (
ir/compile.go) β Transforms AST to IR, resolves template references, binds schemas and prompts - Validate (
ir/validate.go) β Static analysis with 29 diagnostic codes: reachability, routing correctness, cycle detection, schema validation, and more
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Runtime Engine β
β β
β ββββββββ βββββββββ ββββββββββ ββββββββ β
β βAgent β β Judge β β Router β β Join β β
β β β β β β β β β β
β β LLM β β LLM β βfan_out β βmerge β β
β β+toolsβ βverdictβ β cond β βwait β β
β ββββββββ βββββββββ ββββββββββ ββββββββ β
β β
β ββββββββ βββββββββ ββββββββββ ββββββββ β
β βHuman β β Tool β β Done β β Fail β β
β βpause/β β exec β βterminalβ βerror β β
β β auto β β β β β β β β
β ββββββββ βββββββββ ββββββββββ ββββββββ β
β β
β Budget Tracker β Event Emitter β Artifact Store β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
The engine walks the IR graph, executing nodes and selecting edges. Key runtime features:
- Parallel branches β router
fan_out_allspawns concurrent branches, limited bymax_parallel_branches - Workspace safety β only one mutating branch at a time; multiple read-only branches are OK
- Shared budget β mutex-protected token/cost/duration tracking across all branches
- Checkpoint-based pause/resume β the checkpoint in
run.jsonis the authoritative resume source - Event sourcing β every step is recorded in
events.jsonlfor observability and debugging
Run lifecycle: running β paused_waiting_human β running β finished | failed | cancelled
All run state is persisted under a configurable store directory (default: .iterion/):
.iterion/runs/<run_id>/
run.json # Run metadata & checkpoint
events.jsonl # Append-only event log
artifacts/<node_id>/
0.json, 1.json, ... # Versioned node outputs
interactions/<id>.json # Human Q&A exchanges
report.md # Generated run report
See docs/persisted-formats.md for the full specification.
This section is for contributors working on the Iterion codebase itself.
- Devbox β portable dev environment (installs Go, Task, Node)
- direnv β auto-activates the Devbox shell
eval "$(direnv hook bash)" # or: eval "$(direnv hook zsh)"
direnv allowThe repository also includes a .devcontainer/ configuration for VS Code / GitHub Codespaces.
task build # β ./iterion
task test # Unit tests
task test:e2e # End-to-end tests (stub executor)
task test:live # Live e2e tests (requires API keys)
task test:race # Tests with race detector
task lint # go fmt + go vet
task check # lint + test
task editor:dev # Start editor in dev mode (HMR)
task editor:build # Build editor frontendOr directly with Go:
go build -o iterion ./cmd/iterion
go test ./...iterion/
βββ cmd/iterion/ # CLI entry point (Cobra, one file per command)
βββ cli/ # Command implementations
βββ ast/ # Abstract syntax tree definitions
βββ parser/ # Lexer and recursive-descent parser
βββ grammar/ # EBNF grammar specification
βββ ir/ # IR compiler, validator, Mermaid generator
βββ runtime/ # Execution engine, budget, parallel orchestration
βββ store/ # File-backed persistence (runs, events, artifacts)
βββ model/ # LLM executor, model registry, event hooks
βββ delegate/ # Delegation backends (claude_code, codex)
βββ tool/ # Tool adapter and allowlist-based access policy
βββ recipe/ # Recipe/preset management
βββ server/ # HTTP server for editor backend
βββ editor/ # Web UI (React/Vite/TypeScript + XYFlow)
βββ benchmark/ # Metrics collection and reporting
βββ log/ # Leveled logger
βββ unparse/ # IR β .iter serialization
βββ examples/ # Reference .iter workflows
βββ e2e/ # End-to-end test scenarios
βββ docs/ # Format specifications and ADRs
Key dependencies: Go 1.25.0, goai v0.4.0 (vendored). Single external dependency.
Copyright (c) Iterion AI. All rights reserved.