Skip to content

subagent-tool

Delegate tasks to specialized agents, each running as a separate tallow process with its own context window. Three execution modes:

  • Single, one agent, one task, wait for result
  • Parallel, multiple independent tasks running concurrently
  • Centipede, sequential steps where each receives the previous output via {previous} placeholder

Each subagent can use a different model, have a different role description, and work in a different directory. JSON mode captures structured output for the parent agent to process.

Multiple agents run in parallel but the conversation blocks until all finish. Results appear inline.

Foreground workers now have a liveness watchdog so one stuck worker cannot pin a full parallel run indefinitely.

  • startup timeout detects workers that never begin producing activity
  • inactivity timeout covers quiet periods between model/tool events
  • tool-execution timeout widens the window while a tool call is still running
  • message_update, message_end, and tool execution events count as heartbeats
  • stalled workers are marked stalled and terminated with SIGTERM, then SIGKILL after a grace period when needed
  • parallel summaries show separate completed/failed/stalled counts

Stalls are not always deadlocks. Common causes include slow provider startup, very long tool execution with no emitted progress, or an interactive confirmation path that cannot complete inside JSON-mode subagents.

When stalled workers happen with partial completion:

  • stalled workers are automatically retried once in single-worker mode with scope-narrowing retry guidance and explicit model pinning when possible
  • if any workers still stall after auto-rerun, the call returns partial results with isError: true and remediation guidance

Agents run independently while the conversation continues. Check progress with subagent_status. These are background agents, not to be confused with background tasks which are raw shell commands. Background agents are full tallow processes with their own context, tools, and model access. Both appear in the widget but in separate sections.

Completed background subagents are compacted to keep memory bounded:

  • final output text is always retained for subagent_status
  • a bounded tail of recent messages is kept for debugging
  • full message history is dropped after completion unless explicitly overridden
  • stale completed records are removed automatically after a retention window
Env varDefaultEffect
TALLOW_SUBAGENT_KEEP_FULL_HISTORYunsetset to 1 to keep full message histories (debug mode)
TALLOW_SUBAGENT_HISTORY_TAIL_MESSAGES24number of recent messages to retain after compaction
TALLOW_SUBAGENT_COMPLETED_RETENTION_MINUTES30how long completed/failed background records remain in memory
TALLOW_SUBAGENT_STARTUP_TIMEOUT_MS60000foreground startup timeout before a worker is marked stalled
TALLOW_SUBAGENT_INACTIVITY_TIMEOUT_MS180000foreground inactivity timeout when no tool call is active
TALLOW_SUBAGENT_TOOL_EXECUTION_TIMEOUT_MS600000foreground timeout while a tool call is still running
TALLOW_SUBAGENT_WATCHDOG_KILL_GRACE_MS5000SIGTERM grace window before watchdog escalation to SIGKILL

Subagents run in two modes:

  • Foreground, the parent agent blocks waiting for the result. Used in single mode and centipede mode where the output feeds back into the next step.
  • Background, the agent runs independently. Used when the parent says background: true. The agent works while the conversation continues.

Both types appear in the tasks widget with colored @name identifiers, live activity status, and elapsed time. Background agents persist until their task completes or the session ends.

Subagent lines follow shared presentation roles: identity/action context is emphasized, while process-output chatter is deliberately dimmed.

When you press Escape, background agents are killed but background tasks are not. Agents are delegated cognitive work tied to the conversation — if you interrupt, you want all agent work to stop. Background tasks (dev servers, builds, test watchers) are infrastructure that should keep running.

Agents are defined in markdown files in agent directories. They support frontmatter fields that control tool access, resource limits, and model routing.

Agents are loaded from multiple locations with a priority system:

  1. Bundled agents — shipped with tallow
  2. Package agents — from settings.json packages
  3. ~/.claude/agents/ — user-level, Claude Code compatibility
  4. ~/.tallow/agents/ — user-level, tallow
  5. Project .claude/agents/ — project root, Claude Code compatibility
  6. Project .tallow/agents/ — project root, tallow

