pi-subagents 0.73.1 → 0.75.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 +100 -0
- package/README.md +1 -1
- package/docs/agents.md +30 -16
- package/docs/configuration.md +76 -9
- package/docs/extension-api.md +6 -5
- package/docs/missions.md +28 -14
- package/docs/models.md +8 -4
- package/docs/observability.md +10 -5
- package/docs/tool-reference.md +90 -88
- package/docs/workflows.md +166 -172
- package/package.json +2 -2
- package/prompts/review-loop.md +1 -1
- package/skills/council-mode/SKILL.md +1 -1
- package/skills/pi-subagents/SKILL.md +12 -5
- package/skills/pi-subagents/references/constraints-and-recipes.md +3 -3
- package/skills/pi-subagents/references/execution-controls.md +68 -67
- package/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
- package/skills/pi-subagents/references/multi-lane-orchestration.md +1 -1
- package/skills/pi-subagents/references/prompting-and-roles.md +45 -48
- package/src/agents/agent-management.js +2 -2
- package/src/agents/agent-management.js.map +1 -1
- package/src/agents/agents.d.ts +2 -0
- package/src/agents/agents.d.ts.map +1 -1
- package/src/agents/agents.js +73 -3
- package/src/agents/agents.js.map +1 -1
- package/src/api/preflight.d.ts +6 -2
- package/src/api/preflight.d.ts.map +1 -1
- package/src/api/preflight.js +46 -2
- package/src/api/preflight.js.map +1 -1
- package/src/extension/config.d.ts.map +1 -1
- package/src/extension/config.js +15 -4
- package/src/extension/config.js.map +1 -1
- package/src/extension/control-notices.d.ts +2 -0
- package/src/extension/control-notices.d.ts.map +1 -1
- package/src/extension/control-notices.js +2 -0
- package/src/extension/control-notices.js.map +1 -1
- package/src/extension/doctor.d.ts.map +1 -1
- package/src/extension/doctor.js +1 -0
- package/src/extension/doctor.js.map +1 -1
- package/src/extension/fanout-child.d.ts.map +1 -1
- package/src/extension/fanout-child.js +13 -3
- package/src/extension/fanout-child.js.map +1 -1
- package/src/extension/herdr-pi-bridge.d.ts.map +1 -1
- package/src/extension/herdr-pi-bridge.js +2 -0
- package/src/extension/herdr-pi-bridge.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 +87 -179
- package/src/extension/index.js.map +1 -1
- package/src/extension/public-execution.d.ts +10 -1
- package/src/extension/public-execution.d.ts.map +1 -1
- package/src/extension/public-execution.js +73 -35
- package/src/extension/public-execution.js.map +1 -1
- package/src/extension/reply-workflow-script.d.ts +12 -0
- package/src/extension/reply-workflow-script.d.ts.map +1 -0
- package/src/extension/reply-workflow-script.js +61 -0
- package/src/extension/reply-workflow-script.js.map +1 -0
- package/src/extension/rpc.d.ts +2 -0
- package/src/extension/rpc.d.ts.map +1 -1
- package/src/extension/rpc.js +33 -10
- package/src/extension/rpc.js.map +1 -1
- package/src/extension/schemas.d.ts +4 -117
- package/src/extension/schemas.d.ts.map +1 -1
- package/src/extension/schemas.js +42 -127
- package/src/extension/schemas.js.map +1 -1
- package/src/extension/tool-activation.d.ts +2 -4
- package/src/extension/tool-activation.d.ts.map +1 -1
- package/src/extension/tool-activation.js +54 -104
- package/src/extension/tool-activation.js.map +1 -1
- package/src/extension/tool-description.d.ts +8 -5
- package/src/extension/tool-description.d.ts.map +1 -1
- package/src/extension/tool-description.js +51 -27
- package/src/extension/tool-description.js.map +1 -1
- package/src/extension/upgrade-notice.d.ts +7 -0
- package/src/extension/upgrade-notice.d.ts.map +1 -0
- package/src/extension/upgrade-notice.js +37 -0
- package/src/extension/upgrade-notice.js.map +1 -0
- package/src/integrations/herdr-status.d.ts +3 -0
- package/src/integrations/herdr-status.d.ts.map +1 -1
- package/src/integrations/herdr-status.js +17 -3
- package/src/integrations/herdr-status.js.map +1 -1
- package/src/intercom/native-supervisor-channel.d.ts.map +1 -1
- package/src/intercom/native-supervisor-channel.js +4 -1
- package/src/intercom/native-supervisor-channel.js.map +1 -1
- package/src/missions/goal-driver.d.ts +1 -0
- package/src/missions/goal-driver.d.ts.map +1 -1
- package/src/missions/goal-driver.js +49 -34
- package/src/missions/goal-driver.js.map +1 -1
- package/src/missions/store.d.ts.map +1 -1
- package/src/missions/store.js +11 -1
- package/src/missions/store.js.map +1 -1
- package/src/profiles/profiles.d.ts +1 -1
- package/src/profiles/profiles.d.ts.map +1 -1
- package/src/profiles/profiles.js +4 -0
- package/src/profiles/profiles.js.map +1 -1
- package/src/runs/background/async-execution.d.ts +16 -0
- package/src/runs/background/async-execution.d.ts.map +1 -1
- package/src/runs/background/async-execution.js +95 -8
- package/src/runs/background/async-execution.js.map +1 -1
- package/src/runs/background/async-job-tracker.d.ts +1 -0
- package/src/runs/background/async-job-tracker.d.ts.map +1 -1
- package/src/runs/background/async-job-tracker.js +67 -24
- package/src/runs/background/async-job-tracker.js.map +1 -1
- package/src/runs/background/async-retention.d.ts +1 -1
- package/src/runs/background/async-retention.d.ts.map +1 -1
- package/src/runs/background/async-retention.js +47 -15
- package/src/runs/background/async-retention.js.map +1 -1
- package/src/runs/background/await-async-run.d.ts +23 -0
- package/src/runs/background/await-async-run.d.ts.map +1 -0
- package/src/runs/background/await-async-run.js +82 -0
- package/src/runs/background/await-async-run.js.map +1 -0
- package/src/runs/background/chain-root-attachment.d.ts +1 -0
- package/src/runs/background/chain-root-attachment.d.ts.map +1 -1
- package/src/runs/background/chain-root-attachment.js +3 -3
- package/src/runs/background/chain-root-attachment.js.map +1 -1
- package/src/runs/background/control-channel.d.ts +10 -0
- package/src/runs/background/control-channel.d.ts.map +1 -1
- package/src/runs/background/control-channel.js +51 -0
- package/src/runs/background/control-channel.js.map +1 -1
- package/src/runs/background/notify.d.ts +3 -0
- package/src/runs/background/notify.d.ts.map +1 -1
- package/src/runs/background/notify.js +3 -0
- package/src/runs/background/notify.js.map +1 -1
- package/src/runs/background/run-child-session.d.ts.map +1 -1
- package/src/runs/background/run-child-session.js +24 -7
- package/src/runs/background/run-child-session.js.map +1 -1
- package/src/runs/background/run-status.d.ts.map +1 -1
- package/src/runs/background/run-status.js +6 -0
- package/src/runs/background/run-status.js.map +1 -1
- package/src/runs/background/runner-aliases.d.ts +1 -0
- package/src/runs/background/runner-aliases.d.ts.map +1 -1
- package/src/runs/background/runner-aliases.js +6 -2
- package/src/runs/background/runner-aliases.js.map +1 -1
- package/src/runs/background/runner-child-launch.d.ts +1 -0
- package/src/runs/background/runner-child-launch.d.ts.map +1 -1
- package/src/runs/background/runner-child-launch.js +2 -0
- package/src/runs/background/runner-child-launch.js.map +1 -1
- package/src/runs/background/scheduled-runs.d.ts +2 -1
- package/src/runs/background/scheduled-runs.d.ts.map +1 -1
- package/src/runs/background/scheduled-runs.js +33 -16
- package/src/runs/background/scheduled-runs.js.map +1 -1
- package/src/runs/background/stale-run-reconciler.d.ts +1 -1
- package/src/runs/background/stale-run-reconciler.d.ts.map +1 -1
- package/src/runs/background/stale-run-reconciler.js +15 -2
- package/src/runs/background/stale-run-reconciler.js.map +1 -1
- package/src/runs/background/subagent-runner.d.ts +3 -0
- package/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/src/runs/background/subagent-runner.js +49 -3
- package/src/runs/background/subagent-runner.js.map +1 -1
- package/src/runs/foreground/async-stop-action.d.ts.map +1 -1
- package/src/runs/foreground/async-stop-action.js +15 -1
- package/src/runs/foreground/async-stop-action.js.map +1 -1
- package/src/runs/foreground/command-action.d.ts +13 -0
- package/src/runs/foreground/command-action.d.ts.map +1 -0
- package/src/runs/foreground/command-action.js +38 -0
- package/src/runs/foreground/command-action.js.map +1 -0
- package/src/runs/foreground/execution.d.ts.map +1 -1
- package/src/runs/foreground/execution.js +27 -6
- package/src/runs/foreground/execution.js.map +1 -1
- package/src/runs/foreground/subagent-executor.d.ts +7 -5
- package/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/src/runs/foreground/subagent-executor.js +356 -192
- package/src/runs/foreground/subagent-executor.js.map +1 -1
- package/src/runs/shared/child-commands.d.ts +28 -0
- package/src/runs/shared/child-commands.d.ts.map +1 -0
- package/src/runs/shared/child-commands.js +250 -0
- package/src/runs/shared/child-commands.js.map +1 -0
- package/src/runs/shared/child-launch.d.ts +5 -1
- package/src/runs/shared/child-launch.d.ts.map +1 -1
- package/src/runs/shared/child-launch.js +15 -1
- package/src/runs/shared/child-launch.js.map +1 -1
- package/src/runs/shared/child-session.d.ts +13 -0
- package/src/runs/shared/child-session.d.ts.map +1 -1
- package/src/runs/shared/child-session.js +182 -19
- package/src/runs/shared/child-session.js.map +1 -1
- package/src/runs/shared/child-tool-plan.d.ts +4 -0
- package/src/runs/shared/child-tool-plan.d.ts.map +1 -1
- package/src/runs/shared/child-tool-plan.js +12 -5
- package/src/runs/shared/child-tool-plan.js.map +1 -1
- package/src/runs/shared/claude-code-adapter.d.ts +56 -0
- package/src/runs/shared/claude-code-adapter.d.ts.map +1 -1
- package/src/runs/shared/claude-code-adapter.js +138 -2
- package/src/runs/shared/claude-code-adapter.js.map +1 -1
- package/src/runs/shared/dynamic-fanout.js +2 -2
- package/src/runs/shared/dynamic-fanout.js.map +1 -1
- package/src/runs/shared/external-cli-preflight.d.ts +10 -0
- package/src/runs/shared/external-cli-preflight.d.ts.map +1 -1
- package/src/runs/shared/external-cli-preflight.js +50 -6
- package/src/runs/shared/external-cli-preflight.js.map +1 -1
- package/src/runs/shared/external-cli-runner.d.ts.map +1 -1
- package/src/runs/shared/external-cli-runner.js +4 -2
- package/src/runs/shared/external-cli-runner.js.map +1 -1
- package/src/runs/shared/mcp-config-sources.d.ts +1 -0
- package/src/runs/shared/mcp-config-sources.d.ts.map +1 -1
- package/src/runs/shared/mcp-config-sources.js +1 -1
- package/src/runs/shared/mcp-config-sources.js.map +1 -1
- package/src/runs/shared/mcp-direct-tool-allowlist.d.ts +28 -0
- package/src/runs/shared/mcp-direct-tool-allowlist.d.ts.map +1 -1
- package/src/runs/shared/mcp-direct-tool-allowlist.js +79 -2
- package/src/runs/shared/mcp-direct-tool-allowlist.js.map +1 -1
- package/src/runs/shared/model-resolution.d.ts +16 -2
- package/src/runs/shared/model-resolution.d.ts.map +1 -1
- package/src/runs/shared/model-resolution.js +39 -11
- package/src/runs/shared/model-resolution.js.map +1 -1
- package/src/runs/shared/model-scope.d.ts +2 -1
- package/src/runs/shared/model-scope.d.ts.map +1 -1
- package/src/runs/shared/model-scope.js +26 -10
- package/src/runs/shared/model-scope.js.map +1 -1
- package/src/runs/shared/parallel-utils.d.ts +4 -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/pi-spawn.d.ts +1 -10
- package/src/runs/shared/pi-spawn.d.ts.map +1 -1
- package/src/runs/shared/pi-spawn.js +7 -86
- package/src/runs/shared/pi-spawn.js.map +1 -1
- package/src/runs/shared/run-history.d.ts +47 -0
- package/src/runs/shared/run-history.d.ts.map +1 -1
- package/src/runs/shared/run-history.js +70 -0
- package/src/runs/shared/run-history.js.map +1 -1
- package/src/runs/shared/subagent-control.d.ts.map +1 -1
- package/src/runs/shared/subagent-control.js +30 -17
- package/src/runs/shared/subagent-control.js.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.d.ts +1 -0
- package/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.js +14 -5
- package/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
- package/src/runs/shared/worktree.d.ts +1 -1
- package/src/runs/shared/worktree.d.ts.map +1 -1
- package/src/runs/shared/worktree.js +1 -1
- package/src/runs/shared/worktree.js.map +1 -1
- package/src/shared/disabled-features.d.ts +92 -0
- package/src/shared/disabled-features.d.ts.map +1 -0
- package/src/shared/disabled-features.js +113 -0
- package/src/shared/disabled-features.js.map +1 -0
- package/src/shared/extension-context.d.ts +9 -0
- package/src/shared/extension-context.d.ts.map +1 -1
- package/src/shared/extension-context.js +7 -0
- package/src/shared/extension-context.js.map +1 -1
- package/src/shared/required-child-extensions.d.ts +16 -1
- package/src/shared/required-child-extensions.d.ts.map +1 -1
- package/src/shared/required-child-extensions.js +37 -5
- package/src/shared/required-child-extensions.js.map +1 -1
- package/src/shared/settings.d.ts +1 -1
- package/src/shared/types.d.ts +26 -1
- package/src/shared/types.d.ts.map +1 -1
- package/src/shared/types.js +1 -1
- package/src/shared/types.js.map +1 -1
- package/src/slash/prompt-template-bridge.js +2 -2
- package/src/slash/prompt-template-bridge.js.map +1 -1
- package/src/slash/slash-commands.d.ts +2 -0
- package/src/slash/slash-commands.d.ts.map +1 -1
- package/src/slash/slash-commands.js +2 -2
- package/src/slash/slash-commands.js.map +1 -1
- package/src/slash/subagent-cost.d.ts.map +1 -1
- package/src/slash/subagent-cost.js +8 -4
- package/src/slash/subagent-cost.js.map +1 -1
- package/src/tui/render.d.ts +1 -1
- package/src/tui/render.d.ts.map +1 -1
- package/src/tui/render.js +59 -21
- package/src/tui/render.js.map +1 -1
- package/src/watchdog/diff-tool.d.ts +3 -1
- package/src/watchdog/diff-tool.d.ts.map +1 -1
- package/src/watchdog/diff-tool.js +20 -11
- package/src/watchdog/diff-tool.js.map +1 -1
- package/src/watchdog/register-child.js +2 -2
- package/src/watchdog/register-child.js.map +1 -1
- package/src/watchdog/register-main.js +2 -2
- package/src/watchdog/register-main.js.map +1 -1
- package/src/watchdog/review.d.ts +1 -1
- package/src/watchdog/review.d.ts.map +1 -1
- package/src/watchdog/review.js +1 -1
- package/src/watchdog/review.js.map +1 -1
- package/src/watchdog/turn-delta.js +1 -1
- package/src/watchdog/turn-delta.js.map +1 -1
- package/src/workflows/chat-progress.js +2 -2
- package/src/workflows/chat-progress.js.map +1 -1
- package/src/workflows/scripted-workflow.d.ts +8 -0
- package/src/workflows/scripted-workflow.d.ts.map +1 -1
- package/src/workflows/scripted-workflow.js +10 -2
- package/src/workflows/scripted-workflow.js.map +1 -1
- package/src/workflows/structured-workflow-scripts.d.ts +10 -0
- package/src/workflows/structured-workflow-scripts.d.ts.map +1 -0
- package/src/workflows/structured-workflow-scripts.js +166 -0
- package/src/workflows/structured-workflow-scripts.js.map +1 -0
- package/src/workflows/workflow-receipt.d.ts.map +1 -1
- package/src/workflows/workflow-receipt.js +10 -4
- package/src/workflows/workflow-receipt.js.map +1 -1
- package/src/workflows/workflow-resources.d.ts +13 -0
- package/src/workflows/workflow-resources.d.ts.map +1 -1
- package/src/workflows/workflow-resources.js +46 -16
- package/src/workflows/workflow-resources.js.map +1 -1
- package/src/workflows/workflow-reuse.d.ts +51 -0
- package/src/workflows/workflow-reuse.d.ts.map +1 -0
- package/src/workflows/workflow-reuse.js +103 -0
- package/src/workflows/workflow-reuse.js.map +1 -0
- package/src/workflows/workflow-revival.d.ts +32 -0
- package/src/workflows/workflow-revival.d.ts.map +1 -0
- package/src/workflows/workflow-revival.js +111 -0
- package/src/workflows/workflow-revival.js.map +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,106 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.75.0] - 2026-10-02
|
|
6
|
+
|
|
7
|
+
### Highlights
|
|
8
|
+
|
|
9
|
+
- Background subagents work on Pi 1.0.0 again. In 0.74.0 they failed to start with "does not provide @earendil-works/pi-agent-core/node".
|
|
10
|
+
- The built-in `claude-code` and `claude-code-writer` agents can pick a Claude model and effort level per launch, for example `model: "claude-opus-5.5:high"`.
|
|
11
|
+
- On Windows, `claude-code`, `codex-exec`, and `cursor-agent` can now launch CLIs installed with npm.
|
|
12
|
+
- Children on a virtual model from an extension, such as a model router set as `subagents.defaultModel`, now launch and pass model verification.
|
|
13
|
+
- An invalid config value no longer silently turns off `authorityPolicy`, `permissions`, or `toolBudget`. Loading the config fails instead.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- The built-in `claude-code` and `claude-code-writer` agents accept a model and thinking level per launch or in agent frontmatter, and pass them to Claude Code as `--model` and `--effort`. Before, the model could only be set in your global Claude Code settings. `model: "claude-opus-5.5:high"` sets both; `model: ":high"` sets only the effort. An unknown model or level fails the launch and names it. `subagents.maxThinking` and an enforced `subagents.modelScope` apply to these launches; with an enforced scope, a launch that sets no model fails, because Claude Code's default model cannot be checked. Other external runners still reject both fields. See [agents](docs/agents.md). Thanks to [@lexxbyte](https://github.com/lexxbyte) for [#2602](https://github.com/nicobailon/pi-subagents/issues/2602).
|
|
18
|
+
- The parent can now manage a long `bash` command inside a native Pi child that is granted both `bash` and `subagent_command`: `command.status` shows it, `command.yield` lets the child continue while the command keeps running, and `command.cancel` stops only that command. The child can do the same itself with `bash`'s `yieldTimeMs` and the `subagent_command` tool. Commands use Pi's own shell and are stopped when the child exits, and a child that finishes with a command still running fails. Thanks to [@jiuai233](https://github.com/jiuai233) for [#2598](https://github.com/nicobailon/pi-subagents/pull/2598).
|
|
19
|
+
- Hosts that require child extensions with `registerRequiredChildExtensions` can pass `requireForAllRunners: true`. Only local Pi children can load those extensions, so with this flag a launch on an external CLI, an external job, or another machine is refused before it starts instead of running without them. The requirement stays with the run, including nested, resumed, and workflow children, even after the host removes its registration. Without the flag, external runners are skipped as before. See [agents](docs/agents.md). Thanks to [@doc-krieger](https://github.com/doc-krieger) for [#2639](https://github.com/nicobailon/pi-subagents/issues/2639).
|
|
20
|
+
- `schedule.create` accepts an existing `missionId`, so a scheduled workflow keeps the same mission state across runs and session restarts. Schedules with a mission are saved in a new format that older pi-subagents versions reject instead of silently dropping the mission; other schedules keep the old format. Thanks to [@quifox](https://github.com/quifox) for [#2616](https://github.com/nicobailon/pi-subagents/pull/2616).
|
|
21
|
+
- `asyncWidgetCollapsed: true` starts the async widget under the editor folded to one line. Clicking its header still unfolds it, and the default is unchanged. Thanks to [@unrelentingfox](https://github.com/unrelentingfox) for [#2621](https://github.com/nicobailon/pi-subagents/pull/2621).
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- CI now runs the clean-install test against both Pi `0.86.1` and `1.0.0`, as separate jobs with separate logs. Thanks to [@EightDoor](https://github.com/EightDoor) for [#2648](https://github.com/nicobailon/pi-subagents/pull/2648).
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Background subagents failed to start on Pi 1.0.0 with "does not provide @earendil-works/pi-agent-core/node", because Pi 1.0.0 no longer ships that module. They now start without it, and still fail if Pi includes the module but the file is missing. Thanks to [@albertgwo](https://github.com/albertgwo) for [#2634](https://github.com/nicobailon/pi-subagents/pull/2634).
|
|
30
|
+
- An invalid value for any config key no longer silently drops `authorityPolicy`, `permissions`, or `toolBudget`. If the config file sets any of them, loading now fails instead of continuing with an empty config that would allow what those settings forbid. (#2622)
|
|
31
|
+
- A required child extension (`registerRequiredChildExtensions`) that throws during `session_start` now stops the launch. Before, Pi only reported the error, so the child still started and could send model requests without the policy the extension was meant to set up. Ordinary extensions are unchanged: their startup errors are reported and the child still starts. Thanks to [@doc-krieger](https://github.com/doc-krieger) for reporting [#2639](https://github.com/nicobailon/pi-subagents/issues/2639).
|
|
32
|
+
- On Windows, external-CLI agents such as `claude-code`, `codex-exec`, and `cursor-agent` failed with `EINVAL` when the CLI was installed with npm, because npm installs it as a `.cmd` file that Node cannot start without a shell. The runner now runs the CLI's script with Node directly, still without a shell, and refuses any other `.cmd` or `.bat` file. Thanks to [@lexxbyte](https://github.com/lexxbyte) for tracing the cause in [#2631](https://github.com/nicobailon/pi-subagents/issues/2631).
|
|
33
|
+
- A child could not launch on a virtual model that an extension registers with `pi.registerVirtualModel()`, such as a router set as `subagents.defaultModel`. The child looked up its model before the extension's virtual models were registered, so the name matched a model on another provider and the launch failed on that provider's missing API key. Virtual models are now registered first, and a required extension whose registration fails stops the launch. Thanks to [@mauroziux](https://github.com/mauroziux) for [#2636](https://github.com/nicobailon/pi-subagents/pull/2636) (#2635).
|
|
34
|
+
- A child on a virtual model failed with `model_verification_failed` even when it ran correctly, because the check compared the launch model with the real model the router picked. For virtual models, the check now compares the child's selected model with the launch model. Other children are checked as before. Thanks to [@mauroziux](https://github.com/mauroziux) for reporting [#2637](https://github.com/nicobailon/pi-subagents/issues/2637) (#2635).
|
|
35
|
+
- A background chain whose `expand` step runs an external-CLI agent such as `claude-code` failed with "Dynamic chain step N parallel does not support field 'runner'". Each item now runs through that agent's runner, and its output is collected like any parallel child. Thanks to [@lexxbyte](https://github.com/lexxbyte) for reporting [#2629](https://github.com/nicobailon/pi-subagents/issues/2629).
|
|
36
|
+
- Saving builtin agent overrides no longer risks a half-written settings file: if the save is interrupted, the previous settings stay readable. Thanks to [@quifox](https://github.com/quifox) for [#2627](https://github.com/nicobailon/pi-subagents/pull/2627).
|
|
37
|
+
- Codex children now keep tool-call IDs in the `call_id|item_id` form when both parts are at most 64 characters and use only letters, digits, `_`, or `-`. Other IDs are shortened as before. Thanks to [@jtabke](https://github.com/jtabke) for [#2628](https://github.com/nicobailon/pi-subagents/pull/2628) (#2623).
|
|
38
|
+
- With Pi's built-in MCP, `mcp:` entries whose server or tool name contains `-`, such as `mcp:srv/get-item`, failed with "selects MCP tools that Pi's built-in MCP does not offer". pi-subagents now converts `-` to `_` the same way Pi names the tool, so you keep writing names as the server reports them. Thanks to [@sheurich](https://github.com/sheurich) for [#2607](https://github.com/nicobailon/pi-subagents/issues/2607).
|
|
39
|
+
- Some MCP clients, such as pi-claude-bridge, send `workflow: true` as the string `"true"`, which failed with an error asking for `workflow: true`. The string now works the same as the boolean (#2600).
|
|
40
|
+
- `action: "validate"` now checks workflow `args` against the same limits as a launch: 16 fields per object, 64 items per array, depth 8, and 16 KiB total. A script that validates no longer fails at launch because of its `args`. ([#2608](https://github.com/nicobailon/pi-subagents/issues/2608))
|
|
41
|
+
- The parent is now told about every tool call that stays open past the attention threshold, not only the first one in each child. Thanks to [@jiuai233](https://github.com/jiuai233) for [#2598](https://github.com/nicobailon/pi-subagents/pull/2598).
|
|
42
|
+
- Async runs now reach `run-history.jsonl`. Before, only foreground runs were recorded, so per-agent lookups missed every background launch. Single-step runs record the same row as a foreground run, multi-step runs record one row per child step, and a paused run records as `interrupted`, with a later resume recording again. Thanks to [@limin411](https://github.com/limin411) for [#2620](https://github.com/nicobailon/pi-subagents/pull/2620).
|
|
43
|
+
- `/subagent-cost` and the RPC `cost` method now count every round of a resumed foreground workflow child. Before, every round after the first was dropped as a duplicate, so totals came out low with no warning. Results recorded before this fix still undercount. Thanks to [@chagwood](https://github.com/chagwood) for [#2601](https://github.com/nicobailon/pi-subagents/issues/2601).
|
|
44
|
+
- `/subagent-cost` and the RPC `cost` method no longer log a missing-receipt error on every call for foreground workflows. An async workflow that has no receipt yet, such as one still running, is now listed as `Async child usage unavailable` instead of being left out of the total without notice. (#2614)
|
|
45
|
+
- The global mission list now takes title, status, update time, and latest run from each mission's own record, so a mission no longer looks out of date because its index entry is stale. Thanks to [@quifox](https://github.com/quifox) for [#2618](https://github.com/nicobailon/pi-subagents/pull/2618).
|
|
46
|
+
- Headless sessions now deliver goal-mission notices even when finishing background work fails. The failure is still reported to the caller. Thanks to [@quifox](https://github.com/quifox) for [#2605](https://github.com/nicobailon/pi-subagents/pull/2605).
|
|
47
|
+
- One mission with a damaged run status or state no longer stops continuation notices for healthy goal missions. The damaged mission is reported separately. Thanks to [@quifox](https://github.com/quifox) for [#2604](https://github.com/nicobailon/pi-subagents/pull/2604).
|
|
48
|
+
- On Linux, a runner process that exited but was not yet cleaned up by the system no longer leaves its run marked as running, or a workflow waiting for a result that will never arrive. Thanks to [@quifox](https://github.com/quifox) for [#2606](https://github.com/nicobailon/pi-subagents/pull/2606).
|
|
49
|
+
- Saved subagent profiles with an invalid `machine` value are now rejected when loaded or checked, before any settings are written. `machine: false` still clears a pin. Thanks to [@quifox](https://github.com/quifox) for [#2619](https://github.com/nicobailon/pi-subagents/pull/2619).
|
|
50
|
+
|
|
51
|
+
## [0.74.0] - 2026-09-30
|
|
52
|
+
|
|
53
|
+
### Highlights
|
|
54
|
+
|
|
55
|
+
- Workflow scripts are now written as a normal ```` ```js workflow ```` code block in the reply and run with `workflow: true`, with no JSON escaping. This replaces `workflowScript` and `workflowScriptPath`.
|
|
56
|
+
- On models that cannot add a tool mid-conversation, `subagent` is now available from the start, so turning it on no longer reprocesses the whole conversation at full price.
|
|
57
|
+
- The new `disabledFeatures` setting hides parts of the `subagent` tool you do not use, and with `workflow-scripts` turned off you can run children with simple `chain` and `tasks` lists.
|
|
58
|
+
- `/reload` and session resumes no longer kill running background workflows, and relaunching one reuses the children that already finished.
|
|
59
|
+
- Subagent children now respect an untrusted project the same way the main session does.
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
|
|
63
|
+
- `disabledFeatures` in `config.json` removes feature groups you do not use from the `subagent` tool, such as agent management, watchdog, panes, missions, lane management, and per-call options like `toolBudget` or `machine`. Their parameters disappear from the tool, the tool description stops mentioning them, and calls that still use them fail with an error that names the setting. `scheduledRuns.enabled: false` now removes the schedule parameters the same way, and a malformed `scheduledRuns` value is now a config error. Nothing changes unless you opt in. With everything disabled, the tool declaration shrinks from 18,239 to 10,263 characters. See [configuration](docs/configuration.md#disabledfeatures). Thanks to [@tmustier](https://github.com/tmustier) for [#2542](https://github.com/nicobailon/pi-subagents/pull/2542).
|
|
64
|
+
- `disabledFeatures` also accepts `workflow-scripts`. It removes the `workflow`, `args`, `preflight`, `globalConcurrencyLimit`, and `maxSubagentSpawnsPerRun` parameters and the `validate` action, and the tool description no longer explains how to write scripts. In their place, the tool takes `tasks: [{ agent, task }]` to run children in parallel and `chain: [{ agent, task?, as? } | { parallel: [{ agent, task }] }]` to run steps in order. Chain tasks can use `{task}` (the top-level `task`), `{previous}`, and `{outputs.name}`. If a child fails, the run fails but still returns the results of the children that finished. Scripts that still arrive from RPC, `/prompt-workflow`, saved schedules, or delegated launches fail with an error that names the setting; `/run` still works. This mode saves about 2,000 more characters of tool declaration. Without it, the tool is unchanged. In both modes, extensions can no longer register workflow resources named `chain` or `tasks`. See [configuration](docs/configuration.md#chain-and-tasks-without-workflow-scripts).
|
|
65
|
+
- On Pi 0.99 and later without pi-mcp-adapter, `mcp:server` and `mcp:server/tool` entries in an agent's `tools` now select tools from Pi's built-in MCP, and the child gets exactly those tools. Servers from `mcp.json` work in foreground and background children; servers that extensions add with `pi.registerMcpServer()` work in background children. With pi-mcp-adapter installed, nothing changes. Thanks to [@fmoda3](https://github.com/fmoda3) for [#2555](https://github.com/nicobailon/pi-subagents/issues/2555).
|
|
66
|
+
- `subagents.modelScope` allow lists accept a `scoped` token, which stands for the parent session's scoped models (Pi's `/scoped-models`). Subagent model limits then follow Pi's model scoping without a second copy of the list. In an unscoped session, `scoped` means the same as `inherit`. Error messages list at most 8 patterns before summarizing the rest. Thanks to [@coreyryanhanson](https://github.com/coreyryanhanson) for [#2538](https://github.com/nicobailon/pi-subagents/pull/2538).
|
|
67
|
+
- `subagents.agentOverrides.<name>.advertise` lists an agent in the parent's agent catalog from settings, so you no longer have to copy a builtin agent file just to advertise it. Agents registered at runtime still cannot be advertised. Thanks to [@strive-run](https://github.com/strive-run) for [#2534](https://github.com/nicobailon/pi-subagents/pull/2534).
|
|
68
|
+
- Native Pi subagents can use Pi's built-in `codemode` tool when their tool selection allows it. It is loaded only in the child, so the main session can keep codemode off. Older Pi versions without codemode still report it as unavailable when an agent asks for it. Thanks to [@albertgwo](https://github.com/albertgwo) for [#2574](https://github.com/nicobailon/pi-subagents/pull/2574).
|
|
69
|
+
- After you upgrade pi-subagents, your first interactive session shows a short notice with the highlights of each new version and a link to the changelog. It is shown once and never enters the conversation, so it does not affect the model's context or prompt cache. Fresh installs and child sessions show nothing.
|
|
70
|
+
|
|
71
|
+
### Changed
|
|
72
|
+
|
|
73
|
+
- **Breaking:** Workflow scripts had to be passed to the `subagent` tool as a JSON string, so every quote and newline was escaped. The tool now takes one `workflow` field with three forms: `workflow: true` runs the single ```` ```js workflow ```` code block written in the same reply; a string containing `/` (such as `"./ci/sweep.js"`) loads a script file relative to `cwd`; any other string runs a named workflow. The `workflowScript` and `workflowScriptPath` parameters were removed, and calls that still pass them fail with an error that shows the new forms. RPC `spawn` takes inline script text as `script` and a path or workflow name as `workflow`. Saved schedules and run records keep working.
|
|
74
|
+
- On models that cannot take a new tool mid-conversation, calling `subagents_enable` made the provider reprocess the whole conversation at the uncached price. New sessions on those models now start with `subagent` already available. Models that can add tools mid-conversation still start with `subagents_enable`. Resumed sessions keep the tools they had, and switching models mid-session does not change them. The new `toolActivation` setting in `config.json` chooses `"auto"` (the default), `"dynamic"` (always start with `subagents_enable`, the old behavior), or `"eager"` (always start with `subagent`, like `--exclude-tools subagents_enable`). See [configuration](docs/configuration.md#toolactivation). Thanks to [@tinoy1336](https://github.com/tinoy1336) for [#2589](https://github.com/nicobailon/pi-subagents/issues/2589).
|
|
75
|
+
- After `subagents_enable`, the model was sometimes told to wait for the next prompt even when `subagent` was already usable. It is now told to check its tool list: use `subagent` if it is there, otherwise wait for the next prompt instead of retrying.
|
|
76
|
+
- CI now runs the tool-activation smoke test as a required check. Thanks to [@quifox](https://github.com/quifox) for [#2528](https://github.com/nicobailon/pi-subagents/pull/2528).
|
|
77
|
+
|
|
78
|
+
### Fixed
|
|
79
|
+
|
|
80
|
+
- Subagent children now follow the parent session's project trust. Before, a child in an untrusted project still loaded that project's settings, system prompt files, skills and, for background children, its extensions. Fixes [#2569](https://github.com/nicobailon/pi-subagents/issues/2569).
|
|
81
|
+
- `/reload`, a session resume, or a pi-web project switch stopped running background workflows and their children, and relaunching the script ran every child again, including ones that had already finished. Background children now keep running, the workflow's notice says to relaunch it, and relaunching the same script with the same args reuses finished children and waits for running ones. Failed children run again. The stop is recorded as `workflow.stopCause: "runtime-replaced"`. Fixes [#2546](https://github.com/nicobailon/pi-subagents/issues/2546).
|
|
82
|
+
- Stopping a background workflow by a short id, its tool-call id, its run directory, or from the Fleet view did nothing, so the workflow and its children kept running. These stops now work, and the workflow ends as stopped. Fixes [#2571](https://github.com/nicobailon/pi-subagents/issues/2571).
|
|
83
|
+
- Reviving a failed background workflow child with `subagent({ action: "resume", id })` did not show up in the workflow: its status, receipt and keyed `latest: true` resume still pointed at the failed run. Workflow `status` now shows `Revived → <run>: <state>` under the failed key, keyed resume continues from the revived run, and a workflow that finishes afterwards records the revival in its receipt and completion notice. The workflow's return value is unchanged. Thanks to [@l3gz](https://github.com/l3gz) for reporting [#2579](https://github.com/nicobailon/pi-subagents/issues/2579).
|
|
84
|
+
- When a workflow script failed and stopped a sibling that was still running, the sibling got a "Workflow child failed" notice whose error began with a "Run fan-out: N/M used, K remaining" line. The notice now says the child was stopped and gives only the reason. Fixes [#2562](https://github.com/nicobailon/pi-subagents/issues/2562) and [#2567](https://github.com/nicobailon/pi-subagents/issues/2567).
|
|
85
|
+
- After pi-subagents was updated on disk while Pi was running, for example by `git pull` in a local checkout or a package update, the first `subagent` call could fail with an error such as `(0 , _publicExecution.isWorkflowScriptPath) is not a function`, because it mixed new and old code. pi-subagents now loads all of its code shortly after a session starts, without slowing startup. After an update, run `/reload` or restart Pi to use the new version.
|
|
86
|
+
- With Pi 0.99's `codemode` turned on, codemode scripts could call `subagent`, `subagents_enable`, `subagent_supervisor`, `contact_supervisor` and `structured_output`, none of which work from a script: a `subagent` run there had no progress card and was cancelled unless awaited, `contact_supervisor` blocked the script, and `structured_output` had no effect. Codemode also added the whole `subagent` schema to its own description, about 2,200 extra tokens per request. The model can still call these tools directly, but scripts can no longer call them. Older Pi versions are unaffected.
|
|
87
|
+
- With the `subagent` tool registered, every request to llama.cpp (`llama-server --jinja`) failed with a 400 error because one parameter's pattern was not anchored at both ends, which llama.cpp requires. The pattern is now anchored and accepts the same values. Thanks to [@tychart](https://github.com/tychart) for reporting [#2581](https://github.com/nicobailon/pi-subagents/issues/2581).
|
|
88
|
+
- With pi-mcp-adapter 3.x on Pi 0.99 or later, `mcp:` entries in an agent's `tools` looked up Pi's built-in MCP instead of the adapter, so choosing an adapter server failed the launch. The adapter now takes priority whenever it is loaded. Fixes [#2575](https://github.com/nicobailon/pi-subagents/issues/2575).
|
|
89
|
+
- After upgrading pi-mcp-adapter to 3.1.0, `mcp:` tool selections for stdio servers stopped resolving, because the adapter started including `inheritEnv` and `literalEnv` in its config hash. pi-subagents now computes the same hash. Thanks to [@qsgy-edge](https://github.com/qsgy-edge) for [#2539](https://github.com/nicobailon/pi-subagents/pull/2539).
|
|
90
|
+
- When the async widget did not have room for its full view, its compact card showed one line per run and filled the rest with blank rows, hiding a workflow's lanes. The card now shows the lanes in that space and is only as tall as its content. Thanks to [@l3gz](https://github.com/l3gz) for reporting [#2578](https://github.com/nicobailon/pi-subagents/issues/2578).
|
|
91
|
+
- The async widget and the Fleet view counted running agents differently: with a 4-lane workflow and one other run, the widget said `2 agents running` and the Fleet view said `5 active agents`. The widget now counts each running workflow lane and each agent of a parallel run, like the Fleet view. Thanks to [@l3gz](https://github.com/l3gz) for reporting [#2578](https://github.com/nicobailon/pi-subagents/issues/2578).
|
|
92
|
+
- Herdr's subagent count no longer counts a workflow's coordinator as a child, and it updates as soon as a foreground workflow child starts or finishes instead of up to 45 seconds later. Thanks to [@xadips](https://github.com/xadips) for [#2556](https://github.com/nicobailon/pi-subagents/pull/2556).
|
|
93
|
+
- Dynamic tool activation now works when Pi runs inside another app, such as pi-web. Those hosts no longer print "Could not locate the running Pi installation" and no longer fall back to keeping `subagent` always loaded. Thanks to [@q107580018](https://github.com/q107580018) for [#2526](https://github.com/nicobailon/pi-subagents/issues/2526).
|
|
94
|
+
- Answering a background subagent's supervisor request no longer triggers a stale "needs attention" notice afterwards. The notice now waits 60 seconds and is sent only if the request is still unanswered and the run is still active. Status views still show the request right away.
|
|
95
|
+
- `inheritSkills: false` now also removes skills that extensions add to a child session (for example through `subagents.defaultExtensions`), so they no longer appear next to the agent's own skills. Thanks to [@zeezooz](https://github.com/zeezooz) for [#2540](https://github.com/nicobailon/pi-subagents/issues/2540).
|
|
96
|
+
- A child that was aborted by compaction now recovers when Pi reports the compaction late. Thanks to [@jiuai233](https://github.com/jiuai233) for [#2537](https://github.com/nicobailon/pi-subagents/pull/2537).
|
|
97
|
+
- Old background runs that belong to a finished or deleted mission are now cleaned up like other old runs instead of being kept forever. Fixes [#2535](https://github.com/nicobailon/pi-subagents/issues/2535). Thanks to [@LCorleone](https://github.com/LCorleone) for [#2536](https://github.com/nicobailon/pi-subagents/pull/2536).
|
|
98
|
+
- On Windows, the Pi interface froze for about 0.45 seconds once per process while background run cleanup waited on a PowerShell query. The query no longer blocks the interface. Thanks to [@localhedge](https://github.com/localhedge) for reporting [#2559](https://github.com/nicobailon/pi-subagents/issues/2559).
|
|
99
|
+
- On Windows, an idle session no longer checks for supervisor requests every 250 ms for its whole lifetime. Checking stops when no subagent work is pending and starts again when new work begins, as it already did on macOS. Thanks to [@localhedge](https://github.com/localhedge) for reporting [#2558](https://github.com/nicobailon/pi-subagents/issues/2558).
|
|
100
|
+
- Starting, reloading, resuming, or forking a session no longer pauses Pi while the watchdog records the current Git commit (about 50 ms per session start on Windows, even with the watchdog off). The check now runs in the background. Thanks to [@localhedge](https://github.com/localhedge) for reporting [#2560](https://github.com/nicobailon/pi-subagents/issues/2560).
|
|
101
|
+
- Worktree diffs now work with older Git versions that lack the `--default-prefix` option. Thanks to [@quifox](https://github.com/quifox) for [#2527](https://github.com/nicobailon/pi-subagents/pull/2527).
|
|
102
|
+
- Updated `undici` from 8.10.0 to 8.10.2, outside the range of [GHSA-3wwx-pv8p-q78v](https://github.com/advisories/GHSA-3wwx-pv8p-q78v), so projects that install pi-subagents no longer fail `npm audit` because of it. pi-subagents does not use the affected WebSocket client. Thanks to [@advaitpaliwal](https://github.com/advaitpaliwal) for [#2548](https://github.com/nicobailon/pi-subagents/pull/2548).
|
|
103
|
+
- A package-discovery test no longer fails when the system temp directory is inside a Pi project. Thanks to [@abdwhb-png](https://github.com/abdwhb-png) for [#2553](https://github.com/nicobailon/pi-subagents/pull/2553).
|
|
104
|
+
|
|
5
105
|
## [0.73.1] - 2026-09-27
|
|
6
106
|
|
|
7
107
|
### Highlights
|
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ Pi is the parent session. A subagent is a focused child Pi session with its own
|
|
|
44
44
|
|
|
45
45
|
When you ask for a subagent, Pi starts the child, gives it the task, and brings the result back. Foreground children run as sessions inside the parent Pi process and stream in the conversation. Background children run as sessions inside a detached runner process that keeps working and can be checked later.
|
|
46
46
|
|
|
47
|
-
Installing the extension does not start an automatic reviewer in the background.
|
|
47
|
+
Installing the extension does not start an automatic reviewer in the background. When the session's model can take a new tool mid-conversation, fresh parent sessions initially expose the small `subagents_enable` loader instead of the full `subagent` schema. When your request or applicable instructions authorize delegation, Pi can call the loader itself; the unchanged `subagent` tool is available on the next model request. With other models, fresh sessions start with `subagent` active, because adding a tool later would make the provider miss its prompt cache. The [`toolActivation`](docs/configuration.md#toolactivation) setting changes this. Complexity alone does not authorize delegation. `bg_wait` and supervisor replies remain available without activation.
|
|
48
48
|
|
|
49
49
|
If you want every implementation reviewed, say so in your prompt or project instructions:
|
|
50
50
|
|
package/docs/agents.md
CHANGED
|
@@ -110,12 +110,20 @@ The built-in `claude-code` and `claude-code-writer` profiles are the supported C
|
|
|
110
110
|
|
|
111
111
|
Both adapters own `claude -p` argv with stream JSON, strict empty MCP configuration, user-only setting sources, no session persistence, disabled slash commands, and disabled Chrome integration. The writer mode does not include Bash or any permission bypass. Neither mode uses `--bare`, which does not read normal OAuth/keychain authentication. Neither mode requires `--safe-mode`, which is absent from the installed 2.1.150 help. User profiles cannot add argv. Selecting the code-owned `claude-code-writer` adapter identity is the only way to opt into its write tools; the read-only adapter cannot be widened with user argv.
|
|
112
112
|
|
|
113
|
+
A `model`, and a thinking level carried on it as a `:level` suffix, are the one thing these two adapters do accept from a launch; the same two fields work in agent frontmatter. They become Claude Code's own `--model` and `--effort` rather than a Pi child model, so one launch can pin `claude-opus-5.5` with `high` effort without changing the operator's global Claude Code settings. The model must be an alias or a model id, and both values are checked before launch, so an unusable value fails the launch by name and no other token can be added.
|
|
114
|
+
|
|
115
|
+
The level travels as the same `:level` suffix Pi children use, on the `model` field: `model: "claude-opus-5.5:high"` pins the model and the effort, and `model: ":high"` asks for the effort alone. A suffix wins over the frontmatter `thinking` value. `off` passes no `--effort` and `minimal` maps to `low`, and a launch that requests no level leaves the flag out, so Claude Code's own default effort applies and this repository cannot bound it. `off` therefore means "pass no flag", not "no thinking".
|
|
116
|
+
|
|
117
|
+
`subagents.maxThinking` applies here the way it does to a native Pi child: a request above the ceiling fails before the child starts, compared on the requested level rather than on the effort it maps to. An enforced `subagents.modelScope` applies too, checked against the id that will reach the CLI; a launch that pins no model at all fails closed, because the CLI's own default cannot be checked. Every other external runner still refuses both fields.
|
|
118
|
+
|
|
113
119
|
Run it asynchronously:
|
|
114
120
|
|
|
115
121
|
```text
|
|
116
122
|
Use claude-code to analyze this handoff without editing files.
|
|
117
123
|
|
|
118
124
|
Use claude-code-writer to make the requested file changes.
|
|
125
|
+
|
|
126
|
+
Use claude-code-writer with model claude-sonnet-5:high to make the requested file changes.
|
|
119
127
|
```
|
|
120
128
|
|
|
121
129
|
The adapter validates `claude --version` and `claude --help` only when a run launches. Discovery, list, status, and native Pi launches do not execute Claude Code or probe authentication. A capabilities listing performs only a passive PATH/PATHEXT/X_OK lookup and exposes the command as `runner.available`; that does not prove authentication or launch compatibility. JSONL, stderr, and stdout are untrusted. A run succeeds only after bounded valid JSONL contains exactly one successful terminal `result` with non-empty final text. Missing or revoked local authentication, limit stops, malformed JSON, duplicate terminal results, and EOF before a terminal result fail closed.
|
|
@@ -220,7 +228,7 @@ You can override selected agent fields without copying the whole agent. Override
|
|
|
220
228
|
}
|
|
221
229
|
```
|
|
222
230
|
|
|
223
|
-
Supported override fields: `description`, `machine`, `output`, `outputMode`, `defaultReads`, `model`, `defaultProvider`, `thinking`, `systemPromptMode`, `inheritProjectContext`, `inheritGlobalContext`, `inheritSkills`, `defaultContext`, `acceptanceRole`, `disabled`, `skills`, `tools`, and `systemPrompt`.
|
|
231
|
+
Supported override fields: `description`, `advertise`, `machine`, `output`, `outputMode`, `defaultReads`, `model`, `defaultProvider`, `thinking`, `systemPromptMode`, `inheritProjectContext`, `inheritGlobalContext`, `inheritSkills`, `defaultContext`, `acceptanceRole`, `disabled`, `skills`, `tools`, and `systemPrompt`.
|
|
224
232
|
|
|
225
233
|
- `description` replaces the discovered description for builtin and custom agents, which lets list output show deployment-specific routing or model metadata.
|
|
226
234
|
- Use `output: false`, `defaultReads: false`, `defaultContext: false`, `acceptanceRole: false`, or `machine: false` to clear an inherited value.
|
|
@@ -265,7 +273,7 @@ pi-subagents never clones, pulls, or checks out on the machine. Generic `externa
|
|
|
265
273
|
|
|
266
274
|
## Parent prompt discovery
|
|
267
275
|
|
|
268
|
-
Set `advertise: true` in a specialist's agent file frontmatter for parent-prompt discovery. 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
|
|
276
|
+
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.
|
|
269
277
|
|
|
270
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 still calls `subagent({ action: "list", capabilities: true })` before execution to confirm that the selected agent is executable (including `runner.available === true` for external CLI agents).
|
|
271
279
|
|
|
@@ -345,18 +353,18 @@ Field notes:
|
|
|
345
353
|
| `package` | Optional package identifier. A file with `name: scout` and `package: code-analysis` registers as `code-analysis.scout`; serialization keeps `name` and `package` separate. |
|
|
346
354
|
| `advertise` | Set `true` to include this agent's name and description in the parent system prompt when the `subagent` tool is active. Defaults to `false`. |
|
|
347
355
|
| `aliases` | Optional comma-separated or block-list names that resolve to this agent for selection and explicit `agent` and task inputs. Runtime status, persistence, and config still use the canonical `name`. Exact canonical names take precedence over aliases, and alias collisions between distinct canonical agents fail as ambiguous. |
|
|
348
|
-
| `tools` | Strict child tool allowlist. Named extension tools must also have their provider loaded. `mcp:` entries select direct MCP tools
|
|
356
|
+
| `tools` | Strict child tool allowlist. Named extension tools must also have their provider loaded. `mcp:` entries select direct MCP tools from `pi-mcp-adapter` when it is installed, and from Pi's built-in MCP otherwise. |
|
|
349
357
|
| `excludeTools` | Optional child tool deny-list applied after normal tool resolution. With an explicit `tools` allowlist, matching names are removed; when `tools` is omitted, the names are excluded from the child session's default tool set. Unknown names are ignored by Pi without making the agent definition invalid. |
|
|
350
358
|
| `allowNestedSubagents` | Set `true` to authorize the child-safe nested `subagent` runtime without making omitted `tools` an allowlist. Inherited depth and capability ceilings remain authoritative. |
|
|
351
359
|
| `allowedAgents` | Restricts which canonical, case-sensitive agent names this agent may launch. Omitted adds no restriction; an empty list denies every descendant launch. This only narrows an existing nesting grant: `tools: subagent` or `allowNestedSubagents: true` is still required. Inherited/runtime allowlists are intersected and cannot be widened. |
|
|
352
360
|
| `extensions` | Omitted means a background child loads the parent's ambient extensions; empty means no ambient extensions; list values load exactly those extensions. Foreground children never load ambient extensions, so for them only listed values apply. |
|
|
353
361
|
| `subagentOnlyExtensions` | Extension paths loaded only in this agent's child sessions. Tools registered there are unavailable to the main agent unless also installed through normal Pi extension configuration. |
|
|
354
|
-
| `model` | Default model. Bare ids prefer the current provider when possible, then unique registry matches. |
|
|
355
|
-
| `thinking` | Appended as a `:level` suffix at runtime unless a suffix is already present. |
|
|
362
|
+
| `model` | Default model. Bare ids prefer the current provider when possible, then unique registry matches. On the two Claude Code adapters this is Claude Code's own alias or id, and a trailing `:level` picks the effort. |
|
|
363
|
+
| `thinking` | Appended as a `:level` suffix at runtime unless a suffix is already present. On the two Claude Code adapters it becomes `--effort`, and a suffix on `model` wins over it. |
|
|
356
364
|
| `systemPromptMode` | `replace` by default; `append` keeps Pi's base prompt. |
|
|
357
365
|
| `inheritProjectContext` | Keeps or strips inherited repository instruction blocks. |
|
|
358
366
|
| `inheritGlobalContext` | Keeps or strips the operator's global context file from the Pi config agent directory (e.g. `~/.pi/agent/AGENTS.md`). It has an effect only when `inheritProjectContext` is `true`; otherwise all context files are already disabled. Defaults to `false`. |
|
|
359
|
-
| `inheritSkills` | Keeps or strips Pi's discovered skills catalog. |
|
|
367
|
+
| `inheritSkills` | Keeps or strips Pi's discovered skills catalog. For in-process children this includes skills that loaded extensions add; herdr-placed children rely on Pi's `--no-skills`. |
|
|
360
368
|
| `defaultContext` | Optional `fresh` or `fork` launch-context preference. An implicit `fork` falls back to `fresh` when the parent has no persisted session file or current leaf; an explicit launch `context: "fork"` remains strict. |
|
|
361
369
|
| `skills` | Selects specific skills for the child, regardless of `inheritSkills`. |
|
|
362
370
|
| `skillPath` | Invocation-private skill files or discovery directories. Relative paths resolve from the agent definition file. Local matches take precedence, while unresolved or unreadable matches fall back to normal skill discovery. This field discovers candidates only; `skills` still selects what the child receives. |
|
|
@@ -375,9 +383,11 @@ Field notes:
|
|
|
375
383
|
|
|
376
384
|
### Required host extensions
|
|
377
385
|
|
|
378
|
-
Hosts can import `registerRequiredChildExtensions` from `pi-subagents/required-child-extensions` and register `{ sessionId, extensions: [{ id, path }] }`. Paths resolve to existing files and are canonicalized into an immutable launch snapshot; bounded safe IDs appear in evidence instead of paths. One registration is allowed per parent session until its idempotent `dispose()` runs, normally on `session_shutdown`.
|
|
386
|
+
Hosts can import `registerRequiredChildExtensions` from `pi-subagents/required-child-extensions` and register `{ sessionId, extensions: [{ id, path }], requireForAllRunners? }`. Paths resolve to existing files and are canonicalized into an immutable launch snapshot; bounded safe IDs appear in evidence instead of paths. One registration is allowed per parent session until its idempotent `dispose()` runs, normally on `session_shutdown`.
|
|
379
387
|
|
|
380
|
-
Required paths follow ordinary extension resolution and survive agent defaults and `extensions: []` across native foreground, detached, nested, and recovery launches. A `capabilityCeiling.denyExtensions` conflict or required load/provider-registration failure rejects before model resolution.
|
|
388
|
+
Required paths follow ordinary extension resolution and survive agent defaults and `extensions: []` across native foreground, detached, nested, and recovery launches. A `capabilityCeiling.denyExtensions` conflict or required load/provider-registration failure rejects before model resolution. An error a required extension reports while the child binds its extensions, such as a throwing `session_start` handler, disposes the child and rejects the launch before its first prompt. By default external runners are excluded (they run without the required extensions), and status/watch paths do not query the registry.
|
|
389
|
+
|
|
390
|
+
With `requireForAllRunners: true`, a launch that resolves to an external CLI runner, an external-job runner, or a machine placement is rejected before a runner process, provider job, or remote owner starts, because only local native Pi children load these extensions. The requirement stays with the run through nested, detached, resumed, recovered, workflow-script, and appended launches, so disposing the registration or setting `extensions: []` cannot drop it. Launch preflight previews the runner-type rejection for the session's current registration; machine placement and requirements retained by nested or resumed runs are checked at launch.
|
|
381
391
|
|
|
382
392
|
Successful completion is determined by observable gates such as process outcome, required outputs, explicit acceptance, verification commands, independent review, and staged-index integrity. Best-effort mutation observations remain diagnostic: unchanged or unknown evidence does not fail a run, and observed changes do not prove correctness.
|
|
383
393
|
|
|
@@ -442,9 +452,9 @@ How `tools` behaves:
|
|
|
442
452
|
|
|
443
453
|
`excludeTools` is applied after this resolution. It can narrow an explicit `tools` allowlist or, when `tools` is omitted, remove names from Pi's default builtin tool set. Runtime-injected tools are excluded only when their exact names are listed. An empty `excludeTools` list has no effect.
|
|
444
454
|
|
|
445
|
-
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.
|
|
455
|
+
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.
|
|
446
456
|
|
|
447
|
-
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
|
|
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.
|
|
448
458
|
|
|
449
459
|
More rules:
|
|
450
460
|
|
|
@@ -462,7 +472,9 @@ Examples:
|
|
|
462
472
|
- `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.
|
|
463
473
|
- `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.
|
|
464
474
|
|
|
465
|
-
|
|
475
|
+
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 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
|
+
|
|
477
|
+
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.
|
|
466
478
|
|
|
467
479
|
`extensions` controls child extension loading:
|
|
468
480
|
|
|
@@ -498,12 +510,14 @@ Discovery uses project-first precedence:
|
|
|
498
510
|
6. User packages and user settings packages via `package.json -> pi.skills`
|
|
499
511
|
7. `~/.pi/agent/settings.json -> skills`
|
|
500
512
|
|
|
501
|
-
Use agent defaults, override them at runtime, or disable them:
|
|
513
|
+
Use agent defaults, override them at runtime, or disable them inside the ```` ```js workflow ```` block:
|
|
502
514
|
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
{
|
|
506
|
-
{
|
|
515
|
+
```js
|
|
516
|
+
return runs.all([
|
|
517
|
+
{ key: "default", agent: "scout", task: "..." },
|
|
518
|
+
{ key: "override", agent: "scout", task: "...", skill: "tmux, safe-bash" },
|
|
519
|
+
{ key: "disabled", agent: "scout", task: "...", skill: false },
|
|
520
|
+
])
|
|
507
521
|
```
|
|
508
522
|
|
|
509
523
|
For chains, `skill` at the top level is additive. A step-level `skill` overrides that step; `false` disables skills for that step.
|
package/docs/configuration.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`pi-subagents` reads optional JSON config from `~/.pi/agent/extensions/subagent/config.json`. This page lists every key, plus the environment variables and the settings-file keys that affect config resolution.
|
|
4
4
|
|
|
5
|
-
Settings-level keys (`subagents.defaultModel`, `defaultProvider`, `defaultThinking`, `defaultExtensions`, `defaultSubagentOnlyExtensions`, `agentOverrides`, `machines`, `agentScanDirs`, `agentExcludeDirs`, `modelScope`, `disableThinking`, `disableBuiltins`, watchdog settings) live in Pi settings files, not this config file. `modelScope.agents.<name>` adds per-agent restrictions,
|
|
5
|
+
Settings-level keys (`subagents.defaultModel`, `defaultProvider`, `defaultThinking`, `defaultExtensions`, `defaultSubagentOnlyExtensions`, `agentOverrides`, `machines`, `agentScanDirs`, `agentExcludeDirs`, `modelScope`, `disableThinking`, `disableBuiltins`, watchdog settings) live in Pi settings files, not this config file. `modelScope.agents.<name>` adds per-agent restrictions, `allow: ["inherit"]` permits the current parent model, and `allow: ["scoped"]` permits the parent session's scoped models (the parent model when the session is unscoped). See [models.md](models.md), [agents.md](agents.md), and [watchdog.md](watchdog.md).
|
|
6
6
|
|
|
7
7
|
## Project root resolution (settings)
|
|
8
8
|
|
|
@@ -76,14 +76,30 @@ For a native Pi `model_verification_failed` where your proxy accepts `claude-hai
|
|
|
76
76
|
|
|
77
77
|
Replace `YOUR_PROVIDER` with the resolved Pi provider ID. Keep the outgoing model alias unchanged. This native remedy already exists in v0.65.1; it does not infer equivalence from provider prefixes or dates. The built-in external `claude-code` adapter does not invoke this verifier or use this setting. If an external run shows this diagnostic, identify the installed version, resolved runner kind/adapter, and error location before applying a native remedy. Thanks to [sixtus](https://github.com/sixtus) for the concrete request-ID/response-ID example in [#1922](https://github.com/nicobailon/pi-subagents/issues/1922).
|
|
78
78
|
|
|
79
|
+
A local Pi child whose selected model is a virtual model (`pi.registerVirtualModel()`, such as a router) needs no alias. Its assistant messages name whichever physical model the router picked, so verification compares the child's selected virtual `provider/id` with the launch model instead, exactly. A different virtual selection fails, and `modelResponseAliases` does not override it.
|
|
80
|
+
|
|
79
81
|
## Tool activation lifecycle
|
|
80
82
|
|
|
81
|
-
On Pi 0.86.1 or newer, a fresh unrestricted parent starts with `subagents_enable`, `bg_wait`, and `subagent_supervisor` active while `subagent` stays registered but inactive. Calling `subagents_enable({})` preserves unrelated active tools and exposes `subagent` on the next model request. It does not launch a child or infer authority from prompt keywords.
|
|
83
|
+
On Pi 0.86.1 or newer, when the model can take a new tool mid-conversation (see [`toolActivation`](#toolactivation)), a fresh unrestricted parent starts with `subagents_enable`, `bg_wait`, and `subagent_supervisor` active while `subagent` stays registered but inactive. Calling `subagents_enable({})` preserves unrelated active tools and exposes `subagent` on the next model request. It does not launch a child or infer authority from prompt keywords. With other models, a fresh parent starts with `subagent`, `bg_wait`, and `subagent_supervisor` active and no `subagents_enable`.
|
|
82
84
|
|
|
83
|
-
The recorded native `subagent` selection is restored on resume, reload, and tree navigation, so an activated session stays activated and a cold session stays cold. Older history without tool-selection records keeps eager `subagent` availability. If Pi's allowlist or exclusions remove the loader, the extension does not hide `subagent`; if they remove `subagent`, the loader reports it unavailable. Hosts
|
|
85
|
+
The recorded native `subagent` selection is restored on resume, reload, and tree navigation, so an activated session stays activated and a cold session stays cold. With the default `toolActivation`, the recorded `subagents_enable` selection is restored too, so a session that started without the loader never gets it later. Older history without tool-selection records keeps eager `subagent` availability. If Pi's allowlist or exclusions remove the loader, the extension does not hide `subagent`; if they remove `subagent`, the loader reports it unavailable. Hosts whose extension API lacks `getAllTools`, `getActiveTools`, or `setActiveTools` keep eager behavior and log one compatibility warning. The host version is not read from disk, so in-process hosts such as pi-web activate the same way as the Pi CLI.
|
|
84
86
|
|
|
85
87
|
Some providers fix the tool list for a whole prompt, for example bridges that hand Pi's tools to another agent SDK. There `subagent` appears only on the next user prompt, not the next model request. Start Pi with `--exclude-tools subagents_enable` to keep `subagent` active from the start.
|
|
86
88
|
|
|
89
|
+
## `toolActivation`
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{ "toolActivation": "eager" }
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Controls how a new parent session offers the `subagent` tool. The default is `"auto"`.
|
|
96
|
+
|
|
97
|
+
- `"auto"`: a new session starts with the `subagents_enable` loader only when its model can take a new tool mid-conversation. Otherwise it starts with `subagent` active and no loader, because calling the loader on such a model makes Pi resend the conversation in a form the provider may not have cached. A model qualifies when its Pi `compat` settings set `supportsMidConvoSystemMessages: true` and, for its API, `supportsMidConvoToolChanges: true` (`anthropic-messages`), `supportsMidConvoToolAdditions: true` (`openai-completions`), or `supportsAdditionalTools: true` or `supportsToolSearch: true` (`openai-responses`, `openai-codex-responses`, `azure-openai-responses`). Other APIs, missing settings, and no model do not qualify.
|
|
98
|
+
- `"dynamic"`: every new session starts with the loader, whatever the model. This was the behavior before `toolActivation` existed.
|
|
99
|
+
- `"eager"`: the loader is not registered, so `subagent` is active from the first request, as with `--exclude-tools subagents_enable`. A resumed session that recorded the loader changes its tool list once on the next request.
|
|
100
|
+
|
|
101
|
+
The choice is made at session start or tree navigation, and only for a session with no messages. Resumed sessions keep the tools they recorded, and switching models mid-session does not change them. `"auto"` avoids only the loader's cache miss; other tool-list or provider changes can still miss the cache. An active `subagent` sends its full schema on every request. An invalid value is a config error, not a fallback to the default. Restart Pi after changing it.
|
|
102
|
+
|
|
87
103
|
## `toolDescriptionMode`
|
|
88
104
|
|
|
89
105
|
```json
|
|
@@ -94,6 +110,49 @@ Controls the parent-facing `subagent` tool description registered at startup. Th
|
|
|
94
110
|
|
|
95
111
|
`custom` reads `subagent-tool-description.md` from the project config directory, then from `~/.pi/agent/subagent-tool-description.md`. Missing, empty, unreadable, or oversized custom files fall back to the full description. Custom templates may use `{{fullDescription}}`, `{{compactDescription}}`, `{{safetyGuidance}}`, `{{agentDir}}`, and `{{projectConfigDir}}`; the safety guidance is always present so custom prose cannot remove the runtime guardrails. Restart Pi after changing the mode or custom file.
|
|
96
112
|
|
|
113
|
+
## `disabledFeatures`
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{ "disabledFeatures": ["watchdog", "panes", "preflight", "lane-metadata", "gates"] }
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Removes feature groups you do not use from the `subagent` tool. Each listed feature loses its parameters from the model-facing schema, and any request that still uses one of its parameters or actions fails with an error naming this setting. The check covers the parent tool, fanout-child tools, RPC, slash commands, prompt templates, scheduled launches, delegated launches, and workflow `runs.run`/`runs.all`/`runs.lanes` children, which are rejected before they launch. The built-in tool descriptions, the unknown-action list, the fanout-child tool description, and RPC `ping` no longer mention disabled features, and `{ action: "guide", topic: "tool-reference" }` starts with a notice listing what is disabled. Custom tool descriptions are not changed. Nothing is disabled by default, and the default schema and description are unchanged. An unknown or duplicate feature name fails config loading rather than silently re-enabling every feature.
|
|
120
|
+
|
|
121
|
+
| Feature | Parameters removed | Actions rejected |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| `agent-management` | `config` | `create`, `update`, `delete`, `eject`, `disable`, `enable`, `reset`, `refine`, `refine.show`, `refine.rollback` |
|
|
124
|
+
| `watchdog` | `scope`, `target`, `thinking` | `watchdog.status`, `watchdog.check`, `watchdog.configure`, `watchdog.recommend-model` |
|
|
125
|
+
| `panes` | `focus` | `inspector.*`, `project.*` |
|
|
126
|
+
| `missions` | `mission`, `missionUpdate`, `missionStatus`, `missionScope`, `missionId`, `runMode`, `runStatus`, `summary` | `mission.*` |
|
|
127
|
+
| `lane-management` | `handoffPath`, `laneId`, `merge`, `supersession`, `repo`, `planId` | `lane.status`, `lane.recordMerge`, `lane.recordSupersession`, `worktree.discard`, `worktree.cleanup` |
|
|
128
|
+
| `spawn-budget-grants` | `additional` | `grant-spawn-budget` |
|
|
129
|
+
| `preflight` | `preflight` | |
|
|
130
|
+
| `lane-metadata` | `lane` | |
|
|
131
|
+
| `gates` | `gate` | |
|
|
132
|
+
| `usage-budgets` | `usageBudget` | |
|
|
133
|
+
| `tool-budgets` | `toolBudget` | |
|
|
134
|
+
| `control-overrides` | `control` | |
|
|
135
|
+
| `extension-bindings` | `extensionBindings` | |
|
|
136
|
+
| `external-machines` | `machine` | |
|
|
137
|
+
| `workflow-scripts` | `workflow`, `args`, `preflight`, `globalConcurrencyLimit`, `maxSubagentSpawnsPerRun` | `validate` |
|
|
138
|
+
|
|
139
|
+
Disabling a per-call option removes only the per-call override. Configured defaults such as `toolBudget`, `usageBudget`, and `control` in this file still apply, the watchdog still follows its own settings, missions still attach automatically when [`missions`](#missions) enables them, and agents with a `machine` in their definition still run there. Operator screens that do not go through the `subagent` executor, such as `/subagents-admin`, are unchanged. With every feature and [`scheduledRuns.enabled`](#scheduledruns) disabled, the default `subagent` tool declaration (name, description, and parameter schema as JSON) shrinks from 18,239 to 10,263 characters (80 to 41 parameters). Restart Pi after changing this setting.
|
|
140
|
+
|
|
141
|
+
### Chain and tasks without workflow scripts
|
|
142
|
+
|
|
143
|
+
`workflow-scripts` removes workflow scripts and named workflow resources from every entry point. The model can no longer write a script, and a script that still arrives from RPC `spawn` (`script` or `workflow`), `/prompt-workflow`, a saved schedule, or a delegated launch fails with an error that names the setting. Schedule inspection, pause, and delete still work, but `schedule.create` cannot succeed because it needs a script. `/run` still works: it launches its one child directly. The built-in tool description and prompt snippet drop the script guidance and describe two small inputs instead:
|
|
144
|
+
|
|
145
|
+
- `tasks: [{ agent, task }, ...]` runs the children in parallel and returns their results in order.
|
|
146
|
+
- `chain: [step, ...]` runs steps in order. A step is `{ agent, task?, as? }` or a parallel group `{ parallel: [{ agent, task }, ...] }`. A group waits for all of its children.
|
|
147
|
+
|
|
148
|
+
A top-level `task` is the original request. Tasks can use three placeholders:
|
|
149
|
+
|
|
150
|
+
- `{task}` is the top-level `task`. Using it without a top-level `task` is an error.
|
|
151
|
+
- `{previous}` is the output of the previous chain step. For a parallel group, the outputs are joined in input order with a blank line between them. A chain step without `task` uses `{previous}`. The first step has no previous output, so it needs a `task` and cannot use `{previous}`.
|
|
152
|
+
- `{outputs.name}` is the output of an earlier sequential step that set `as: "name"`. Names are identifiers, and each name can be used once.
|
|
153
|
+
|
|
154
|
+
`tasks` items can only use `{task}`. Placeholders are replaced in one pass, so placeholder text inside an output is not replaced again. Other brace text stays as written. `chain` and `tasks` exclude each other, `agent`, and `action`. Steps accept only the fields above, and inputs are limited to 64 items and 16 KiB. Top-level child options such as `model`, `skill`, `output`, and `worktree` apply to every child. If a child fails, the run fails: a chain stops after the failed step or group, `tasks` fails once every child has settled, and the error names each failed child. The results of the children that already finished are still returned. Without this setting, `chain` and `tasks` are rejected as removed legacy inputs.
|
|
155
|
+
|
|
97
156
|
## `inlineToolDisplay`
|
|
98
157
|
|
|
99
158
|
```json
|
|
@@ -165,7 +224,7 @@ Set `enabled` to `false` (or remove the block) as a kill switch. In that state,
|
|
|
165
224
|
{ "asyncByDefault": false }
|
|
166
225
|
```
|
|
167
226
|
|
|
168
|
-
|
|
227
|
+
Workflow script calls use background execution when the request omits `async`. Set `asyncByDefault` to `false` to restore foreground-by-default behavior for tool launches that still use the internal single-run primitive. Callers can still force foreground with `async: false` unless `forceTopLevelAsync` is enabled.
|
|
169
228
|
|
|
170
229
|
## `defaultSubagentContext`
|
|
171
230
|
|
|
@@ -237,6 +296,14 @@ Prompt modes keep their fixed keys. For example, `Esc` still cancels steer text
|
|
|
237
296
|
|
|
238
297
|
Controls the under-editor widget for active background runs. It defaults to `true`, including when FleetView is enabled, so active work remains visible after reload. Set it to `false` to hide this widget while keeping FleetView available.
|
|
239
298
|
|
|
299
|
+
## `asyncWidgetCollapsed`
|
|
300
|
+
|
|
301
|
+
```json
|
|
302
|
+
{ "asyncWidgetCollapsed": true }
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Starts each newly mounted under-editor async widget in its one-line folded state. It defaults to `false`. A header click still toggles the widget, and the folded state still resets when the widget is removed or Pi reloads.
|
|
306
|
+
|
|
240
307
|
## `waitTool`
|
|
241
308
|
|
|
242
309
|
```json
|
|
@@ -273,7 +340,7 @@ Forces depth-0 internal single, parallel, and chain runs into background mode an
|
|
|
273
340
|
{ "timeoutMs": 3600000 }
|
|
274
341
|
```
|
|
275
342
|
|
|
276
|
-
Global default runtime deadline, in milliseconds, for subagent runs. It replaces the built-in 30-minute backstop for foreground launches (single, parallel, chain, and
|
|
343
|
+
Global default runtime deadline, in milliseconds, for subagent runs. It replaces the built-in 30-minute backstop for foreground launches (single, parallel, chain, and workflow scripts) and plain single-agent async runs whenever no call-level `timeoutMs`/`maxRuntimeMs` applies. For single-agent launches, selected agent frontmatter `timeoutMs` still wins. This only moves the *default*. Expiring this run-level deadline is terminal.
|
|
277
344
|
|
|
278
345
|
This deadline bounds the whole run. The wait for a single model response is bounded separately by Pi's `httpIdleTimeoutMs` setting (default 300000; `0` disables it), which Pi applies both as the SDK request timeout and as the undici header/body idle timeout. Detached async runners read the same setting from `~/.pi/agent/settings.json` and the project `.pi/settings.json` for their own HTTP dispatcher, so a local model that queues or prefills for longer than five minutes needs `httpIdleTimeoutMs` raised or disabled in Pi settings, plus a `timeoutMs` long enough for the run.
|
|
279
346
|
|
|
@@ -309,7 +376,7 @@ An explicit `subagent` call value wins over this default. Choose a value at leas
|
|
|
309
376
|
{ "globalConcurrencyLimit": 20 }
|
|
310
377
|
```
|
|
311
378
|
|
|
312
|
-
Caps simultaneously running children inside one run, including durable legacy multi-child runs and
|
|
379
|
+
Caps simultaneously running children inside one run, including durable legacy multi-child runs and workflow script launches through `runs.run`/`runs.all`. Queued workflow children retain their stable keys and begin when a running sibling releases capacity. The default is `20`.
|
|
313
380
|
|
|
314
381
|
Inline or file-backed top-level workflow calls may set a positive safe-integer `globalConcurrencyLimit` to override this value for that workflow. The override is workflow-only and is not forwarded to child calls.
|
|
315
382
|
|
|
@@ -363,7 +430,7 @@ This limit bounds current top-level async load. It is separate from cumulative `
|
|
|
363
430
|
{ "scheduledRuns": { "enabled": false, "maxPending": 20 } }
|
|
364
431
|
```
|
|
365
432
|
|
|
366
|
-
Durable schedules are enabled by default and stored per project under `.pi/subagents/schedules/<id>/`. See [missions.md](missions.md#schedules) for usage.
|
|
433
|
+
Durable schedules are enabled by default and stored per project under `.pi/subagents/schedules/<id>/`. See [missions.md](missions.md#schedules) for usage. Setting `enabled` to `false` also removes the schedule parameters (`name`, `at`, `every`, `sessionOnly`, `quiet`, `on`, `timezone`, `overlap`, `catchUp`) from the `subagent` tool and rejects `schedule.*` actions from every entry point. Saved schedules are kept and become manageable again when you re-enable schedules.
|
|
367
434
|
|
|
368
435
|
Set `storeRoot` to keep durable schedules outside project repositories. It must be an absolute path or a `~/` path, which expands from the user home directory. Each project is stored under a hash of its resolved working directory, so projects do not share schedules.
|
|
369
436
|
|
|
@@ -426,7 +493,7 @@ Foreground children remain sessions inside the parent. Npm background children r
|
|
|
426
493
|
export PI_PACKAGE_DIR=/path/to/pi-coding-agent-package
|
|
427
494
|
```
|
|
428
495
|
|
|
429
|
-
Pi's own package/assets root
|
|
496
|
+
Pi's own package/assets root. Npm background children receive the detected npm host root as `PI_PACKAGE_DIR`, which overrides an inherited bundled layout; Bun-compiled hosts pass the parent's value through so children keep their release assets.
|
|
430
497
|
|
|
431
498
|
## `PI_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT`
|
|
432
499
|
|
|
@@ -434,7 +501,7 @@ Pi's own package/assets root is also authoritative when pi-subagents verifies th
|
|
|
434
501
|
export PI_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT=/path/to/pi-coding-agent-package
|
|
435
502
|
```
|
|
436
503
|
|
|
437
|
-
Overrides host-package discovery for spawned children. Foreground CLI resolution uses this root to locate the `pi` CLI script, and the detached background runner uses it for jiti host resolution and peer-package aliases, so both child kinds agree on one host.
|
|
504
|
+
Overrides host-package discovery for spawned children. Foreground CLI resolution uses this root to locate the `pi` CLI script, and the detached background runner uses it for jiti host resolution and peer-package aliases, so both child kinds agree on one host. The value must be the root of a canonical `@earendil-works/pi-coding-agent` installation (the directory containing its `package.json`, with that package name); both child kinds still validate the package name and its peer packages from that install tree, so a package whose manifest carries a different name is rejected even with the override set. Empty or whitespace-only values are ignored.
|
|
438
505
|
|
|
439
506
|
The default in-process child session loader consults the same discovery. Before falling back to a bare `@earendil-works/pi-coding-agent` import, it resolves the host package root (the running pi process's location, then this override, then pi-subagents' own install tree as a last fallback) and imports the host's entry file directly, so children share the host's single SDK instance instead of a second copy. Roots whose `package.json` name is not `@earendil-works/pi-coding-agent` are rejected. When this override is selected, an unimportable root is reported instead of falling back to a bare import from a different tree.
|
|
440
507
|
|
package/docs/extension-api.md
CHANGED
|
@@ -19,7 +19,7 @@ registerWorkflowResource({
|
|
|
19
19
|
}): { dispose(): void }
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Names are case-sensitive, at most 128 characters, and match `[A-Za-z0-9][A-Za-z0-9._-]*`; use an extension prefix. Versions are positive safe integers. Registration throws for invalid input, protected builtins (`review`, `run-ci`), or duplicate names within the same session. Different sessions may register the same name. Dispose before replacement; there is no silent overwrite.
|
|
22
|
+
Names are case-sensitive, at most 128 characters, and match `[A-Za-z0-9][A-Za-z0-9._-]*`; use an extension prefix. Versions are positive safe integers. Registration throws for invalid input, protected builtins (`review`, `run-ci`, and `chain` and `tasks`, which back the tool's structured inputs), or duplicate names within the same session. Different sessions may register the same name. Dispose before replacement; there is no silent overwrite.
|
|
23
23
|
|
|
24
24
|
Register in `session_start` using **`ctx.sessionManager.getSessionId()`**, not the session file path or a tool argument. Dispose in `session_shutdown`. New/resumed/forked sessions and reloads need registration from the replacement runtime's `session_start`; do not retain old `pi`/`ctx` references. The extension owns cleanup, not an automatic registration lifecycle manager. Disposal is idempotent and cannot remove a newer replacement. Missing cleanup can cause a duplicate-registration failure on reload.
|
|
25
25
|
|
|
@@ -108,7 +108,7 @@ pi.events.emit("subagents:rpc:v1:request", {
|
|
|
108
108
|
requestId,
|
|
109
109
|
method: "spawn",
|
|
110
110
|
params: {
|
|
111
|
-
|
|
111
|
+
script: `return runs.run("main", { agent: "reviewer", task: "Review the current diff" })`,
|
|
112
112
|
context: "fresh"
|
|
113
113
|
}
|
|
114
114
|
});
|
|
@@ -119,7 +119,7 @@ The RPC methods are `ping`, `status`, `manage`, `spawn`, `steer`, `interrupt`, `
|
|
|
119
119
|
Method notes:
|
|
120
120
|
|
|
121
121
|
- `manage` exposes a narrow schedule-only allowlist: `schedule.list`, `schedule.show`, `schedule.history`, `schedule.pause`, `schedule.resume`, `schedule.run`, and `schedule.delete`. All actions except `schedule.list` require `id`. Mission, agent, config, worktree, and arbitrary management actions are rejected before executor dispatch. `ping.capabilities.managementActions` advertises the exact allowlist.
|
|
122
|
-
- `spawn` accepts structured single-child execution (`agent`, `task?`), inline `
|
|
122
|
+
- `spawn` accepts structured single-child execution (`agent`, `task?`), inline script text as `script`, or `workflow` with a script path (containing `/`, such as `"./ci/sweep.js"`) or a named workflow resource. `workflow: true` is rejected because RPC requests have no assistant reply to read a block from; the removed `workflowScript` and `workflowScriptPath` fields are rejected with errors naming `script` and `workflow`. Spawn is async-only: omit `async` or set `async: true`, omit `clarify`, and do not pass management `action` values. Relative script paths resolve against the request `cwd`. It goes through the same executor as the `subagent` tool, so agent discovery, validation, session attribution, configured spawn caps, child-safety depth, artifacts, and async status all behave the same.
|
|
123
123
|
- `steer` requires an async run `id` (plus optional child `index`) and a non-empty `message`; its reply preserves the normal acknowledged-delivery result. Optional `mode` values are `steer` (default), `follow_up`, and `auto`, and receipts include `deliveryStatus: "delivered" | "queued"`. RPC steering disables the direct tool's pause-and-revive recovery in every mode so an extension keeps authority over the exact child it spawned; `ping.capabilities.nonRecoveringSteer` advertises this guarantee.
|
|
124
124
|
- `resume` requires a run target and non-empty `message`. It delegates to the existing revival path, which validates current-session ownership, persisted session/recovery metadata, stopped/live state, capability ceilings, and the exclusive session lease before returning the new async run details. Callers may request a `file-only` output path for the revived result without overriding its model, tools, or budgets. `ping.capabilities.resume` advertises this seam.
|
|
125
125
|
- `cost` returns the same parent-plus-child accounting `/subagent-cost` renders, as data: `{ version: 1, parent, children, childTotal, total, unresolvedAsyncChildren }`, where each usage is `{ input, output, cacheRead, cacheWrite, cost, turns }` and each child carries `label`, `agent`, `runId`, `usage`, and `sessionFile` when known. It is read-only and walks the current session branch plus existing run artifacts, so request it on your own turn boundaries (for example after `agent_settled` or an async completion wake), not on a timer. `unresolvedAsyncChildren` counts async children whose metadata could not be read; treat `childTotal` as a lower bound when it is non-zero, exactly as documented for `/subagent-cost` in [observability.md](observability.md). `ping.capabilities.cost` advertises `{ version: 1 }`.
|
|
@@ -251,7 +251,7 @@ const result = await resolveSubagentLaunchContract({
|
|
|
251
251
|
if (!result.ok) {
|
|
252
252
|
// missing_agent, ambiguous_agent, missing_skill, denied_required_tool,
|
|
253
253
|
// invalid_artifact_dir, invalid_cwd, unsupported_mode, restricted_agent,
|
|
254
|
-
// thinking_ceiling, invalid_extension_bindings, or invalid_intercom_bridge
|
|
254
|
+
// thinking_ceiling, model_scope, invalid_extension_bindings, or invalid_intercom_bridge
|
|
255
255
|
throw new Error(result.message);
|
|
256
256
|
}
|
|
257
257
|
|
|
@@ -262,7 +262,8 @@ Preflight covers ordinary single-agent launch resolution:
|
|
|
262
262
|
|
|
263
263
|
- Selected agent identity and shadowed candidates.
|
|
264
264
|
- A parsed-definition digest, including system prompt and launch-affecting model, tool, skill, extension, output, and memory fields. Runtime overlays such as the Intercom bridge never change it.
|
|
265
|
-
- Fresh/fork context, effective model and thinking, skill and tool resolution, direct MCP selections, runtime/configured extensions.
|
|
265
|
+
- Fresh/fork context, effective model and thinking, skill and tool resolution, direct MCP selections, runtime/configured extensions. Pass your extension's `pi` as `runtimeSnapshotHost` so `mcp:` selections resolve against Pi's built-in MCP the way a launch does. Without it, preflight cannot see built-in MCP and resolves `mcp:` selections through pi-mcp-adapter's configuration, as before.
|
|
266
|
+
- Model scope allow lists accept the reserved tokens `inherit` and `scoped`; `scoped` expands to the caller-supplied `scopedModelIds` snapshot, degrading to `inherit` when it is omitted. Callers whose `modelScope.allow` uses `scoped` must pass `scopedModelIds` (the session's `/scoped-models` snapshot) alongside `parentModel`, otherwise preflight resolves it as `inherit` and may reject models the actual launch allows.
|
|
266
267
|
- The resolved Intercom bridge state (`intercomBridge.mode` and `intercomBridge.active`). An active bridge appends the bridge instruction to the child prompt and adds `contact_supervisor` to a declared tool list, exactly as execution does.
|
|
267
268
|
- Artifact/session paths, async lifecycle/status/result/event/process-terminal paths, package/lifecycle versions, capability-ceiling audit data, and stable digests.
|
|
268
269
|
|