@ghoulm370/pi-subagent-ui
v0.1.1
Published
Pi extension: subagent tool with background runs, intercom, watchdog, live status/widgets for pi-web.
Maintainers
Readme
@ghoulm370/pi-subagent-ui
A pi extension that adds a subagent tool with live status and TUI widgets. Delegate focused work (review, testing, planning, research, analysis) to specialized subagents with isolated context and persisted child sessions.
Supports three run modes (single, parallel, chain), background fire-and-forget runs, intercom (child → parent questions), and a watchdog that kills stuck children — so a child can never silently hang the parent.
Features
- Three orchestration modes
single— one agent + one taskparallel— run many tasks concurrently (configurable, default 3, max 8, up to 16 tasks)chain— sequential tasks; each task may embed the previous output via{previous}
- Background runs —
background: truereturns immediately with arunId; the run continues and the parent is notified on completion. Interact viasubagent_status/subagent_result/await_subagent/reply_subagent. - Intercom (child → parent) —
allowIntercom: trueinjectsask_parent/notify_parent/update_progresstools into children so a genuinely-blocked child can ask the parent a question mid-run; the parent answers withreply_subagent. - Watchdog (no more silent hangs) — each child is watched; if it produces no events for
stallMs(default 90s) it is aborted, instead of hanging until the 10-min timeout. - Multi-source agent discovery (later sources override earlier ones by name)
- pi-web agents from
~/.pi/agent/agents.json(global defaults) - User markdown agents at
~/.pi/agent/agents/*.md - Project-local agents at
<cwd>/.pi/agents/*.md(opt-in viaagentScope)
- pi-web agents from
- Isolated child context — each subagent runs in its own
AgentSessionwith its own resource loader, injected with a "you are a subagent" instruction so it doesn't recurse. - Live status — TUI widget + status bar +
subagent:*events for web/TUI consumers; richdetailspayloads for custom renderers. - Persisted & restorable — runs are written to a
<session>.subagents.jsonsidecar and restored onsession_start, so refreshes/session switches keep history. - Resilient — watchdog stall detection, per-task hard timeout, abort propagation, and full
stopReasoncoverage (error/aborted/max_tokens/refusal/ …) all mark tasks correctly. - Usage accounting — input/output/cache/cost/turns aggregated per task and per run.
- Safety rails — project-local agents require explicit UI confirmation; the available-agent catalog is injected into context to prevent hallucinated agent names.
Install
npm install @ghoulm370/pi-subagent-uiPi auto-discovers the extension via the pi.extensions field in package.json. No build step — pi loads the TypeScript source directly.
Usage
Read the "Available subagents for the subagent tool" list that is injected into context, then call the tool with an exact agent name or id.
Single
subagent({
agent: "code-reviewer",
task: "Review the current diff for correctness and edge cases"
})Parallel
subagent({
tasks: [
{ agent: "researcher", task: "Summarize the market context for X" },
{ agent: "risk-reviewer", task: "List implementation risks for X" }
],
concurrency: 2
})Chain
subagent({
chain: [
{ agent: "analyst", task: "Analyze the current implementation" },
{ agent: "planner", task: "Create an execution plan from this analysis:\n{previous}" }
]
})Background (fire-and-forget)
subagent({
tasks: [/* … long-running work … */],
background: true // returns immediately with a runId
})You'll be notified when it completes. Meanwhile:
subagent_status({ runId: "run_…" }) // non-blocking snapshot
subagent_result({ runId: "run_…" }) // full finalText + usage
await_subagent({ runId: "run_…" }) // block until it finishesIntercom (child asks parent)
subagent({
agent: "implementer",
task: "Add feature X, but ask me if the API contract is ambiguous",
allowIntercom: true
})
// child calls ask_parent("…") → you get notified → you answer:
reply_subagent({ runId: "run_…", taskId: "task_1", message: "Use POST /v2" })Per-task overrides
Each task item accepts optional cwd, model (provider/model-id), thinking, tools (allowlist), and maxRuntimeMs.
Parameters
| Field | Type | Description |
| --------------------- | --------------------------------- | ------------------------------------------------------ |
| agent + task | string | Single mode |
| tasks | TaskItem[] | Parallel mode |
| chain | TaskItem[] | Sequential mode; {previous} replaced with prior output |
| agentScope | "user" \| "project" \| "both" | Default "user" |
| confirmProjectAgents| boolean | Default true; require UI confirm for project agents |
| concurrency | number | Parallel concurrency (default 3, max 8) |
| model | string | provider/model-id override for single mode |
| thinking | string | Thinking-level override |
| tools | string[] | Tool allowlist override (default read-only) |
| maxRuntimeMs | number | Per-task timeout (default 10 min) |
| background | boolean | Default false. If true, return immediately with a runId and notify on completion. |
| stallMs | number | Watchdog: abort a child if no events for this many ms (default 90000). |
| allowIntercom | boolean | Default false. If true, inject ask_parent / notify_parent / update_progress into children. |
Exactly one mode (single, tasks, or chain) must be provided.
Control tools
These tools are registered alongside subagent for interacting with background runs:
| Tool | Description |
| ------------------ | ----------------------------------------------------------------- |
| subagent_status | Non-blocking live status of a background run (runId). |
| subagent_result | Full result (finalText + usage) of a run, or a specific taskId. |
| await_subagent | Block until a run finishes (optional timeoutMs). |
| reply_subagent | Answer a child's ask_parent question; resumes the child. |
Intercom tools (injected into children when allowIntercom: true)
| Tool | Description |
| ----------------- | ----------------------------------------------------------------- |
| ask_parent | Blocking: ask the parent a question, wait for reply_subagent. |
| notify_parent | One-way message to the parent (does not block). |
| update_progress | Update the task's progress phase shown in the widget/panel. |
Defining agents
Markdown (user or project)
~/.pi/agent/agents/my-agent.md or <repo>/.pi/agents/my-agent.md:
---
name: code-reviewer
description: Reviews diffs for correctness and edge cases
tools: read, grep, find, ls
model: zenmux/claude-sonnet-4-6
thinking: medium
---
You are a meticulous code reviewer. Focus on correctness, edge cases,
and regressions. Return a concise, actionable summary.pi-web JSON
Configured through pi-web's ~/.pi/agent/agents.json.
Events
Emitted on the pi event bus for web/TUI consumers:
subagent:run-created/subagent:run-updated/subagent:run-completedsubagent:task-updatedsubagent:session-event(forwarded childmessage_end/tool_execution_*)subagent:notification(background run completed/failed/aborted, or a child is asking the parent)subagent:intercom(childnotify_parent/update_progress)subagent:runs-restored(after sidecar reload onsession_start)
License
MIT