Project root is determined by git rev-parse --show-toplevel, falling back to the current working directory when not in a git repo. This replaces the previous ancestor-walk behavior.

Priority: last wins per name. Within a scope, .tallow/ takes precedence over .claude/. This means a project .tallow/agents/researcher.md overrides both .claude/agents/researcher.md in the same directory and ~/.tallow/agents/researcher.md.

Subagents inherit the parent session’s model by default. Precedence:

  1. Per-call model parameter (highest)
  2. Agent frontmatter model field
  3. Parent session model (inherited automatically)

This means you don’t need to specify a model in most cases — agents use whatever model you’re running in the main session.

Subagents can run in detached temporary git worktrees by setting:

  • single mode: top-level isolation: "worktree"
  • parallel mode: per-task tasks[i].isolation: "worktree"
  • centipede mode: per-step centipede[i].isolation: "worktree"

Frontmatter defaults also support isolation:

---
name: reviewer
description: review code changes
isolation: worktree
---

_defaults.md can set a fallback isolation for all agents:

---
isolation: worktree
---

Isolation precedence is:

  1. per-call parameter
  2. agent frontmatter
  3. _defaults.md frontmatter

Instead of specifying a concrete model in agent frontmatter, you can use a routing keyword to express cost intent. The routing engine picks the best model from your available providers automatically.

KeywordEffect
auto-cheapCheapest model that meets the task’s complexity
auto-ecoAlias for auto-cheap
auto-balancedBest fit for task complexity, then cheapest
auto-premiumMost capable model available
---
name: explore
model: auto-cheap
---

Routing keywords integrate with the existing model routing system:

  • Per-call hints override keywords. If the parent LLM passes costPreference: "premium", it wins over auto-cheap in frontmatter.
  • Explicit model overrides everything. model: "haiku" in a subagent call always takes precedence.
  • Keywords force auto-routing. Even when routing is disabled in settings, a routing keyword activates the task classifier and model selection algorithm.

Keywords are case-insensitive (AUTO-CHEAP works).

You can set default auto-routing behavior in settings.json:

{
"routing": {
"enabled": true,
"primaryType": "code",
"costPreference": "balanced"
}
}

Supported values:

  • routing.enabled: true or false
  • routing.primaryType: "code" | "vision" | "text"
  • routing.costPreference: "eco" | "balanced" | "premium"

Settings precedence is:

  1. <project>/.tallow/settings.json
  2. ~/.tallow/settings.json
  3. built-in defaults (enabled: true, primaryType: "code", costPreference: "balanced")

Model selection precedence is:

  1. explicit model parameter
  2. per-call routing hints (costPreference, taskType, complexity, modelScope)
  3. routing keyword from agent frontmatter (auto-cheap, etc.)
  4. routing defaults from settings

When a requested agent name doesn’t match any discovered agent, the tool recovers gracefully instead of erroring:

  1. Exact match — found agent with matching name
  2. Best match — fuzzy match (prefix, suffix, contains) above a confidence threshold
  3. Ephemeral — creates a temporary agent with built-in defaults

The result metadata shows the resolution source (user, project, ephemeral) for transparency.

Create a _defaults.md file in any agent directory to set fallback values for all agents:

---
maxTurns: 25
tools: read, bash, edit, write, grep, find, ls
missingAgentBehavior: match-or-ephemeral
---

Supported in:

  • ~/.tallow/agents/_defaults.md (user-level)
  • ~/.claude/agents/_defaults.md (user-level)
  • <project>/.tallow/agents/_defaults.md (project-level)
  • <project>/.claude/agents/_defaults.md (project-level)

Precedence: project defaults override user defaults. Defaults only apply when neither the per-call parameters nor the agent frontmatter specify a value.

Tool denylist — removes tools from the default set. Takes precedence over the tools: allowlist.

---
name: researcher
description: Research agent with restricted write access
tools: read, bash, edit, write
disallowedTools: bash, write
---

Effective tools: read, edit (allowlist minus denylist).

If only disallowedTools is set, it filters against the built-in tool set: read, bash, edit, write, grep, find, ls.

