pi-subagents 0.49.0 → 0.50.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 +35 -0
- package/agents/oracle.md +7 -5
- package/agents/researcher.md +1 -1
- package/agents/reviewer.md +2 -2
- package/agents/scout.md +1 -1
- package/agents/worker.md +1 -1
- package/docs/agents.md +2 -0
- package/docs/configuration.md +47 -3
- package/docs/extension-api.md +36 -0
- package/docs/missions.md +1 -1
- package/docs/observability.md +16 -0
- package/docs/tool-reference.md +19 -2
- package/docs/workflows.md +2 -2
- package/package.json +1 -1
- package/skills/pi-subagents/references/constraints-and-recipes.md +3 -2
- package/skills/pi-subagents/references/execution-controls.md +5 -4
- package/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
- package/skills/pi-subagents/references/prompting-and-roles.md +31 -15
- package/src/agents/agent-serializer.ts +2 -0
- package/src/agents/agents.ts +10 -0
- package/src/api/external-runs.ts +174 -84
- package/src/api/preflight.ts +12 -6
- package/src/extension/config.ts +33 -0
- package/src/extension/index.ts +48 -5
- package/src/extension/public-execution.ts +3 -1
- package/src/extension/rpc.ts +5 -1
- package/src/extension/schemas.ts +2 -1
- package/src/extension/tool-description.ts +4 -2
- package/src/inspectors/herdr/actions.ts +3 -7
- package/src/inspectors/herdr/project-panes.ts +2 -6
- package/src/inspectors/herdr/shell-command.ts +16 -0
- package/src/intercom/intercom-bridge.ts +2 -3
- package/src/intercom/native-supervisor-channel.ts +19 -42
- package/src/missions/goal-driver.ts +3 -1
- package/src/runs/background/active-run-index.ts +71 -1
- package/src/runs/background/async-execution.ts +49 -7
- package/src/runs/background/async-job-tracker.ts +1 -0
- package/src/runs/background/async-resume.ts +3 -5
- package/src/runs/background/async-status-snapshot.ts +277 -0
- package/src/runs/background/async-status.ts +8 -3
- package/src/runs/background/chain-root-attachment.ts +2 -2
- package/src/runs/background/completion-replay.ts +11 -1
- package/src/runs/background/fleet-view.ts +3 -1
- package/src/runs/background/result-files.ts +437 -0
- package/src/runs/background/result-watcher.ts +188 -41
- package/src/runs/background/retained-children.ts +69 -20
- package/src/runs/background/run-id-resolver.ts +30 -24
- package/src/runs/background/run-status.ts +7 -2
- package/src/runs/background/scheduled-runs.ts +54 -28
- package/src/runs/background/stale-run-reconciler.ts +27 -13
- package/src/runs/background/subagent-runner.ts +294 -32
- package/src/runs/background/subagent-wait.ts +2 -0
- package/src/runs/background/wait-completions.ts +5 -2
- package/src/runs/foreground/async-dismiss-action.ts +2 -1
- package/src/runs/foreground/chain-execution.ts +16 -0
- package/src/runs/foreground/execution.ts +219 -15
- package/src/runs/foreground/subagent-executor.ts +114 -28
- package/src/runs/shared/completion-guard.ts +96 -6
- package/src/runs/shared/external-cli-runner.ts +4 -0
- package/src/runs/shared/model-fallback.ts +16 -2
- package/src/runs/shared/nested-events.ts +66 -62
- package/src/runs/shared/orca-progress-tabs.ts +375 -0
- package/src/runs/shared/parallel-utils.ts +2 -0
- package/src/runs/shared/subagent-control.ts +15 -0
- package/src/runs/shared/subagent-prompt-runtime.ts +1 -9
- package/src/runs/shared/subagent-startup-retry.ts +12 -0
- package/src/runs/shared/tool-timeout.ts +93 -0
- package/src/shared/types.ts +29 -2
- package/src/slash/slash-commands.ts +34 -25
- package/src/slash/slash-live-state.ts +3 -0
- package/src/tui/fleet-status.ts +160 -45
- package/src/tui/fleet.ts +125 -15
- package/src/tui/render.ts +41 -10
- package/src/workflows/chat-progress.ts +6 -4
- package/src/workflows/scripted-workflow.ts +227 -70
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.50.0] - 2026-08-15
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Add optional Orca progress tabs with bounded, sanitized mirrors for native Pi and external CLI children. Thanks to @hyein-cbio for #1080.
|
|
9
|
+
- Show caller-owned external jobs in FleetView through a bounded push/cache API, without polling or exposing managed controls. Thanks to @ssyram for #1083.
|
|
10
|
+
- Add a bounded current-status snapshot for async runs in RPC surfaces, without replaying terminal history. Thanks to @yanqianglu for #1078.
|
|
11
|
+
- Add an optional `foregroundDetachShortcut` binding and show it in the running single-subagent card, so foreground work can be moved to the background without editing package source. Thanks to @Lewis-E for #1097.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- Clarify retained-child resumability and native supervisor coordination guidance. Thanks to @ELA718 for #1126.
|
|
15
|
+
- Clarify that completed retained writers should use `resume`, while `steer` with `mode: "follow_up"` only queues text for the next revival (#1104).
|
|
16
|
+
- Treat oracle/advisor consultation prompts as supervisor-backed dialogue when material unknowns remain (#1102).
|
|
17
|
+
- Show explicit resumable and not-resumable states, with fallback guidance, in retained child listings (#1101).
|
|
18
|
+
- Reduce reload work for large async histories by indexing the async result inbox by session, observer, and tool-call id instead of scanning every old result file. Stale terminal active markers now age out, and replay cleanup scans run less often.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- Keep Orca progress tabs from treating write-stream backpressure as mirror truncation.
|
|
22
|
+
- Stop advertising an `output-<index>.log` artifact in run transcripts when that file was never written, so workflow runs no longer point at a path that cannot exist. Thanks to @lbijeau for #1124.
|
|
23
|
+
- Keep FleetView working when a session file path is longer than a short identity, instead of failing external-job inspection on every poll. Thanks to @albertgwo for #1121 and @Don-Yin for #1122.
|
|
24
|
+
- Keep structured single-child runs from overriding output paths in the task, while preserving explicit and agent-configured outputs. Thanks to @pasemes for #1119.
|
|
25
|
+
- Keep no-edit confirmations guarded after later changes retract a prior implementation (#1115).
|
|
26
|
+
- Remove the native generic `intercom` compatibility fallback from supervisor coordination while preserving `contact_supervisor`, `subagent_supervisor`, and external `intercom` providers. Thanks to @jaudiger for #1107.
|
|
27
|
+
- Report an actionable project-settings override when duplicate ambient Pi extensions prevent a child from starting (#1114).
|
|
28
|
+
- Keep the FleetView overlay refreshed while open and count active leaf agents in the compact summary. Thanks to @Don-Yin for #1108.
|
|
29
|
+
- Keep user-requested foreground detaches from showing supervisor-response recovery guidance. Thanks to @Lewis-E for #1109.
|
|
30
|
+
- Reject configured subagent models that are not in the active host model registry before spawning a child, instead of forwarding an invalid `--model` argument to Pi. Thanks to @DresvyanskiyDenis for #1093.
|
|
31
|
+
- Start Herdr inspector and project pane commands with a shell-safe executable token, including paths that need quoting in Nushell. Thanks to @Rival for #1092.
|
|
32
|
+
- Stop `agentContract.version` from using an `enum` on an integer, which Gemini's function-calling schema subset rejects. Integer bounds express the same constraint and are valid everywhere. Thanks to @MarcusNeufeldt for #1095.
|
|
33
|
+
- Show supervisor-detached workflow children as paused and needing attention instead of failed while preserving recovery guidance (#1096).
|
|
34
|
+
- Show workflow-owned foreground children and recursive nested runs as a bounded tree in FleetView. Thanks to @expoli for #1086.
|
|
35
|
+
- Warn once, instead of on every heartbeat, when a long-running workflow child outlives its mission record. Thanks to @albertgwo for #1079.
|
|
36
|
+
- Keep deleted-schedule timers from exiting Pi and re-arm recurring schedules after unexpected timer fire failures. Thanks to @albertgwo for #1084.
|
|
37
|
+
- Count native `await` use of `runs.run`, `runs.all`, and launch-containing Promise combinators as consumed without allowing fire-and-forget launches. Thanks to @kebinzhi for #1082.
|
|
38
|
+
|
|
5
39
|
## [0.49.0] - 2026-08-13
|
|
6
40
|
|
|
7
41
|
### Added
|
|
@@ -10,6 +44,7 @@
|
|
|
10
44
|
- Inspect async run state with `debug.run`, without exposing prompts, secrets, or transcripts (#1037).
|
|
11
45
|
- Let builtin role overrides keep Pi's normal tools and extensions with `tools: "inherit"`. Thanks to @estanexanavsem for #1047 and @davidarny for #1049.
|
|
12
46
|
- Add simple terminal examples for FleetView, the async widget, and inline tool display. Thanks to @czottmann for #1050.
|
|
47
|
+
- Add per-tool-call wedge protection with `toolTimeoutMs` call → agent → config → environment precedence. Known-fast built-in tools get a five-minute default, long-running tools get attention notices without a hard default, matching `toolCallId` timers survive parallel tool completions, and supervisor waits (`contact_supervisor`, `intercom`, `subagent_wait`) remain exempt. Thanks to @forrestbthomas for #1077.
|
|
13
48
|
|
|
14
49
|
### Changed
|
|
15
50
|
- Clean up active-run limits and artifact packaging code without changing behavior.
|
package/agents/oracle.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: oracle
|
|
3
3
|
aliases: advisor
|
|
4
4
|
description: High-context decision-consistency oracle that protects inherited state and prevents drift
|
|
5
|
-
tools: read, grep, find, ls, bash
|
|
5
|
+
tools: read, grep, find, ls, bash
|
|
6
6
|
thinking: high
|
|
7
7
|
systemPromptMode: replace
|
|
8
8
|
inheritProjectContext: true
|
|
@@ -16,9 +16,11 @@ Your primary job is to prevent the main agent from making hidden, conflicting, o
|
|
|
16
16
|
|
|
17
17
|
Before you do anything else, reconstruct the key inherited decisions, constraints, and open questions from the forked conversation, codebase state, and task. Those decisions form your baseline contract. Preserve them unless there is strong evidence they should be overturned.
|
|
18
18
|
|
|
19
|
-
If
|
|
19
|
+
If the task is framed as asking or consulting the oracle, treat it as a live consultation unless the parent explicitly requests a one-shot report. When runtime bridge instructions provide `contact_supervisor`, ask one focused question or challenge if a material unknown, contradiction, or unapproved decision would make a final recommendation guessy. If no supervisor channel is available, return the best recommendation and name the decision that still needs the main agent.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
If you need clarification from the main agent and bridge instructions provide `contact_supervisor`, use it with `reason: "need_decision"` and wait for the reply. Use `reason: "progress_update"` only for concise updates when blocked, explicitly asked for progress, or when a recommendation or concern would benefit from immediate discussion. Keep coordination traffic tight and purposeful. Do not narrate your whole review through `contact_supervisor`.
|
|
22
|
+
|
|
23
|
+
Do not send routine completion handoffs. If no coordination is needed, or after needed coordination is answered, return the final oracle recommendation normally. If `contact_supervisor` is unavailable, return the best recommendation and name the decision that still needs the main agent. Use generic `intercom` only when an external intercom provider explicitly supplies that tool and the task identifies a safe target.
|
|
22
24
|
|
|
23
25
|
Core responsibilities:
|
|
24
26
|
- reconstruct inherited decisions, constraints, and open questions from the context
|
|
@@ -39,8 +41,8 @@ What you do not do by default:
|
|
|
39
41
|
|
|
40
42
|
Working rules:
|
|
41
43
|
- Use `bash` only for inspection, verification, or read-only analysis.
|
|
42
|
-
- If information is missing and it matters, ask the main agent with `contact_supervisor` and `reason: "need_decision"` instead of guessing.
|
|
43
|
-
- If the answer depends on a decision the main agent has not made yet, stop and ask with `contact_supervisor`
|
|
44
|
+
- If information is missing and it matters, ask the main agent with `contact_supervisor` and `reason: "need_decision"` when bridge instructions provide that tool. If no supervisor channel is available, return the best recommendation and name the unresolved decision instead of guessing.
|
|
45
|
+
- If the answer depends on a decision the main agent has not made yet, stop and ask with `contact_supervisor` when bridge instructions provide that tool. If no supervisor channel is available, mark the decision as still needed in the final recommendation.
|
|
44
46
|
- When bridge instructions are present, send concise coordination messages only when a recommendation, concern, or question would benefit from immediate discussion instead of waiting silently until the final return.
|
|
45
47
|
- Prefer narrow, specific corrections to the current path over rewriting the whole plan.
|
|
46
48
|
|
package/agents/researcher.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: researcher
|
|
3
3
|
description: Autonomous web researcher — searches, evaluates, and synthesizes a focused research brief
|
|
4
|
-
tools: read, write, web_search, fetch_content, get_search_content
|
|
4
|
+
tools: read, write, web_search, fetch_content, get_search_content
|
|
5
5
|
thinking: medium
|
|
6
6
|
systemPromptMode: replace
|
|
7
7
|
inheritProjectContext: true
|
package/agents/reviewer.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: reviewer
|
|
3
3
|
description: Versatile review specialist for code diffs, plans, proposed solutions, codebase health, and PR/issue validation
|
|
4
|
-
tools: read, grep, find, ls
|
|
4
|
+
tools: read, grep, find, ls
|
|
5
5
|
thinking: high
|
|
6
6
|
systemPromptMode: replace
|
|
7
7
|
inheritProjectContext: true
|
|
@@ -62,7 +62,7 @@ Review a PR or issue by understanding the context, then verifying:
|
|
|
62
62
|
## Supervisor coordination
|
|
63
63
|
If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Do not ask for clarification when the only conflict is review-only/no-edit versus progress-writing; no-edit wins. Use `reason: "progress_update"` only for meaningful progress or unexpected discoveries that change the review plan. Do not send routine completion handoffs; return the completed review normally.
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
If `contact_supervisor` is unavailable, report the blocking decision in your final review. Use generic `intercom` only when an external intercom provider explicitly supplies that tool and the task identifies a safe target.
|
|
66
66
|
|
|
67
67
|
## Review output format
|
|
68
68
|
Structure your findings clearly:
|
package/agents/scout.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scout
|
|
3
3
|
description: Fast codebase recon that returns compressed context for handoff
|
|
4
|
-
tools: read, grep, find, ls, bash, write
|
|
4
|
+
tools: read, grep, find, ls, bash, write
|
|
5
5
|
thinking: low
|
|
6
6
|
systemPromptMode: replace
|
|
7
7
|
inheritProjectContext: true
|
package/agents/worker.md
CHANGED
|
@@ -22,7 +22,7 @@ The builtin worker uses a strict tool allowlist. It does not inherit ambient ext
|
|
|
22
22
|
|
|
23
23
|
If the task is framed as an approved direction, oracle handoff, or execution plan, treat that direction as the contract. Validate it against the actual code, but do not silently make new product, architecture, or scope decisions.
|
|
24
24
|
|
|
25
|
-
If the implementation reveals a decision that was not approved and is required to continue safely, pause and escalate through the live coordination channel. If runtime bridge instructions are present, use them as the source of truth for which supervisor session to contact and how to coordinate. Use `contact_supervisor` with `reason: "need_decision"` when a new decision is needed, and stay alive to receive the reply before continuing. Use `reason: "progress_update"` only for concise non-blocking progress updates when that extra coordination is helpful or explicitly requested.
|
|
25
|
+
If the implementation reveals a decision that was not approved and is required to continue safely, pause and escalate through the live coordination channel. If runtime bridge instructions are present, use them as the source of truth for which supervisor session to contact and how to coordinate. Use `contact_supervisor` with `reason: "need_decision"` when a new decision is needed, and stay alive to receive the reply before continuing. Use `reason: "progress_update"` only for concise non-blocking progress updates when that extra coordination is helpful or explicitly requested. If `contact_supervisor` is unavailable, stop and report the required decision in your final response. Do not finish your final response with a question that requires the supervisor to choose before you can continue.
|
|
26
26
|
|
|
27
27
|
Default responsibilities:
|
|
28
28
|
- validate the task or approved direction against the actual code
|
package/docs/agents.md
CHANGED
|
@@ -133,6 +133,7 @@ defaultReads: context.md
|
|
|
133
133
|
defaultProgress: true
|
|
134
134
|
async: true
|
|
135
135
|
timeoutMs: 900000
|
|
136
|
+
toolTimeoutMs: 600000
|
|
136
137
|
turnBudget: {"maxTurns":20,"graceTurns":2}
|
|
137
138
|
acceptance: {"level":"none","reason":"lightweight lookup"}
|
|
138
139
|
acceptanceRole: read-only
|
|
@@ -178,6 +179,7 @@ Field notes:
|
|
|
178
179
|
| `defaultProgress` | Maintain `progress.md`. |
|
|
179
180
|
| `async` | Default a single-agent launch to background (`true`) or foreground (`false`) when the call omits `async`. Explicit call values and `forceTopLevelAsync` win. |
|
|
180
181
|
| `timeoutMs` | Positive integer default runtime deadline in milliseconds for single-agent launches. Foreground launches use 30 minutes when neither the call nor agent provides a timeout; explicit `timeoutMs`/`maxRuntimeMs` and agent defaults win. |
|
|
182
|
+
| `toolTimeoutMs` | Optional positive integer hard per-tool-call deadline in milliseconds. An explicit call value wins, then this agent default, global `toolTimeoutMs`, and `PI_SUBAGENT_TOOL_TIMEOUT_MS`. When omitted, known-fast built-in tools get a five-minute default; long-running tools get attention notices but no hard default. It does not extend the run-level deadline; `contact_supervisor`, `intercom`, and `subagent_wait` are exempt. |
|
|
181
183
|
| `turnBudget` | JSON object default such as `{"maxTurns":20,"graceTurns":2}` for single-agent launches. An explicit call value wins, followed by this agent default, then global `turnBudget` config. |
|
|
182
184
|
| `acceptance` | Acceptance default for single-agent launches. Use a scalar level such as `checked` or an inline/block YAML map such as `{ level: "none", reason: "lightweight lookup" }`. Explicit call values win; chain and parallel acceptance remains task/step configuration. |
|
|
183
185
|
| `acceptanceRole` | Optional `read-only` or `writer` role for automatic acceptance inference. Explicit task mutation or no-edit intent wins; otherwise the declared role replaces agent-name guessing. This does not grant or revoke tools. |
|
package/docs/configuration.md
CHANGED
|
@@ -67,6 +67,38 @@ With `"summary"`, a tool result looks like this:
|
|
|
67
67
|
✓ reviewer · completed
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
+
## `foregroundDetachShortcut`
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{ "foregroundDetachShortcut": "ctrl+b" }
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Optionally binds a shortcut that detaches the active foreground single-subagent run without terminating it. The running foreground card shows the configured shortcut beside its live-detail hint. The default is unset, so pi-subagents does not reserve a global key.
|
|
77
|
+
|
|
78
|
+
Pi binds `Ctrl+B` to editor cursor-left by default. The extension shortcut takes precedence, but Pi reports the conflict at startup. To reserve the key without that warning, override the editor action in `~/.pi/agent/keybindings.json`:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"tui.editor.cursorLeft": "left"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## `orcaProgressTabs` (experimental)
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"orcaProgressTabs": {
|
|
91
|
+
"enabled": true
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Opt in to a best-effort Orca observer that creates one Orca terminal tab for each subagent child and mirrors its live tool, assistant, stdout, and stderr progress. Tab titles use a persistent worktree-local sequence (`subagent · <agent> · 1`, `... · 2`, and so on), so separate workflows and concurrent children do not reuse the same number. This does **not** replace Pi as the child runner: native Pi children keep the same process, lifecycle, status, control, artifact, and result paths. External CLI profiles also keep their existing runner and can mirror their stdout/stderr.
|
|
97
|
+
|
|
98
|
+
The integration is off by default and supports macOS and Linux. It is disabled on Windows. When enabled, `pi-subagents` looks for executable `orca` on `PATH`, or uses the executable path in `PI_SUBAGENT_ORCA_BINARY`. If no executable is available, Orca is not running, the cwd is not an Orca-managed worktree, or `terminal create` fails, the authoritative subagent still runs normally. Tab creation is deliberately best-effort and never changes the child result.
|
|
99
|
+
|
|
100
|
+
Set `enabled` to `false` (or remove the block) as a kill switch. In that state, `pi-subagents` does not invoke `orca` and creates no Orca tabs. The temporary mirror files contain child output, use private file modes where supported, and are removed shortly after the child finishes. Each mirror is capped at 1 MiB. The observer stops accepting progress when the cap or stream backpressure is reached and appends a truncation notice. The viewer removes terminal control sequences with parser state that persists across file reads. On completion, the viewer exits back to the Orca terminal's shell prompt; the tab and its terminal scrollback remain open until the user closes the tab. A successfully completed native Pi child with a recorded session ends with a safely quoted `rm -- <exact-session-path>` command; failed, stopped, timed-out, and sessionless children do not show the removal command.
|
|
101
|
+
|
|
70
102
|
## `asyncByDefault`
|
|
71
103
|
|
|
72
104
|
```json
|
|
@@ -150,6 +182,18 @@ Use it when foreground orchestration or plain async single-agent runs need a lon
|
|
|
150
182
|
|
|
151
183
|
Composite async runs (async chains, parallel tasks, and scripted workflows) stay unbounded at the top level by design. Their runner children are bounded individually by their own agent or runner defaults, so this value does not cap them. Must be a positive integer no greater than `2147483647` (the largest delay a Node.js timer can honor, roughly 24.8 days); invalid or out-of-range values are ignored and the built-in defaults apply.
|
|
152
184
|
|
|
185
|
+
## `toolTimeoutMs`
|
|
186
|
+
|
|
187
|
+
```json
|
|
188
|
+
{ "toolTimeoutMs": 600000 }
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Optional hard per-tool-call deadline in milliseconds. When configured, a child that emits `tool_execution_start` but not `tool_execution_end` is terminated with `timedOut: true` and a tool-specific error. The effective value is resolved per child: explicit `subagent` call value, then agent frontmatter, then this config value, then `PI_SUBAGENT_TOOL_TIMEOUT_MS`.
|
|
192
|
+
|
|
193
|
+
Without a configured value, Pi still applies a five-minute hard timeout to known-fast built-in tools: `read`, `grep`, `find`, `ls`, `edit`, `write`, and `structured_output`. Long-running tools such as `bash`, custom tools, and MCP tools do not get a hard default. They get the normal open-tool attention notice after `activeNoticeAfterMs` and remain bounded by the run-level deadline.
|
|
194
|
+
|
|
195
|
+
The tool timer tracks each active `toolCallId` separately and never extends the run-level deadline: when the remaining run budget is shorter, the ordinary run-level timeout wins. `contact_supervisor`, `intercom`, and `subagent_wait` are exempt because their legitimate purpose can be to wait for a human, supervisor, or child run. Use hard tool timeouts only for wedge protection; an elapsed timeout is not a mutation-safe boundary. Configured values must be positive integers no greater than `2147483647`; invalid or out-of-range values are rejected with a visible error rather than silently ignored.
|
|
196
|
+
|
|
153
197
|
## `globalConcurrencyLimit`
|
|
154
198
|
|
|
155
199
|
```json
|
|
@@ -275,7 +319,7 @@ Use `file` on hosts where endpoint protection (EDR) pre-execution scanning denie
|
|
|
275
319
|
}
|
|
276
320
|
```
|
|
277
321
|
|
|
278
|
-
Controls whether subagents receive runtime
|
|
322
|
+
Controls whether subagents receive runtime coordination instructions and whether `contact_supervisor` is auto-added to their tool allowlist when needed.
|
|
279
323
|
|
|
280
324
|
Fields:
|
|
281
325
|
|
|
@@ -283,9 +327,9 @@ Fields:
|
|
|
283
327
|
- `instructionFile`: optional Markdown template replacing the default bridge instructions. `{orchestratorTarget}` is interpolated. Relative paths resolve from `~/.pi/agent/extensions/subagent/`.
|
|
284
328
|
- `resultDelivery`: default `false`; set `true` only when an external listener consumes `subagent:result-intercom` and acknowledges the grouped completion payload. This is optional external result delivery, not native supervisor messaging. Enabled delivery waits for acknowledgement and reports acknowledgement failures. It does not change supervisor asks or progress updates.
|
|
285
329
|
|
|
286
|
-
Bridge activation requires a targetable current parent session id, which `pi-subagents` passes to children automatically. Native supervisor messaging does not require an external `pi-intercom` installation or per-agent extension allowlists: children use `contact_supervisor`, and parents use `subagent_supervisor` to inspect or reply.
|
|
330
|
+
Bridge activation requires a targetable current parent session id, which `pi-subagents` passes to children automatically. Native supervisor messaging does not require an external `pi-intercom` installation or per-agent extension allowlists: children use `contact_supervisor`, and parents use `subagent_supervisor` to inspect or reply. Agents can still use an external `intercom` tool when they explicitly request a provider that supplies it.
|
|
287
331
|
|
|
288
|
-
The default injected guidance tells children to use `contact_supervisor` with `reason: "need_decision"` when blocked or needing a decision, `reason: "progress_update"` only for meaningful blocked/progress updates,
|
|
332
|
+
The default injected guidance tells children to use `contact_supervisor` with `reason: "need_decision"` when blocked or needing a decision, `reason: "progress_update"` only for meaningful blocked/progress updates, and avoid routine completion handoffs.
|
|
289
333
|
|
|
290
334
|
## `worktreeBaseDir`
|
|
291
335
|
|
package/docs/extension-api.md
CHANGED
|
@@ -56,6 +56,42 @@ The DTO intentionally never exposes run, async, or tool IDs. Clients must ignore
|
|
|
56
56
|
|
|
57
57
|
`pi.events` is in-process only. It does not reach separate Pi processes or child subagents; use the file lifecycle artifacts or `pi-intercom` for cross-process coordination.
|
|
58
58
|
|
|
59
|
+
## External jobs in FleetView
|
|
60
|
+
|
|
61
|
+
Use `pi-subagents/external-runs` to publish display-only current-session jobs owned by another extension:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import {
|
|
65
|
+
registerExternalRun,
|
|
66
|
+
updateExternalRun,
|
|
67
|
+
unregisterExternalRun,
|
|
68
|
+
} from "pi-subagents/external-runs";
|
|
69
|
+
|
|
70
|
+
registerExternalRun({
|
|
71
|
+
id: "dependency-review",
|
|
72
|
+
sessionId: ctx.sessionManager.getSessionId(),
|
|
73
|
+
source: "interactive-shell",
|
|
74
|
+
label: "Dependency review",
|
|
75
|
+
state: "running",
|
|
76
|
+
startedAt: Date.now(),
|
|
77
|
+
currentAction: "Inspecting package metadata",
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
updateExternalRun(ctx.sessionManager.getSessionId(), "dependency-review", {
|
|
81
|
+
state: "completed",
|
|
82
|
+
updatedAt: Date.now(),
|
|
83
|
+
endedAt: Date.now(),
|
|
84
|
+
preview: "No dependency blockers found.",
|
|
85
|
+
reportPath: "/tmp/dependency-review.md",
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
unregisterExternalRun(ctx.sessionManager.getSessionId(), "dependency-review");
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The API validates and caches bounded display fields when the caller registers or updates a job. FleetView reads that cache only. It does not poll caller code. `snapshotExternalRuns(sessionId)` and `listExternalRuns(sessionId)` return bounded current-session snapshots. By default, malformed cached records throw with the validation error. Display-only Fleet callers can pass `{ ignoreMalformed: true, onMalformedRecord }` to remove bad records and keep rendering with a programmatic diagnostic.
|
|
92
|
+
|
|
93
|
+
External jobs are observational. The caller owns execution, persistence, cancellation, and result delivery. FleetView does not expose stop, steer, resume, cancel, or Herdr controls for them. Supplied report and transcript paths are shown as bounded text only; FleetView does not read arbitrary external paths.
|
|
94
|
+
|
|
59
95
|
## Launch contract preflight
|
|
60
96
|
|
|
61
97
|
Use `pi-subagents/preflight` when an extension needs to inspect the resolved child launch contract before deciding whether to run anything:
|
package/docs/missions.md
CHANGED
|
@@ -58,7 +58,7 @@ subagent({
|
|
|
58
58
|
})
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
After each parent turn, an idle goal mission sends one needs-attention notice with its title, remaining token budget, and next ready action. The action comes from `state.nextReadyAction`, `state.nextAction`, a state item with `status: "ready"`, an open decision, or linked-run state. A workflow can write `state.nextReadyAction` to tell the next notice exactly what work is ready. When the latest linked workflow has a
|
|
61
|
+
After each parent turn, an idle goal mission sends one needs-attention notice with its title, remaining token budget, and next ready action. The action comes from `state.nextReadyAction`, `state.nextAction`, a state item with `status: "ready"`, an open decision, or linked-run state. A workflow can write `state.nextReadyAction` to tell the next notice exactly what work is ready. When the latest linked workflow has a resumable retained child, the notice names that child as the `resume` target. Non-resumable retained children stay visible in `children.list` with their reason, but goal notices do not present them as resume targets. The extension never launches or replans goal work by itself.
|
|
62
62
|
|
|
63
63
|
Linked-run token totals are stored on each run and folded into mission `usage`. An active linked run suppresses notices. Reaching the token budget changes the goal status to `budget-exhausted` and stops notices without closing the mission or reporting success.
|
|
64
64
|
|
package/docs/observability.md
CHANGED
|
@@ -81,6 +81,22 @@ Without a TUI, `/subagents-fleet` retains the textual `subagent({ action: "statu
|
|
|
81
81
|
|
|
82
82
|
Use `/subagents-detach [run-id]` only for an active foreground single-subagent run you want to leave running without terminating; the eventual result remains available through status/wait.
|
|
83
83
|
|
|
84
|
+
Set `foregroundDetachShortcut` in `~/.pi/agent/extensions/subagent/config.json` to bind the same action to a shortcut. The running foreground card shows the configured shortcut beside its live-detail hint:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"foregroundDetachShortcut": "ctrl+b"
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Pi binds `Ctrl+B` to editor cursor-left by default. The extension shortcut takes precedence, but Pi reports the conflict at startup. To reserve the key without that warning, override the editor action in `~/.pi/agent/keybindings.json`:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"tui.editor.cursorLeft": "left"
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
84
100
|
If something feels misconfigured, run `/subagents-doctor` or ask: "Check whether subagents and intercom are set up correctly."
|
|
85
101
|
|
|
86
102
|
## Async run artifacts
|
package/docs/tool-reference.md
CHANGED
|
@@ -44,6 +44,7 @@ Parameters and actions for the `subagent` tool. These are what the LLM passes wh
|
|
|
44
44
|
| `async` | boolean | default-on | Background execution. Workflows default to background and accept `async:false` as an explicit foreground escape hatch. |
|
|
45
45
|
| `chatProgress` | `auto \| off \| live-card` | `auto` | WorkflowScript chat projection. `auto` renders a live in-chat card only for watched foreground workflows in the same Git repository, including managed worktrees; it is off otherwise. Explicit `live-card` requires `async:false` and the same Git repository. |
|
|
46
46
|
| `timeoutMs` / `maxRuntimeMs` | number | config `timeoutMs`, else 30 min foreground / single-agent async | Optional run-level max runtime in milliseconds. When omitted, the global [`timeoutMs`](configuration.md#timeoutms) config provides the default; absent that, foreground and plain single-agent async runs fall back to 30 minutes, while composite async runs (chains, parallel tasks, workflows) stay unbounded at the top level. |
|
|
47
|
+
| `toolTimeoutMs` | number | fast-tool default | Optional positive hard per-tool-call deadline in milliseconds. Precedence: call value → agent frontmatter → config → `PI_SUBAGENT_TOOL_TIMEOUT_MS`. The timer starts on `tool_execution_start`, clears on the matching `tool_execution_end`, and terminates the run with `timedOut: true` if the tool remains open. When omitted, known-fast built-in tools get a five-minute default; long-running tools get attention notices but no hard default. It never extends the run deadline; `contact_supervisor`, `intercom`, and `subagent_wait` are exempt. |
|
|
47
48
|
| `turnBudget` | object | none | Optional assistant-turn budget `{ maxTurns, graceTurns }`. At `maxTurns` the child is warned to wrap up. After the grace window (default 1), termination occurs at the next assistant boundary; a response that starts tool work records `termination-deferred` until a later boundary. Partial output is returned on abort. |
|
|
48
49
|
| `toolBudget` | object | none | Optional child tool-call budget `{ soft?, hard, block? }`. At `soft` the child is nudged to finalize. After `hard`, configured tools are blocked; `block` defaults to `read`, `grep`, `find`, and `ls`, while `"*"` blocks every tool call. Final assistant text is never blocked. |
|
|
49
50
|
| `usageBudget` | object | none | Optional root-only reported-usage budget `{ tokens?: { soft?, hard }, costUsd?: { soft?, hard } }`. Soft limits are status-only. Hard limits prevent later child launches after reported usage is reconciled; already-running children are not stopped and no reservations are made. |
|
|
@@ -86,7 +87,7 @@ Rendering only returns text to the sandbox. It does not give the script filesyst
|
|
|
86
87
|
|
|
87
88
|
### Retained children
|
|
88
89
|
|
|
89
|
-
Completed workflow children from the current parent session stay addressable as retained children. `{ action: "children.list" }` lists up to the last 10 with their run ids. A later workflow continues
|
|
90
|
+
Completed workflow children from the current parent session stay addressable as retained children. `{ action: "children.list" }` lists up to the last 10 with their run ids and explicit `resumable` or `not resumable` state. Resume only rows reported `resumable`; if no row is resumable, start a same-role fallback challenge and label it as fallback. A later workflow continues a resumable child by passing `resume` instead of `agent`:
|
|
90
91
|
|
|
91
92
|
```js
|
|
92
93
|
{ workflowScript: `
|
|
@@ -102,6 +103,8 @@ Completed workflow children from the current parent session stay addressable as
|
|
|
102
103
|
|
|
103
104
|
Inside `workflowScript`, `await runs.run(key, { resume, task })` waits for the revived child to finish and returns its completed output and new `runId`. Each resume can return a new retained run id, so loops must continue from the latest returned `runId`. Top-level `{ action: "resume" }` remains detached and returns a background-run receipt.
|
|
104
105
|
|
|
106
|
+
For a simple implementation challenge outside a workflow script, send the challenge through `subagent({ action: "resume", id: "<retained-writer-run>", message: "Reconsider the implementation and make any better current-scope change." })` only when `children.list` reports that retained writer as `resumable`. If no retained writer is resumable, start a same-role fallback challenge and record why it is a fallback. Use workflow `runs.run({ resume })` only when the script must await the revived writer output before the next step. Do not use `steer` as the sole challenge action for a completed retained child; `steer` with `mode: "follow_up"` only queues text for the next `resume`.
|
|
107
|
+
|
|
105
108
|
`resume` and `agent` are mutually exclusive. The revived child keeps its stored agent, model, and tool contract. `gate` is rejected on retained resume items because resume uses the retained child contract.
|
|
106
109
|
|
|
107
110
|
## Management actions
|
|
@@ -238,7 +241,7 @@ subagent({ action: "doctor" })
|
|
|
238
241
|
|
|
239
242
|
`steer` waits up to three seconds for a correlated child-Pi input acceptance and returns a request id with `delivered`, `scheduled`, `pending`, `partial`, `recovered`, or `failed` plus per-child states. The receipt also has `deliveryStatus: "delivered" | "queued"`. Delivery means Pi accepted the user message, not model compliance. A pending indexed child returns `scheduled`.
|
|
240
243
|
|
|
241
|
-
The optional `mode` is `steer` by default and keeps the current interrupt behavior. `follow_up` waits for the next turn boundary. `auto` queues during an active turn and delivers immediately between turns. The bounded FIFO holds 20 messages and returns a clear error when full. Terminal details report queued messages that the run did not deliver. A `follow_up` sent to a completed retained workflow child becomes the first brief for its next `resume
|
|
244
|
+
The optional `mode` is `steer` by default and keeps the current interrupt behavior. `follow_up` waits for the next turn boundary. `auto` queues during an active turn and delivers immediately between turns. The bounded FIFO holds 20 messages and returns a clear error when full. Terminal details report queued messages that the run did not deliver. A `follow_up` sent to a completed retained workflow child becomes the first brief for its next `resume`; it does not revive the child by itself.
|
|
242
245
|
|
|
243
246
|
Only a top-level single run may interrupt after the acknowledgment deadline and recover after a further 15-second pause/revival bound; durable multi-child and nested runs never auto-interrupt. Recovery launches a replacement only after the source is confirmed paused, a valid persisted session exists, and deadline, turn, and tool budgets remain. It preserves the original child contract and remaining limits; otherwise the source stays paused with an explicit failure. Late acceptance is recorded but cannot cancel committed recovery.
|
|
244
247
|
|
|
@@ -315,6 +318,20 @@ The parser canonicalizes known enum synonyms, snake_case report keys and wrapper
|
|
|
315
318
|
|
|
316
319
|
Acceptance fences are removed from normal output artifacts, while the raw child transcript remains intact and per-child metadata stores the complete acceptance ledger and parsed report. Explicit failed gates fail the run. Inferred gates remain observable without failing the run.
|
|
317
320
|
|
|
321
|
+
## Orca progress tabs (experimental observer)
|
|
322
|
+
|
|
323
|
+
Orca progress tabs are a global, opt-in observer, not an agent runner. Enable them in the extension config:
|
|
324
|
+
|
|
325
|
+
```json
|
|
326
|
+
{ "orcaProgressTabs": { "enabled": true } }
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Every foreground or background child keeps running through its normal native Pi or `external-cli` path. For each logical child, the observer asks Orca to create a background terminal tab in that child's current worktree and mirrors progress into it. Titles receive a persistent worktree-local sequence number, including across separate workflow calls. Model/startup retries reuse the same tab. Parallel and chain children each receive their own tab; attaching an already-running async root does not create a duplicate. Terminal control sequences are removed at the viewer sink across read boundaries. Each mirror is capped at 1 MiB and truncates when the cap or stream backpressure is reached. After the child finishes, its viewer returns to the terminal shell instead of ending the terminal session, so the tab and scrollback remain until the user closes them. Successful native Pi children with a known session append a safely quoted removal command for the exact verified session path; unsuccessful and sessionless children append only their terminal status.
|
|
330
|
+
|
|
331
|
+
The observer supports macOS and Linux and is disabled on Windows. It requires executable `orca` on `PATH` (or `PI_SUBAGENT_ORCA_BINARY`) and a running Orca runtime that recognizes the child cwd. Availability and tab creation are best-effort: failures never fail, stop, or delay the subagent. Set `orcaProgressTabs.enabled` to `false` to guarantee that no Orca command or tab is created.
|
|
332
|
+
|
|
333
|
+
Agent profile `runner.type` remains unchanged: supported values are native Pi (the default) and `external-cli`. Orca is intentionally not a profile runner and does not own subagent execution, completion, cancellation, artifacts, or result delivery.
|
|
334
|
+
|
|
318
335
|
## External CLI agent profiles
|
|
319
336
|
|
|
320
337
|
Agent profiles can opt into a local one-shot command instead of a Pi child. External runners add no install dependency, but the configured executable must exist at runtime. They are async-only, receive one combined system/task prompt over stdin, and use argv arrays without a shell:
|
package/docs/workflows.md
CHANGED
|
@@ -90,12 +90,12 @@ Configure the worktree base directory and setup hook in [configuration.md](confi
|
|
|
90
90
|
|
|
91
91
|
## Supervisor coordination (child asks parent)
|
|
92
92
|
|
|
93
|
-
Child agents can talk back to the parent Pi session without installing `pi-intercom`. `pi-subagents` provides the child-facing `contact_supervisor` tool and the parent-facing `subagent_supervisor({ action: "reply" })` path natively.
|
|
93
|
+
Child agents can talk back to the parent Pi session without installing `pi-intercom`. `pi-subagents` provides the child-facing `contact_supervisor` tool and the parent-facing `subagent_supervisor({ action: "reply" })` path natively. Generic `intercom` remains available only when an explicitly loaded external provider supplies it.
|
|
94
94
|
|
|
95
95
|
Use it for work where the child might need a decision instead of guessing:
|
|
96
96
|
|
|
97
97
|
```text
|
|
98
|
-
Run this implementation in the background. If the worker gets blocked or needs a product decision, have it ask me through
|
|
98
|
+
Run this implementation in the background. If the worker gets blocked or needs a product decision, have it ask me through the supervisor channel.
|
|
99
99
|
```
|
|
100
100
|
|
|
101
101
|
```text
|
package/package.json
CHANGED
|
@@ -61,7 +61,7 @@ Give subagents specific tasks rather than vague mandates.
|
|
|
61
61
|
|
|
62
62
|
### Escalate decisions upward
|
|
63
63
|
|
|
64
|
-
If a subagent encounters an unapproved product, architecture, scope, merge, release, credential, or authority choice, it should use `contact_supervisor` and wait for the reply instead of deciding alone. Generic `intercom` is
|
|
64
|
+
If a subagent encounters an unapproved product, architecture, scope, merge, release, credential, or authority choice, it should use `contact_supervisor` and wait for the reply instead of deciding alone. Generic `intercom` is external or provider-supplied only. Use it only when external bridge instructions provide an explicit safe target. External checks, receipts, and review bots provide evidence only; they do not grant authority.
|
|
65
65
|
|
|
66
66
|
### Intervene only on clear control signals
|
|
67
67
|
|
|
@@ -211,7 +211,8 @@ Use distinct keys, prompts, and output paths. Do not launch parallel writers int
|
|
|
211
211
|
**"Unknown agent"**
|
|
212
212
|
```typescript
|
|
213
213
|
subagent({ action: "list" })
|
|
214
|
-
// Check available agents
|
|
214
|
+
// Check available agents, then confirm scope/precedence. Saved chains are not a
|
|
215
|
+
// public execution surface; author orchestration with workflowScript.
|
|
215
216
|
```
|
|
216
217
|
|
|
217
218
|
**Setup, discovery, or intercom confusion**
|
|
@@ -72,7 +72,7 @@ Scripts run in a timed worker with only `runs.run`, `runs.all`, `runs.status`, `
|
|
|
72
72
|
|
|
73
73
|
For one host-run verification command, pass `gate: "npm test"` on a `runs.run`/`runs.all` item (or at the top level as a workflow default). It is shorthand for verified acceptance with that single command: the runtime executes it on the host, records the result as evidence, and memoizes it per tracked workspace state and effective environment. `gate` cannot be combined with `acceptance`; use explicit `acceptance.verify` for multiple commands or custom criteria.
|
|
74
74
|
|
|
75
|
-
Completed workflow children from this parent session stay addressable as retained children. `subagent({ action: "children.list" })` lists up to the last 10 with run ids
|
|
75
|
+
Completed workflow children from this parent session stay addressable as retained children. `subagent({ action: "children.list" })` lists up to the last 10 with run ids and reports each row as `resumable` or `not resumable` with a reason. Resume only rows reported `resumable`. For a retained-child challenge, use `resume` instead of `steer` when the child is complete. If no retained child is resumable, launch a same-role fallback challenge and label it as fallback. A later workflow continues a resumable child with `runs.run(key, { resume: "<run-id>", task: "follow-up" })`. Inside `workflowScript`, awaiting that call waits for the revived child to finish and returns its completed output and new `runId`; top-level `{ action: "resume" }` remains detached. A follow-up loop can render each task with `await prompts.render(...)`. Assign each returned child result back to the loop variable because every resume can return a new retained `runId`; always resume the latest returned id. `resume` and `agent` are mutually exclusive, the revived child keeps its stored agent/model/tool contract, and `gate` is rejected on retained resume items.
|
|
76
76
|
|
|
77
77
|
### Async/background
|
|
78
78
|
|
|
@@ -287,7 +287,7 @@ Use `mission.update` while work runs to record decisions, artifacts, labels, sum
|
|
|
287
287
|
- **Use `missionId` for follow-up work.** Attach later work to an existing objective with `missionId`; attachment re-marks the mission active. `missionId` and `mission` are mutually exclusive. Explicit attachment fails before launch if the mission is missing, while automatic missions degrade to `details.missionWarning` without blocking the run.
|
|
288
288
|
- **Keep `state` small.** Mission `state` is JSON coordination across workflows on the same mission. Keys use the same format as run keys, values must be JSON, and the whole state file is capped at 256 KiB. Each `set` merges one key under a file lock. Put large content in artifact files and store paths in state. In goal missions, write `state.set("nextReadyAction", "...")` so the next idle-turn notice names the exact ready step.
|
|
289
289
|
- **Use artifacts and receipts as evidence.** Mission-backed launches already record run artifacts such as async `status.json`, `events.jsonl`, child output paths, and handoff manifests. Add `mission.update` artifacts only for extra durable outputs such as `patch`, `review`, or `note` files. Add receipts for external outcomes: `pull_request`, `ci`, `deployment`, or `release`; each receipt needs an absolute URL. Receipts are evidence, not authority to merge, deploy, or release.
|
|
290
|
-
- **
|
|
290
|
+
- **Resolve decisions explicitly.** `mission.update` `decisions` can only add open decisions; `mission.update` itself cannot resolve one — use the `mission.resolve-decision` action (decision `id` plus a non-empty `summary`) to settle and close it. In a goal mission, an unresolved decision becomes the fallback next ready action in each notice. Use decisions sparingly there; record them for escalation and audit, steer goal continuation through `state.nextReadyAction`, and close the mission when the question is settled.
|
|
291
291
|
- **Close missions when done.** `mission.close` takes `missionStatus` `completed`, `failed`, or `cancelled` plus a concise `summary`, and ends any goal loop. Goal notices go only to the owning session and stop silently at `budget-exhausted` without closing or claiming success, so close explicitly. Terminal missions are pruned beyond configured retention, so store durable outputs as artifacts, receipts, and summary before closing.
|
|
292
292
|
|
|
293
293
|
After compaction, restart, or confusing history, recover from durable state first: `mission.list` in the project, `mission.list` with `missionScope: "global"` for the user-local cross-project pointer index, then `mission.show` for the relevant mission. `mission.show` refreshes linked async status when available and returns warnings instead of hiding the mission if a linked status file is temporarily unreadable. Use the linked run ids with normal `status`, `steer`, `resume`, or `stop` actions. Project mission JSON remains authoritative over chat history.
|
|
@@ -305,6 +305,7 @@ subagent({ action: "mission.create", mission: { title: "Ship auth refresh", obje
|
|
|
305
305
|
subagent({ workflowScript: `return runs.run("main", { agent: "worker", task: "Implement the approved plan" })`, missionId: "<mission-id>" })
|
|
306
306
|
subagent({ workflowScript: `return runs.run("main", { agent: "scout", task: "Quickly answer whether this file exists" })`, mission: false })
|
|
307
307
|
subagent({ action: "mission.list", missionScope: "global" })
|
|
308
|
+
subagent({ action: "mission.resolve-decision", missionId: "<mission-id>", id: "<decision-id>", summary: "Settled: ship the v2 API; no schema freeze needed." })
|
|
308
309
|
subagent({ action: "project.open", cwd: "/path/to/other-repo", message: "Own this mission for the project and report back with receipts." })
|
|
309
310
|
subagent({ action: "project.status", cwd: "/path/to/other-repo" })
|
|
310
311
|
subagent({ action: "project.close", cwd: "/path/to/other-repo" })
|
|
@@ -381,7 +382,7 @@ Use `oracle` as a smart-friend escalation when the parent needs help with trajec
|
|
|
381
382
|
|
|
382
383
|
This is separate from optional external completion delivery. Set `intercomBridge.resultDelivery: true` only when an external listener consumes and acknowledges `subagent:result-intercom` grouped results. It does not deliver results by itself, and it does not change native supervisor asks or progress updates.
|
|
383
384
|
|
|
384
|
-
|
|
385
|
+
Generic `intercom` is external or provider-supplied only. Native supervisor coordination injects `contact_supervisor`, not generic `intercom`. Use generic `intercom` only when external bridge instructions provide an explicit safe target. Do not invent a target. Prefer the tool from the injected bridge instructions.
|
|
385
386
|
|
|
386
387
|
Use `contact_supervisor` with `reason: "need_decision"` when:
|
|
387
388
|
- a subagent is blocked on a decision
|
|
@@ -423,6 +424,6 @@ Or inspects unresolved asks first:
|
|
|
423
424
|
subagent_supervisor({ action: "pending" })
|
|
424
425
|
```
|
|
425
426
|
|
|
426
|
-
|
|
427
|
+
Native supervisor coordination does not expose generic `intercom` as a fallback. Use `subagent_supervisor` for parent replies.
|
|
427
428
|
|
|
428
429
|
If intercom messages do not show up, run `subagent({ action: "doctor" })` or `/subagents-doctor`.
|
|
@@ -18,7 +18,7 @@ subagent({ action: "list" })
|
|
|
18
18
|
subagent({ action: "children.list" })
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Lists up to the last 10
|
|
21
|
+
Lists up to the last 10 retained workflow children from this parent session with explicit `resumable` or `not resumable` rows. Resume only rows reported `resumable`. Send a simple follow-up or implementation challenge with `subagent({ action: "resume", id: "<run-id>", message: "..." })`. Continue one inside a workflow with `runs.run(key, { resume: "<run-id>", task: "follow-up" })`; the revived child keeps its stored agent, model, and tool contract. If no resumable child is listed, start a same-role fallback challenge and label it as fallback. `steer` with `mode: "follow_up"` only queues text for the next `resume` when the child has already completed.
|
|
22
22
|
|
|
23
23
|
### Refinement overlays
|
|
24
24
|
|
|
@@ -158,4 +158,4 @@ Additional user prompt templates can delegate into `pi-subagents` through the na
|
|
|
158
158
|
|
|
159
159
|
Other Pi extensions can call `pi-subagents` through the in-process event bus. The RPC channels are `subagents:rpc:v1:ready`, `subagents:rpc:v1:request`, and per-request replies at `subagents:rpc:v1:reply:<requestId>`. Envelopes use `{ version: 1, requestId, method, params }`, and replies use `{ version: 1, requestId, success, data | error }`. `ping` advertises the exact process-local async completion event as `events.asyncComplete` for RPC-spawn consumers.
|
|
160
160
|
|
|
161
|
-
Methods: `ping`, `status`, `spawn`, `steer`, `interrupt`, `resume`, and `stop`. `ping` capability metadata advertises optional projections: `capabilities.fleetStatus: { version: 1 }` adds bounded current-session `data.fleet` records (opaque reconciliation `key`, resolved `agent`, optional `role`, `model`, `effort`, caller-facing `goal`, `startedAt`, split `{ input, output, total }` tokens, plus `totalActive`/`omitted` overflow counts) to successful `status` replies; `capabilities.launchResolvedExtensions` advertises parent-resolved opaque launch-extension identifiers in status details; `capabilities.runtimeAcknowledgedExtensions` advertises the best-effort child-runtime acknowledgement projection fed by cooperating extensions emitting `subagent:acknowledge-extension`. Foreground `details.results[]` rows carry a stable numeric `index`; correlate children by `(runId, index)` rather than row position. Consumers should read status/result artifacts and RPC projections instead of scraping terminal output and must ignore unknown fields. `spawn` requires `workflowScript`, is async-only, and rejects management actions, `async: false`, or `clarify: true`; it reuses the normal executor, so discovery, validation, session attribution, configured spawn caps, child-safety depth, artifacts, and async status are shared with the `subagent` tool. `status`, acknowledged async `steer`, and `interrupt` map to the normal control actions. RPC steer disables pause-and-revive recovery and advertises `capabilities.nonRecoveringSteer`, preserving the caller's authority over the exact spawned child. `resume` requires a target plus non-empty message and delegates to the package-owned revival path; it may set a caller-owned `file-only` output path but cannot override the persisted child model, tools, budgets, session ownership, or exclusive session lease. `stop` targets running async runs through the existing timeout control channel. `pi.events` is process-local, so separate Pi processes and child subagents need lifecycle artifact files or `pi-intercom` instead.
|
|
161
|
+
Methods: `ping`, `status`, `spawn`, `steer`, `interrupt`, `resume`, and `stop`. `ping` capability metadata advertises optional projections: `capabilities.fleetStatus: { version: 1 }` adds bounded current-session `data.fleet` records (opaque reconciliation `key`, resolved `agent`, optional `role`, `model`, `effort`, caller-facing `goal`, `startedAt`, split `{ input, output, total }` tokens, plus `totalActive`/`omitted` overflow counts) to successful `status` replies; `capabilities.launchResolvedExtensions` advertises parent-resolved opaque launch-extension identifiers in status details; `capabilities.runtimeAcknowledgedExtensions` advertises the best-effort child-runtime acknowledgement projection fed by cooperating extensions emitting `subagent:acknowledge-extension`. Foreground `details.results[]` rows carry a stable numeric `index`; correlate children by `(runId, index)` rather than row position. Consumers should read status/result artifacts and RPC projections instead of scraping terminal output and must ignore unknown fields. `spawn` requires `workflowScript`, is async-only, and rejects management actions, `async: false`, or `clarify: true`; it reuses the normal executor, so discovery, validation, session attribution, configured spawn caps, child-safety depth, artifacts, and async status are shared with the `subagent` tool. `status`, acknowledged async `steer`, and `interrupt` map to the normal control actions. RPC steer disables pause-and-revive recovery and advertises `capabilities.nonRecoveringSteer`, preserving the caller's authority over the exact spawned child. `resume` requires a target plus non-empty message and delegates to the package-owned revival path; it may set a caller-owned `file-only` output path but cannot override the persisted child model, tools, budgets, session ownership, or exclusive session lease. For retained-child workflows, list children first and resume only rows reported `resumable`; otherwise start a same-role fallback challenge and label it as fallback. `stop` targets running async runs through the existing timeout control channel. `pi.events` is process-local, so separate Pi processes and child subagents need lifecycle artifact files or `pi-intercom` instead.
|
|
@@ -101,13 +101,13 @@ Use this after implementation when the user wants cleanup review or when a final
|
|
|
101
101
|
|
|
102
102
|
### Staged fix orchestration technique
|
|
103
103
|
|
|
104
|
-
Use this when a broad diff has known reviewer findings across several items and the user wants the parent to “orchestrate subagents like a boss.” Keep the active worktree safe with a three-stage
|
|
104
|
+
Use this when a broad diff has known reviewer findings across several items and the user wants the parent to “orchestrate subagents like a boss.” Keep the active worktree safe with a three-stage `workflowScript`:
|
|
105
105
|
|
|
106
106
|
1. A parallel read-only planning fanout, one reviewer per issue cluster. Each child inspects the real diff and returns exact files, line refs, proposed fixes, and focused validation. They must not edit.
|
|
107
|
-
2. One writer worker. It receives the reviewer summaries
|
|
107
|
+
2. One writer worker. It receives the reviewer summaries as the awaited planning results (or their durable output paths) interpolated into its task, plus the parent’s accepted scope, stop rules, and verification contract. It is the only child allowed to edit the active worktree.
|
|
108
108
|
3. A parallel read-only validation fanout. Validators inspect the worker diff from fresh context with distinct angles, report pass/fail, remaining blockers, and missing verification.
|
|
109
109
|
|
|
110
|
-
Prefer `async: true`, `context: "fresh"` for reviewers/validators, `outputMode: "file-only"` for large summaries, and per-stage output names that will not collide.
|
|
110
|
+
Prefer `async: true`, `context: "fresh"` for reviewers/validators, `outputMode: "file-only"` for large summaries, and per-stage output names that will not collide. Use stable `runs` keys plus `phase` and `label` on each launch item to make async status readable, and hold each awaited result in an ordinary JavaScript variable when a later step needs that specific result — interpolate it (or the durable output path you declared for that child) into the later task text instead of passing a whole aggregate blob. Use this pattern instead of launching several writer workers into a dirty worktree. Include non-blocking suggestions in the writer prompt only when they are small, safe, and do not expand product scope; otherwise record them as deferred.
|
|
111
111
|
|
|
112
112
|
When one child returns a structured target list, use ordinary JavaScript to validate/filter it and map bounded entries into `runs.all`; do not use the removed chain fanout DSL.
|
|
113
113
|
|
|
@@ -117,18 +117,34 @@ Example shape:
|
|
|
117
117
|
subagent({
|
|
118
118
|
async: true,
|
|
119
119
|
context: "fresh",
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
{ agent: "reviewer", phase: "Planning", label: "
|
|
124
|
-
{ agent: "reviewer", phase: "Planning", label: "
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
120
|
+
workflowScript: `
|
|
121
|
+
// Stage 1: parallel read-only planning fanout (stable keys, one per issue cluster)
|
|
122
|
+
const plans = await runs.all([
|
|
123
|
+
{ key: "deploy-plan", agent: "reviewer", phase: "Planning", label: "Deploy docs", task: "Plan fixes for deploy docs/workflow. Inspect the current diff. Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "plans/deploy.md", outputMode: "file-only" },
|
|
124
|
+
{ key: "scheduler-plan", agent: "reviewer", phase: "Planning", label: "Scheduler contract", task: "Plan fixes for scheduler contract. Inspect the current diff. Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "plans/scheduler.md", outputMode: "file-only" },
|
|
125
|
+
{ key: "sandbox-plan", agent: "reviewer", phase: "Planning", label: "Sandbox/security", task: "Plan fixes for sandbox/security. Inspect the current diff. Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "plans/sandbox.md", outputMode: "file-only" }
|
|
126
|
+
]);
|
|
127
|
+
|
|
128
|
+
// Stage 2: single writer — the only child allowed to edit the active worktree.
|
|
129
|
+
// Under outputMode "file-only" the awaited .output is the saved-output
|
|
130
|
+
// reference, so pass the durable paths declared above to the writer.
|
|
131
|
+
const worker = await runs.run("apply-fixes", {
|
|
132
|
+
agent: "worker",
|
|
133
|
+
phase: "Implementation",
|
|
134
|
+
label: "Apply accepted fixes",
|
|
135
|
+
task: "Apply only the accepted fixes from these planning summaries. You are the sole writer for the active worktree. Run focused validation and report changed files, commands, failures, and remaining issues.\\n\\nDeploy plan: plans/deploy.md\\n\\nScheduler plan: plans/scheduler.md\\n\\nSandbox plan: plans/sandbox.md",
|
|
136
|
+
output: "worker/fixes.md",
|
|
137
|
+
outputMode: "file-only"
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Stage 3: parallel read-only validation fanout
|
|
141
|
+
const validations = await runs.all([
|
|
142
|
+
{ key: "validate-deploy-scheduler", agent: "reviewer", phase: "Validation", label: "Deploy/scheduler validation", task: "Validate the post-worker diff for deploy and scheduler fixes. Start from the worker result: " + worker.output + " (also worker/fixes.md). Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "validation/deploy-scheduler.md", outputMode: "file-only" },
|
|
143
|
+
{ key: "validate-sandbox", agent: "reviewer", phase: "Validation", label: "Sandbox validation", task: "Validate the post-worker diff for sandbox/security fixes. Start from the worker result: " + worker.output + " (also worker/fixes.md). Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "validation/sandbox.md", outputMode: "file-only" }
|
|
144
|
+
]);
|
|
145
|
+
|
|
146
|
+
return { worker: worker.output, validations: validations.map(v => v.output) };
|
|
147
|
+
`
|
|
132
148
|
})
|
|
133
149
|
```
|
|
134
150
|
|