Skip to content

About

A pi extension that delegates work to focused subagents.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

pi-subagents

A pi extension that delegates tasks to focused, in-process subagents. Each subagent runs as a nested session with its own system prompt, tools, and context window — allowing long investigations or parallel reviews to complete without consuming main-conversation tokens.

An interactive list beneath the prompt displays active subagents, their model, reasoning effort, and context usage. Arrow keys navigate the list, enter opens a full-screen view to inspect or steer a subagent, and typing @name routes messages directly to a subagent without spending a turn on the main model.

… inspector Analyze dependencies       claude-3-5-haiku 12%
… finder    Find tool definitions      claude-3-7-sonnet (high) 31%
✓ counter   Count lines in src/test    gemini-2.5-flash 18%

How It Works

Subagents are real pi AgentSession instances created inside the host process:

  • Isolated context: Each subagent operates within its own context window. Only the final answer or concise completion status is delivered back to the main conversation.
  • In-process & detached: Runs execute asynchronously in the background. The main model receives an ID immediately upon spawning and continues working while subagents run concurrently.
  • Persistent transcripts: Each subagent writes its own transcript file nested under the parent session. Resuming a subagent continues its existing conversation history.
  • Recursion guard: Subagent sessions are instantiated without extension tools, preventing nested subagents from spawning further children.

For domain terms and architectural records, see CONTEXT.md, docs/specifications/, and docs/adr/.

Requirements

  • Node.js 22.19 or newer
  • pi installed and authenticated

Installation

Install pi-subagents globally across all projects or locally to a checkout:

pi install git:github.com/Integralist/pi-subagents      # all projects
pi install git:github.com/Integralist/pi-subagents -l   # this project only
pi install .                                            # from a local clone
Command Description
pi list Display installed extensions and packages
pi update <source> Pull latest extension updates
pi remove <source> Uninstall extension
pi install <source>@v0.1.0 Pin a tag, branch, or commit

Quickstart

To try the extension in a standalone session without altering settings:

make install   # npm install
make try       # launches pi with this extension loaded

Prompt the model to delegate through a saved agent file or a caller-defined character:

  • "Use the saved explore subagent to find tool definitions in src/"
  • "Create a read-only performance analyst to review src/queue.ts"
  • "Use the saved reviewer subagent to inspect the current diff"

A saved subagent takes its model setting, thinking level, tools, system prompt, and turn limit from its agent file. Model selection is subject to the fallback policy; omitting model inherits the main model. A caller-defined inline subagent may choose its own execution settings. Model queries resolve fuzzily against configured providers (for example, "flash", "haiku", or "gemini 3.7"). An ambiguous query opens an interactive model-selection dialog.

Physical and Virtual Main Selections

Subagents run physical models only. They do not load the main session's router or change its selected model or effort. No Auto extension is required.

  • With a physical main selection, omitted settings inherit that selected model and effort, even if an older response came from another model.
  • With a native virtual selection, inheritance uses the latest successful physical assistant response on the active branch. Its catalog model and its recorded effort belong together; failed or aborted responses and opaque router state are not evidence. The virtual selection's effort is never reused.
  • If that physical target is unknown or no longer in the catalog, name an explicit physical model. An effort-only override is not enough. Explicit model and effort overrides apply independently; if no physical effort is known and effort is omitted, the subagent SDK chooses its default.
  • Model choices exclude virtual entries, including entries listed alongside physical models under the same provider. An explicit virtual target refuses to start rather than silently substituting another model.

Startup and resume capture their physical settings before waiting for a slot. Later main-selection or routing changes do not alter accepted runs. Allowed runtime fallback uses the captured physical main pair, preserving any explicit subagent effort. If that fallback is unknown, the original failure is reported with guidance to choose a physical model; it never retries a virtual label or an unspecified SDK model. The strict no-fallback policy below is unchanged.

The default runner uses the chosen physical provider's public parent transport and auth API, including providers registered only by a parent extension. The child does not reload that extension or copy its stored credentials. Only the chosen physical model is available in the child; no virtual definitions or other provider catalogs are inherited. A missing parent provider fails with guidance rather than silently using a default transport. Allowed fallback still uses only the captured physical pair described above.

