@williamcr01/pi-subagents
Recursive, isolated, asynchronous subagents for Pi
Package details
Install @williamcr01/pi-subagents from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@williamcr01/pi-subagents- Package
@williamcr01/pi-subagents- Version
0.2.5- Published
- Sep 8, 2026
- Downloads
- 681/mo · 681/wk
- Author
- williamcr01
- License
- MIT
- Types
- extension
- Size
- 333.9 KB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
],
"image": "https://raw.githubusercontent.com/williamcr01/pi-subagents/main/assets/pi-subagents-demo.png"
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-subagents
Recursive, isolated, asynchronous subagents for the Pi coding agent.
pi-subagents adds background delegation to Pi without external npm dependencies. Spawn several focused agents in parallel, let agents recursively delegate their own work, monitor the live tree in Pi's footer, inspect real child transcripts, and collect results when they finish.

Features
- Asynchronous spawning —
spawn_agentreturns immediately while the child runs in its own Pi process and session. - Recursive delegation — children can create grandchildren within the configured depth budget.
- Parallel work — concurrency is configurable, including unlimited mode with
maxConcurrency: -1. - Live monitoring — the footer shows a recursive status tree with provider/model, activity, and elapsed time.
- Interactive transcripts — open any child to read its complete Pi session from the original delegation prompt, including messages and tool calls.
- Steering and follow-ups — message a running child to redirect it, or message a finished child to continue its existing session.
- Automatic delivery — finished results arrive with the next completed parent tool result. An idle parent receives one batch and resumes.
check_subagentscan collect pending results explicitly. - Cancellation — stop a running or queued child by run ID, session ID, or name.
- No added dependencies — uses Pi's extension and TUI APIs plus Node.js built-ins.
Install
Install from npm with Pi:
pi install npm:@williamcr01/pi-subagents
This version requires Pi 0.85.0 or newer. Restart Pi or run /reload after installing. To install the latest published version explicitly:
pi update npm:@williamcr01/pi-subagents
For local development, the git install still works:
pi install git:github.com/williamcr01/pi-subagents.git
Usage
Once installed, Pi automatically loads the extension. Ask Pi to delegate work, or use the tools directly:
spawn_agent({
task: "Inspect the authentication flow and report security risks",
name: "auth-reviewer",
cwd: ".",
tools: ["read", "grep"]
})
Use check_subagents to inspect progress or wait for results:
check_subagents({ wait: true, timeoutMs: 120000 })
Use send_to_subagent to steer a running child or continue a completed one. Use cancel_subagent to stop a child. Both accept a full run ID, a unique run-ID prefix (including the eight characters shown in tool output), a session ID, or an exact name. Exact matches take precedence over prefixes; ambiguous targets are rejected with full run IDs for disambiguation.
Isolation model
Each child has a separate Pi process and session, but it is not an OS sandbox. Children use the same user account, filesystem permissions, environment, and installed extensions as the parent.
A trusted parent passes project approval only when the child's canonical working directory remains inside the parent's canonical directory. A symlink that points outside that tree does not inherit approval, so Pi evaluates trust for the target directory normally.
In TUI mode, press Down at the bottom of the editor to open the live subagent panel. Open a transcript, type a message, and press Enter to steer or continue that subagent. Use /subagents to review finished agents and transcripts.
Tools
spawn_agent
Start an isolated child in the background. It returns immediately, so continue other work while the child runs.
spawn_agent({
task: "Inspect the authentication flow and report security risks",
name: "auth-reviewer",
cwd: ".",
tools: ["read", "grep"]
})
Optional fields are name, cwd, model, thinking, and an exact tools allowlist. Model selection is resolved as:
- Per-spawn
model defaultModelin configuration- The creating agent's active model
When the creating session has a model scope from Pi's --models flag or enabledModels setting, the selected child model must be in that scope. The scope and its pinned thinking levels are passed to the child. A pin is applied as the child's --thinking value; an explicit thinking that disagrees with the pin is rejected. An empty scope keeps Pi's unrestricted model behavior.
Omitting tools copies the creating session's active tool set. An explicit list can only remove tools from that set, and tools: [] starts the child with --no-tools. Include spawn_agent to allow recursive delegation. A child receives it automatically only when spawn_agent is active in the parent and tools is omitted or explicitly includes it.
Thinking level follows the same precedence and is clamped to the selected child model.
check_subagents
Inspect descendants and collect newly finished results without repeating results already delivered. Each ancestor sees a descendant execution once, without claiming the direct parent's result. Use wait: true before relying on work that is still running:
check_subagents({ wait: true, timeoutMs: 120000 })
timeoutMs defaults to 30 seconds and is capped at 300 seconds. The wait returns as soon as every descendant finishes; the timeout is only a maximum.
send_to_subagent
Steer a running child or continue its completed session by exact name, run ID, unique run-ID prefix, or session ID. Messages to deeper descendants are acknowledged by their creating session after RPC acceptance (or retention during queued startup). Cross-process admission waits are cancellable and time out after five minutes; cancellation does not undo a prompt already accepted, and the creator keeps the concurrency slot until that turn settles:
send_to_subagent({ target: "auth-reviewer", message: "Focus on the token refresh path." })
cancel_subagent
Stop a child by exact name, run ID, or session ID:
cancel_subagent({ target: "auth-reviewer" })
Result delivery
While the parent works, finished child reports stay in the registry until a completed parent tool result or check_subagents consumes them. Automatic delivery appends reports to the tool output without steering the parent or skipping sibling tool calls. If the parent becomes idle first, it receives the pending reports in one message that starts a new turn.
This replaces the previous behavior of queueing a separate follow-up prompt for every completion. Reports no longer accumulate behind a long parent run and replay after its final answer. If a child completes several follow-ups before the parent consumes its report, only the latest execution is delivered. Earlier output remains available in the child's transcript.
Configuration
Global settings live at ~/.pi/agent/subagents.json. A trusted project's <configDir>/subagents.json (.pi by default; Pi's CONFIG_DIR_NAME) can override them for that project.
{
"defaultModel": "anthropic/claude-sonnet-4-5",
"defaultThinking": "medium",
"maxDepth": 4,
"maxConcurrency": -1
}
All fields are optional. Defaults are maxDepth: 2 and maxConcurrency: 4.
defaultModel— fallback model for spawns that omitmodel.defaultThinking— fallback thinking level for spawns that omitthinking.maxDepth— maximum recursive depth. The root is depth0;maxDepth: 0disables spawning. Descendants inherit the root limit and may only tighten it.maxConcurrency— number of children allowed to run at once per creating session. Use-1for unlimited or a positive integer for a limit; extra children queue automatically. Resuming a completed child also waits for its creator's slot, even when an ancestor sends the follow-up. Steering a running child does not require another slot.rpcMaxLineChars— defensive limit per child stdout JSONL record, default67108864(64 Mi UTF-16 code units, including an optional trailing CR but excluding LF). Must be a positive safe integer; there is no unlimited mode. Set it in global or trusted-projectsubagents.json, for example"rpcMaxLineChars": 134217728for unusually large workloads.
Pi RPC embeds base64 images in tool/message events and aggregates messages in turn_end and agent_end. The 64 Mi default allows several multi-megabyte images and aggregate results that exceed ordinary text-output limits; it is a client safety bound, not a Pi protocol maximum. Both terminated and unterminated records exceeding it fail the child with an explicit error. Input is checked before buffering, scanned incrementally, and discarded on failure. Memory remains proportional to the configured bound (UTF-16 storage, joining, and JSON parsing can require several times the record size per concurrent child); raise it cautiously or reduce concurrency. LF-only framing and split UTF-8 decoding are preserved.
The --subagent-depth N Pi flag overrides configured depth for the tree; descendants inherit that override rather than reapplying file limits. Without a flag override, explicit global or trusted-project depth settings may tighten the inherited limit. Built-in defaults never tighten an inherited limit. An explicit descendant --subagent-depth N may also tighten the limit and overrides file limits for its subtree. No descendant can raise an inherited limit.
Footer controls
When children exist, the footer displays a tree rooted at the current agent:
main · openai-codex/gpt-5.5
├─ ● auth-reviewer · openai-codex/gpt-5.5 · running grep
└─ ● test-runner · openai-codex/gpt-5.5 · running npm test
↓ inspect
- Press Down at the bottom edge of the editor to inspect subagents.
- Press Up/Down to select; Enter/Right to open a child transcript; x stops a running child.
- In a transcript, type a message and press Enter to steer or continue the child.
- Transcripts open in a focused overlay: Up/Down, PageUp/PageDown, and mouse-wheel scrolling affect only the child transcript, not the main conversation.
- In a transcript, Esc or Left on an empty input returns.
- Press Left to go back; Esc is also supported.
- Finished children remain visible until the next user turn, then leave the footer. Use
/subagentsto review full history.
Development
The extension is plain TypeScript loaded directly by Pi. The regression suite uses a local fake Pi child and makes no API calls:
node subagents.test.cjs
Source files are organized by responsibility:
index.ts— Pi registration, lifecycle hooks, tools, delivery, and UI wiringconfig.ts— settings validation and precedenceregistry.ts— atomic run recordswait.ts— event-driven wait for descendant completion (check_subagentswait:true)spawn-agent.ts— RPC process control, concurrency, cancellation, and depth enforcementowner-control.ts— cross-process requests/acknowledgements routed through the target's creating session; revoked requests abort pending admissionevents.ts— child JSON event parsing and status updatespanel.ts— footer tree, selection, and transcript detail viewtranscript.ts— rendering child session files
Publishing
This repository is ready to publish as @williamcr01/pi-subagents:
npm login
node subagents.test.cjs
npm pack --dry-run
npm publish --access public
After publishing, verify the package from a clean Pi installation:
pi install npm:@williamcr01/pi-subagents
For a later release, bump the version (for example with npm version patch), push the commit and tag, then run npm publish again.
License
MIT © William Crona
