@everyx/pi-subagent
Pi agents that work together – three primitives (spawn/stop/send) build a tree of named, message-passing agents
Package details
Install @everyx/pi-subagent from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@everyx/pi-subagent- Package
@everyx/pi-subagent- Version
1.5.1- Published
- Oct 20, 2026
- Downloads
- 353/mo · 196/wk
- Author
- every.x
- License
- MIT
- Types
- extension
- Size
- 197.1 KB
- Dependencies
- 1 dependency · 3 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-subagent
Pi agents that work together — three primitives, a tree of named agents, no noise.
You: Research this project's database schema for me
→ pi calls agent_spawn, spawns a resident `pi --mode rpc` child
→ Child works independently in its own context window
→ Result comes back; you keep chatting
Why?
Pi has no built‑in sub‑agents. So heavy, parallel, or context‑heavy work crowds into your one window. pi‑subagent moves that work to a child pi: the noise stays there, only the answer comes back.
Features
- Quiet context — logs, search hits, and test output stay in the child's window. You get the final result, not the churn.
- True parallel — fire several background agents at once; each delivers its own notification when done. No queue, no result tool. A report that has to wait for the turn's next step shows as a dim
Agent … (queued)line until its card lands. - Stay in control —
agent_sendredirects a running agent (or wakes an idle one);agent_stopkills it. A child's message up the tree is delivered best-effort (no ack). - Persistent on demand — spawn with
persistent: trueand the child stays resident after completion: idle at zero tokens, ready to be woken by a lateragent_sendfor follow‑ups in the same context — or killed byagent_stop. - Pi‑native — rendering, sessions, and attach all reuse pi's own mechanisms; the cards look like built‑in tools because they are.
- Inherit or override — a child inherits your model and thinking level by default; override it per child. A cheap model for recon, a strong one for the build.
- No hidden limits — no token ceiling, no deadline, no concurrency cap by default. An optional
timeoutMsadds a guardrail when you want one. - Reviewable — every session persists and is never deleted; attach any result with
pi --session <path>. - Nestable — a child is a full pi instance, so it can spawn another child.
- Token economy — the system side stays lean:
- System prompt — three tools and terse guidance inject roughly 2–3KB of system prompt (token count drifts with the tokenizer).
- Notification — the LLM sees only minimal structured data; decoration (label, usage) stays in the render layer.
- Results — tail‑truncated (2000 lines / 50KB); expand any card for the full transcript.
Comparison with similar extensions
pi-subagent, @tintinweb/pi-subagents, and pi-subagents all give pi isolated, parallel sub‑agents. They sit on a primitives → framework spectrum, and pi-subagent sits at the minimal end: three primitives, no predefined roles, no harness — you compose. What that buys you is in Features; where the trade‑offs fall is below.
| pi-subagent | @tintinweb/pi-subagents | pi-subagents (nicobailon) | |
|---|---|---|---|
| Design stance | Minimal primitives | Full framework | Full framework |
| Tool surface | agent_spawn / agent_stop / agent_send (3) |
Claude Code‑style Agent / get_subagent_result / steer_subagent |
subagent + management/status/control families |
| Predefined roles | None — defined by prompt | Custom types via .pi/agents/*.md (frontmatter) |
8 built‑in (scout / reviewer / worker / oracle…) |
| Parallelism | Uncap (one process per agent) | Queued, default 4 concurrent | spawn / turn / usage budgets |
| Default limits | None (optional timeoutMs) |
Graceful turn limits | turn / usage budgets |
| Observability | pi‑native cards + widget + pi --session |
FleetView + conversation viewer | FleetView inspector + fleet |
| Nesting | Built‑in, no depth cap | Opt‑in, depth cap | Recursion guard |
| Extras | Token economy, minimal runtime deps, no orphans on reload/crash | Memory, worktree isolation, schedule, cross‑extension RPC, event bus | Missions/scheduling, watchdog, worktree, intercom, chain orchestration |
| Best for | Owning your own composition | A turnkey sub‑agent system | Built‑in roles + workflow orchestration |
Install
pi install npm:@everyx/pi-subagent
Or symlink for development:
ln -sf /path/to/pi-extensions/packages/pi-subagent ~/.pi/agent/extensions/subagent
Restart pi, then tell it "ask a sub‑agent to…".
Quick start
Kick off a task
Ask a sub‑agent to analyze the auth logic under src/
Pi calls agent_spawn, gets an agent id back at once, and the child runs in isolation; the result arrives as a notification when it is done.
Run several in parallel
Spawn three sub‑agents to look at the auth module, the database layer, and the API routes
Pi issues three agent_spawn calls in one block — they all return immediately, and each agent's final output arrives in its own notification (no polling, no extra result tool).
Message or stop
That data‑layer sub‑agent — the approach won't work, rewrite it with composition instead
Pi calls agent_send to inject a redirecting message into the running agent (delivered after its current turn settles). To stop a runaway agent: "kill that sub‑agent" → agent_stop. Both work on a running agent; with persistent: true they also work after completion — agent_send wakes the idle agent for follow‑ups, agent_stop kills it.
Configuration
Environment variables
| Variable | Default | Meaning |
|---|---|---|
PI_SUBAGENT_SESSION_DIR |
<agentDir>/subagent-sessions/ |
Where sub‑agent session files live; set to relocate. <agentDir> follows pi's agent dir (~/.pi/agent, or pi's own PI_CODING_AGENT_DIR). |
The directory lives outside pi's standard session tree so pi -r (resume) stays clean. Sessions are never deleted.
Tool reference
agent_spawn — spawn an isolated sub‑agent
| Param | Type | Default | Meaning |
|---|---|---|---|
prompt |
string | required | Self‑contained task description for the sub‑agent. |
label |
string | required | Short label shown on the tool card, notification card, widget row, and session name. |
model |
string | inherited | Override the sub‑agent's model. Specified but not registered → error, no silent fallback. |
thinking |
"off"…"max" |
inherited | Override thinking level; omit to run at your current session's level. |
tools |
string[] | all | Whitelist of tool names visible to the sub‑agent — anything else is invisible. |
resume |
string | none | Session file to continue instead of starting fresh — the path a previous completion notification reported. The agent picks up that history and runs prompt on top of it. |
timeoutMs |
number | none | Optional deadline (ms). On firing, the extension stops the child, waits for it to settle, and shuts down gracefully. |
persistent |
boolean | false |
Keep the child resident (idle, zero tokens) after completion instead of shutting down. A later agent_send wakes it to continue the same context; agent_stop tears it down. |
agent_stop — terminate an agent
| Param | Meaning |
|---|---|
agent_id |
required — the id agent_spawn returned. Stops a running agent, or an idle persistent one. Graceful shutdown (stdin EOF); no completion notification. |
agent_send — message an agent in the tree
| Param | Meaning |
|---|---|
to |
required — the agent id agent_spawn gave you (a short human name like max), or "@parent" to message the session that spawned you. |
message |
required — the message text; delivered after the target's current turn settles, or wakes an idle persistent agent. |
Messages travel the parent↔child edges of the agent tree: a direct child is delivered straight down, @parent goes up, and cross‑level/sibling messages are forwarded through the parent LLM's context along the way.
The LLM is guided by promptSnippet + promptGuidelines (system‑prompt injection): when to delegate, to keep prompts self‑contained, and to never poll.
Advanced
Pick a model
Spawn a sub‑agent with claude-sonnet to analyze the database design
No model specified → inherits your current session's model. Same for thinking — omit it and the sub-agent runs at your current level; pass "off"…"max" to override.
Model specified but not found in the registry → error, no silent fallback.
Restrict tools
Ask a sub‑agent to research the project structure, but only let it use read and grep
Sub‑agent won't see any other tools. Read‑only exploration with a cheaper model is a good pattern for research tasks.
How it works
Every sub‑agent is a resident pi --mode rpc child with a persisted session:
- Foreground —
agent_spawnwaits for the child to settle, fetches the final output, then closes stdin (graceful shutdown). - Background —
agent_spawnreturns immediately; onagent_settledthe extension delivers asubagent-notification(JSON content to the LLM, rendered card to the user) and the child shuts down gracefully. - Send/stop —
agent_senddelivers a message to the child's stdin (queued while it runs, delivered after its current turn settles);agent_stopcloses stdin for a graceful shutdown. Both work on a running agent. - Persistent idle — with
persistent: truethe child stays resident after completion (idle, zero tokens). A lateragent_sendwakes it to continue the same context;agent_stoptears it down. The completion notification and widget row carry theidlemarker. - Attach / review — sub‑agent sessions live in
<agent dir>/subagent-sessions/(see Configuration). Find the session path in the main conversation and runpi --session <path>— or ask the LLM, the notification carries the path too. - Graceful turn limits (opt‑in) — no hidden deadline: a sub‑agent runs until it finishes or is stopped unless you pass
timeoutMs. No abrupt SIGTERM. No token limits — usage is only reported on the notification card.
Nested sub‑agents
A child is a full pi instance — so if you installed this extension globally, it spawns children of its own. Each level is its own process with its own context; depth multiplies startup time and token cost. You — or the model — judge when it's worth it.
The mechanism is a pure point-to-point deliverer: agent_send delivers to a direct child by its id (a short human name like max), or to "@parent" — and errors on anything else. Routing is the LLM's job: each agent addresses only the ids it was given, hop by hop (a grandchild reaching the root goes through its parent's LLM deciding to forward with @parent). Information disclosure is the only limit — a parent holds the ids of the agents it spawned; nobody knows ids they were never told.
Costs & caveats
- Headless children die with the host (
pi -p). The main process exits at the end of its reply; children are then torn down via stdin EOF — never orphaned. Since results arrive as notifications,pi -pcannot wait for them: the always‑alive TUI session is where a spawn's result can land. - One process per child. Every spawn is the same kind of resident rpc child. Many children = many processes — spawn with care.
- One‑shot results. A result is delivered once; if the main session dies before delivery, the result survives in the session file (
pi --session <path>). Agents still running when the session ends are recorded in the transcript, so a resumed session knows they are gone. - Send/stop need an addressable child.
agent_sendandagent_stoptarget a live child — or, forpersistentspawns, the resident idle child after completion. A non‑persistent child is gone once its completion notification fires; messaging or stopping it errors.
Cleanup
When pi exits, sub‑agents (running or idle) get a graceful stdin‑EOF shutdown. Sessions stay on disk for attach/replay — nothing is killed, nothing deleted.