Appearance
Agent nodes
An agent node hands a single prompt turn to a registered agent runtime. The runtime decides what to do, calls tools, streams its thinking, and finishes. Z.E.N. captures the whole trace and stores it with the run.
yaml
nodes:
- id: triage
agent:
harness: hermes/acp
prompt: Read the latest 5 unread emails and flag anything that looks like an invoice.That's the whole syntax for the common case. Everything else is optional.
What "harness" means here
Pick one from the Harnesses card in Settings. Every entry there is the canonical id:
| id | What it is |
|---|---|
claude/compat | Claude Code via Z.E.N.'s built-in provider |
codex/compat | OpenAI Codex via the provider |
pi/compat | Pi via the provider (streaming chat) |
pi/agent_session | Pi running its multi-turn agent loop with tools |
gemini/agent_session | Gemini Vertex multi-turn loop |
hermes/acp | Hermes Agent over the Agent Client Protocol (stdio) |
The id is <vendor>/<implementation> — vendor is who made the runtime, implementation is how Z.E.N. talks to it. Picking a different implementation for the same vendor (when both are registered) gives you the same model with a different feature surface. Both stay listed in Settings → Harnesses with their capability chips so you can see what each supports.
Full surface
Everything below agent: is optional except harness and prompt.
yaml
- id: research
agent:
harness: hermes/acp
prompt: |
Find the three most cited papers on $topic from 2025.
Reply with title, authors, and a one-line summary each.
model: claude-sonnet-4-5
system_prompt: You are a research librarian. Cite sources.
resume_session: $previous.output.sessionId
fork_session: false
max_budget_usd: 0.50
fallback_model: claude-haiku-4-5
output_format:
type: json_schema
schema:
type: object
properties:
papers:
type: array
session_config:
workspace: research-runs
compiled:
tools:
- name: arxiv_search
description: Search arxiv by topic
schema:
type: object
properties: {topic: {type: string}}prompt supports $nodeId.output substitution from upstream nodes — the same syntax every other node kind uses.
session_config is opaque per-harness bootstrap config (passed once when the session opens). compiled is per-turn data — tools, options, anything the harness needs each turn. Most harnesses don't need either; leave both out.
resume_session reads a sessionId from a previous agent node's output and continues that conversation. Only works when the harness's capability chip includes resume (Settings → Harnesses).
What you get back
A successful agent node writes JSON to $nodeId.output:
json
{
"text": "The three most cited papers are…",
"sessionId": "f4d5584e-95a8-4012-b1e7-2cc195517a1c",
"reason": "end_turn"
}text is the final assistant message. sessionId is what you pass to resume_session later. reason is the harness's stop signal — end_turn, max_tool_calls, max_turns, cancelled, error, or whatever the underlying runtime returns.
Downstream nodes reference fields with the usual syntax:
yaml
- id: respond
depends_on: [research]
prompt: Summarize this in 100 words → $research.output.textWatching the run
Open a workflow run, click the Agent tab. Every message chunk, tool call, plan update, and error from every agent node streams there in real time, grouped by node id. The same events live in the database as workflow_events with event_type: runtime_event, so any UI subscribing to /api/stream/<conv> sees them too.
Errors
Agent nodes fail like any other — state: failed with a verbatim error message. Common ones:
| Error | What happened |
|---|---|
Unknown harness 'X' | The id isn't registered. Check Settings → Harnesses. |
binary 'hermes' not found on PATH | The ACP binary isn't installed or isn't on the daemon's PATH. Set ZEN_HERMES_BIN to the absolute path. |
no credentials for provider 'google' | The underlying provider needs an API key. Set GEMINI_API_KEY or whichever env var the error names. |
agent harness resolution failed: … | The harness threw at session open. Check the daemon log for the harness's stderr tail — Z.E.N. captures the last 8KB. |
When to use this vs prompt:
prompt: runs one chat turn through the workflow's configured provider — fast, cheap, no tools by default.
agent: opens a session with a runtime that can plan, call tools, and emit a richer trace. Slower, more expensive, more capable. Use it when the work isn't a single answer — when the model needs to do something.
Related
- Tool nodes — deterministic single-tool invocation, no AI
- Hermes (ACP) — installing + wiring Hermes
- What is a harness? — the harness registry concept in depth