Queued rows show accepted settings. Once a session is created, rows show the model and effort actually applied by Pi, including fallback and effort clamping. The same rules apply to named spawns, inline spawns, and mention startup/resume.

Interacting with Subagents

Subagent List

The list displays beneath the editor while subagents are active. Completed rows linger for 10 seconds before clearing.

Key Action
↓ Focus list and move down
↑ Move up (or return to prompt from top row)
← → Move across columns
enter Open full-screen conversation view
delete Stop selected subagent
escape Exit list focus

Navigation keys only intercept when the prompt is empty.

Full-Screen Conversation Viewer

Pressing enter on a subagent opens its conversation transcript in full view:

Key Action
↑ ↓ pgup pgdn Scroll transcript history
home end Jump to beginning or end
text input Type a message; enter sends it
ctrl+x Stop subagent execution
escape Clear input or close the viewer

Direct Mentions (@handle)

Subagents receive a unique handle based on their name (e.g. @explore, @explore-2). Type @handle <message> at the main prompt to route input directly:

Input Action
@explore inspect auth path Steer, resume, or auto-launch @explore
@explore Regular text; a bare handle is not routed
ask @explore about auth Regular text; only leading mentions route
@main @explore text Route to the main model after stripping @main
@unknown hello Regular text; handle is unknown and no saved agent matches

Mentioning a running subagent injects the message before its next turn. Messaging a completed subagent resumes it with full conversation history. Mentioning a saved agent file that has not yet run starts it.

Defining Subagents

Subagents can be defined dynamically at spawn time or saved as reusable Markdown files.

Caller-Defined Inline Characters

Callers and skills can define a one-off character with spawn_inline_subagent:

spawn_inline_subagent(
  name: "security",
  system_prompt: "You are a Security and Abuse reviewer...",
  tools: ["read", "grep", "find", "ls"],
  prompt: "Review the diff at $TMPDIR/review.diff...",
  description: "Security and abuse review",
)

system_prompt is the complete character definition. prompt is the task that character performs. The main model supplies the short name; it must not ask the user to invent one. An inline call does not inherit or compose with an agent file, even when their names match.

Required inline fields are name, system_prompt, prompt, and description. Optional inline fields are tools, model, thinking, max_turns, wake_on_finish, and allow_model_fallback.

Reusable Agent Files

Agent files are Markdown documents with YAML frontmatter:

---
name: explore
description: Reads codebase files and reports findings
tools: [read, grep, find, ls, bash]
color: cyan
thinking: high
maxTurns: 20
# model: haiku
---

You are a read-only codebase explorer. Answer the prompt with specific file
references (`path/to/file.ts:42`) and outline unexamined areas.

Launch it exactly as configured:

spawn_named_subagent(
  subagent_type: "explore",
  prompt: "Find the tool definitions in src/",
  description: "Find tool definitions",
)

Required frontmatter fields:

  • name: identifier used for delegation and @handle routing.
  • description: summary displayed in tool descriptions and the UI list.

Optional agent-file frontmatter fields, set in the file rather than at launch:

  • tools: pi tool allowlist; omission uses the read-only defaults.
  • model: model query such as haiku; omission inherits the main model.
  • thinking: reasoning effort such as off, low, or high.
  • color: terminal colour; omission selects the next palette colour.
  • maxTurns: turns before the wrap-up warning; the default is 20.
  • allowModelFallback: whether to substitute or retry on the main model; defaults to true. Set the YAML boolean false to require an explicit model and refuse fallback. Non-boolean values make the agent file invalid.

Control Model Fallback

By default, an unavailable model or a dismissed model-selection dialog uses the main model. A run that fails on a different explicit model also retries once on the captured physical main model. These substitutions require a known physical target as described above.

For a subagent that must stay on its selected model, pass allow_model_fallback: false to spawn_inline_subagent, or set allowModelFallback: false in its saved agent file. Both spellings require an explicit model. An unavailable model, dismissed selection, or missing model refuses to start; a runtime failure returns a failed outcome without retrying on the main model. Inline model, thinking, and fallback settings persist when that subagent is resumed through @handle.