---
name: safe-analyzer
description: Read-only analysis agent
disallowedTools: bash, write, edit
---

Effective tools: read, grep, find, ls.

The subprocess is spawned with --tools <effective-list>.

Hard limit on tool-use turns. When the subprocess reaches this many tool_call events, it receives SIGTERM (then SIGKILL after 5 seconds).

---
name: quick-search
description: Fast search with budget limit
maxTurns: 5
---

The extension injects a budget hint into the subprocess system prompt:

You have a maximum of 5 tool-use turns for this task. Plan your approach to complete within this budget. If you are running low, output your best result immediately.

When the limit is reached, the result includes a [Terminated: reached maxTurns limit of 5] annotation.

This is hard enforcement — the process is killed. Compare with agent-commands-tool which does soft enforcement only (system prompt hint, no kill).

Restrict which MCP servers connect in the subprocess. Passes server names as PI_MCP_SERVERS=slack,github environment variable.

---
name: github-helper
description: Agent with GitHub MCP access only
mcpServers: github
---

Multiple servers:

mcpServers: slack, github, linear

Or as YAML array:

mcpServers:
- slack
- github

Inline server definitions (objects) are not supported in v1:

mcpServers:
- name: custom-server
command: node
args: [server.js]

This will show a warning and be skipped. Use string references to servers configured in ~/.tallow/settings.json or .tallow/settings.json.

See mcp-adapter-tool for how PI_MCP_SERVERS filtering works.

---
name: test-writer
description: Writes tests with restricted tool access and turn limit
tools: read, bash, edit, write
disallowedTools: write
mcpServers: github
maxTurns: 15
model: sonnet
---
You are a test writing specialist. Your job is to read existing code,
understand the patterns, and write comprehensive test suites.
Focus on:
- Edge cases and error handling
- Clear test names and descriptions
- Minimal setup/teardown
Use the GitHub MCP server to check for existing test conventions in the repo.

Tallow ships with agent templates in templates/agents/. These are copied to ~/.tallow/agents/ during installation and can be customized or overridden.

Cheap, fast codebase discovery. Uses auto-cheap routing to pick the most economical model, restricted to read-only tools, and limited to 5 tool turns.

---
name: explore
description: Cheap, fast model for codebase discovery
tools: read, grep, find, ls
maxTurns: 5
model: auto-cheap
---

Use it for reconnaissance tasks that don’t need a frontier model:

subagent(agent: "explore", task: "find all API route handlers in src/")
subagent(agent: "explore", task: "what testing framework is used and where are tests?")
subagent(agent: "explore", task: "list all database models and their relationships")

The explore agent has no bash, write, or edit access — it can only read, search, and list. This makes it safe for untrusted exploration and keeps costs low.

AgentPurposeModel
scoutDeep codebase recon with bash accessinherited
architectSystem design and architectureinherited
workerGeneral task executioninherited
reviewerCode reviewinherited
debugDebugging and troubleshootinginherited
refactorCode refactoringinherited
plannerTask planning and breakdowninherited
tallow-expertTallow internals, extensions, and configurationinherited

All bundled agents can be overridden by placing a file with the same name in ~/.tallow/agents/ or your project’s .tallow/agents/.

Subagents and the task board are deeply integrated. When a subagent claims a task (via manage_tasks with owner), the task widget shows (@agent-name) attribution in the agent’s color. The in-progress spinner animates only while the owning agent is actively running, if the agent finishes but the task isn’t marked complete, the spinner switches to a static indicator.

In-progress tasks show their activeForm text (e.g., “Writing tests”) instead of the subject, giving live visibility into what each agent is doing.

On wide terminals, running agents appear in a right column alongside the task list. On narrow terminals, they stack below. See tasks, responsive layout for the full breakdown.

Subagents and background bash tasks share display space in the tasks widget. When both are active, agents render above background tasks with a spacer between. Each gets independent truncation based on the available width.

The footer shows a (sub) count when subagents are running. The tasks extension adds a separate agent bar to the status area: @main @alice @bob · 2 teammates with colored names matching the widget display.