8 Step Types
Usage and field reference of single Agent, group_chat, agent_based, code, classifier, state_machine, sub_workflow, manual_approval.
Braidrun currently offers 8 step types. Only one main mode must be selected for each step; other fields are enhancements (retry, condition, manual_approval, etc.).
1. Single — Single Agent
The most common step: asking an Agent to perform a task.
- step: plan
agent: planner
input: "Plan a daily report pipeline"
depends_on: [intro]
retry:
maxAttempts: 3
backoff: exponentialAllowed combined enhancements: parallel、repeat_until、iterate_over.
2. group_chat — Multi-Agent Discussion
Multiple Agents take turns speaking on the same topic. You can specify the speaking order, or let the orchestrator decide.
- step: peer_review
group_chat:
agents: [coder, reviewer]
topic: "Review the change"
max_rounds: 6
repeat_until: "score >= 8"repeat_until The conditional expression will be evaluated after each round; if it is met, group_chat will end.
3. agent_based — Dynamic Delegation
The orchestrator agent selects workers and dispatches subtasks at runtime. Compared with static group_chat, it is more suitable for the scenario of "I don't know who is suitable, let the planner decide".
- step: delegate
agent_based:
orchestrator: planner
workers: [coder, analyst, writer]
input: "{{steps.plan.output}}"4. Code — Deterministic Script
Supports 7 languages: Python / JavaScript / TypeScript / Bash / Ruby / Lua / CLI. In production, they run in a sandboxed container by default.
code_preamble:
python:
inline: |
import json, os
workflow:
- step: transform
code:
language: python
timeout: 30
script: |
data = json.loads(os.environ.get("STEP_INPUTS", "{}"))
print(json.dumps({"rows": len(data)}))When multiple code steps need to share imports or utility functions, use the top-level code_preamble, grouped by programming language; at run time it's automatically prepended to the script of code steps in the same language.
5. Classifier — Routing Variable
Let the Agent take "Which category the current context belongs to" as output and write it into a routing variable for use by condition in subsequent steps.
- step: classify_request
classifier:
agent: router
input: "Classify the user intent"
categories:
- name: coding
description: Needs code changes
- name: analysis
description: Needs investigation only
output_variable: route
- step: coding_path
agent: coder
condition: route == coding
depends_on: [classify_request]Recommended classifier + condition instead of complex on_success.next String array.
6. state_machine — Nested State Machine
Running as a DAG composite node, it can have several states and transitions inside it.
- step: triage
state_machine:
initial: ingest
states:
- name: ingest
agent: planner
transitions:
- condition: route == analysis
next: analyze
- condition: route == coding
next: code
- name: analyze
agent: analyst
transitions:
- next: DONE
- name: code
agent: coder
transitions:
- next: DONEDo not configure parallel in the outer steps; there is only one flow entering state_machine.
7. sub_workflow — Sub-Workflow Module
Call another published Module. Input/output adheres to the contract declared by the module; loop detection is performed at runtime.
- step: fetch_report
sub_workflow:
workflow_id: 0d2c…ab12 # UUID of the published module
version_strategy: pinned
pinned_version: "2.0.1"
inputs:
app_id: "{{var:app_id}}"
window: last_7d
outputs:
report_path: report_path # parent variable <- module outputList all built-in modules: Built-In Module Library.
8. workflow_output_read — Cross-Workflow Reads
A system-level step: it reads values from the outputs published by an execution of another workflow (see publish_outputs below) and writes them into this workflow's variables. By default it reads the source workflow's most recent successful execution.
- step: read_spend_report
workflow_output_read:
workflow_id: 7f3a…9c21 # source workflow UUID
selector:
mode: latest_successful
outputs:
report_url: spend_report_url # published name -> local variable
missing_policy: use_default
defaults:
report_url: ""selector.mode— Defaults to latest_successful (the most recent successful execution); you can also use execution_id to pick a specific execution, or input_variable to take the execution id from a variableoutputs— Required: a mapping from published output names to this workflow's variable namesmissing_policy— When an output is missing: fail (default, the step errors), skip_step (skip this step), or use_default (take the value from defaults)require_workflow_status— By default the source execution must have status COMPLETED
Step-Level Enhancements
The following fields aren't standalone step types but enhancement configs added onto a step.
manual_approval — Manual Approval
Add a manual gate before any step: execution pauses and notifies the reviewer, continues on approval, and stops on rejection or timeout.
- step: deploy
agent: deployer
input: "Deploy to production"
manual_approval:
enabled: true
approvers:
- team-lead@company.com
timeout: 3600
approval_message: "Ready to ship?"View the complete parameter list and approval process: Manual Approval.
publish_outputs — Publish Step Outputs Externally
After a step succeeds, publish named outputs for other workflows to read via workflow_output_read. By default, no internal artifacts are published.
- step: build_report
agent: analyst
input: "Summarize yesterday's spend"
publish_outputs:
- name: report_url
type: url
source: "{{steps.build_report.output}}"
description: Latest spend report link
visibility:
scope: teamsource— Required: a template expression evaluated at publish time, e.g. referencing this step's outputtype— Defaults to text; also supports markdown, json, number, boolean, url, file, and morevisibility.scope— private (default, only the workflow owner), team, or workflow_allowlist (paired with the allowed_workflows allowlist)
structured_output — Structured Final Output
Single-Agent steps only: the Agent calls tools as usual, but its final reply is parsed into a structured result against a registered schema; when write_to is set, the result is also serialized to a file.
- step: final_commentary
agent: analyst
input: "Write the commentary"
structured_output:
schema: ai_commentary_parts
write_to: "{{var:output_dir}}/commentary.json"
fail_on_empty: trueschema— Required: the name of a registered structured schemawrite_to— Optional: the file path to write to, with template-variable support; the write format currently supports only jsonfail_on_empty— Whether to fail the step when the structured result is empty; defaults to true
A Quick Look at Combo Limits
parallel— Only single Agent steps can be configuredrepeat_until— Only single Agent or group_chatiterate_over— Only single Agent or codestructured_output— Single-Agent steps onlystate_machine— Run as a DAG composite node, do not configure parallel in the outer layer