{
  "model": "provider/model-id",
  "thinking": "xhigh",
  "allow_model_fallback": false
}

Replace provider/model-id with an available model; these are the execution fields to include alongside the required inline character and task fields. The flag controls model fallback, not thinking-level support or test outcomes. Inspect partial changes before retrying a failed run: neither mode rolls back edits made before failure.

Discovery Tiers

Pi discovers agent files across two tiers (project overrides user on collision):

  1. ~/.pi/agent/agents/*.md — User agents available globally
  2. <project>/.pi/agents/*.md — Project-specific agents

Example Agents

Nine template definitions live in examples/:

  • General workflow: explore.md, reviewer.md, scribe.md
  • Dimension-split code review: behaviour.md, security.md, reliability.md, maintainability.md, plan-adherence.md, verifier.md

To copy examples into the active project:

make agents   # copies examples/*.md into .pi/agents/

Tool Reference

Six tools manage subagents:

Tool Parameters Purpose
spawn_named_subagent subagent_type, prompt, description Launch a saved agent file
spawn_inline_subagent name, system_prompt, prompt, description Launch an inline character
get_subagent_result id Wait for and retrieve an outcome (up to 10 minutes)
list_subagents none Summarize session subagents
steer_subagent id, message Steer a running subagent
stop_subagent id Stop and preserve partial results

Choose the spawn tool by character source:

Need Tool
Launch a reviewed saved agent spawn_named_subagent
Supply a one-off character spawn_inline_subagent
Customize a saved character Not supported

No tool accepts both subagent_type and system_prompt. Saved agent files cannot be overridden at launch.

Workflow: Dimension-Split Code Review

A code review skill can decompose analysis across parallel dimensions:

graph TD
    Main[Main Agent] -->|spawn| S1[security: diff review]
    Main -->|spawn| S2[reliability: concurrency review]
    Main -->|spawn| S3[maintainability: conventions review]
    S1 -->|findings JSON| Main
    S2 -->|findings JSON| Main
    S3 -->|findings JSON| Main
    Main -->|spawn| V[verifier: refute findings]
    V -->|verified findings| Main
Loading
  1. Parallel review: The main agent writes the diff once to a temporary file and launches saved dimension subagents whose agent files restrict their tools to read, grep, find, and ls.
  2. Concurrent execution: Subagents run concurrently up to the configured limit without queueing.
  3. Status polling: list_subagents inspects overall progress across all dimensions in a single call.
  4. Adversarial verification: Verification subagents (verifier) challenge tentative findings to eliminate false positives before final presentation.

Configuration

Configure concurrency limits in ~/.pi/agent/settings.json or project-level .pi/settings.json. Project settings override user settings; the default is 5:

{
  "subagents": {
    "limit": 5
  }
}

Development & Testing

Run verification checks before submitting changes:

make verify
Target Check
make test Unit and integration suite under vitest
make typecheck TypeScript type checking (tsc --noEmit)
make lint Lint and formatting check with Biome
make format Apply formatting and safe lint fixes with Biome
make load-check Six tools registered through Pi's public loader
make host-check Offline type, test, lint, and public-load checks

The compatibility checks cover the installed Pi 0.84.2 physical host and Pi 1.2.0 native virtual host. They do not establish compatibility with untested versions or installation readiness. Development pins and the lockfile are unchanged; no dependency installation is needed for an already installed host.

To check another installed host, supply the directory containing its node_modules (not a router source dependency):

PI_SDK_ROOT=/path/to/installed-host make host-check

The host check disables Vitest and Jiti caches and aliases only the public Pi packages and TypeBox. Both hosts exercise the production-default SDK factory without a session-factory override, using parent-extension-only faux transports and synthetic API-key/OAuth credentials. Pi 1.2.0 also checks native virtual inheritance through that default path.

Separate native registered-tool and mention tests use the injected session factory seam with an isolated faux runtime. They check caller behavior, queue capture and resume, not the default transport handoff. All child sessions are extension-free; no Auto extension, live provider calls or real credentials are used.

Licence

MIT

About

A pi extension that delegates work to focused subagents.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages