agent.yaml reference
yaml
name: research_crew # lowercase [a-z][a-z0-9_]*; becomes the schema/agent key
model: anthropic/claude-opus-5 # or openai/gpt-4o, mock/echo (offline). Prefix picks the provider
maxTokens: 16000 # per model call (default 16000)
reasoning_effort: low # OpenAI reasoning models: none|low|medium|high. gpt-5.6+ need it to use tools
limits:
maxStepsPerTask: 50 # hard cap on loop steps per task (default 50)
maxAttemptsPerTask: 20 # opt-in poison-pill: fail terminally after N faulted attempts (conversation turns and approval wakes never count)
maxWallClockMin: 240 # opt-in wall-clock budget: a task run older than this fails with a timeout
# class. Parked time counts; sessions are exempt (conversations live for days)
contextWindow: 200000 # tokens; defaults per provider (anthropic 200k, openai 128k). Drives compaction
builtin_tools: [web_search] # standalone tools; see the Tools docs
sandbox: # true, or a block: gives the agent a computer (bash + file tools)
image: node:22-slim # docker image (local backend) or E2B template (cloud backend)
network: false # egress from the sandbox (default: none)
approval: always # a human approves each bash command (default), or "never"
env: [MY_APP_DB_URL] # which of YOUR variables the sandbox may see (folds into env.required)
env:
required: [TICKETS_API_KEY] # missing values fail fast at startup
optional:
REGION: "us-east-1" # fallback used when unset
bind: # BETA — per-agent redirection: this agent reads the logical
SQL_DATABASE_URL: CMO_DB_URL # name from a different process variable. Lets co-located
# agents give the same key different values (per-agent DB roles)
default_process: daily-digest # process run when a trigger names none (only useful with workflows/)
agents: # BETA — cross-agent calls; both sides must declare (see Guides → Cross-agent calls)
can_call: [cfo] # peers this agent may delegate to (grants the call_agent tool)
accept_from: [cmo] # peers this agent consents to answer
telegram:
bot_token_env: REPORTER_BOT_TOKEN # this agent gets its own Telegram bot; see Channels → Telegram- Every field is optional except that the file must exist at the agent root (
subagents/*/agent.yamlmay omit anything, defaults apply). instructions.mdbeside it is the system prompt; missing → a generic default.- Model routing is by prefix:
mock/(offline echo),anthropic/,openai/,bedrock/. Subagents may each use different models, and SDKs load lazily. Auth, reasoning models, Bedrock ids, and pricing overrides: Model providers. mock/echois fully offline and deterministic: it repliesecho(<the task's input>)and never calls tools, useful for asserting orchestration without a model bill.mock/slowis the same echo at three seconds per call, slow enough tokill -9mid-run. Mock models get no default context window, so they never trigger compaction.envvalues reach tool handlers asctx.env, never via rawprocess.env. A builtin tool's required env (likeTAVILY_API_KEYforweb_search) folds intoenv.requiredautomatically.sandbox: true(or the block above) grants bash plus the workspace file tools; the operator picks the backend withTOREN_SANDBOX(docker or e2b). Full details in Sandbox.telegram.bot_token_envnames the env var holding this agent's Telegram bot token — the standard way to put an agent on Telegram. (The all-agents fleet bot viaTELEGRAM_BOT_TOKENis an operator tool.)telegram.groups: observeturns group chats into silent observation — recorded to a stable table, never answered;telegram.observe.updatespicks the kinds (message,edited_message,my_chat_member). Details in Telegram.- An agent may define several named processes: a
workflows/directory with one file per process (workflows/daily-digest.ts,workflows/weekly-report.ts), filename → process name. Triggers select one by name (--process,POST /runs {process},schedule create --process);default_processpicks the one used when a trigger names none; otherwisemain, or the sole process. A loneworkflow.ts(or none) is a single process namedmain, so existing agents are unchanged. See the Workflow API.
Planned keys (planned, not yet implemented, will fail silently today, don't set them): fallbacks, runtime: short|long, sandbox.snapshotEvery, limits.maxWaves, limits.maxBudgetUsd.