@bacnh85/pi-subagent
v0.9.1
Published
In-process subagents for Pi with isolated SDK sessions, parallel and chained delegation, and inspectable threads.
Maintainers
Readme
pi-subagent
Isolated in-process subagents for Pi. The subagent tool supports single, parallel (8 tasks, 4 concurrent), and chained execution; /agent opens inspectable child threads.
Install
pi install npm:@bacnh85/pi-subagent
# local checkout
pi install ./pi-subagentRequires Node.js >= 20.18.
Bundled roles
| Role | Ordered model preferences | Thinking | Tools |
| --- | --- | --- | --- |
| scout | opencode-go/deepseek-v4-flash → openai-codex/gpt-5.6-luna → opencode-go/mimo-v2.5 | low | read, grep, find, ls |
| tester | openai-codex/gpt-5.6-luna → opencode-go/mimo-v2.5 → opencode-go/deepseek-v4-flash | low | read, bash, grep, find, ls |
| worker | openai-codex/gpt-5.6-terra → opencode-go/deepseek-v4-pro | medium | read, bash, edit, write, grep, find, ls |
| general-purpose | openai-codex/gpt-5.6-terra → opencode-go/deepseek-v4-pro | medium | read, bash, edit, write, grep, find, ls |
| planner | openai-codex/gpt-5.6-sol → opencode-go/deepseek-v4-pro | high | read, grep, find, ls |
| reviewer | openai-codex/gpt-5.6-sol → opencode-go/deepseek-v4-pro | high | read, grep, find, ls |
Each role uses the first authenticated preference available through Pi's model registry, then falls back to the authenticated parent model. User/project agent files remain stronger overrides and may set legacy model, ordered models, and thinking.
Agent files
Create ~/.pi/agent/agents/*.md or .pi/agents/*.md:
---
name: scout-fast
description: Locate relevant files and symbols
tools: read, grep, find, ls
model: openai-codex/gpt-5.6-luna
models: opencode-go/mimo-v2.5, opencode-go/deepseek-v4-flash
---
Return concise evidence with file/symbol anchors.Agent definitions are cached with file-signature invalidation; /subagent reload clears the cache.
Context and limits
Children use in-memory SDK sessions with no extensions, skills, prompt templates, or automatic AGENTS.md loading. The optional instructions argument passes a bounded 16 KB task/repository contract. Only Pi built-in tools are available; Serena, FFF, web, and Munin are not available in lean children.
Threads are session-memory only and are cleared when Pi replaces or reloads the session. Timeout and parent cancellation propagate to child sessions. Subagents cannot recursively invoke subagent.
Security model
Project-local agents
Agent files under .pi/agents/ are controlled by the current repository. A project agent's system prompt may instruct a child to execute shell commands or modify files.
- Project-agent approval cannot be disabled by the model. The
confirmProjectAgentsparameter is not exposed in the tool schema. Confirmation policy comes from trusted user configuration only. - Interactive sessions prompt the user before executing project agents.
- Headless sessions fail closed. Project agents are not executed without UI confirmation unless the trusted setting
allowUnconfirmedProjectAgentsis enabled (viaPI_SUBAGENT_ALLOW_UNCONFIRMED_PROJECT_AGENTS=trueenvironment variable or pi settings). - The extension service path (
pi-subagent:runevent) follows the same policy.
Child working directories
Child working directories are restricted to the parent session's workspace by default:
- Relative paths are resolved within the workspace.
..traversal that escapes the workspace is rejected.- Absolute paths outside the workspace are rejected.
- Symlinks are resolved via realpath; symlink escapes are rejected.
- Non-existent directories and file paths are rejected.
The trusted setting allowExternalCwd (via PI_SUBAGENT_ALLOW_EXTERNAL_CWD=true env or pi settings) can opt out. This setting cannot be enabled by the model.
Tool validation
Child agent tools are validated against a fixed allowlist:
- Allowed:
read,grep,find,ls,bash,edit,write - Always rejected:
subagent(prevents recursive delegation) - Read-only restriction: When a service requests read-only execution, only
read,grep,find,lsare permitted.bash,edit, andwriteare rejected.
Unknown or misspelled tool names produce clear diagnostics. Duplicate tool names are deduplicated.
Timeouts
Every child execution receives a timeout:
- Default inactivity window: 3 minutes (
DEFAULT_TIMEOUT_MS); real SDK lifecycle activity resets it. - Absolute cap: 20 minutes for every child, even when active.
- Maximum requested inactivity window: 60 minutes (
MAX_TIMEOUT_MS); values must be positive integers. - Timeout diagnostics distinguish
Idle timeoutfromHard timeoutand parent cancellation. - 30-second progress heartbeats only keep the parent transport alive; they never reset inactivity.
/agentshows last real activity and the remaining idle window; parallel tasks and chain steps may have per-item windows.
Output safety
Child output is untrusted data and may contain prompt injection. Treat child results as model-generated content, not as verified facts.
Cost awareness
Parallel delegation may multiply provider usage and cost. Each parallel task runs as a separate SDK session with its own token consumption.
Agent file review
User and project agent files should be reviewed before use. Malformed files produce diagnostics but do not prevent valid agents from loading.
Modes
Single mode
subagent({ agent: "scout", task: "Find auth-related files" })Parallel mode
subagent({
tasks: [
{ agent: "scout", task: "Find API routes" },
{ agent: "scout", task: "Find database models" },
{ agent: "scout", task: "Find test files" },
],
abortOnFailure: false
})Max 8 tasks, 4 concurrent. Results are returned in input order. When abortOnFailure is true, the first failed task cancels remaining siblings.
Chain mode
subagent({
chain: [
{ agent: "scout", task: "Find API routes" },
{ agent: "worker", task: "Based on this, implement the routes: {previous}" },
]
}){previous} in each step's task is replaced with the previous step's output. The chain stops on the first failed step.
Result status
Each SubAgentResult includes a canonical status field:
| Status | Meaning |
|--------|---------|
| success | Completed normally |
| partial | Truncated (max_tokens, length, context_limit) |
| error | Provider error, tool error, or unknown stop reason |
| aborted | Cancelled by parent or sibling |
| timeout | Exceeded the allowed timeout |
The raw stopReason from the Pi SDK is preserved in the result.
Timeout and cancellation
- Default timeout: 10 minutes per child.
- Per-task/step override: Use
timeoutin task/step params. - Parent cancellation: Aborting the parent tool call cancels all children.
- Sibling cancellation: In parallel mode with
abortOnFailure: true, the first failed task cancels running siblings. - Timeout vs. abort: Timeout errors set
status: "timeout"andstopReason: "timeout"; parent cancellation setsstatus: "aborted". - Transient provider failures: One automatic retry runs within the same timeout; Codex WebSocket failures use the SDK's SSE fallback on retry.
- Transport idle: The parent tool receives periodic progress heartbeats while a child runs; these do not extend its timeout.
Extension contract
pi-subagent owns the pi-subagent:run event contract for one named-agent request. pi-review uses it for isolated review. Requests use an immediate boolean accept() claim and exactly one respond() callback; this suppresses duplicate responders while missing services and timeouts remain caller-controlled.
Compatibility
- Requires
@earendil-works/pi-coding-agent >=0.80.0 <0.81.0 - Requires
@earendil-works/pi-ai >=0.80.0 <0.81.0 - Requires
@earendil-works/pi-agent-core >=0.80.0 <0.81.0 - Requires
@earendil-works/pi-tui >=0.80.0 <0.81.0 - Requires
typebox >=1.3.0 <2.0.0 - Requires Node.js >= 20.18
See agent-format.md for all frontmatter fields.
