Skip to content

Subagents

Subagents let an agent delegate work to a child agent with its own isolated context window. The child runs as a separate pi process — it gets its own token budget, executes with a scoped set of tools, and returns a distilled result to the parent. The parent’s conversation stays clean and focused.

When the agent calls the subagent tool, PizzaPi:

  1. Discovers available agent definitions from multiple directories (see Agent discovery paths)
  2. Creates an in-process AgentSession via the pi SDK (no child process, zero overhead)
  3. Streams progress updates through the relay server for real-time Web UI display
  4. Returns the child’s final output as the tool result

The key difference from spawn_session is that subagents run inline — they block like any other tool call and return their output directly. No cross-session messaging needed.

Create ~/.pizzapi/agents/researcher.md:

---
name: researcher
description: Read-only codebase research
tools: read,grep,find,ls
---
You are a research agent. Read files, trace dependencies,
and summarize findings without modifying anything.

The agent can invoke the subagent tool like this:

{
"agent": "researcher",
"task": "Summarize the authentication module and list all endpoints"
}

The subagent runs in its own context, reads the relevant files, and returns a summary. Only the summary enters the parent’s context window.

Agent definitions are markdown files with YAML frontmatter. PizzaPi is compatible with Claude Code agent files.

Agents are discovered from multiple directories. Within each scope, .pizzapi/ paths are checked first (higher precedence), then .claude/ paths:

  • User scope: ~/.pizzapi/agents/*.md, ~/.claude/agents/*.md — available in all your sessions
  • Project scope: .pizzapi/agents/*.md, .claude/agents/*.md — repo-specific agents (walk-up search from cwd)

When agents with the same name exist in multiple directories, the first-found wins (.pizzapi before .claude, project overrides user).

FieldRequiredDescription
nameUnique identifier for the agent
descriptionBrief description (shown in agent listings)
toolsComma-separated list of allowed tools (e.g., read,grep,find)
disallowedToolsComma-separated tools to deny (removed from inherited list)
modelModel override (e.g., claude-haiku-3; inherit to use parent model)
maxTurnsMaximum agentic turns before the subagent stops
permissionModePermission mode: default, acceptEdits, dontAsk, bypassPermissions, plan
backgroundIf true, hints the agent should run as a background task

The markdown body after the frontmatter becomes the agent’s system prompt.

---
name: reviewer
description: Code review for bugs and style
tools: read,grep,find,ls
---
You are a code review agent. Identify bugs, security issues,
and style inconsistencies. Rate findings P0-P3 by severity.
Output "LGTM" if the code looks good.

PizzaPi ships with three default agents in packages/cli/agents/. Copy them to ~/.pizzapi/agents/ to use them:

AgentToolsPurpose
researcherread, grep, find, lsRead-only codebase analysis and research
reviewerread, grep, find, lsCode review with severity-rated findings
refactorerread, write, edit, bash, grep, find, lsSafe incremental code transformations

Invoke one agent with one task:

{
"agent": "researcher",
"task": "What authentication strategy does this project use?"
}

Run multiple agents concurrently (up to 4 at once, max 8 tasks):

{
"tasks": [
{ "agent": "reviewer", "task": "Review src/auth/login.ts" },
{ "agent": "reviewer", "task": "Review src/auth/session.ts" },
{ "agent": "researcher", "task": "Find all SQL queries in the project" }
]
}

Run agents sequentially, passing each step’s output to the next via {previous}:

{
"chain": [
{ "agent": "researcher", "task": "Analyze the database schema and list all tables" },
{ "agent": "reviewer", "task": "Review the schema design described here:\n\n{previous}" }
]
}

If any step fails, the chain stops and reports which step failed.

Use the model field in agent definitions to route cheap tasks to fast models:

---
name: scout
description: Quick file exploration
tools: read,find,ls
model: claude-haiku-3
---
Quickly scan files and report what you find. Be brief.

This saves money by using an inexpensive model for exploration while the parent session uses a more capable model for synthesis.

Control which agent directories are searched:

ScopeSearches
"user" (default)~/.pizzapi/agents/ and ~/.claude/agents/
"project".pizzapi/agents/ and .claude/agents/
"both"All directories (project overrides user on name conflict)

Project-scope agents (.pizzapi/agents/ and .claude/agents/) are loaded from the repository and could contain untrusted prompts. When agentScope includes project agents:

  • PizzaPi prompts for confirmation before running them (in TUI mode)
  • Set confirmProjectAgents: false to skip the prompt (only for trusted repos)
  1. Create a .md file in ~/.pizzapi/agents/
  2. Add the required frontmatter (name, description)
  3. Optionally restrict tools and set a model
  4. Write a clear system prompt in the body
  • Be specific about the agent’s role and boundaries
  • Define output format so results are predictable
  • Restrict tools to the minimum needed (principle of least privilege)
  • Keep prompts short (< 500 words) — the agent’s context should be spent on the task, not the prompt
  • Use model routing for simple tasks — Haiku/Flash for exploration, Sonnet/Opus for analysis

Subagent progress is streamed through the relay server to the Web UI in real-time:

  • While running: The Web UI shows a streaming card with the subagent’s current output, including which agent is active and its progress
  • When complete: The card collapses to show the final result with usage statistics (tokens, cost, turns)
  • Parallel mode: Multiple progress indicators update simultaneously as each task completes

The streaming uses pi’s built-in tool_execution_update event pipeline:

  1. The subagent tool calls onUpdate() with partial results including structured details
  2. Pi core fires a tool_execution_update event with the partial
  3. The remote extension forwards it over WebSocket to the relay server
  4. The relay broadcasts to all connected Web UI viewers
  5. The UI buffers partials via RAF-based debouncing and renders live updates

No additional configuration is needed — streaming works automatically when using PizzaPi’s Web UI.

Featuresubagentspawn_session
CommunicationTool call → result (synchronous)send_message / wait_for_message
ContextIsolated in-process sessionFully independent session
UIInline in parent sessionSeparate session view
OverheadNear-zero (in-process SDK)Higher (relay round-trip, new PTY)
Best forQuick delegation, research, reviewLong-running parallel work, cross-runner tasks
Model selectionVia agent definition or parameterVia spawn parameter
Agent definitionsFile-based (~/.pizzapi/agents/)Prompt-based (inline in spawn call)

Use subagent for focused, quick tasks. Use spawn_session for independent, long-running work.

When using spawn_session, spawned sessions are automatically linked — child events surface as trigger messages in the parent’s conversation. Three trigger types are delivered:

Fires when the child session finishes. The trigger includes the child’s final output and an exitReason field:

  • exitReason: 'completed' — normal completion
  • exitReason: 'error' — the child hit a usage limit or provider failure

When a child session hits a usage limit or provider error, a session_error trigger fires immediately to the parent — before session_complete. This allows the parent to react early (e.g., retry with a different model, skip the task, or escalate to the user).

When a child calls plan_mode or AskUserQuestion, a trigger appears in the parent’s conversation. The parent responds with respond_to_trigger(triggerId, response).

Linked child sessions (spawned via spawn_session) do not trigger push notifications. Only top-level sessions — those started by a user or the runner daemon directly — send push notifications. This prevents notification spam when orchestrating multiple child sessions.

PizzaPi subagents are designed to be compatible with Claude Code agent files:

  • Agent definition files — The same .md files with YAML frontmatter work in both systems
  • Discovery paths — PizzaPi searches .claude/agents/ alongside .pizzapi/agents/
  • Frontmatter fieldsname, description, tools, disallowedTools, model, maxTurns, permissionMode, background
  • Tool name — The Web UI renders both subagent and Task tool calls with the subagent card
FeatureClaude Code (Task)PizzaPi (subagent)
ExecutionIn-processIn-process via pi SDK (isolated session)
Built-in agentsgeneral-purpose, Explore, PlanNone (define your own)
Skillsskills frontmatter fieldNot yet supported
MCP serversmcpServers frontmatter fieldNot yet supported
Hookshooks frontmatter fieldNot yet supported
Memorymemory frontmatter fieldNot yet supported
ModesSingle onlySingle, parallel, chain

To use Claude Code agents with PizzaPi, simply ensure the agent .md files are in a directory PizzaPi scans. If you already have agents in .claude/agents/, they’ll be discovered automatically.