Agent Step
Run the Tsumugi AI agent as a workflow step. The agent executes a multi-turn tool-calling loop — it reads files, runs commands, edits code, and searches the web to accomplish the task described in messages.
Basic Usage
steps:
- name: analyze-logs
type: agent
messages:
- role: user
content: |
Analyze the error logs at /var/log/app/errors.log from the last hour.
Summarize the root causes and suggest fixes.
output: ANALYSIS_RESULTThe agent uses the default model configured in Agent Settings (/settings/agent). No per-step model configuration is needed.
Configuration
The agent block is optional. When omitted, the step uses defaults from the global Agent Settings.
steps:
- name: fix-config
type: agent
agent:
model: claude-sonnet
tools:
enabled:
- bash
- read
- patch
prompt: |
Focus only on files in /etc/app/.
max_iterations: 30
safe_mode: true
messages:
- role: user
content: "Fix the invalid database_url in /etc/app/config.yaml"
output: RESULTagent Fields
| Field | Type | Default | Description |
|---|---|---|---|
model | string | global default | Model ID from Agent Settings. Overrides the default model for this step. |
tools | object | — | Tool selection and bash policy. See Tools. |
memory | object | { enabled: false } | When enabled: true, loads global and per-DAG memory into the agent context. |
prompt | string | — | Additional instructions appended to the built-in system prompt. |
max_iterations | int | 50 | Maximum tool-call rounds before the agent stops. |
safe_mode | bool | true | When true, bash commands matching dangerous patterns require HITL approval. |
Model Resolution
The agent step resolves its model from the global Agent Settings (configured at /settings/agent):
- If
agent.modelis set in the step, look up that model ID in the globalModelStore - If
agent.modelis omitted, use the global default model (DefaultModelIDfrom Agent Settings) - If no default model is configured, the step fails with:
"no model configured; set a default model in Agent Settings or specify agent.model in the step"
Model configuration (provider, API key, base URL) is managed entirely through Agent Settings. This avoids duplicating credentials in DAG files.
Tools
Available Tools
The agent step has access to these tools:
| Tool | Description |
|---|---|
bash | Execute shell commands (timeout: 120s default, max 600s) |
read | Read file contents with line numbers (max 1MB, 2000 lines default) |
patch | Create, edit, or delete files |
think | Record reasoning without executing actions |
read_schema | Look up DAG YAML schema documentation |
web_search | Search the internet via DuckDuckGo |
output | Write the final result to stdout (step-only, see Output Capture) |
The navigate and ask_user tools are not available in agent steps because they require the Web UI.
See Tools Reference for full parameter documentation.
output Tool
The output tool is unique to agent steps. When the agent calls it, the content parameter is written directly to the step's stdout. This is how the step produces its output variable.
| Parameter | Type | Required | Description |
|---|---|---|---|
content | string | Yes | The final result to output. Cannot be empty. |
The output tool is always included even if not listed in tools.enabled.
Tool Selection
Tools are filtered in two layers:
- Global policy (from Agent Settings): Tools disabled in the global
ToolPolicy.Toolsare removed. You cannot re-enable a globally-disabled tool at the step level. - Step-level
tools.enabled: If specified, only the listed tools are available (intersected with what's globally allowed).
When tools.enabled is omitted, all globally-enabled tools are available.
agent:
tools:
enabled:
- bash
- read
- thinkIf read is disabled in global Agent Settings and the step specifies enabled: [bash, read], only bash and output will be available. The step does not produce a warning for this.
Bash Policy
Bash command policy rules are loaded from the global Agent Settings and enforced via a BeforeToolExecHook on every bash tool call. Rules are evaluated in order; the first matching rule determines the action.
Step-Level Bash Policy
The step can define its own bash policy rules via tools.bash_policy:
agent:
tools:
bash_policy:
default_behavior: deny
deny_behavior: block
rules:
- name: allow-read-commands
pattern: "^(cat|head|tail|grep|find|ls)\\b"
action: allow
- name: deny-destructive
pattern: "^(rm|chmod|chown|mkfs)\\b"
action: deny| Field | Type | Values | Description |
|---|---|---|---|
default_behavior | string | allow, deny | Action when no rule matches. Global default: allow. |
deny_behavior | string | block, hitl | What happens when denied. hitl degrades to block in agent steps (no UI). Global default: ask_user (treated as block). |
rules[].name | string | — | Human-readable rule name. |
rules[].pattern | string | — | Regex pattern matched against each command segment. Required. |
rules[].action | string | allow, deny | Action when pattern matches. Required. |
When a bash command is denied, the agent receives: "Blocked by policy: bash command denied by policy: {reason}".
Messages
At least one message is required. Validation fails with "agent step requires at least one message" if messages is empty.
Message content supports variable substitution with ${VAR} syntax. Variables are evaluated at runtime via runtime.EvalString:
params:
- INPUT_FILE
- OUTPUT_DIR
steps:
- name: process
type: agent
messages:
- role: user
content: "Analyze ${INPUT_FILE} and write results to ${OUTPUT_DIR}"
output: RESULTExecution
The agent runs as a single-shot loop. It processes the user messages, calls tools as needed, and stops when either:
- The agent finishes processing with no more tool calls (normal completion)
max_iterationsis reached (the loop is cancelled)
Stderr Logging
All agent activity is logged to stderr with [agent] prefix. This keeps stdout clean for output capture.
[agent] Starting (model: Claude Sonnet, tools: 7, safe_mode: true, max_iterations: 50)
[agent] Tool call: bash {"command":"ls -la /var/log/app/"}
[agent] Tool result: [success, 1234 chars]
[agent] Assistant: I found the following log files...
[agent] Tool call: read {"path":"/var/log/app/errors.log","limit":100}
[agent] Tool result: [success, 5678 chars]
[agent] Completed (2 iterations)Tool call arguments are truncated at 200 characters. Assistant content is truncated at 500 characters with newlines replaced by spaces.
Output Capture
The step's output field captures whatever the agent writes to stdout via the output tool:
steps:
- name: analyze
type: agent
messages:
- role: user
content: "Count the number of .go files in this directory"
output: FILE_COUNT
- name: report
command: echo "Found ${FILE_COUNT} Go files"
depends: [analyze]The agent is instructed (via system prompt) to call the output tool with its final result. The content is written directly to stdout and captured by the output field.
If the agent never calls the output tool, the output variable will be empty.
Examples
Minimal
steps:
- name: summarize
type: agent
messages:
- role: user
content: "Summarize the README.md in this repository"
output: SUMMARYWith Model Override
steps:
- name: review
type: agent
agent:
model: claude-opus
messages:
- role: user
content: "Review the code in src/main.go for bugs and security issues"
output: REVIEWRestricted Tools
steps:
- name: read-only-analysis
type: agent
agent:
tools:
enabled:
- read
- think
safe_mode: false
messages:
- role: user
content: "Analyze the architecture of this codebase without modifying anything"
output: ANALYSISWith Bash Policy
steps:
- name: deploy-check
type: agent
agent:
tools:
bash_policy:
default_behavior: deny
deny_behavior: block
rules:
- name: allow-status-commands
pattern: "^(kubectl get|kubectl describe|helm status)\\b"
action: allow
prompt: |
Check the deployment status of the staging environment.
Only use read-only kubectl and helm commands.
max_iterations: 20
messages:
- role: user
content: "Report the health of all pods in the staging namespace"
output: HEALTH_REPORTPipeline with Multiple Agent Steps
params:
- REPO_PATH
steps:
- name: analyze
type: agent
messages:
- role: user
content: "Analyze the test coverage of ${REPO_PATH} and identify untested code paths"
output: COVERAGE_ANALYSIS
- name: write-tests
type: agent
agent:
model: claude-opus
max_iterations: 100
messages:
- role: user
content: |
Based on this analysis:
${COVERAGE_ANALYSIS}
Write unit tests for the untested code paths in ${REPO_PATH}.
depends: [analyze]
output: TEST_RESULTGraph DAG with Agent and HITL
type: graph
steps:
- name: draft
type: agent
messages:
- role: user
content: "Draft a migration plan for upgrading the database from v3 to v4"
output: MIGRATION_PLAN
- name: approve
type: hitl
config:
prompt: "Review the migration plan and approve if acceptable"
depends: [draft]
- name: execute
type: agent
agent:
safe_mode: true
messages:
- role: user
content: "Execute the approved migration plan: ${MIGRATION_PLAN}"
depends: [approve]See Also
- Agent Overview — Web UI agent with sessions and interactive tools
- Tools Reference — Full parameter documentation for each tool
- Chat & AI Agents —
type: chatfor simple LLM calls with DAG-based tools - HITL — Human-in-the-loop approval steps
- Data Flow — Passing data between steps with
output
