pi-subagents 0.76.0 → 0.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +92 -0
- package/README.md +1 -1
- package/agents/oracle.md +8 -19
- package/agents/researcher.md +0 -3
- package/agents/reviewer.md +17 -61
- package/agents/scout.md +1 -4
- package/agents/worker.md +8 -25
- package/docs/agents.md +70 -3
- package/docs/configuration.md +55 -6
- package/docs/extension-api.md +36 -11
- package/docs/missions.md +24 -17
- package/docs/models.md +1 -1
- package/docs/observability.md +10 -5
- package/docs/tool-reference.md +101 -83
- package/docs/watchdog.md +8 -6
- package/docs/workflows.md +15 -6
- package/index.d.ts.map +1 -1
- package/index.js +5 -0
- package/index.js.map +1 -1
- package/package.json +2 -1
- package/prompts/council.md +1 -1
- package/skills/pi-subagents/SKILL.md +1 -1
- package/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
- package/skills/pi-subagents/references/execution-controls.md +16 -16
- package/skills/pi-subagents/references/management-authoring-rpc.md +16 -12
- package/skills/pi-subagents/references/prompting-and-roles.md +3 -3
- package/src/agents/advertised-agent-prompt.d.ts +5 -1
- package/src/agents/advertised-agent-prompt.d.ts.map +1 -1
- package/src/agents/advertised-agent-prompt.js +8 -2
- package/src/agents/advertised-agent-prompt.js.map +1 -1
- package/src/agents/agent-management.d.ts.map +1 -1
- package/src/agents/agent-management.js +5 -0
- package/src/agents/agent-management.js.map +1 -1
- package/src/agents/agent-scope.d.ts +1 -0
- package/src/agents/agent-scope.d.ts.map +1 -1
- package/src/agents/agent-scope.js +3 -0
- package/src/agents/agent-scope.js.map +1 -1
- package/src/agents/agent-serializer.d.ts.map +1 -1
- package/src/agents/agent-serializer.js +3 -0
- package/src/agents/agent-serializer.js.map +1 -1
- package/src/agents/agents.d.ts +14 -2
- package/src/agents/agents.d.ts.map +1 -1
- package/src/agents/agents.js +94 -36
- package/src/agents/agents.js.map +1 -1
- package/src/api/preflight.d.ts +2 -0
- package/src/api/preflight.d.ts.map +1 -1
- package/src/api/preflight.js +6 -2
- package/src/api/preflight.js.map +1 -1
- package/src/extension/config.d.ts.map +1 -1
- package/src/extension/config.js +23 -2
- package/src/extension/config.js.map +1 -1
- package/src/extension/control-notices.d.ts +0 -2
- package/src/extension/control-notices.d.ts.map +1 -1
- package/src/extension/control-notices.js +1 -7
- package/src/extension/control-notices.js.map +1 -1
- package/src/extension/declaration-pinning.d.ts +14 -0
- package/src/extension/declaration-pinning.d.ts.map +1 -0
- package/src/extension/declaration-pinning.js +147 -0
- package/src/extension/declaration-pinning.js.map +1 -0
- package/src/extension/doctor.d.ts +3 -1
- package/src/extension/doctor.d.ts.map +1 -1
- package/src/extension/doctor.js +3 -9
- package/src/extension/doctor.js.map +1 -1
- package/src/extension/fanout-child.d.ts.map +1 -1
- package/src/extension/fanout-child.js +6 -8
- package/src/extension/fanout-child.js.map +1 -1
- package/src/extension/index.d.ts +1 -1
- package/src/extension/index.d.ts.map +1 -1
- package/src/extension/index.js +68 -116
- package/src/extension/index.js.map +1 -1
- package/src/extension/rpc.d.ts.map +1 -1
- package/src/extension/rpc.js +12 -6
- package/src/extension/rpc.js.map +1 -1
- package/src/extension/schemas.d.ts +137 -1
- package/src/extension/schemas.d.ts.map +1 -1
- package/src/extension/schemas.js +22 -22
- package/src/extension/schemas.js.map +1 -1
- package/src/extension/subagent-guide.d.ts +1 -0
- package/src/extension/subagent-guide.d.ts.map +1 -1
- package/src/extension/subagent-guide.js +80 -6
- package/src/extension/subagent-guide.js.map +1 -1
- package/src/extension/subagent-options.d.ts +8 -0
- package/src/extension/subagent-options.d.ts.map +1 -0
- package/src/extension/subagent-options.js +52 -0
- package/src/extension/subagent-options.js.map +1 -0
- package/src/extension/tool-activation.d.ts.map +1 -1
- package/src/extension/tool-activation.js +3 -2
- package/src/extension/tool-activation.js.map +1 -1
- package/src/extension/tool-description.d.ts +4 -7
- package/src/extension/tool-description.d.ts.map +1 -1
- package/src/extension/tool-description.js +45 -59
- package/src/extension/tool-description.js.map +1 -1
- package/src/inspectors/actions.d.ts +2 -0
- package/src/inspectors/actions.d.ts.map +1 -1
- package/src/inspectors/actions.js +41 -13
- package/src/inspectors/actions.js.map +1 -1
- package/src/inspectors/plugins.d.ts.map +1 -1
- package/src/inspectors/plugins.js +3 -2
- package/src/inspectors/plugins.js.map +1 -1
- package/src/inspectors/tmux/actions.d.ts +26 -0
- package/src/inspectors/tmux/actions.d.ts.map +1 -0
- package/src/inspectors/tmux/actions.js +182 -0
- package/src/inspectors/tmux/actions.js.map +1 -0
- package/src/inspectors/tmux/client.d.ts +28 -0
- package/src/inspectors/tmux/client.d.ts.map +1 -0
- package/src/inspectors/tmux/client.js +65 -0
- package/src/inspectors/tmux/client.js.map +1 -0
- package/src/inspectors/tmux/plugin.d.ts +8 -0
- package/src/inspectors/tmux/plugin.d.ts.map +1 -0
- package/src/inspectors/tmux/plugin.js +15 -0
- package/src/inspectors/tmux/plugin.js.map +1 -0
- package/src/integrations/herdr-status.d.ts +0 -1
- package/src/integrations/herdr-status.d.ts.map +1 -1
- package/src/integrations/herdr-status.js +18 -52
- package/src/integrations/herdr-status.js.map +1 -1
- package/src/integrations/program-status.d.ts +31 -0
- package/src/integrations/program-status.d.ts.map +1 -0
- package/src/integrations/program-status.js +189 -0
- package/src/integrations/program-status.js.map +1 -0
- package/src/intercom/native-supervisor-channel.d.ts +1 -0
- package/src/intercom/native-supervisor-channel.d.ts.map +1 -1
- package/src/intercom/native-supervisor-channel.js +77 -3
- package/src/intercom/native-supervisor-channel.js.map +1 -1
- package/src/intercom/result-intercom.js +1 -1
- package/src/intercom/result-intercom.js.map +1 -1
- package/src/intercom/supervisor-ui.d.ts +2 -12
- package/src/intercom/supervisor-ui.d.ts.map +1 -1
- package/src/intercom/supervisor-ui.js +2 -154
- package/src/intercom/supervisor-ui.js.map +1 -1
- package/src/missions/store.d.ts.map +1 -1
- package/src/missions/store.js +27 -5
- package/src/missions/store.js.map +1 -1
- package/src/runs/background/async-execution.d.ts +9 -1
- package/src/runs/background/async-execution.d.ts.map +1 -1
- package/src/runs/background/async-execution.js +250 -141
- package/src/runs/background/async-execution.js.map +1 -1
- package/src/runs/background/async-job-tracker.d.ts +4 -1
- package/src/runs/background/async-job-tracker.d.ts.map +1 -1
- package/src/runs/background/async-job-tracker.js +3 -2
- package/src/runs/background/async-job-tracker.js.map +1 -1
- package/src/runs/background/async-resume.d.ts.map +1 -1
- package/src/runs/background/async-resume.js +6 -2
- package/src/runs/background/async-resume.js.map +1 -1
- package/src/runs/background/await-async-run.d.ts +8 -4
- package/src/runs/background/await-async-run.d.ts.map +1 -1
- package/src/runs/background/await-async-run.js +14 -8
- package/src/runs/background/await-async-run.js.map +1 -1
- package/src/runs/background/binary-bootstrap.d.ts.map +1 -1
- package/src/runs/background/binary-bootstrap.js +2 -1
- package/src/runs/background/binary-bootstrap.js.map +1 -1
- package/src/runs/background/chain-root-attachment.d.ts +2 -0
- package/src/runs/background/chain-root-attachment.d.ts.map +1 -1
- package/src/runs/background/chain-root-attachment.js +5 -2
- package/src/runs/background/chain-root-attachment.js.map +1 -1
- package/src/runs/background/fleet-view.js +5 -5
- package/src/runs/background/fleet-view.js.map +1 -1
- package/src/runs/background/notify.d.ts +12 -2
- package/src/runs/background/notify.d.ts.map +1 -1
- package/src/runs/background/notify.js +148 -13
- package/src/runs/background/notify.js.map +1 -1
- package/src/runs/background/result-files.d.ts +29 -0
- package/src/runs/background/result-files.d.ts.map +1 -1
- package/src/runs/background/result-files.js +104 -6
- package/src/runs/background/result-files.js.map +1 -1
- package/src/runs/background/result-watcher.d.ts.map +1 -1
- package/src/runs/background/result-watcher.js +60 -64
- package/src/runs/background/result-watcher.js.map +1 -1
- package/src/runs/background/resume-guidance.js +2 -2
- package/src/runs/background/resume-guidance.js.map +1 -1
- package/src/runs/background/run-child-session.d.ts.map +1 -1
- package/src/runs/background/run-child-session.js +2 -1
- package/src/runs/background/run-child-session.js.map +1 -1
- package/src/runs/background/run-id-resolver.d.ts.map +1 -1
- package/src/runs/background/run-id-resolver.js +9 -6
- package/src/runs/background/run-id-resolver.js.map +1 -1
- package/src/runs/background/run-status.d.ts.map +1 -1
- package/src/runs/background/run-status.js +19 -15
- package/src/runs/background/run-status.js.map +1 -1
- package/src/runs/background/runner-child-launch.d.ts.map +1 -1
- package/src/runs/background/runner-child-launch.js +1 -0
- package/src/runs/background/runner-child-launch.js.map +1 -1
- package/src/runs/background/runner-http-dispatcher.d.ts +3 -0
- package/src/runs/background/runner-http-dispatcher.d.ts.map +1 -1
- package/src/runs/background/runner-http-dispatcher.js +2 -0
- package/src/runs/background/runner-http-dispatcher.js.map +1 -1
- package/src/runs/background/scheduled-runs.d.ts +9 -0
- package/src/runs/background/scheduled-runs.d.ts.map +1 -1
- package/src/runs/background/scheduled-runs.js +124 -36
- package/src/runs/background/scheduled-runs.js.map +1 -1
- package/src/runs/background/subagent-runner-bootstrap.d.ts.map +1 -1
- package/src/runs/background/subagent-runner-bootstrap.js +5 -1
- package/src/runs/background/subagent-runner-bootstrap.js.map +1 -1
- package/src/runs/background/subagent-runner.d.ts +3 -1
- package/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/src/runs/background/subagent-runner.js +15 -6
- package/src/runs/background/subagent-runner.js.map +1 -1
- package/src/runs/background/subagent-wait.d.ts +2 -0
- package/src/runs/background/subagent-wait.d.ts.map +1 -1
- package/src/runs/background/subagent-wait.js +34 -20
- package/src/runs/background/subagent-wait.js.map +1 -1
- package/src/runs/background/terminal-run-index.d.ts +1 -0
- package/src/runs/background/terminal-run-index.d.ts.map +1 -1
- package/src/runs/background/terminal-run-index.js +47 -1
- package/src/runs/background/terminal-run-index.js.map +1 -1
- package/src/runs/background/wait-tool.d.ts.map +1 -1
- package/src/runs/background/wait-tool.js +36 -23
- package/src/runs/background/wait-tool.js.map +1 -1
- package/src/runs/foreground/async-stop-action.d.ts +7 -1
- package/src/runs/foreground/async-stop-action.d.ts.map +1 -1
- package/src/runs/foreground/async-stop-action.js +49 -25
- package/src/runs/foreground/async-stop-action.js.map +1 -1
- package/src/runs/foreground/execution.d.ts.map +1 -1
- package/src/runs/foreground/execution.js +50 -24
- package/src/runs/foreground/execution.js.map +1 -1
- package/src/runs/foreground/subagent-executor.d.ts +5 -1
- package/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/src/runs/foreground/subagent-executor.js +174 -65
- package/src/runs/foreground/subagent-executor.js.map +1 -1
- package/src/runs/shared/child-hooks.js +6 -5
- package/src/runs/shared/child-hooks.js.map +1 -1
- package/src/runs/shared/child-launch.d.ts +2 -0
- package/src/runs/shared/child-launch.d.ts.map +1 -1
- package/src/runs/shared/child-launch.js +1 -0
- package/src/runs/shared/child-launch.js.map +1 -1
- package/src/runs/shared/child-session.d.ts +4 -0
- package/src/runs/shared/child-session.d.ts.map +1 -1
- package/src/runs/shared/child-session.js +28 -23
- package/src/runs/shared/child-session.js.map +1 -1
- package/src/runs/shared/child-tool-plan.d.ts.map +1 -1
- package/src/runs/shared/child-tool-plan.js +11 -10
- package/src/runs/shared/child-tool-plan.js.map +1 -1
- package/src/runs/shared/dynamic-fanout.js +1 -1
- package/src/runs/shared/dynamic-fanout.js.map +1 -1
- package/src/runs/shared/herdr-placed-run.d.ts +1 -0
- package/src/runs/shared/herdr-placed-run.d.ts.map +1 -1
- package/src/runs/shared/herdr-placed-run.js +10 -6
- package/src/runs/shared/herdr-placed-run.js.map +1 -1
- package/src/runs/shared/model-resolution-diagnostic.d.ts +10 -0
- package/src/runs/shared/model-resolution-diagnostic.d.ts.map +1 -1
- package/src/runs/shared/model-resolution-diagnostic.js +24 -0
- package/src/runs/shared/model-resolution-diagnostic.js.map +1 -1
- package/src/runs/shared/model-resolution.d.ts.map +1 -1
- package/src/runs/shared/model-resolution.js +29 -1
- package/src/runs/shared/model-resolution.js.map +1 -1
- package/src/runs/shared/nested-events.d.ts +2 -0
- package/src/runs/shared/nested-events.d.ts.map +1 -1
- package/src/runs/shared/nested-events.js +4 -0
- package/src/runs/shared/nested-events.js.map +1 -1
- package/src/runs/shared/parallel-handoff.js +2 -2
- package/src/runs/shared/parallel-handoff.js.map +1 -1
- package/src/runs/shared/parallel-utils.d.ts +2 -0
- package/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/src/runs/shared/parallel-utils.js.map +1 -1
- package/src/runs/shared/runner-launcher.d.ts +12 -0
- package/src/runs/shared/runner-launcher.d.ts.map +1 -0
- package/src/runs/shared/runner-launcher.js +25 -0
- package/src/runs/shared/runner-launcher.js.map +1 -0
- package/src/runs/shared/single-output.d.ts +20 -0
- package/src/runs/shared/single-output.d.ts.map +1 -1
- package/src/runs/shared/single-output.js +57 -0
- package/src/runs/shared/single-output.js.map +1 -1
- package/src/runs/shared/structured-output.d.ts.map +1 -1
- package/src/runs/shared/structured-output.js +17 -8
- package/src/runs/shared/structured-output.js.map +1 -1
- package/src/runs/shared/subagent-control.js +3 -3
- package/src/runs/shared/subagent-control.js.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.d.ts +8 -2
- package/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.js +43 -20
- package/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
- package/src/runs/shared/workflow-async-child-guidance.js +1 -1
- package/src/runs/shared/workflow-async-child-guidance.js.map +1 -1
- package/src/runs/shared/worktree-cleanup-plan.js +1 -1
- package/src/runs/shared/worktree-cleanup-plan.js.map +1 -1
- package/src/shared/atomic-json.d.ts +4 -3
- package/src/shared/atomic-json.d.ts.map +1 -1
- package/src/shared/atomic-json.js +3 -1
- package/src/shared/atomic-json.js.map +1 -1
- package/src/shared/edit-distance.d.ts +5 -0
- package/src/shared/edit-distance.d.ts.map +1 -0
- package/src/shared/edit-distance.js +33 -0
- package/src/shared/edit-distance.js.map +1 -0
- package/src/shared/formatters.d.ts.map +1 -1
- package/src/shared/formatters.js +1 -6
- package/src/shared/formatters.js.map +1 -1
- package/src/shared/model-info.d.ts +8 -0
- package/src/shared/model-info.d.ts.map +1 -1
- package/src/shared/model-info.js +22 -0
- package/src/shared/model-info.js.map +1 -1
- package/src/shared/package-version.d.ts +3 -0
- package/src/shared/package-version.d.ts.map +1 -0
- package/src/shared/package-version.js +15 -0
- package/src/shared/package-version.js.map +1 -0
- package/src/shared/parent-wake.d.ts +18 -0
- package/src/shared/parent-wake.d.ts.map +1 -0
- package/src/shared/parent-wake.js +60 -0
- package/src/shared/parent-wake.js.map +1 -0
- package/src/shared/pruned-fork.d.ts +1 -1
- package/src/shared/pruned-fork.d.ts.map +1 -1
- package/src/shared/pruned-fork.js +6 -0
- package/src/shared/pruned-fork.js.map +1 -1
- package/src/shared/runtime-module-path.d.ts +11 -0
- package/src/shared/runtime-module-path.d.ts.map +1 -0
- package/src/shared/runtime-module-path.js +17 -0
- package/src/shared/runtime-module-path.js.map +1 -0
- package/src/shared/types.d.ts +26 -2
- package/src/shared/types.d.ts.map +1 -1
- package/src/shared/types.js +3 -0
- package/src/shared/types.js.map +1 -1
- package/src/shared/utils.d.ts.map +1 -1
- package/src/shared/utils.js +8 -7
- package/src/shared/utils.js.map +1 -1
- package/src/slash/slash-commands.js +3 -3
- package/src/slash/slash-commands.js.map +1 -1
- package/src/slash/subagents-admin.d.ts.map +1 -1
- package/src/slash/subagents-admin.js +2 -1
- package/src/slash/subagents-admin.js.map +1 -1
- package/src/tui/fleet-transcript.d.ts +2 -0
- package/src/tui/fleet-transcript.d.ts.map +1 -1
- package/src/tui/fleet-transcript.js +7 -2
- package/src/tui/fleet-transcript.js.map +1 -1
- package/src/tui/fleet.d.ts.map +1 -1
- package/src/tui/fleet.js +9 -4
- package/src/tui/fleet.js.map +1 -1
- package/src/tui/render.d.ts +2 -2
- package/src/tui/render.d.ts.map +1 -1
- package/src/tui/render.js +19 -17
- package/src/tui/render.js.map +1 -1
- package/src/tui/subagent-messages.d.ts +23 -0
- package/src/tui/subagent-messages.d.ts.map +1 -0
- package/src/tui/subagent-messages.js +270 -0
- package/src/tui/subagent-messages.js.map +1 -0
- package/src/watchdog/register-main.d.ts.map +1 -1
- package/src/watchdog/register-main.js +1 -19
- package/src/watchdog/register-main.js.map +1 -1
- package/src/watchdog/render.d.ts +2 -10
- package/src/watchdog/render.d.ts.map +1 -1
- package/src/watchdog/render.js +1 -19
- package/src/watchdog/render.js.map +1 -1
- package/src/watchdog/tool-actions.js +2 -2
- package/src/watchdog/tool-actions.js.map +1 -1
- package/src/workflows/scripted-workflow.d.ts.map +1 -1
- package/src/workflows/scripted-workflow.js +20 -6
- package/src/workflows/scripted-workflow.js.map +1 -1
- package/src/workflows/workflow-resources.d.ts.map +1 -1
- package/src/workflows/workflow-resources.js +12 -0
- package/src/workflows/workflow-resources.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,98 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.77.0] - 2026-10-09
|
|
6
|
+
|
|
7
|
+
### Highlights
|
|
8
|
+
|
|
9
|
+
- Subagents cost the parent far fewer tokens. The `subagent` tool's schema and description dropped from about 18,700 to 3,300 characters per request, `bg_wait` from about 4,500 to 1,100, and the bundled role prompts are about 20% shorter. Long child reports and guide pages now arrive as a short preview plus a file path instead of the full text.
|
|
10
|
+
- Upgrading pi-subagents no longer costs resumed sessions their prompt cache, and upgrading under a running Pi no longer breaks every child launch.
|
|
11
|
+
- Fewer wasted parent turns: launch an agent by name and a wrong agent or model name comes back with suggestions, the new built-in `parallel` workflow runs a batch of children without a script, and a parent woken by a result handles it instead of going quiet.
|
|
12
|
+
- Background children can run inside a sandbox with `launcher:`, terminals such as Ghostty show each run's state, and tmux users get a bundled inspector pane.
|
|
13
|
+
- A session that declined project trust no longer takes models, agents, or settings from that project.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Running independent subagents in parallel needed a JavaScript workflow script that the model had to write in its reply, and some parents had to save it to a file first. The built-in `parallel` workflow takes the children as data: `subagent({ workflow: "parallel", args: { tasks: [{ agent, task }, ...] } })` runs them in one batch and returns each child's output in order. The tool schema is unchanged. ([#2773](https://github.com/nicobailon/pi-subagents/issues/2773))
|
|
18
|
+
- Background children could run in a sandbox only through an external CLI runner, which loses native steering and results. An agent can now set `launcher:` to a command from the user config's `runnerLaunchers`, such as a sandbox, and that command wraps its background runner. Steering, supervisor questions, stop, resume and results keep working. Thanks to [@aaronkyriesenbach](https://github.com/aaronkyriesenbach) for the idea, design and nono testing. ([#2577](https://github.com/nicobailon/pi-subagents/issues/2577))
|
|
19
|
+
- A terminal could not tell which background subagent runs were working, waiting on you, finished, or failed without reading the screen. Each run's state is now reported with OSC 7501, the Program Status Protocol, which terminals such as Ghostty can show next to Pi's own status. Set `programStatus: false` or `PI_PROGRAM_STATUS=0` to turn it off. ([#2724](https://github.com/nicobailon/pi-subagents/issues/2724))
|
|
20
|
+
- Fleet's `Enter`/`H` inspector needed Herdr or Ghostty, so tmux users had to write their own provider. A bundled `tmux` inspector now opens the read-only inspector in a split pane of the current tmux window, with status and close support. Thanks to [@tobymao](https://github.com/tobymao) for the plugin. ([#2719](https://github.com/nicobailon/pi-subagents/pull/2719))
|
|
21
|
+
- The async widget under the editor gives each active background run two or more lines while the terminal has room, and `asyncWidgetCollapsed: true` folds it to a count that names no run. Set `asyncWidgetLayout: "rows"` to show a header and one line per run; clicking the header still folds the widget, and Pi's expand key still shows the details. Thanks to [@pwguler](https://github.com/pwguler) for [#2738](https://github.com/nicobailon/pi-subagents/pull/2738).
|
|
22
|
+
- Session browsers and usage tools could link a subagent run to the session that launched it only by parsing the directory layout. A new child session's header now records the launching session's file as `parentSession`, the same field Pi writes for forks, and the run's `_meta.json` records `parentSessionId`. Thanks to [@yingzhi0808](https://github.com/yingzhi0808) for the request. ([#2763](https://github.com/nicobailon/pi-subagents/issues/2763))
|
|
23
|
+
- A host that shows subagent activity could not tell which run a `subagent-notify` completion notice belonged to without parsing its text. Each entry in the notice's `details.runs` now carries the run id (`runId`, plus `workflowRunId` and per-child `childRuns` for workflows), status, duration and saved paths. The text the model sees is unchanged. Thanks to [@kushaldotdev](https://github.com/kushaldotdev) for the request. ([#2788](https://github.com/nicobailon/pi-subagents/issues/2788))
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- The `subagent` tool sent about 13,000 characters of parameter schema on every model request, mostly for management fields a typical delegation never uses. The schema now lists `agent`, `task`, `workflow`, `args`, `async`, `model`, `cwd`, `worktree`, `output`, `action`, `id` and `message` at the top level and every other field inside one `options` object, which cuts it to about 2,100 characters. Management fields and the `runId`, `maxRuntimeMs` and `isolation` aliases still work at the top level, so existing calls and resumed sessions are unaffected. An unknown `options` key gets the closest valid name, and a field given in both places with different values is rejected. Docs, guides, skills and the run hints in tool results now show `options`. ([#2767](https://github.com/nicobailon/pi-subagents/issues/2767))
|
|
28
|
+
- The default `subagent` tool description took about 5,700 characters on every model request, and the rule about when delegation is allowed appeared three times. The description is now about 1,200 characters and states each rule once: how to call the tool, that async runs wake the parent on their own, one writer per worktree, and not to silently switch to another runner after a failure. It points to the guide for workflow scripts, resume and external CLIs. The tool no longer registers a prompt guideline, and its prompt snippet no longer repeats the delegation rule. `toolDescriptionMode: "full"` keeps the old detail inline. ([#2768](https://github.com/nicobailon/pi-subagents/issues/2768))
|
|
29
|
+
- The `bg_wait` tool's description and parameters took about 4,500 characters on every model request, and each of its five parameters repeated that ordinary async runs already wake the session. They now take about 1,100 characters: the description says it once and lists the call shapes, and each parameter has a short label. ([#2769](https://github.com/nicobailon/pi-subagents/issues/2769))
|
|
30
|
+
- The `subagent` tool description told the parent to call `{action:"list"}` before delegating and `{action:"models"}` before choosing a model, which cost an extra parent turn each time plus 1,300–2,000 tokens that stayed in history. It now says to launch by name with an exact `provider/id`. An unknown or disabled agent fails with a "did you mean" and the available agents with one-line descriptions (at most 30). An unknown or ambiguous model fails with up to 5 of the closest model ids. `list` and `models` still work on demand. ([#2771](https://github.com/nicobailon/pi-subagents/issues/2771))
|
|
31
|
+
- The catalog of agents marked `advertise: true` also told the parent to call `{action:"list"}` before every delegation. Now that a launch with an unknown agent returns the available agents, new sessions no longer get that instruction. A resumed session keeps the catalog text it already has, so the upgrade does not change its prompt or cost it the provider's prompt cache. ([#2791](https://github.com/nicobailon/pi-subagents/issues/2791))
|
|
32
|
+
- Changing a pi-subagents tool description, schema, prompt snippet, or guideline made every resumed or reloaded session re-declare that tool before its next request, so the provider re-read the whole conversation without its prompt cache. The `subagent`, `bg_wait` and `subagents_enable` tools, and a child session's `bg_wait` and fanout `subagent`, now keep the definition and prompt text the session already declared. Only sessions that never declared a tool get its current definition. ([#2778](https://github.com/nicobailon/pi-subagents/issues/2778))
|
|
33
|
+
- Every turn of a child launched with a bundled role resent its full role prompt, and those prompts repeated their own rules and the supervisor instructions that are already appended. The `oracle`, `reviewer`, `worker`, `researcher` and `scout` prompts drop the repeats and keep every rule, going from 21,283 to 17,139 characters in total (oracle 6,059 → 4,789, reviewer 5,211 → 4,443, worker 4,296 → 3,083). ([#2775](https://github.com/nicobailon/pi-subagents/issues/2775))
|
|
34
|
+
- Async completion notices, completed-run `status` and foreground results put a child's whole output into the parent's context (about 38,000 characters for one long report), and every async launch receipt repeated about 870 characters of waiting guidance. They now show the first 2,000 characters of a longer output followed by the path, size and line count of the file that holds all of it; output with no such file stays whole. Workflow child previews are capped at 2,000 characters, structured-output previews in `status` at 500 when a path line follows, failure notices now include an `Error:` line even when the child produced output, and the receipt guidance is two short lines. ([#2774](https://github.com/nicobailon/pi-subagents/issues/2774))
|
|
35
|
+
- `subagent({action:"guide",topic})` returned a whole document, up to 62 KB for `tool-reference`, and that text stayed in the parent's history for every later turn. A docs-backed topic now returns its intro and a list of sections, and `topic: "<topic>/<section>"` returns one section of at most 8,000 characters. `overview` and `council` are unchanged. ([#2772](https://github.com/nicobailon/pi-subagents/issues/2772))
|
|
36
|
+
- Each message pi-subagents put in the main chat had its own look: bordered cards for supervisor requests, replies and attention notices, `✓`/`✗` lines for completions, plain colored lines for steering, and Pi's default block with raw labels such as `[subagent-wait-subscription]` for reminders and wakes. They now all use Pi's own message block, the one behind `[skill]`: a single `[subagent]` line whose label color names the kind (supervisor question or attention, reply, result, or watchdog) and whose status word uses the theme's status color. A click opens one block and Pi's expand key opens them all, showing the text the main agent read. Thanks to [@pwguler](https://github.com/pwguler) for [#2753](https://github.com/nicobailon/pi-subagents/pull/2753).
|
|
37
|
+
- Subagent model displays (Fleet, the async widget, run status, nested renders and result cards) showed only the model id, so two providers or logins serving the same model looked identical. They now show `provider/model`. Thanks to [@IdrisGit](https://github.com/IdrisGit) for [#2734](https://github.com/nicobailon/pi-subagents/pull/2734).
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- A session that declined Pi project trust still took subagent models, `modelScope` and agent definitions from the project, although Pi loads nothing from an untrusted project's `.pi` directory. Such a session now ignores project subagent settings, project agents and chains, and agents from packages installed for the project or declared in its `package.json`. The default scope behaves as `user`, and an explicit `agentScope: "project"` is rejected. Public preflight takes `projectTrusted` to match. Thanks to [@Saturnoon](https://github.com/Saturnoon) for the report. ([#2764](https://github.com/nicobailon/pi-subagents/issues/2764))
|
|
42
|
+
- In a session that declined project trust, a malformed project `.pi/settings.json` still made subagent discovery and launch checks fail with "Failed to parse settings file", and a project's `agentExcludeDirs` could still hide user agents. An untrusted lookup now reads nothing from the project's settings; trusted lookups still report a broken file. ([#2804](https://github.com/nicobailon/pi-subagents/issues/2804))
|
|
43
|
+
- After pi-subagents was upgraded under a running Pi session, every child launch could fail at once with "Extension path does not exist" or MODULE_NOT_FOUND, because the paths of the child runtime extensions and the async runner kept the file extension (`.ts` or `.js`) of the copy loaded at startup. They are now found on disk at each launch, preferring `.js`. Thanks to [@barjatiyasaurabh](https://github.com/barjatiyasaurabh) for the fix ([#2761](https://github.com/nicobailon/pi-subagents/pull/2761)) and [@gitwyy](https://github.com/gitwyy) for the report. ([#2780](https://github.com/nicobailon/pi-subagents/issues/2780))
|
|
44
|
+
- A parent could wake for a supervisor decision or a finished workflow, reply with nothing, and leave the delegated work unhandled until you sent another message. The wake message now asks the parent to handle the result within the authority it already has. If it still replies with nothing, it gets one more turn and then a short notice that the work is unhandled, never an automatic approval. A visible reply, including a question to you, does not force another turn. Thanks to [@CamAnNguyen](https://github.com/CamAnNguyen) for [#2716](https://github.com/nicobailon/pi-subagents/pull/2716).
|
|
45
|
+
- When a subagent notice and an intercom message reached an idle parent at the same moment, both extensions started a turn, and the second failed with `Extension "<runtime>" error: Agent is already processing a prompt`. pi-subagents and pi-intercom now share one wake per session, so the second message joins the turn the first one starts. This needs the matching pi-intercom release.
|
|
46
|
+
- A message you typed while a blocking `bg_wait` was open sat in Pi's queue until the wait ended, which could take the whole wait window (30 minutes by default). A steer or follow-up from you now ends the wait with a non-error `user_input` result that lists the work still running; the work keeps going. Messages sent by extensions do not end the wait. Thanks to [@nuzayets](https://github.com/nuzayets) for [#2736](https://github.com/nicobailon/pi-subagents/pull/2736).
|
|
47
|
+
- A scheduled run whose async runner died before writing a final status kept its schedule's claim, so every later fire was recorded as `skipped_overlap` and the schedule did nothing until someone deleted its `active.lock`. A fire that overlaps an active run, and a session that restores the schedule, now check whether that run is still alive: when its process is gone, or its status has not changed for 24 hours, the run is recorded as `failed_run` with the reason and the due fire launches. A run whose runner is alive is still skipped. Thanks to [@kmatzen](https://github.com/kmatzen) for the report and the first fix. ([#2806](https://github.com/nicobailon/pi-subagents/issues/2806))
|
|
48
|
+
- Starting Pi in the home directory failed with "Project schedule root ... resolves outside the real project" when `~/.pi` was a symlink to a directory outside home, such as a mounted drive. When the project is the home directory, the real user config directory is now accepted as a schedule root; a project `.pi` that links outside its project is still rejected. Thanks to [@mecha](https://github.com/mecha) for the report. ([#2737](https://github.com/nicobailon/pi-subagents/issues/2737))
|
|
49
|
+
- A host still handling a background run's paused result could delete or overwrite the final result written after it under the same run id, or remove that run's session, run and mission indexes. When the final result could not replace the paused file (EPERM/EACCES), it was delivered over and over without completing. Results are now written and consumed under a per-run lock, and a consumer leaves alone any result written after it read the run, along with its indexes. ([#2744](https://github.com/nicobailon/pi-subagents/issues/2744))
|
|
50
|
+
- When a workflow awaited an async child, it could read the child's result before the child had written its index entries, so those entries were written after the workflow cleaned up and stayed behind in the child's run directory. A child now writes all index entries before its result becomes readable. ([#2741](https://github.com/nicobailon/pi-subagents/issues/2741))
|
|
51
|
+
- A foreground child that detached to ask its supervisor kept running after a reload or session switch. Status and resume then said "Async run not found", and its workflow showed as stopped. Reloading pi-subagents now stops each detached foreground child and records it as stopped, so status shows the stop and its cause, resume works from its session, and its pending supervisor question is closed. Thanks to [@Saturnoon](https://github.com/Saturnoon) for the report. ([#2762](https://github.com/nicobailon/pi-subagents/issues/2762))
|
|
52
|
+
- Interrupting a run id that could not be resolved interrupted the newest unrelated running job instead, and a nested async child whose owner had no foreground route to it could not be interrupted at all. An explicit interrupt id now fails when it does not resolve (a bare interrupt still picks the newest run), and an interrupt the owner cannot route now goes to the nested child directly. Thanks to [@leopepe](https://github.com/leopepe) for the fix ([#2760](https://github.com/nicobailon/pi-subagents/pull/2760)).
|
|
53
|
+
- RPC stop refused queued and paused async runs, which the `subagent` tool's own stop action already handles. RPC stop now follows the tool's stop rules, with the same session and process checks. Thanks to [@alexei-led](https://github.com/alexei-led) for the fix (split from [#2717](https://github.com/nicobailon/pi-subagents/pull/2717)).
|
|
54
|
+
- An RPC client that lost the spawn reply for a direct async run could not find the run by its tool-call ID once the result was delivered. Direct runs now keep the tool-call ID for status lookup after delivery, and an ID shared by a live run and a finished run is reported as ambiguous. Thanks to [@alexei-led](https://github.com/alexei-led) for [#2717](https://github.com/nicobailon/pi-subagents/pull/2717).
|
|
55
|
+
- Over Pi's RPC mode, the `/subagents` admin screen's "Change model" and "Change thinking level", `/subagents-fleet` and `/subagents-stop` closed with no screen and no message, because RPC mode has no custom UI. These screens now use their component only in the TUI; elsewhere they use a select prompt or text instead. Thanks to [@gelubodrug](https://github.com/gelubodrug) for the report. ([#2766](https://github.com/nicobailon/pi-subagents/issues/2766))
|
|
56
|
+
- A mission created through one path to a project was "not found" by `mission.show`, `mission.list` or a `missionId` launch through another path to the same directory, such as `/tmp/x` and its real path `/private/tmp/x` on macOS. The default mission store is now keyed by the project's real path, so symlinks, junctions and, on case-insensitive filesystems, letter case no longer split it; a configured `directory` or `globalIndexDir` still expands against the path as given. Missions created before this change through a path other than the real one stay on disk but are no longer found through that path. Thanks to [@hughy](https://github.com/hughy) for the report and the fix ([#2785](https://github.com/nicobailon/pi-subagents/pull/2785)). ([#2783](https://github.com/nicobailon/pi-subagents/issues/2783))
|
|
57
|
+
- When TypeBox was installed only in Pi's own dependencies, every `structured_output` call failed with "Cannot load typebox/compile for structured output validation" unless `PI_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT` was set. Validation now also looks for TypeBox in the running Pi's package. Thanks to [@Saturnoon](https://github.com/Saturnoon) for the report. ([#2765](https://github.com/nicobailon/pi-subagents/issues/2765))
|
|
58
|
+
- Pruned fork context failed with `400 MissingSessionID` when `forkContext.model` was an OpenCode or OpenCode Go model, because the summary request carried no session id. It now sends the parent session id and the `x-opencode-session` header, as the watchdog and prompt-audit requests do. ([#2759](https://github.com/nicobailon/pi-subagents/issues/2759))
|
|
59
|
+
- The `subagent` tool schema marked the `reviewed` value of `acceptance` with `deprecated: true`, which strict tool-schema validators reject with HTTP 400, so the tool failed on those providers. The schema no longer includes `deprecated`. Thanks to [@kingofdies](https://github.com/kingofdies) for the report. ([#2713](https://github.com/nicobailon/pi-subagents/issues/2713))
|
|
60
|
+
- Background children failed within a second with "Request timed out" on networks where connecting to the provider takes longer than 250 ms. The background runner used Node's 250 ms per-address connection limit, while Pi uses 2 s; the runner now uses 2 s too. Thanks to [@robinchm](https://github.com/robinchm) for the report and the fix. ([#2758](https://github.com/nicobailon/pi-subagents/issues/2758))
|
|
61
|
+
- A foreground child whose model comes from a provider that a parent extension registered gets the provider but not that extension's session hooks, so a provider that needs those hooks failed the first request with an error only the provider understood. That failure now also says the child ran in the foreground without the extension and names the fixes: `async: true`, or loading the extension for that agent. Thanks to [@tharanee-bit](https://github.com/tharanee-bit) for the report. ([#2730](https://github.com/nicobailon/pi-subagents/issues/2730))
|
|
62
|
+
- Prompt sections that other extensions add in `before_agent_start` reached a child's transcript but not its provider requests, because the child prompt was finished before those extensions ran. The child's prompt now keeps their sections and adds its own boundary after every other extension. Thanks to [@adameq](https://github.com/adameq) for the report. ([#2745](https://github.com/nicobailon/pi-subagents/issues/2745))
|
|
63
|
+
- Every workflow script failed before its first line with "Cannot redefine property: then" (or "Attempting to change value of a readonly property") when the host Pi build froze `Promise.prototype` everywhere, including the workflow sandbox. The runner now works with a frozen `Promise.prototype` and still catches children that were never awaited. Thanks to [@albertgwo](https://github.com/albertgwo) for [#2793](https://github.com/nicobailon/pi-subagents/pull/2793).
|
|
64
|
+
- A workflow script failed with "emit.<field> must be a JSON value; received undefined" when it emitted an object with an undefined field, such as a child result's missing `outputPathMapping`, although `return` accepted the same object. `emit` now drops undefined object fields and turns undefined array entries into `null`, as `return` does, and workflow script errors report the script's own line numbers instead of one line later. Thanks to [@vip0351](https://github.com/vip0351) for [#2751](https://github.com/nicobailon/pi-subagents/issues/2751).
|
|
65
|
+
- A workflow stage that resumed an earlier stage without its own `output` reused the earlier stage's report path, so it failed before launch when the earlier stage ran in the background, and overwrote the earlier report otherwise. It now writes to its own default report path. ([#2711](https://github.com/nicobailon/pi-subagents/issues/2711))
|
|
66
|
+
- A background workflow's child rows showed no token usage or turn count, although each child's own status had them and the workflow total was their sum. Each child row now shows the usage and turn count from that child's result. Thanks to [@moxuun](https://github.com/moxuun) for the report. ([#2715](https://github.com/nicobailon/pi-subagents/issues/2715))
|
|
67
|
+
- A long-running foreground child re-formatted every past tool call on each progress update, although progress shows only the latest 64, so each update got slower as the child's history grew. Progress updates now format only those 64 calls. ([#2704](https://github.com/nicobailon/pi-subagents/issues/2704))
|
|
68
|
+
- Fleet reread and re-rendered the selected transcript every 750 ms even when it had not changed, which took hundreds of milliseconds per refresh for a long transcript. It now reuses the rendered transcript until the file, selection, width or tool view changes. ([#2705](https://github.com/nicobailon/pi-subagents/issues/2705))
|
|
69
|
+
- A Herdr-placed Pi child's bridge kept every frame it received, so a healthy run failed and started reconnecting after its 1,024th frame. Frames are now released once the session has taken them. ([#2706](https://github.com/nicobailon/pi-subagents/issues/2706))
|
|
70
|
+
- Two inspector opens for the same run or child at once, for example from Fleet and a tool call or from two Pi processes, could each open a pane and save a binding, so one pane could no longer be reached by `inspector.status` or `inspector.close`, and a close racing an open could miss the pane the open created. Open and close for the same run or child now wait for each other, across processes too. ([#2727](https://github.com/nicobailon/pi-subagents/issues/2727))
|
|
71
|
+
|
|
72
|
+
## [0.76.1] - 2026-10-05
|
|
73
|
+
|
|
74
|
+
### Highlights
|
|
75
|
+
|
|
76
|
+
- When a subagent result wakes an idle parent, that run keeps the subagent list, MCP servers, and other extensions' prompt sections, and no longer churns the provider's prompt cache.
|
|
77
|
+
- Updating pi-subagents while Pi is running now stops `/reload` with a clear "restart Pi" error instead of running a mix of old and new code.
|
|
78
|
+
- In Herdr, a child asking its parent agent for help no longer turns the pane red.
|
|
79
|
+
- `stop` works on a paused run whose result was already delivered, and `subagent doctor` now shows the same async capacity that launches use.
|
|
80
|
+
- Reloading extensions while a child's result is waiting no longer lets a host such as pi-web lose that result.
|
|
81
|
+
|
|
82
|
+
### Changed
|
|
83
|
+
|
|
84
|
+
- The npm package now has the `extension` keyword, so Pi's extension catalog lists pi-subagents under Extensions instead of Unlabelled.
|
|
85
|
+
|
|
86
|
+
### Fixed
|
|
87
|
+
|
|
88
|
+
- When a subagent result, supervisor question, or other notice woke an idle parent, the run it started skipped Pi's normal prompt setup. From its second request on, it lost the subagent list, the MCP server list, and other extensions' prompt sections, and the changing prompt could invalidate the provider's prompt cache. The parent now gets the notice followed by a short `Subagent updates above.` message, which starts the run the normal way. Thanks to [@ashlineldridge](https://github.com/ashlineldridge) for [#2688](https://github.com/nicobailon/pi-subagents/issues/2688).
|
|
89
|
+
- Reloading extensions while a child's result was waiting in Pi's queue made the session look idle, so a host such as pi-web could replace the session and lose the result. The session now stays busy until Pi picks up the result. Thanks to [@brettinternet](https://github.com/brettinternet) for [#2687](https://github.com/nicobailon/pi-subagents/pull/2687).
|
|
90
|
+
- After pi-subagents was updated while Pi was running, `/reload` ran a mix of old and new code and failed with errors such as `completionNotifier.messageStarted is not a function`. Node cannot reload a module it has already imported, so loading now stops with an error that names both versions and asks you to restart Pi. Thanks to [@TheAsda](https://github.com/TheAsda) for [#2695](https://github.com/nicobailon/pi-subagents/issues/2695).
|
|
91
|
+
- Child system prompts started with pi-subagents' own instructions instead of Pi's base prompt. Providers and extensions that recognize Pi's default prompt by its first sentence then sent `systemPromptMode: append` children Pi's whole prompt unchanged. Pi's prompt now comes first. ([#2692](https://github.com/nicobailon/pi-subagents/issues/2692))
|
|
92
|
+
- When a per-tool timeout stopped a foreground child, its output said `Subagent timed out after <run timeout>ms.` (or `0ms` when no run timeout was set), naming a deadline that never fired. It now names the tool timeout, for example `Tool 'find' exceeded its timeout of 300000ms.` Thanks to [@mannainsect](https://github.com/mannainsect) for [#2691](https://github.com/nicobailon/pi-subagents/issues/2691).
|
|
93
|
+
- `stop` failed with `paused result is missing` on a paused run whose result had already been delivered or was never written, and a finished parent workflow kept that run's async capacity slot. When the run's process has exited, `stop` now marks it stopped and the slot is freed. Thanks to [@builtroller](https://github.com/builtroller) for reporting [#2699](https://github.com/nicobailon/pi-subagents/issues/2699).
|
|
94
|
+
- `subagent doctor` could report `usage: 0/3 used` while launches were rejected with `3/3 used`, for example in a session resumed with `pi --session <id>`, because doctor counted a different capacity pool than launches do. It now reads the same pool for both active async capacity and the spawn budget. Thanks to [@builtroller](https://github.com/builtroller) for reporting [#2698](https://github.com/nicobailon/pi-subagents/issues/2698).
|
|
95
|
+
- In Herdr, the pane turned red, which means a person needs to act, whenever an async child needed attention, including a child waiting for its parent agent's answer. Those requests go to the parent agent, so pi-subagents no longer marks the pane blocked; the `⚠` in the pane's subagent label still shows it. Thanks to [@nateberkopec](https://github.com/nateberkopec) for reporting [#2702](https://github.com/nicobailon/pi-subagents/issues/2702).
|
|
96
|
+
|
|
5
97
|
## [0.76.0] - 2026-10-04
|
|
6
98
|
|
|
7
99
|
### Highlights
|
package/README.md
CHANGED
|
@@ -110,7 +110,7 @@ For bounded orchestration, `maxSubagentSpawnsPerRun` limits cumulative logical c
|
|
|
110
110
|
|
|
111
111
|
or ask: "Check whether subagents and intercom are set up correctly."
|
|
112
112
|
|
|
113
|
-
For installed-version help, use `/subagents-guide [topic]` or `subagent({ action: "guide", topic: "workflows" })`. The default topic is `overview`; available topics are `overview`, `workflows`, `agents`, `missions`, `observability`, `tool-reference`, `configuration`, `models`, `watchdog`, `extension-api`, and `council`.
|
|
113
|
+
For installed-version help, use `/subagents-guide [topic]` or `subagent({ action: "guide", options: { topic: "workflows" } })`. The default topic is `overview`; available topics are `overview`, `workflows`, `agents`, `missions`, `observability`, `tool-reference`, `configuration`, `models`, `watchdog`, `extension-api`, and `council`.
|
|
114
114
|
|
|
115
115
|
## Documentation
|
|
116
116
|
|
package/agents/oracle.md
CHANGED
|
@@ -14,40 +14,29 @@ You are the oracle: a high-context decision-consistency subagent.
|
|
|
14
14
|
|
|
15
15
|
Your primary job is to prevent the main agent from making hidden, conflicting, or inconsistent decisions by treating the inherited forked context as the authoritative contract. You are not the primary executor. You do not silently become a second decision-maker.
|
|
16
16
|
|
|
17
|
-
Before
|
|
17
|
+
Before anything else, reconstruct the key inherited decisions, constraints, and open questions from the forked conversation, codebase state, and task. They form your baseline contract. Preserve them unless there is strong evidence they should be overturned.
|
|
18
18
|
|
|
19
19
|
Match search scope to the question. For runtime behavior, begin with specific source symbols, types, methods, and paths. For product, plan, policy, or decision drift, treat supplied documents and inherited context as first-class evidence. If source conflicts with docs about runtime behavior, trust source and report the conflict.
|
|
20
20
|
|
|
21
|
-
If the task asks about asking or consulting the oracle, or asks to ask, consult, discuss with, or come to agreement with the oracle about a plan, design, or architecture decision, treat it as a short live consultation unless the parent explicitly requests a one-shot report. In a first response, return the strongest challenge point or focused follow-up question when a material tradeoff remains, so the parent can resume this same session for one targeted round. A one-shot response
|
|
21
|
+
If the task asks about asking or consulting the oracle, or asks to ask, consult, discuss with, or come to agreement with the oracle about a plan, design, or architecture decision, treat it as a short live consultation unless the parent explicitly requests a one-shot report. In a first response, return the strongest challenge point or focused follow-up question when a material tradeoff remains, so the parent can resume this same session for one targeted round. A one-shot response suits an explicit one-shot request, a trivial question, or a fully settled first answer.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Do not send routine completion handoffs. If no coordination is needed, or after needed coordination is answered, return the final oracle recommendation normally. If `contact_supervisor` is unavailable, return the best recommendation and name the decision that still needs the main agent. Use generic `intercom` only when an external intercom provider explicitly supplies that tool and the task identifies a safe target.
|
|
23
|
+
When runtime bridge instructions provide `contact_supervisor` and a material unknown, contradiction, or unapproved decision would make a recommendation guessy, ask one focused question with `reason: "need_decision"` and wait for the reply. Do not guess. Use `reason: "progress_update"` only for concise updates when blocked, when explicitly asked for progress, or when a recommendation or concern would benefit from immediate discussion. Keep coordination traffic tight and purposeful; do not narrate your review through `contact_supervisor` or send routine completion handoffs. If no supervisor channel is available, return the best recommendation and name the decision that still needs the main agent. Use generic `intercom` only when an external intercom provider explicitly supplies that tool and the task identifies a safe target.
|
|
26
24
|
|
|
27
25
|
Core responsibilities:
|
|
28
|
-
-
|
|
29
|
-
- identify drift between the current trajectory and those inherited decisions
|
|
26
|
+
- identify drift between the current trajectory and the inherited decisions, and call out when a proposed move conflicts with an earlier decision or constraint
|
|
30
27
|
- surface contradictions and hidden assumptions the main agent may be missing
|
|
31
|
-
- call out when a proposed move conflicts with an earlier decision or constraint
|
|
32
28
|
- protect consistency over novelty; prefer the path that honors existing decisions unless the context clearly supports a pivot
|
|
33
|
-
- when you
|
|
34
|
-
-
|
|
29
|
+
- when you recommend a pivot, explain exactly which prior assumption or decision should be revised and why
|
|
30
|
+
- use your clean forked context to spot what the main agent may have missed due to context rot, accumulated reasoning, or errors in the original instruction
|
|
35
31
|
- look beyond the explicit question and suggest guidance based on the overall agent trajectory, even when not directly asked
|
|
36
32
|
|
|
37
33
|
What you do not do by default:
|
|
38
|
-
- do not edit files or write code
|
|
34
|
+
- do not edit files or write code; use `bash` only for inspection, verification, or read-only analysis
|
|
39
35
|
- do not propose additional parallel decision-makers or new subagent trees unless explicitly asked
|
|
40
36
|
- do not assume a `worker` implementation handoff is the default outcome
|
|
41
|
-
- do not propose broad pivots unless the context clearly supports them
|
|
37
|
+
- do not propose broad pivots unless the context clearly supports them; prefer narrow, specific corrections to the current path over rewriting the whole plan
|
|
42
38
|
- do not continue the user conversation directly
|
|
43
39
|
|
|
44
|
-
Working rules:
|
|
45
|
-
- Use `bash` only for inspection, verification, or read-only analysis.
|
|
46
|
-
- If information is missing and it matters, ask the main agent with `contact_supervisor` and `reason: "need_decision"` when bridge instructions provide that tool. If no supervisor channel is available, return the best recommendation and name the unresolved decision instead of guessing.
|
|
47
|
-
- If the answer depends on a decision the main agent has not made yet, stop and ask with `contact_supervisor` when bridge instructions provide that tool. If no supervisor channel is available, mark the decision as still needed in the final recommendation.
|
|
48
|
-
- When bridge instructions are present, send concise coordination messages only when a recommendation, concern, or question would benefit from immediate discussion instead of waiting silently until the final return.
|
|
49
|
-
- Prefer narrow, specific corrections to the current path over rewriting the whole plan.
|
|
50
|
-
|
|
51
40
|
Your output should follow this shape. If no executor handoff is warranted, say so plainly.
|
|
52
41
|
|
|
53
42
|
Inherited decisions:
|
package/agents/researcher.md
CHANGED
|
@@ -57,6 +57,3 @@ Unverified claims and unresolved questions.
|
|
|
57
57
|
|
|
58
58
|
## Next steps
|
|
59
59
|
Only the most useful follow-up research.
|
|
60
|
-
|
|
61
|
-
## Supervisor coordination
|
|
62
|
-
If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Use `reason: "progress_update"` only for meaningful progress or unexpected discoveries that change the plan. Do not send routine completion handoffs; return the completed research brief normally.
|
package/agents/reviewer.md
CHANGED
|
@@ -8,63 +8,26 @@ inheritProjectContext: true
|
|
|
8
8
|
inheritSkills: false
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
You are a disciplined review subagent.
|
|
11
|
+
You are a disciplined review subagent. Inspect, evaluate, and report findings with evidence. Do not guess; verify from the code, tests, docs, or requirements.
|
|
12
12
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- Tests cover the change and still pass.
|
|
20
|
-
- No unintended side effects or regressions.
|
|
21
|
-
- The change is minimal and readable.
|
|
22
|
-
|
|
23
|
-
### 2. Plans
|
|
24
|
-
Validate a proposed plan for:
|
|
25
|
-
- Feasibility and completeness.
|
|
26
|
-
- Missing steps or hidden risks.
|
|
27
|
-
- Alignment with existing architecture and constraints.
|
|
28
|
-
- Whether the scope is appropriately bounded.
|
|
29
|
-
|
|
30
|
-
### 3. Proposed solutions
|
|
31
|
-
Evaluate a suggested approach for:
|
|
32
|
-
- Correctness and tradeoffs.
|
|
33
|
-
- Fit with existing codebase patterns.
|
|
34
|
-
- Whether simpler alternatives exist.
|
|
35
|
-
- Edge cases the proposal may miss.
|
|
36
|
-
|
|
37
|
-
### 4. Current overall state of the codebase
|
|
38
|
-
Assess codebase health by inspecting key files, tests, and structure. Look for:
|
|
39
|
-
- Architecture drift or tech debt.
|
|
40
|
-
- Inconsistent patterns or naming.
|
|
41
|
-
- Areas lacking tests or documentation.
|
|
42
|
-
- Obvious bugs or fragile code.
|
|
43
|
-
- Opportunities to simplify or consolidate.
|
|
44
|
-
|
|
45
|
-
### 5. Specific PR or issue
|
|
46
|
-
Review a PR or issue by understanding the context, then verifying:
|
|
47
|
-
- The fix or feature addresses the root cause.
|
|
48
|
-
- Changes are minimal and focused.
|
|
49
|
-
- No regressions are introduced.
|
|
50
|
-
- Tests and docs are updated as needed.
|
|
13
|
+
## What to check by review type
|
|
14
|
+
- Code diffs: the implementation matches intent and requirements; it is correct and handles edge cases; tests cover the change and still pass; no unintended side effects or regressions; the change is minimal and readable.
|
|
15
|
+
- Plans: feasibility and completeness, missing steps or hidden risks, fit with existing architecture and constraints, and appropriately bounded scope.
|
|
16
|
+
- Proposed solutions: correctness and tradeoffs, fit with codebase patterns, simpler alternatives, and missed edge cases.
|
|
17
|
+
- Codebase state: architecture drift or tech debt, inconsistent patterns or naming, areas lacking tests or docs, obvious bugs or fragile code, and chances to simplify or consolidate.
|
|
18
|
+
- A specific PR or issue: understand the context, then verify the change addresses the root cause, stays minimal and focused, introduces no regressions, and updates tests and docs as needed.
|
|
51
19
|
|
|
52
20
|
## Working rules
|
|
53
|
-
- Start from the exact diff and named source seam for code-behavior review.
|
|
54
|
-
- Read the relevant files first
|
|
55
|
-
- Repo-local `progress.md` files are allowed scratch/memory files. Do not flag them as repo noise, delete them, or ask to remove them
|
|
56
|
-
-
|
|
57
|
-
- Do not use shell commands, mutate the repository, or request general Git access. Report any test command
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
- If everything looks good, say so plainly.
|
|
61
|
-
- If you are asked to maintain progress, record what you checked and what you found.
|
|
62
|
-
- If review-only or no-edit instructions conflict with progress-writing instructions, review-only/no-edit wins. Do not write `progress.md`; mention the conflict in your final review only if it matters.
|
|
21
|
+
- Start from the exact diff and named source seam for code-behavior review. Discover with specific source, symbol, type, method, and path searches. Use broad or unscoped `grep` only when exhaustive verification is required, such as checking call sites, imports, removed names, or absence of a pattern.
|
|
22
|
+
- Read the relevant files first, and the plan and progress when the task supplies them.
|
|
23
|
+
- Repo-local `progress.md` files are allowed scratch/memory files. Do not flag them as repo noise, delete them, or ask to remove them because they are untracked; in a coding repo they should stay untracked and be covered by `.gitignore`.
|
|
24
|
+
- `watchdog_diff` does not inspect committed ranges. When a task asks for one, require a supplied artifact or report that limitation rather than claiming the commit was reviewed.
|
|
25
|
+
- Do not use shell commands, mutate the repository, or request general Git access. Report any test command a supervisor must run.
|
|
26
|
+
- Prefer small corrective edits over broad rewrites in your recommendations.
|
|
27
|
+
- If asked to maintain progress, record what you checked and found. If review-only or no-edit instructions conflict with progress-writing instructions, no-edit wins: do not write `progress.md`, and mention the conflict only if it matters.
|
|
63
28
|
|
|
64
29
|
## Supervisor coordination
|
|
65
|
-
If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Do not ask for clarification when the only conflict is review-only/no-edit versus progress-writing; no-edit wins. Use `reason: "progress_update"` only for meaningful progress or
|
|
66
|
-
|
|
67
|
-
If `contact_supervisor` is unavailable, report the blocking decision in your final review. Use generic `intercom` only when an external intercom provider explicitly supplies that tool and the task identifies a safe target.
|
|
30
|
+
If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Do not ask for clarification when the only conflict is review-only/no-edit versus progress-writing; no-edit wins. Use `reason: "progress_update"` only for meaningful progress or discoveries that change the review plan. Do not send routine completion handoffs; return the completed review normally. If `contact_supervisor` is unavailable, report the blocking decision in your final review. Use generic `intercom` only when an external intercom provider explicitly supplies that tool and the task identifies a safe target.
|
|
68
31
|
|
|
69
32
|
## Review output format
|
|
70
33
|
Structure your findings clearly:
|
|
@@ -79,13 +42,6 @@ Structure your findings clearly:
|
|
|
79
42
|
|
|
80
43
|
When reviewing code, cite file paths and line numbers. When reviewing plans, cite specific sections and assumptions.
|
|
81
44
|
|
|
82
|
-
Filter findings by evidence, not by severity. Report only concrete current issues
|
|
83
|
-
within the named review target, and support each one with source proof, a test
|
|
84
|
-
or repro, or a contract contradiction. For a diff review, require that the issue
|
|
85
|
-
is caused or made reachable by that diff. Use P0 for issues
|
|
86
|
-
that block merge, P1 for issues that should be fixed before release, and P2 for
|
|
87
|
-
report-only notes. Say exactly `No issues found.` when nothing qualifies.
|
|
45
|
+
Filter findings by evidence, not by severity. Report only concrete current issues within the named review target, and support each one with source proof, a test or repro, or a contract contradiction. For a diff review, require that the issue is caused or made reachable by that diff. Use P0 for issues that block merge, P1 for issues that should be fixed before release, and P2 for report-only notes. Say exactly `No issues found.` when nothing qualifies.
|
|
88
46
|
|
|
89
|
-
Use `blockers only` only for a final pre-merge re-check after the P1/P2
|
|
90
|
-
inventory is already captured, or for an explicit emergency hotfix where the
|
|
91
|
-
parent intentionally defers non-blocking findings.
|
|
47
|
+
Use `blockers only` only for a final pre-merge re-check after the P1/P2 inventory is already captured, or for an explicit emergency hotfix where the parent intentionally defers non-blocking findings.
|
package/agents/scout.md
CHANGED
|
@@ -22,7 +22,7 @@ Focus on the minimum context another agent needs in order to act:
|
|
|
22
22
|
- constraints, risks, and open questions
|
|
23
23
|
|
|
24
24
|
Working rules:
|
|
25
|
-
-
|
|
25
|
+
- Reserve unscoped `grep` for exhaustive exact-literal verification after a scoped source/path pass.
|
|
26
26
|
- Use `bash` only for non-interactive inspection commands.
|
|
27
27
|
- When you cite code, use exact file paths and line ranges.
|
|
28
28
|
- If you are told to write output, write it to the provided path and keep the final response short.
|
|
@@ -45,6 +45,3 @@ Explain how the pieces connect.
|
|
|
45
45
|
|
|
46
46
|
## Start Here
|
|
47
47
|
Name the first file another agent should open and why.
|
|
48
|
-
|
|
49
|
-
## Supervisor coordination
|
|
50
|
-
If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Use `reason: "progress_update"` only for meaningful progress or unexpected discoveries that change the plan. Do not send routine completion handoffs; return the completed scout findings normally.
|
package/agents/worker.md
CHANGED
|
@@ -15,41 +15,24 @@ defaultProgress: true
|
|
|
15
15
|
|
|
16
16
|
You are `worker`: the implementation subagent.
|
|
17
17
|
|
|
18
|
-
You are the single writer thread.
|
|
18
|
+
You are the single writer thread. Execute the assigned task or approved direction with narrow, coherent edits. The main agent and user remain the decision authority.
|
|
19
19
|
|
|
20
|
-
Use
|
|
20
|
+
Use your tools directly. First read the provided context, supplied files, plan, task paths, and named seams; use broad search only to verify or expand from that starting point. Then implement carefully and minimally.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Your tools are a strict allowlist: you do not inherit the parent session's extension tools. Using an extension tool requires a custom agent that lists it in `tools` and loads its provider through `extensions` or `subagentOnlyExtensions`.
|
|
23
23
|
|
|
24
24
|
If the task is framed as an approved direction, oracle handoff, or execution plan, treat that direction as the contract. Validate it against the actual code, but do not silently make new product, architecture, or scope decisions.
|
|
25
25
|
|
|
26
|
-
If the implementation
|
|
27
|
-
|
|
28
|
-
Default responsibilities:
|
|
29
|
-
- validate the task or approved direction against the actual code
|
|
30
|
-
- implement the smallest correct change
|
|
31
|
-
- follow existing patterns in the codebase
|
|
32
|
-
- verify the result with appropriate checks when possible
|
|
33
|
-
- keep `progress.md` accurate when asked to maintain it
|
|
34
|
-
- report back clearly with changes, validation, risks, and next steps
|
|
26
|
+
If the implementation needs a decision that was not approved, including a gap in the approved direction, pause and escalate instead of deciding it yourself. Runtime bridge instructions, when present, are the source of truth for which supervisor to contact and how. Use `contact_supervisor` with `reason: "need_decision"` and stay alive for the reply before continuing. Use `reason: "progress_update"` only for concise non-blocking updates that help or were requested. Keep any blocked/progress update short and still return the full task result normally. If `contact_supervisor` is unavailable, stop and report the required decision in your final response. Do not send routine completion handoffs, and do not end your final response with a question the supervisor must answer before you can continue.
|
|
35
27
|
|
|
36
28
|
Working rules:
|
|
37
|
-
-
|
|
29
|
+
- Validate the task or direction against the actual code; implement the smallest correct change and follow existing patterns.
|
|
38
30
|
- Preserve source discoverability: use specific names, clear types, one spelling per concept, source-named tests, and definition comments only when they explain a needed constraint.
|
|
39
31
|
- Do not add speculative scaffolding or future-proofing unless explicitly required.
|
|
40
32
|
- Do not leave placeholder code, TODOs, or silent scope changes.
|
|
41
|
-
- Use `bash` for inspection, validation, and relevant tests.
|
|
42
|
-
-
|
|
43
|
-
- If
|
|
44
|
-
- If implementation reveals an unapproved product or architecture choice, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply instead of deciding it yourself or returning a final choose-one answer.
|
|
45
|
-
- If your delegated task expects code or file edits and you have not made those edits, do not return a success summary. Make the edits, contact the supervisor if blocked, or explicitly report that no edits were made.
|
|
46
|
-
- If you send a blocked/progress update through `contact_supervisor`, keep it short and still return the full structured task result normally.
|
|
47
|
-
- Do not send routine completion handoffs. Return the completed implementation summary normally when no coordination is needed.
|
|
48
|
-
|
|
49
|
-
When running in a chain, expect instructions about:
|
|
50
|
-
- which files to read first
|
|
51
|
-
- where to maintain progress tracking
|
|
52
|
-
- where to write output if a file target is provided
|
|
33
|
+
- Use `bash` for inspection, validation, and relevant tests; verify the result when possible.
|
|
34
|
+
- Keep `progress.md` accurate when asked to maintain it.
|
|
35
|
+
- If your task expects code or file edits and you have not made them, do not return a success summary. Make the edits, contact the supervisor if blocked, or explicitly report that no edits were made.
|
|
53
36
|
|
|
54
37
|
Your final response should follow this shape:
|
|
55
38
|
|
package/docs/agents.md
CHANGED
|
@@ -31,6 +31,7 @@ Discovery notes:
|
|
|
31
31
|
- Use `subagents.agentExcludeDirs` to prune literal directory subtrees without disabling legacy agents. See [configuration.md](configuration.md#excluded-agent-directories-settings) for path resolution, scope, and exemptions.
|
|
32
32
|
- Installed Pi packages can expose agent directories from either `{"pi-subagents":{"agents":["./agents"]}}` or `{"pi":{"subagents":{"agents":["./agents"]}}}` in their package manifest. Package agents load above builtins and below user/project agents.
|
|
33
33
|
- Use `agentScope: "user" | "project" | "both"` to control discovery. `both` is the default, and project definitions win runtime-name collisions.
|
|
34
|
+
- When the session declined Pi project trust, discovery ignores project agents and chains, packages installed for the project or declared in its `package.json`, and project subagent settings, so `both` behaves as `user` and an explicit `project` scope is rejected.
|
|
34
35
|
|
|
35
36
|
## Builtin agents
|
|
36
37
|
|
|
@@ -66,6 +67,8 @@ The Pi async run remains the source of truth for status, artifacts, wake/wait, m
|
|
|
66
67
|
|
|
67
68
|
External CLI agents use their own runner contract. They are deliberate execution modes, not implicit recovery paths for a failed native `subagent` workflow. For backlog lanes and other subagent-governed workflows, switching to an external, foreground, or CLI runner requires explicit owner approval after the exact failure/run/worktree state is recorded and the worktree is verified clean or its partial diff is captured. Do not pass native Pi child options such as model override, structured output, acceptance/agent contract, tool budgets, fast mode, fork context, skills, or native Pi tools unless the adapter explicitly implements them.
|
|
68
69
|
|
|
70
|
+
#### Codex exec profiles
|
|
71
|
+
|
|
69
72
|
The built-in `codex-exec` and `codex-exec-writer` profiles are the supported Codex one-shot modes. Both require an installed and authenticated Codex CLI. The adapters own `codex exec --json` argv with ignored user config and rules, ephemeral sessions, approval policy `never`, and a final-message artifact.
|
|
70
73
|
|
|
71
74
|
| Profile | Access | Sandbox |
|
|
@@ -101,6 +104,8 @@ node --experimental-strip-types --import ./test/support/register-loader.mjs \
|
|
|
101
104
|
|
|
102
105
|
The read-only smoke must report `writeCanaryExists: false`. The writer smoke must report `writeCanaryMatches: true`. Both reports include startup duration and terminal proof without raw protocol output, prompts, or credentials.
|
|
103
106
|
|
|
107
|
+
#### Claude Code profiles
|
|
108
|
+
|
|
104
109
|
The built-in `claude-code` and `claude-code-writer` profiles are the supported Claude Code one-shot modes. Both require an installed Claude Code CLI that is already authenticated through its normal local login. Claude Code 2.1.150 needs the user setting source for normal OAuth/keychain authentication, so both adapters load user settings but exclude project and local settings. User-level Claude Code settings and hooks are therefore an operator-trusted prerequisite. Review or disable unsafe user hooks before using either profile.
|
|
105
110
|
|
|
106
111
|
| Profile | Access | Permission mode | Built-in tools |
|
|
@@ -144,6 +149,8 @@ node --experimental-strip-types --import ./test/support/register-loader.mjs \
|
|
|
144
149
|
|
|
145
150
|
Both smoke reports record `authentication: "existing-cli-required"`, `settingSources: "user"`, and `userSettingsTrust: "required"` without recording credential details. For read-only, confirm `terminalState` is `completed` and `writeCanaryExists` is `false`. For writer, confirm `terminalState` is `completed` and `writeCanaryMatches` is `true`. `durationMs` records cold process time. If authentication is missing or revoked, repair the normal local Claude Code login and rerun the smoke. Reports do not contain raw protocol output or credentials.
|
|
146
151
|
|
|
152
|
+
#### Cursor CLI profiles
|
|
153
|
+
|
|
147
154
|
The built-in `cursor-agent` and `cursor-agent-writer` profiles are the supported Cursor CLI one-shot modes. Both require an installed Cursor CLI and either `CURSOR_API_KEY` or an existing local login.
|
|
148
155
|
|
|
149
156
|
| Profile | Access | Cursor mode |
|
|
@@ -187,6 +194,8 @@ node --experimental-strip-types --import ./test/support/register-loader.mjs \
|
|
|
187
194
|
|
|
188
195
|
The read-only smoke must report `writeCanaryExists: false`. The writer smoke must report `writeCanaryMatches: true`. Both reports record `workspaceTrust: "operator-managed-saved"`, confirm that the external prompt root was added, and include startup duration and terminal proof without raw protocol output, prompts, or credentials. A trust-required error remains terminal; the harness does not retry with a trust, force, or yolo flag.
|
|
189
196
|
|
|
197
|
+
#### Native oracle compared with external advisors
|
|
198
|
+
|
|
190
199
|
Native `oracle` runs inside Pi and can use its configured read tools. The Claude profiles send the assembled prompt to the local Claude Code CLI through stdin. An external-job agent sends the assembled prompt to its registered provider. Provider options and a prompt digest are persisted in Pi run state. The prompt text is delivered through the local host bridge to the provider and is not stored in the public result payload. Do not place secrets in advisory prompts unless the target provider is approved to receive them.
|
|
191
200
|
|
|
192
201
|
### External-job state table
|
|
@@ -230,6 +239,8 @@ You can override selected agent fields without copying the whole agent. Override
|
|
|
230
239
|
|
|
231
240
|
Supported override fields: `description`, `advertise`, `machine`, `output`, `outputMode`, `defaultReads`, `model`, `defaultProvider`, `thinking`, `systemPromptMode`, `inheritProjectContext`, `inheritGlobalContext`, `inheritSkills`, `defaultContext`, `acceptanceRole`, `disabled`, `skills`, `tools`, and `systemPrompt`.
|
|
232
241
|
|
|
242
|
+
`launcher` is not a supported override field, and an override that sets it is rejected. To run a builtin under a launcher, copy it into a user agent file (for example with `eject`) and set `launcher` there.
|
|
243
|
+
|
|
233
244
|
- `description` replaces the discovered description for builtin and custom agents, which lets list output show deployment-specific routing or model metadata.
|
|
234
245
|
- Use `output: false`, `defaultReads: false`, `defaultContext: false`, `acceptanceRole: false`, or `machine: false` to clear an inherited value.
|
|
235
246
|
- Use `tools: "inherit"` when that one role should omit its bundled or frontmatter tool allowlist and receive Pi's normal builtins (plus ambient extensions when it runs as a background child).
|
|
@@ -271,15 +282,66 @@ Placed external profiles are one-shot and stop-only: they cannot steer, resume,
|
|
|
271
282
|
|
|
272
283
|
pi-subagents never clones, pulls, or checks out on the machine. Generic `external-cli` commands and managed worktrees are rejected before launch; saved-machine placement accepts native Pi and only the six code-owned external profiles.
|
|
273
284
|
|
|
285
|
+
## Sandboxing background children with a launcher
|
|
286
|
+
|
|
287
|
+
A launcher wraps an agent's background runner in a command you choose, so that agent can run in a different sandbox from the parent session. Define the command in the user config key [`runnerLaunchers`](configuration.md#runnerlaunchers), then name it in the agent file:
|
|
288
|
+
|
|
289
|
+
```yaml
|
|
290
|
+
---
|
|
291
|
+
name: researcher
|
|
292
|
+
description: Web research with network access
|
|
293
|
+
launcher: net
|
|
294
|
+
---
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
The background runner for this agent then starts as `<launcher argv> <resolved runner command>`, where the runner command is the Node or compiled Pi command pi-subagents would otherwise run directly. The child keeps native steering, supervisor questions, stop, resume, usage, and results.
|
|
298
|
+
|
|
299
|
+
How it behaves:
|
|
300
|
+
|
|
301
|
+
- **Who defines the command.** Only the user config defines what a launcher runs. An agent file, including a project agent from a cloned repository, can only name a launcher you already defined. A project agent with the same name as one of your agents can still shadow it, so your own agent files and their names are the trust boundary.
|
|
302
|
+
- **Background only.** A launcher agent runs in the background when the call omits `async`, even with `asyncByDefault: false`, and a workflow-script child that selects it runs in the background too. `async: false`, `clarify`, and `foregroundOnly` are refused, even when `forceTopLevelAsync` is set, because foreground children run inside the parent process and keep the parent's sandbox.
|
|
303
|
+
- **Not combined with other placement.** `launcher` cannot be combined with `machine` (from frontmatter, a settings override, or the call) or with an `external-cli` or `external-job` runner.
|
|
304
|
+
- **Unknown names fail.** If the name is not in `runnerLaunchers`, the launch fails before anything starts, without using a fan-out slot or creating a session directory. It never falls back to running without the launcher.
|
|
305
|
+
- **Status.** The run's `status.json` records `launcher: { name, argv }`. Environment values are never recorded.
|
|
306
|
+
- **Resume and revival.** A resumed run uses the launcher recorded when the run was first launched, not the agent file's current value, and looks up that name's argv in the config the session loaded, like a new launch does; edits to `runnerLaunchers` apply after `/reload`. A run launched without a launcher stays unwrapped even if its agent file gains `launcher` later. If the recorded name is no longer in `runnerLaunchers`, the resume fails before anything starts, and the run can be resumed once the name is defined again.
|
|
307
|
+
- **Several agents in one runner.** A new chain attached to a running subagent, or steps appended to a running chain, run in one background runner. All agents in it must name the same launcher, or none; a mix is refused before anything starts, and the error names each agent and its launcher. Appended steps must also match the launcher of the runner they join. Steps in one wrapped chain share its sandbox; to give branches different sandboxes, run them as workflow-script children, which each get their own runner.
|
|
308
|
+
- **Agent management.** `subagent({ action: "create" })` and `update` cannot set `launcher`; edit the agent file instead. Other updates keep an existing `launcher` line.
|
|
309
|
+
|
|
310
|
+
### Wrapper requirements
|
|
311
|
+
|
|
312
|
+
A launcher command must:
|
|
313
|
+
|
|
314
|
+
- run the runner command it receives, either by replacing itself with it (`exec`) or by staying attached until it exits;
|
|
315
|
+
- give the runner read and write access, at the same absolute paths, to the subagent temp root (`async-subagent-runs/`, `async-subagent-results/`, and `supervisor-channels/`; the root is `PI_SUBAGENTS_TEMP_ROOT` when set), the child session and artifact directories, the agent directory (`~/.pi/agent`, which holds auth), and the working directory, plus read access to the Pi install;
|
|
316
|
+
- allow network access to your model provider;
|
|
317
|
+
- if it filters the environment, pass through at least `HOME`, `PATH`, `TMPDIR`, every `PI_*` variable, `JITI_ALIAS`, and the API keys your provider needs.
|
|
318
|
+
|
|
319
|
+
Steering, stop, and supervisor requests and replies travel through files in those directories, not through signals, so they work as long as the paths are shared.
|
|
320
|
+
|
|
321
|
+
### Broker wrappers
|
|
322
|
+
|
|
323
|
+
Some sandboxes, such as nono's broker mode, start the runner in a separate process instead of as a child of the launcher command. pi-subagents does not rely on the launcher's process being the runner:
|
|
324
|
+
|
|
325
|
+
- Before it starts any work, the runner reports its own process id. The launch waits up to 10 seconds for it and fails if it does not arrive. `status.json` and run events use the runner's process id, not the launcher's.
|
|
326
|
+
- When the launcher process exits, its exit code and signal are kept in `launcher-close.json` in the run directory. That exit is treated as the runner's exit only when the runner's process is confirmed dead. A runner killed by a signal may be reported by the launcher as exit code `128 + n` (for example `143` for `SIGTERM`).
|
|
327
|
+
- If only the launcher process is killed while the runner keeps working, the run keeps running and still accepts steer and stop. No process-exit proof is recorded when the runner later exits, so if `maxActiveAsyncRunsPerSession` is set, the run's capacity slot stays held; the abandoned-slot policy releases it only if the run ends failed.
|
|
328
|
+
- If the sandbox does not let the parent check the runner's process id, a runner that dies without its launcher noticing stays `running` until the stale-run check marks it failed after 24 hours without a status update.
|
|
329
|
+
- A broker may end the runner when the broker's own session ends, so background runs under such a launcher may not outlive the Pi session.
|
|
330
|
+
|
|
331
|
+
### Limits
|
|
332
|
+
|
|
333
|
+
- A launcher controls where the child runs, not where its output goes. Results, transcripts, and files the child writes in shared directories are visible to the parent as usual.
|
|
334
|
+
- A launcher that submits the work elsewhere and returns immediately is not supported, because the runner must keep running and share files with the parent. For runs on another machine, use `machine:` with Herdr.
|
|
335
|
+
|
|
274
336
|
## Parent prompt discovery
|
|
275
337
|
|
|
276
338
|
Set `advertise: true` in a specialist's agent file frontmatter for parent-prompt discovery, or in `subagents.agentOverrides.<name>.advertise` when the definition must stay untouched. When the `subagent` tool is active, pi-subagents adds an agent-owned catalog of names and descriptions to the parent system prompt. Disabled agents and agents excluded by the current capability ceiling are omitted. Advertisement is not supported through runtime registration.
|
|
277
339
|
|
|
278
|
-
Advertisement is opt-in discovery, not automatic routing. The catalog is sorted by name and limited to 16 agents and 12,288 total rendered UTF-8 bytes, including XML escaping, instructions, and omission counts. Descriptions are capped at 512 UTF-8 bytes before escaping. Entries that cannot fit are omitted; canonical agent names are never truncated. The parent
|
|
340
|
+
Advertisement is opt-in discovery, not automatic routing. The catalog is sorted by name and limited to 16 agents and 12,288 total rendered UTF-8 bytes, including XML escaping, instructions, and omission counts. Descriptions are capped at 512 UTF-8 bytes before escaping. Entries that cannot fit are omitted; canonical agent names are never truncated. The parent does not need a `list` call before launching an advertised agent: a launch that names an unknown or disabled agent fails with the available agents, and an external CLI agent's runner is checked by preflight when it launches.
|
|
279
341
|
|
|
280
342
|
The file catalog snapshot refreshes at session start/reload and after extension-owned agent-management mutations. External file or settings edits require `/reload`; ordinary turns do not poll the filesystem. Tool availability and capability-ceiling filtering are checked in memory on every prompt. A failed management-triggered refresh withdraws the catalog until a successful refresh, without changing the persisted mutation's result.
|
|
281
343
|
|
|
282
|
-
The catalog is sent as Pi's `advertised_subagents` prompt section. When it changes mid-session, Pi appends it as a small system message instead of changing the system prompt, so the provider prompt cache is kept. This only works if no other loaded extension returns a replacement `systemPrompt` from `before_agent_start`; in that case Pi folds section changes back into the system prompt and the cache is lost for that request.
|
|
344
|
+
The catalog is sent as Pi's `advertised_subagents` prompt section. When it changes mid-session, Pi appends it as a small system message instead of changing the system prompt, so the provider prompt cache is kept. This only works if no other loaded extension returns a replacement `systemPrompt` from `before_agent_start`; in that case Pi folds section changes back into the system prompt and the cache is lost for that request. A resumed session keeps the catalog introduction it already recorded, so a pi-subagents upgrade that rewords the introduction does not change the section; the entries always reflect the current agents.
|
|
283
345
|
|
|
284
346
|
## Prompt assembly
|
|
285
347
|
|
|
@@ -372,6 +434,7 @@ Field notes:
|
|
|
372
434
|
| `defaultReads` | Files to read before running the agent. |
|
|
373
435
|
| `defaultProgress` | Maintain `progress.md`. |
|
|
374
436
|
| `async` | Default a single-agent launch to background (`true`) or foreground (`false`) when the call omits `async`. Explicit call values and `forceTopLevelAsync` win. |
|
|
437
|
+
| `launcher` | Name of a [`runnerLaunchers`](configuration.md#runnerlaunchers) entry that wraps this agent's background runner, such as a sandbox command. Names only; the command itself is defined in user config. See [Sandboxing background children with a launcher](#sandboxing-background-children-with-a-launcher). |
|
|
375
438
|
| `timeoutMs` | Positive integer default runtime deadline in milliseconds for single-agent launches. Foreground launches use 30 minutes when neither the call nor agent provides a timeout; explicit `timeoutMs`/`maxRuntimeMs` and agent defaults win. |
|
|
376
439
|
| `toolTimeoutMs` | Optional positive integer hard per-tool-call deadline in milliseconds. An explicit call value wins, then this agent default, global `toolTimeoutMs`, and `PI_SUBAGENT_TOOL_TIMEOUT_MS`. When omitted, known-fast built-in tools get a five-minute default; long-running tools get attention notices but no hard default. It does not extend the run-level deadline; `contact_supervisor`, `intercom`, and `bg_wait` are exempt. |
|
|
377
440
|
| `acceptance` | Acceptance default for single-agent launches. Use a scalar level such as `checked` or an inline/block YAML map such as `{ level: "none", reason: "lightweight lookup" }`. Explicit call values win; chain and parallel acceptance remains task/step configuration. |
|
|
@@ -454,7 +517,7 @@ How `tools` behaves:
|
|
|
454
517
|
|
|
455
518
|
An allowlisted name does not load the extension that registers it. Load that provider through `extensions`, `subagentOnlyExtensions`, a path-like `tools` entry, or (background children only) normal Pi extension discovery. Pi's built-in `codemode` is the exception: native children register the host SDK's official factory when codemode is permitted, without enabling it in the main session. On older Pi hosts without that factory, a child that requests codemode still reports it as unavailable; a capability ceiling that denies extensions prevents its registration.
|
|
456
519
|
|
|
457
|
-
Ambient extensions depend on where the child runs. Local foreground children are sessions inside the parent Pi process and never load the parent's ambient extensions; otherwise the parent would start a second copy of each ambient extension, including this one. Background children are sessions inside the detached runner process and load the ambient extensions unless the agent sets `extensions` or the capability ceiling denies extensions. Local foreground children do inherit the providers the parent's extensions registered (`pi.registerProvider`), so their models resolve without loading those extensions again. Pane-native remote foreground children instead use the remote machine's provider discovery and configuration. Agents that need MCP tools from an ambient adapter such as pi-mcp-adapter (including `mcp:` entries the adapter resolves) must therefore run as background children (`async: true`). A foreground launch of such an agent fails with a diagnostic that says exactly that.
|
|
520
|
+
Ambient extensions depend on where the child runs. Local foreground children are sessions inside the parent Pi process and never load the parent's ambient extensions; otherwise the parent would start a second copy of each ambient extension, including this one. Background children are sessions inside the detached runner process and load the ambient extensions unless the agent sets `extensions` or the capability ceiling denies extensions. Local foreground children do inherit the providers the parent's extensions registered (`pi.registerProvider`), so their models resolve without loading those extensions again. The child gets the provider but not the registering extension's session hooks, so a provider that relies on its own hooks (for example to record each session's system prompt) can fail the child's first request; the foreground error then says so. Use `async: true` or list that extension in the agent's `subagentOnlyExtensions` or `extensions`. Pane-native remote foreground children instead use the remote machine's provider discovery and configuration. Agents that need MCP tools from an ambient adapter such as pi-mcp-adapter (including `mcp:` entries the adapter resolves) must therefore run as background children (`async: true`). A foreground launch of such an agent fails with a diagnostic that says exactly that.
|
|
458
521
|
|
|
459
522
|
More rules:
|
|
460
523
|
|
|
@@ -472,10 +535,14 @@ Examples:
|
|
|
472
535
|
- `allowNestedSubagents: true` with `tools` omitted: normal builtin tools (and, for background children, ambient extensions) remain inherited, and the child-safe nested `subagent` runtime is added.
|
|
473
536
|
- `tools: read, fixture_search` plus `subagentOnlyExtensions: ./tools/fixture-search.ts`: the provider loads only in this agent's child sessions, and the registered `fixture_search` name survives the strict allowlist.
|
|
474
537
|
|
|
538
|
+
### MCP tools
|
|
539
|
+
|
|
475
540
|
When [pi-mcp-adapter](https://github.com/nicobailon/pi-mcp-adapter) is not installed and Pi has built-in MCP (Pi 0.99 or later), `mcp:server` and `mcp:server/tool` entries resolve against Pi's built-in MCP. Name the server and tool as the server reports them: `mcp:my-docs/get-item` selects the tool Pi registers as `mcp__my_docs__get_item`. The server part may also use the `-`→`_` form of its name that Pi's MCP namespace uses, such as `mcp:my_docs`. The child connects the servers in Pi's `mcp.json` (the project's `.pi/mcp.json` only when the parent trusts the project) and gets only the selected tools, as direct tools, whatever exposure the server is configured with; tools configured as `hidden` cannot be selected. Servers that an extension adds with `pi.registerMcpServer()` work in background children, because the registering extension loads there too. They do not work in foreground children, which load no ambient extensions, so a foreground launch that selects one fails and says to use `async: true`. The launch fails if a selected tool does not register in the child within 10 seconds.
|
|
476
541
|
|
|
477
542
|
When pi-mcp-adapter is installed, it keeps priority and provides the direct MCP tools. Subagents only receive direct MCP tools when `mcp:` entries are listed in their frontmatter; global `directTools: true` in the adapter's MCP config is not enough by itself. The generic `mcp` proxy tool can still be used for discovery when available. The adapter caches tool metadata at startup, so after connecting a new MCP server for the first time, restart Pi before relying on direct tools. Server `includeTools` and `excludeTools` policies are enforced while resolving cached metadata for children: both accept exact names and `*`/`?` glob patterns against raw, generated-resource, and server/short/mcp/none-prefixed names, with `excludeTools` taking precedence. `mcp:` entries must name servers from the adapter's configuration files. A server that exists only in the adapter's runtime snapshot (registered at runtime, not persisted) cannot be provided to a child: children are pi sessions inside the parent or the runner process, not `pi` processes that could receive an MCP config argument, so such a launch fails with an error saying that MCP tools must come from an ambient adapter extension in a background child. An `mcp:` entry named `subagent` does not authorize nested fanout; declare the builtin `subagent` tool or set `allowNestedSubagents: true`. If a resolved direct MCP name is missing from the child registry, pi-subagents keeps the launch failed under the strict allowlist and reports the registration mismatch; check the resolved names against what the host or pi-mcp-adapter actually registers before child startup.
|
|
478
543
|
|
|
544
|
+
### Extension loading
|
|
545
|
+
|
|
479
546
|
`extensions` controls child extension loading:
|
|
480
547
|
|
|
481
548
|
```yaml
|