Focused subagents and bounded programmatic workflows for Pi.
- One
subagent_runtool per isolated child, matching Claude Code's simple delegation model. - Natural parallelism: Pi can emit several sibling
subagent_runcalls in one assistant turn. - One global scheduler with foreground priority, concurrency limits, and shared-workspace writer leases.
- Foreground and background runs with quiet transcript rows, live activity, usage, cancellation, timeout, and bounded artifacts.
- Durable versioned run artifacts under
~/.pi/agent/subagents/runs/. - Programmatic TypeScript workflows with stable steps, dynamic fan-out, joins, and replay.
- Worktree isolation with patch capture for write-capable children.
- Session-scoped run status and a polished recent-run fleet inspector.
- Built-in
general,scout,planner,reviewer, andworkerroles, with task-specific run names that can inherit any role. - Built-in
scout-plan,parallel-review, andimplement-and-reviewworkflows.
Subagents are separate Pi processes, not security sandboxes. They run with your OS account's permissions.
From this repository, install the local package persistently so /reload can rediscover it:
npm install
pi install /absolute/path/to/pi-subagentsUse pi -e . only for a temporary development smoke test. You can also add the absolute repository path to Pi's package settings.
Ask naturally:
Use the reviewer subagent to inspect the authentication implementation.
Run three scouts in parallel: API entry points, tests, and persistence.
Pi should emit multiple subagent_run calls together for parallel work. Every call still passes through the global scheduler.
Start background work:
Ask scout to map the whole repository in the background.
Both subagent_run and workflow_run accept background: true. A background launch returns immediately, so the parent agent can continue useful independent work or end its turn and rely on the completion notification. While a standalone foreground subagent is running, press Ctrl+B to move it to the background. Inspect or wait only when the result is needed; status calls are one-shot checks, not a polling loop.
Use subagent_control to list runs and wait for the scout result.
The extension adds concise tool-specific system-prompt guidance that encourages proactive delegation, explains foreground versus background launches, and reminds the parent about lifecycle and write-safety constraints.
Run the scout-plan workflow for adding rate limiting.
Run implement-and-review in the background for this request.
Create ~/.pi/agent/workflows/example.workflow.ts or, in a trusted project, .pi/workflows/example.workflow.ts:
import { defineWorkflow } from "@inv1x/pi-subagents/workflow";
export default defineWorkflow({
name: "review-many",
description: "Review several areas concurrently",
async run(ctx, input: { request: string }) {
const areas = ["API", "database", "tests"];
const reviews = await ctx.map(
"reviews",
areas,
(area) => ({
agent: "reviewer",
difficulty: 3,
task: `Review ${area} for: ${input.request}`,
}),
{ concurrency: 3 },
);
return reviews.map((review) => review.output).join("\n\n---\n\n");
},
});Stable IDs (reviews, plan, implement, and so on) are part of the durability contract. On resume, completed steps with the same normalized specification are reused. A changed specification produces a workflow-drift error rather than silently repeating side effects. Agent-step specs can set difficulty: 1 | 2 | 3 | 4 | 5 for model routing; omitted difficulty defaults to 3. Results include the actual model, thinking effort, usage, cost, and artifact paths.
Workflow context methods:
ctx.agent(stepId, spec)ctx.parallel(groupId, specs, options?)ctx.map(groupId, items, factory, options?)ctx.output(stepId)ctx.log(message, data?)ctx.setResult(value)ctx.signal
Workflows cannot pause for approval or other runtime input; split interactive decision points into separate workflows. Project TypeScript workflows are arbitrary local code. Trusted-project listing and preview use inert companion/static metadata and do not import the module; execution requires an interactive confirmation, then imports the unchanged source. Headless project-workflow launches fail closed.
Create ~/.pi/agent/agents/reviewer.md or .pi/agents/reviewer.md in a trusted project:
---
name: reviewer
description: Reviews code without editing
tools: read, grep, find, ls
model: inherit
thinking: medium
context: fresh
workspace: shared
maxTurns: 128
timeoutMs: 3600000
---
Review correctness, tests, security, and unnecessary complexity.
Return actionable findings with file and line evidence.Supported frontmatter:
name,description,toolsmodel,thinkingcontext: fresh | summaryworkspace: shared | worktreemaxTurns,timeoutMsskills(exact discovered skill names; children load only those resolved paths)systemPromptMode: replace | appendinheritProjectContext
Discovery precedence is built-in, user, then trusted project. Project definitions override the same agent name.
Each child has a difficulty from 1 to 5:
1: trivial2: light or narrowly focused3: standard work (the default)4: complex or risky5: critical or high-uncertainty
The head agent estimates this value for standalone calls; workflow authors set it on each agent step. Configure an ordered threshold ladder per resolved agent type—including general—with /subagent-models or the agentModels setting. The extension selects the profile with the smallest maxDifficulty that covers the request. If no threshold covers it, the highest configured threshold is the strongest fallback.
Model and thinking fields resolve independently in this order:
- Explicit
subagent_runor workflow-stepmodel/thinkingoverride - The selected difficulty profile
- Agent frontmatter (
model,thinking) - The parent Pi session's current model and thinking level
With no configured ladder, behavior remains the same as before. model: inherit follows the live parent selection. The extension passes resolved values through Pi's --model and --thinking flags, then records the difficulty, requested model/effort, and actual provider/model reported by the child in durable run status.
Compact run rows show the selected model and effort for that individual run without rendering child response bodies, including when Pi expands a tool row. Full results remain model-visible in tool/custom-message content and available in /subagents-fleet and durable artifacts. The fleet status intentionally omits a single model because concurrent children can use different configurations.
The child transport passes the canonical model through --model and the clamped effort through --thinking. Explicit models, bare model resolution, profile settings, doctor diagnostics, and workflow routing resolve against every model in modelRegistry.getAvailable(); ctx.scopedModels and old persisted workflow scopedModels fields are ignored. Run metadata records the requested model/effort and the model reported by Pi; a reported selected-model mismatch fails the run instead of silently falling back. Concrete upstream responseModel values are retained when providers expose them.
Children run with --no-session because this package owns their durable artifacts. Session-file-only usage trackers therefore see the parent session but not child requests; use the per-run status files or fleet totals for authoritative child usage.
Runs one child. agent is a descriptive run name such as task-auditor. Set baseAgent to an exact discovered definition such as reviewer to inherit its prompt, tools, and defaults. If baseAgent is omitted, an exact agent match is used; otherwise the child falls back to general.
Set difficulty from 1 to 5 and normally omit model and thinking so the configured profile ladder can route the child. Explicit model overrides must be exact provider/model identifiers.
Run task-auditor based on reviewer to inspect the current task implementation.
Important options:
baseAgentbackgroundcontextmodel,thinking,difficulty(defaults to3)cwdworkspacetimeoutMs,maxTurns,maxRetriesagentScope: user | project | both(defaults tobothin trusted projects, otherwiseuser)
Usually omit timeoutMs and maxTurns. Built-in agents default to one hour and 128 assistant turns; explicit values are hard safety ceilings, and low ad hoc caps can terminate broad work before it returns a useful handoff.
Actions: list, status, wait, interrupt, stop.
send is reserved for the future persistent RPC/SDK child transport and currently returns an explicit unsupported error.
Runs a named TypeScript workflow with arbitrary JSON-compatible input.
Actions: list, status, wait, stop, resume.
/subagents/subagent-models [agent]/subagents-fleet/subagents-stop [runId]/workflows/workflow-run <name> [--bg] <input>/workflow-status [runId]/subagents-doctor
User configuration: ~/.pi/agent/pi-subagents.json
Trusted project override: .pi/pi-subagents.json
{
"agentModels": {
"general": [
{
"model": "openai-codex/gpt-5.6-sol",
"thinking": "low",
"maxDifficulty": 2
},
{
"model": "openai-codex/gpt-5.6-sol",
"thinking": "high",
"maxDifficulty": 5
}
],
"scout": [
{
"model": "openai-codex/gpt-5.6-sol",
"thinking": "medium",
"maxDifficulty": 5
}
]
},
"maxConcurrency": 4,
"maxWorkflowConcurrency": 4,
"maxFanout": 16,
"hardMaxFanout": 64,
"maxWorkflowNodes": 100,
"defaultTimeoutMs": 3600000,
"defaultMaxTurns": 128,
"maxRetries": 2,
"retryBaseDelayMs": 2000,
"resultMaxBytes": 51200,
"transcriptMaxEvents": 500,
"retentionDays": 30,
"showStatus": true,
"confirmProjectAgents": true,
"confirmProjectWorkflows": true
}Project TypeScript workflow confirmation is mandatory and cannot be disabled; confirmProjectWorkflows additionally controls previews for non-project /workflow-run command launches.
Agent profile keys use the resolved agent definition name, not a descriptive run name. Project arrays replace user arrays for the same agent while leaving other user agent ladders intact. An explicit empty array disables routing for that agent. /subagent-models provides searchable model/agent pickers, can save either user settings or trusted-project settings, can remove a project override to resume user-level inheritance, and preserves unrelated configuration fields.
An agent with bash, edit, or write is conservatively write-capable.
- Read-only children may run concurrently in a shared workspace.
- Shared-workspace writers are serialized by a workspace lease.
- Choose
workspace: "worktree"for parallel writers. - Worktree mode requires a clean Git repository.
- The extension captures changes as
changes.patch, then removes the temporary worktree and branch. - It does not auto-merge parallel patches.
Each run has a private directory:
~/.pi/agent/subagents/runs/<run-id>/
├── manifest.json
├── status.json
├── events.jsonl
├── workflow.json # workflows only
├── system-prompt.md # child runs
├── output.md
├── transcript.log
└── changes.patch # worktree changes, when present
Model-visible output is capped; full output remains in output.md. JSON event lines and stderr are independently bounded.
Pi 0.84 assistant deltas are intentionally ignored so child response bodies never stream into the parent transcript; the final message_end remains authoritative and is runtime-validated. A zero-exit child still fails if it does not produce a valid final assistant result followed by agent_settled.
After Pi exhausts its own provider-level retries, the extension retries a child process for recognized transient failures such as WebSocket disconnects, connection resets, rate limits, and 5xx responses. Retries use bounded exponential backoff, preserve cumulative usage/cost and attempt history, and stay within the original run timeout. To avoid repeating side effects, the extension does not restart a child after it has invoked bash, edit, or write. Set maxRetries to 0 globally or per run to disable process-level retries.
The current session's active fleet is summarized in one compact status line. Workflow children are represented by their workflow rather than counted as standalone agents. Finished standalone runs and complete workflow families remain visible for exactly five minutes from their endedAt timestamps; later metadata updates do not extend the window. Open the fleet inspector with /subagents-fleet; with pi-ui-customization loaded, editor footer navigation can select the status and Enter opens it. The extension opts this status into preserving its accent color during selection, so terminal inversion uses that color as the selected background. That navigation is owned by the editor only, so selectors and overlays keep normal ownership of their keys. The inspector groups workflow children beneath their parent, uses state-colored markers, and shows task, final result/error, model/usage, and output/transcript/patch artifact paths in a scrollable details panel. Difficulty is intentionally omitted. Use Up/Down to select runs, g/G to jump, j/k to scroll the selected details without changing selection, b to background an eligible run, r to refresh, and Esc, Ctrl+C, or q to close. Literal shortcuts support Kitty keyboard sequences. Set showStatus to false to hide the summary; the former showWidget: false setting is still honored for compatibility.
Background work returns control to the parent immediately and survives parent turns, Pi session switches, and extension reloads inside the same Pi process through a process-global runtime. Runs continue globally, but status, costs, notifications, fleet views, commands, and control tools are projected only into the owning Pi session.
A full Pi process exit aborts and awaits owned agents and workflows, escalating the detached POSIX process group when needed so descendants do not survive the parent. On the next startup, any unfinished persisted runs are marked orphaned; workflows can be explicitly resumed and replay completed stable steps.
This release does not yet run a fully detached durable orchestrator daemon.
A direct workflow ctx.agent() failure rejects the workflow. ctx.map() and ctx.parallel() collect failed children as result values by default so successful siblings are retained; set { failFast: true } to reject the group after in-flight work settles. Declared TypeBox workflow input/output schemas and agent-step JSON output schemas fail validation before the corresponding success is persisted. Automatic process retry remains disabled after a mutating tool call.
Workflow definitions may declare input and output TypeBox schemas. Agent steps may declare output; the child is asked for JSON-only output and the parsed value is exposed as result.value after validation.
Node.js 22.19 or newer is required.
npm install
npm run check
npm run typecheck
npm test
npm pack --dry-run
pi -e . --list-modelsTests cover protocol framing and limits, scheduler concurrency/resource leases, trust-aware discovery, child JSON event parsing, compact UI rendering, status projection, and workflow fan-out/persistence.
Run npm run changeset for each user-facing change and commit the generated .changeset/*.md file. To prepare a release, run npm run release:status and then npm run release:version; Changesets consumes the pending files and updates package.json, package-lock.json, and CHANGELOG.md. These commands do not publish to npm or create a GitHub Release.