Skip to main content
Workflow graphs are made of typed steps. Each step has an id, type, name, optional depends_on, and type-specific fields. The JSON schema is published at agentruntime.io/schemas/workflow-graph.schema.json. Runtime graphs use { "steps": [...] } — not a top-level step-id map.

mcp_call

Invoke a tool on an MCP instance. | Field | Description | |-------|-------------| | server_url | Portable system canonical_url — use when sharing graphs across workspaces | | instance_id | Tenant MCP instance UUID — optional override; Studio sets this when you pick an instance | | tool_name | Tool to call on the server | | tool_args | JSON arguments; supports template variables | | timeout_s | Step timeout in seconds | | retry_count | Number of retries on failure | At run start the engine resolves server_urlinstance_id when needed (and may auto-create a tenant instance). Dry-run validation warns when an instance will be created. Importing shared graphs: Workflow Studio Import accepts canvas JSON or { "steps": [] }, previews the graph, then maps each server_url to an instance in your workspace before applying to the canvas. Example use cases: Send an email via Resend, query Postgres, create a GitHub issue, post a WhatsApp message.

llm_call

Call a large language model with a prompt. | Field | Description | |-------|-------------| | model | Wire model name (for example gpt-4o). Required if model_ref is omitted. | | model_ref | Providers catalog reference (for example direct.openai.gpt-4o). Required if model is omitted. | | prompt | Prompt text with template variables | | llm_params | Temperature, max tokens, and other provider params | | llm_credential_id / llm_credential_scope | Optional explicit tenant or system API key from Providers | In Workflow Studio, use the LLM Call palette node and pick model + source in the node config; the editor writes these fields on save. At run time, the platform resolves model_ref against your Providers keys automatically.

human_task

Pause the run until a human approves, rejects, or provides input. | Field | Description | |-------|-------------| | task_type | Task category (for example, approval) | | task_payload | Data shown in Command Center (title, description, editable fields) | The run enters a paused state until the task is completed via the Console or API.

lua_script

Run inline Lua to transform upstream data. | Field | Description | |-------|-------------| | script | Lua source (max 64 KB). Access upstream via steps.<id>.result and trigger input via input.<field>. Must return a table. | Use Lua for lightweight mapping, filtering, and aggregation without an extra MCP round-trip.

for_each

Fan out over a list with controlled parallelism. | Field | Description | |-------|-------------| | for_each_items | Template or path to an array, e.g. {{steps.gen.result.items}} | | for_each_max_parallel | Max concurrent body runs (default 10, max 100) | | for_each_body_steps | Ordered inline inner step chain per item (lua_script, llm_call, mcp_call, agent_call) | Inner agent_call steps run synchronously inside the parent; they do not participate in episode handoff routing. Inside for_each_body_steps, reference resolved inner inputs with {{steps.<inner-id>.input.<field>}} (use the inner step id from the body array, not the runtime qualified key parent#body#inner).

while

Conditional loop (L5): repeat an inline step chain until a stop condition or while_max_iterations. | Field | Description | |-------|-------------| | while_mode | until (stop when condition true) or while (continue while condition true) | | while_max_iterations | Hard cap on iterations (required, ≥ 1) | | while_body_steps | Ordered inline inner steps per iteration | | while_condition | Template boolean, e.g. {{body.score.result.pass}} | | while_eval_script | Lua returning { pass = true/false }; wins if both condition fields are set | Template scopes inside composite bodies: {{body.<innerId>.*}}, {{while.iteration}}, {{while.prev.<innerId>.*}}. In Lua use loop (not while) and body globals. Reference resolved inner step inputs with {{steps.<inner-id>.input.<field>}} and parent loop inputs with {{steps.<while-node-id>.input.while_condition}} (and related while_* fields).

Template variables (Studio + JSON)

Workflow Studio Variables drawer and autocomplete expose copyable paths. At run time the engine resolves templates after each step’s inputs are prepared. Composite inner steps: steps.<id>.input.* uses the inner step authoring id from for_each_body_steps[] or while_body_steps[]. Parent for_each / while nodes use the canvas step id for their own input.* fields (for_each_items, while_condition, etc.). Legacy authoring (do not use on new graphs): for_each_body, slug step ids, catalog-agent-only canvas nodes.

Execution controls

All step types support: | Field | Description | |-------|-------------| | depends_on | Array of step IDs that must complete first | | enabled | When false, step is skipped with a synthetic completion | | retry_count | Retries after failure | | timeout_s | Per-step timeout | | no_auto_start | When true on a root, block auto-start until trigger_steps grants entry | | terminal | When true, completing this step may close an autonomous/mixed episode |

Parallelism

Parallelism emerges naturally from the DAG. Steps with no dependency relationship run concurrently. The runtime manages step scheduling, retries, and failure propagation.
Author graphs with depends_on, no_auto_start, and trigger_steps — not legacy condition, parallel, or sequence step types (removed from the engine).