pi-subagents 0.54.0 → 0.55.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 -1
- package/agents/reviewer.md +12 -2
- package/docs/agents.md +4 -4
- package/docs/configuration.md +4 -4
- package/docs/extension-api.md +14 -4
- package/docs/models.md +24 -3
- package/docs/observability.md +14 -3
- package/docs/tool-reference.md +21 -6
- package/docs/workflows.md +7 -1
- package/package.json +1 -1
- package/prompts/council.md +9 -0
- package/prompts/parallel-review.md +5 -1
- package/prompts/review-loop.md +9 -5
- package/skills/council-mode/SKILL.md +33 -10
- package/skills/pi-subagents/references/constraints-and-recipes.md +16 -1
- package/skills/pi-subagents/references/execution-controls.md +11 -4
- package/skills/pi-subagents/references/multi-lane-orchestration.md +3 -3
- package/skills/pi-subagents/references/prompting-and-roles.md +8 -8
- package/src/agents/agent-management.ts +30 -9
- package/src/agents/agent-serializer.ts +2 -2
- package/src/agents/agents.ts +146 -41
- package/src/api/external-job-provider.ts +10 -1
- package/src/api/preflight.ts +26 -17
- package/src/api/project-panes.ts +2 -0
- package/src/extension/index.ts +20 -1
- package/src/extension/public-execution.ts +12 -9
- package/src/extension/rpc.ts +77 -3
- package/src/extension/schemas.ts +2 -1
- package/src/extension/tool-description.ts +9 -6
- package/src/inspectors/herdr/focus.ts +55 -0
- package/src/inspectors/herdr/project-panes.ts +228 -44
- package/src/integrations/herdr-status.ts +26 -4
- package/src/runs/background/async-execution.ts +103 -9
- package/src/runs/background/async-job-tracker.ts +33 -14
- package/src/runs/background/async-resume.ts +20 -2
- package/src/runs/background/async-status.ts +10 -0
- package/src/runs/background/control-channel.ts +98 -10
- package/src/runs/background/notify.ts +62 -1
- package/src/runs/background/run-status.ts +15 -1
- package/src/runs/background/subagent-runner.ts +226 -37
- package/src/runs/foreground/async-stop-action.ts +23 -2
- package/src/runs/foreground/execution.ts +81 -7
- package/src/runs/foreground/subagent-executor.ts +348 -40
- package/src/runs/foreground/workflow-detach-reconcile.ts +3 -0
- package/src/runs/shared/acceptance.ts +1 -0
- package/src/runs/shared/child-identity.ts +36 -0
- package/src/runs/shared/completion-guard.ts +50 -1
- package/src/runs/shared/external-job-bridge.ts +53 -37
- package/src/runs/shared/external-job-runner.ts +126 -23
- package/src/runs/shared/model-fallback.ts +10 -0
- package/src/runs/shared/orca-progress-tabs.ts +71 -9
- package/src/runs/shared/parallel-utils.ts +12 -0
- package/src/runs/shared/pi-args.ts +9 -12
- package/src/runs/shared/subagent-prompt-runtime.ts +3 -1
- package/src/runs/shared/tool-availability.ts +1 -3
- package/src/shared/launch-contract.ts +6 -5
- package/src/shared/thinking-ceiling.ts +52 -0
- package/src/shared/types.ts +59 -2
- package/src/tui/fleet-status.ts +66 -13
- package/src/tui/render.ts +5 -4
- package/src/workflows/scripted-workflow.ts +107 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,40 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [
|
|
3
|
+
## [0.55.0] - 2026-08-23
|
|
4
|
+
|
|
5
|
+
### Highlights
|
|
6
|
+
- Stop a single stuck child in an async workflow without stopping the whole run.
|
|
7
|
+
- Continue finished external jobs, like Surf's `gpt-pro`, with follow-up requests through `resume`.
|
|
8
|
+
- Cap child thinking with `subagents.maxThinking` and set a preferred default provider for bare model ids.
|
|
9
|
+
- Scripted workflow outputs now land in the run's managed artifact directory instead of the repository root.
|
|
10
|
+
- Child launches fail fast with clear reasons when requested models or write tools are unavailable.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Add `subagents.maxThinking` to enforce a thinking ceiling across native subagent launches. Thanks to [@alex-real14](https://github.com/alex-real14) for #1397.
|
|
14
|
+
- Add `subagents.defaultProvider` and per-agent `defaultProvider` overrides so bare subagent model ids can prefer a configured provider. Thanks to [@swingtempo](https://github.com/swingtempo) for #1393.
|
|
15
|
+
- Add external-job follow-ups through `subagent({ action: "resume" })` for completed provider jobs that expose `followUp(input)`, with duplicate request dedupe, durable parent-job lineage (#1381), and clearer errors when a follow-up cannot start.
|
|
16
|
+
- Add child-scoped stop support and child stop observer events for async/workflow runs. Malformed child stop requests are rejected instead of widening to a run-level stop. Thanks to [@yanqianglu](https://github.com/yanqianglu) for #1367.
|
|
17
|
+
- Create one passive Orca observer tab per top-level subagent call, with shared chain/parallel progress and project-local observer manifests. Thanks to [@hyein-cbio](https://github.com/hyein-cbio) for #1360.
|
|
18
|
+
- Count Herdr project panes in inline status and report compact Herdr pane title suffixes for active subagent work.
|
|
19
|
+
- Let `agentOverrides` set or clear default `output` paths and `defaultReads`, while preserving explicit custom-agent frontmatter and preventing settings-derived values from being serialized into custom definitions. Thanks to [@mevatron](https://github.com/mevatron) for #1349.
|
|
20
|
+
- Surface copyable `provider/id` model selectors from `{ action: "models" }` and point invalid model warnings at that discovery path. Thanks to [@lixinglong27](https://github.com/lixinglong27) for #1365.
|
|
21
|
+
- Add bundled skill guidance for lightweight task profiles before subagent fanout. Thanks to [@srcKod](https://github.com/srcKod) for #1395.
|
|
22
|
+
- Add delegated review guidance that separates evidence requirements from severity labels so first-pass reviews do not default to `blockers only`.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- Route relative `workflowScript` output paths through managed artifacts instead of creating report files in the repository root.
|
|
26
|
+
- Keep the async widget spinner and elapsed timer moving while the parent is idle by routing animation ticks through the live widget rebuild path. Thanks to [@0xFlo](https://github.com/0xFlo) for #1390.
|
|
27
|
+
- Slow async widget animation rerenders to 1 Hz so quiet running jobs do not repaint the full TUI at the liveness tick rate. Thanks to [@0xFlo](https://github.com/0xFlo) for #1376.
|
|
28
|
+
- Fail a Pi child launch when the child reports a different provider/model than the resolved requested model. Thanks to [@zzzubair](https://github.com/zzzubair) for #1377.
|
|
29
|
+
- Render detached workflow supervisor handoffs as paused/waiting and include workflow and child run ids in completion notifications.
|
|
30
|
+
- Report implementation runs blocked by missing child tools as blocked mutation effects instead of no-edit completion guard failures.
|
|
31
|
+
- Fail child launch attempts when the runtime lacks requested core write tools or an implementation worker has only read-only launch tools, including workflow children that inherit a read-only capability ceiling.
|
|
32
|
+
- Let read-only reviewer acceptance rely on the parent-side staged-file check instead of requiring child-reported `noStagedFiles` evidence.
|
|
33
|
+
- Run public single-child launches directly instead of wrapping them in a workflow, so async external-job agents do not show a completed workflow before the real provider job finishes.
|
|
34
|
+
- Start omitted-`async` public external-runner single-child launches in the supported background mode, so package agents such as Surf's `gpt-pro` do not fail as foreground requests.
|
|
35
|
+
- Let workflow scripts await omitted-`async` external-runner children by launching them in the background internally and returning their terminal result.
|
|
36
|
+
- Report helpful workflow errors when `runs.all(...)` results are read as keyed objects instead of ordered arrays. Thanks to [@ravshansbox](https://github.com/ravshansbox) for #1351.
|
|
37
|
+
- Clarify that Council Mode can include installed external-runner advisors such as Surf's `gpt-pro` when the `surf-cli` Pi extension has registered `surf-oracle`, with text JSON reports instead of `outputSchema`.
|
|
4
38
|
|
|
5
39
|
## [0.54.0] - 2026-08-21
|
|
6
40
|
|
package/agents/reviewer.md
CHANGED
|
@@ -72,8 +72,18 @@ Structure your findings clearly:
|
|
|
72
72
|
## Review
|
|
73
73
|
- Correct: what is already good (with evidence)
|
|
74
74
|
- Fixed: issue, location, and resolution (if you applied a fix)
|
|
75
|
-
-
|
|
76
|
-
-
|
|
75
|
+
- Finding: P0/P1/P2, issue, location, evidence, and smallest fix
|
|
76
|
+
- Merge verdict: BLOCK, OK, or OK with notes
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
When reviewing code, cite file paths and line numbers. When reviewing plans, cite specific sections and assumptions.
|
|
80
|
+
|
|
81
|
+
Filter findings by evidence, not by severity. Report only concrete current issues
|
|
82
|
+
that are caused or made reachable by the target diff, and support each one with
|
|
83
|
+
source proof, a test or repro, or a contract contradiction. Use P0 for issues
|
|
84
|
+
that block merge, P1 for issues that should be fixed before release, and P2 for
|
|
85
|
+
report-only notes. Say exactly `No issues found.` when nothing qualifies.
|
|
86
|
+
|
|
87
|
+
Use `blockers only` only for a final pre-merge re-check after the P1/P2
|
|
88
|
+
inventory is already captured, or for an explicit emergency hotfix where the
|
|
89
|
+
parent intentionally defers non-blocking findings.
|
package/docs/agents.md
CHANGED
|
@@ -80,9 +80,9 @@ Native `oracle` runs inside Pi and can use its configured read tools. `claude-ad
|
|
|
80
80
|
|
|
81
81
|
| Durable file | Owner | States | Release predicate | Rollback predicate | Stale-head behavior | Fail-closed cases |
|
|
82
82
|
|--------------|-------|--------|-------------------|--------------------|---------------------|-------------------|
|
|
83
|
-
| `status.json` step `runner` and `externalJob` | pi-subagents async runner | `queued`, `running`, `completed`, `failed`, `stopped`, `blocked` | Provider `result` returns terminal data and the async result is written | Provider start/status/result/reattach returns an error | If a status file already has a provider job id, recovery calls `reattach` and `result`; it refuses to start a new prompt when the provider
|
|
83
|
+
| `status.json` step `runner` and `externalJob` | pi-subagents async runner | `queued`, `running`, `completed`, `failed`, `stopped`, `blocked` | Provider `result` returns terminal data and the async result is written | Provider start/follow-up/status/result/reattach returns an error | If a status file already has a provider job id, recovery calls `reattach` and `result`; it refuses to start a new prompt when the provider, prompt digest, parent job id, request id, request digest, or options differ | Missing provider, unsupported follow-up provider, capacity conflict, malformed provider response, bridge timeout, prompt digest mismatch, parent conversation missing |
|
|
84
84
|
| `result.json` or session result payload | pi-subagents async runner | `complete`, `failed`, `stopped` | All steps reach terminal state and result publication succeeds or is recoverably indexed | Result write fails and pending result repair records the terminal state | Stale status can repair from an existing result file | Unindexed sessionless stale failure |
|
|
85
|
-
| `external-job-requests/` and `external-job-responses/` | Host-mediated provider bridge | pending request, terminal response | Host process writes a matching response and removes the request | Bridge timeout or malformed request response | Requests are operation-scoped. Recovery sends `reattach`/`result`, not `start`, when job metadata exists | Provider not registered, host bridge not loaded, malformed request, provider exception |
|
|
85
|
+
| `external-job-requests/` and `external-job-responses/` | Host-mediated provider bridge | pending request, terminal response | Host process writes a matching response and removes the request | Bridge timeout or malformed request response | Requests are operation-scoped. Recovery sends `reattach`/`result`, not `start` or `follow-up`, when job metadata exists. `start` and `follow-up` use durable dispatch claims | Provider not registered, host bridge not loaded, malformed request, provider exception, ambiguous dispatch without a provider job id |
|
|
86
86
|
| Provider artifact path | External provider | provider-defined terminal artifact | Provider returns `artifactPath`, or Pi writes returned text to `external-job-<index>.result.md` | Provider reports failure or no result | Existing artifact path is retained in `status.json` | Missing artifact with no text output returns a terminal message instead of inventing content |
|
|
87
87
|
|
|
88
88
|
The `researcher` builtin uses `web_search`, `fetch_content`, and `get_search_content`. Those require [pi-web-access](https://github.com/nicobailon/pi-web-access):
|
|
@@ -111,10 +111,10 @@ You can override selected builtin fields without copying the whole agent. Overri
|
|
|
111
111
|
}
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
-
Supported override fields: `description`, `model`, `fallbackModels`, `thinking`, `systemPromptMode`, `inheritProjectContext`, `inheritSkills`, `defaultContext`, `acceptanceRole`, `disabled`, `skills`, `tools`, and `systemPrompt`.
|
|
114
|
+
Supported override fields: `description`, `output`, `outputMode`, `defaultReads`, `model`, `defaultProvider`, `fallbackModels`, `thinking`, `systemPromptMode`, `inheritProjectContext`, `inheritSkills`, `defaultContext`, `acceptanceRole`, `disabled`, `skills`, `tools`, and `systemPrompt`.
|
|
115
115
|
|
|
116
116
|
- `description` replaces the discovered description for builtin and custom agents, which lets list output show deployment-specific routing or model metadata.
|
|
117
|
-
- Use `
|
|
117
|
+
- Use `output: false`, `defaultReads: false`, `defaultContext: false`, or `acceptanceRole: false` to clear an inherited value.
|
|
118
118
|
- Use `tools: "inherit"` on a builtin when that one role should omit its bundled tool allowlist and receive Pi's normal builtins and ambient extensions. This keeps strict tools as the default for other builtins.
|
|
119
119
|
- Project overrides beat user overrides.
|
|
120
120
|
- Matching user and project agents also receive override fields that their frontmatter leaves unset, so a shared project config agent can keep the persona while local settings choose the model.
|
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`, `defaultThinking`, `defaultExtensions`, `agentOverrides`, `modelScope`, `disableThinking`, `disableBuiltins`, watchdog settings) live in Pi settings files, not this config file. `modelScope.agents.<name>` adds per-agent restrictions, and `allow: ["inherit"]` permits the current parent model. See [models.md](models.md), [agents.md](agents.md), and [watchdog.md](watchdog.md).
|
|
5
|
+
Settings-level keys (`subagents.defaultModel`, `defaultProvider`, `defaultThinking`, `defaultExtensions`, `agentOverrides`, `modelScope`, `disableThinking`, `disableBuiltins`, watchdog settings) live in Pi settings files, not this config file. `modelScope.agents.<name>` adds per-agent restrictions, and `allow: ["inherit"]` permits the current parent model. See [models.md](models.md), [agents.md](agents.md), and [watchdog.md](watchdog.md).
|
|
6
6
|
|
|
7
7
|
## Project root resolution (settings)
|
|
8
8
|
|
|
@@ -85,11 +85,11 @@ Pi binds `Ctrl+B` to editor cursor-left by default. The extension shortcut takes
|
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
Opt in to a best-effort Orca observer that creates one Orca terminal tab for each subagent
|
|
88
|
+
Opt in to a best-effort Orca observer that creates one Orca terminal tab for each top-level subagent call and mirrors the run's live tool, assistant, stdout, and stderr progress. Parallel and chain children share that one tab, with child section headers in the mirrored log. Tab titles use a persistent worktree-local sequence (`subagents · <run-label> · 1`, `... · 2`, and so on), so separate top-level calls do not reuse the same number. For the same worktree, `orca terminal create` runs one at a time in that sequence so observer tabs appear from left to right as `1`, then `2`, then `3`. This does **not** replace Pi as the 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.
|
|
89
89
|
|
|
90
|
-
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.
|
|
90
|
+
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. A passive observer manifest is also written under `<worktree>/.pi/subagents/views/orca/` when possible so future view surfaces can discover the Orca tab without making Orca authoritative.
|
|
91
91
|
|
|
92
|
-
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
|
|
92
|
+
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 run 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 run with a recorded session ends with a safely quoted `rm -- <exact-session-path>` command; failed, stopped, timed-out, and sessionless runs do not show the removal command.
|
|
93
93
|
|
|
94
94
|
## `asyncByDefault`
|
|
95
95
|
|
package/docs/extension-api.md
CHANGED
|
@@ -28,7 +28,7 @@ The RPC methods are `ping`, `status`, `manage`, `spawn`, `steer`, `interrupt`, `
|
|
|
28
28
|
Method notes:
|
|
29
29
|
|
|
30
30
|
- `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.
|
|
31
|
-
- `spawn`
|
|
31
|
+
- `spawn` accepts structured single-child execution (`agent`, `task?`) or `workflowScript` and is async-only: omit `async` or set `async: true`, omit `clarify`, and do not pass management `action` values. 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.
|
|
32
32
|
- `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.
|
|
33
33
|
- `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.
|
|
34
34
|
- `stop` targets current-session top-level async runs through the stop control channel and records a `stopped` lifecycle instead of reporting a timeout.
|
|
@@ -275,6 +275,7 @@ import { registerExternalJobProvider } from "pi-subagents/external-job-provider"
|
|
|
275
275
|
const dispose = registerExternalJobProvider({
|
|
276
276
|
name: "surf-oracle",
|
|
277
277
|
start: ({ prompt, promptDigest, cwd, runId, stepIndex, agent, options }) => startSurfJob({ prompt, promptDigest, cwd, runId, stepIndex, agent, options }),
|
|
278
|
+
followUp: ({ prompt, parentProviderJobId, requestId, requestDigest, options }) => followUpSurfJob({ prompt, parentProviderJobId, requestId, requestDigest, options }),
|
|
278
279
|
status: (providerJobId) => getSurfJobStatus(providerJobId),
|
|
279
280
|
result: (providerJobId) => getSurfJobResult(providerJobId),
|
|
280
281
|
reattach: (providerJobId) => reattachSurfJob(providerJobId),
|
|
@@ -283,7 +284,9 @@ const dispose = registerExternalJobProvider({
|
|
|
283
284
|
|
|
284
285
|
The provider returns handles with `providerJobId`, `state`, optional `handleUrl`/`conversationUrl`, optional `failureCode`/`failureMessage`, and optional `blockingJobId` for capacity conflicts. `result` can also return `output` and/or `artifactPath`.
|
|
285
286
|
|
|
286
|
-
|
|
287
|
+
`followUp(input)` is optional. When it is present, a completed external-job run can be continued with `subagent({ action: "resume", id: "<run>", message: "..." })`. Pi sends the completed parent provider job id plus a stable `requestId` and `requestDigest`. The provider must continue that parent conversation or fail closed. It must not open a fresh thread when the parent conversation is missing.
|
|
288
|
+
|
|
289
|
+
The async runner process does not import provider internals. It writes operation requests into its async run directory. The parent Pi process services those requests against the registered provider and writes operation responses. If the provider is not registered, the bridge fails closed with an actionable error. If a run is recovered after provider job metadata exists, the runner calls `reattach` and `result`; it does not call `start` or `follow-up` again.
|
|
287
290
|
|
|
288
291
|
## Herdr integration
|
|
289
292
|
|
|
@@ -292,6 +295,7 @@ When Pi runs inside [Herdr](https://herdr.dev), pi-subagents automatically repor
|
|
|
292
295
|
- The bridge is enabled only when Herdr supplies `HERDR_ENV=1` and `HERDR_PANE_ID`; outside Herdr it registers no listeners or timers.
|
|
293
296
|
- It restores current-session active runs after `/reload` or `/resume`, refreshes metadata while work is active, and clears it on completion or shutdown.
|
|
294
297
|
- The bridge uses Herdr's existing `herdr:blocked` sibling event when an async child needs attention, and emits `herdr:busy` while async work remains. Herdr versions that support the sibling event keep the pane's semantic state `working`; older versions ignore it safely and still display the metadata label while the Pi integration remains the lifecycle authority.
|
|
298
|
+
- The owning Pi session is the only publisher for its own pane metadata. While active subagents exist, it reports a compact `title-suffix` token: one active run uses that agent name, two or more use the active-run count, and attention adds `⚠`. The suffix is cleared when active work reaches zero.
|
|
295
299
|
|
|
296
300
|
To show the reported label in the expanded Agent sidebar, include `state_text` or `$summary` in its row layout:
|
|
297
301
|
|
|
@@ -327,7 +331,7 @@ subagent({ action: "project.status", cwd: "/path/to/repo" })
|
|
|
327
331
|
subagent({ action: "project.close", cwd: "/path/to/repo" })
|
|
328
332
|
```
|
|
329
333
|
|
|
330
|
-
A project pane runs its own Pi session in the target directory, so subagents launched from that pane use that project's config, agents, skills, files, git state, and missions. The parent session keeps coordination authority
|
|
334
|
+
A project pane runs its own Pi session in the target directory, so subagents launched from that pane use that project's config, agents, skills, files, git state, and missions. The parent session keeps coordination authority, but it does not own or control the subagents inside the peer pane. Existing headless runs are not moved into the pane. Pane bindings live under `<projectRoot>/.pi/subagents/project-panes/herdr.json` and are only a local pointer to the Herdr pane.
|
|
331
335
|
|
|
332
336
|
Other Pi extensions should use the versioned public TypeScript surface instead of invoking the model-facing tool or importing inspector internals:
|
|
333
337
|
|
|
@@ -336,15 +340,21 @@ import {
|
|
|
336
340
|
PROJECT_PANES_API_VERSION,
|
|
337
341
|
openProjectPane,
|
|
338
342
|
getProjectPaneStatus,
|
|
343
|
+
focusProjectPane,
|
|
339
344
|
closeProjectPane,
|
|
340
345
|
} from "pi-subagents/project-panes";
|
|
341
346
|
|
|
342
347
|
const opened = await openProjectPane({ cwd: "/path/to/repo", focus: false });
|
|
343
348
|
const status = await getProjectPaneStatus({ cwd: "/path/to/repo" });
|
|
349
|
+
const focused = await focusProjectPane({ cwd: "/path/to/repo" });
|
|
344
350
|
const closed = await closeProjectPane({ cwd: "/path/to/repo", requireIdle: true });
|
|
345
351
|
```
|
|
346
352
|
|
|
347
|
-
The API returns discriminated structured results with canonical project root, binding path, pane identity, bounded Herdr runtime fields,
|
|
353
|
+
The API returns discriminated structured results with canonical project root, binding path, pane identity, bounded Herdr runtime fields, stable error codes, and `PROJECT_PANES_API_VERSION: 1`.
|
|
354
|
+
|
|
355
|
+
- Close fails closed unless the saved pane id is still verified for that project and Herdr explicitly reports `agent_status: "idle"`. `requireIdle` is retained for callers that already pass it, but it cannot weaken that rule.
|
|
356
|
+
- Focus uses the saved pane id, asks Herdr for its `tab_id` or `workspace_id`, and then calls the matching Herdr focus command.
|
|
357
|
+
- The API reports `trust: "human-verification-required"`. It never bypasses or claims to attest Pi's project-trust prompt.
|
|
348
358
|
|
|
349
359
|
## Host session lifetime and completion wakes
|
|
350
360
|
|
package/docs/models.md
CHANGED
|
@@ -5,10 +5,12 @@ How subagents pick models, and how to change that.
|
|
|
5
5
|
Builtin agents inherit your current Pi default model. This keeps new installs from depending on a provider you may not have configured. From there you can layer defaults and overrides:
|
|
6
6
|
|
|
7
7
|
- `subagents.defaultModel` — a default for every subagent that does not set its own model.
|
|
8
|
+
- `subagents.defaultProvider` — a provider preference for bare model ids, such as `llama-3`, when multiple providers expose the same id.
|
|
8
9
|
- `subagents.agentOverrides.<name>.model` — pin one role.
|
|
10
|
+
- `subagents.agentOverrides.<name>.defaultProvider` — choose or clear the provider preference for one role.
|
|
9
11
|
- Per-run overrides — for one launch only.
|
|
10
12
|
|
|
11
|
-
Precedence, strongest first: per-run override → agent frontmatter `model` → `agentOverrides.<name>.model` → `subagents.defaultModel` → the parent session model.
|
|
13
|
+
Precedence, strongest first: per-run override → agent frontmatter `model` → `agentOverrides.<name>.model` → `subagents.defaultModel` → the parent session model. A provider preference does not replace this order; it only resolves bare model ids when the active registry has more than one match. Fully qualified `provider/model` strings still win exactly.
|
|
12
14
|
|
|
13
15
|
Use `model: "inherit"` in agent frontmatter or `agentOverrides.<name>.model` to select the current parent session model explicitly.
|
|
14
16
|
|
|
@@ -21,9 +23,13 @@ In `~/.pi/agent/settings.json` (user) or the project config settings file (`.pi/
|
|
|
21
23
|
"defaultModel": "deepseek-v4-pro",
|
|
22
24
|
"subagents": {
|
|
23
25
|
"defaultModel": "deepseek-v4-flash",
|
|
26
|
+
"defaultProvider": "gpu-a",
|
|
24
27
|
"agentOverrides": {
|
|
25
28
|
"oracle": {
|
|
26
29
|
"model": "deepseek-v4-pro"
|
|
30
|
+
},
|
|
31
|
+
"worker": {
|
|
32
|
+
"defaultProvider": "gpu-b"
|
|
27
33
|
}
|
|
28
34
|
}
|
|
29
35
|
}
|
|
@@ -52,14 +58,14 @@ For a persistent role override with a backup model for provider failures:
|
|
|
52
58
|
}
|
|
53
59
|
```
|
|
54
60
|
|
|
55
|
-
`subagents.defaultModel`
|
|
61
|
+
`subagents.defaultModel` and `subagents.defaultProvider` apply to builtin, package, user, and project agents. `defaultModel` fills only agents that do not set `model` in frontmatter. `defaultProvider` is also applied to frontmatter and override models so bare ids resolve against the intended provider. Per-run model overrides and `agentOverrides.<name>.model` still win, and explicit agent frontmatter still wins over the global default. The same `agentOverrides` block can change `tools`, `skills`, inherited context, prompt text, or disable a builtin (see [agents.md](agents.md)). Matching user and project agents also receive override fields that their frontmatter leaves unset, so a shared project config agent can keep the persona while local settings choose the model or provider.
|
|
56
62
|
|
|
57
63
|
## Recommended model tiering (optional)
|
|
58
64
|
|
|
59
65
|
A setup that works well in practice: route agents by task shape instead of running everything on one model. Four tiers:
|
|
60
66
|
|
|
61
67
|
1. **Fast workhorse** — the cheapest capable model at low thinking, for recon, lookups, and mechanical edits. Example: `openai-codex/gpt-5.6-luna:low` on `scout`.
|
|
62
|
-
2. **Standard well-scoped** — a mid-tier model at medium thinking, for most delegations: routine multi-file edits, focused reviews, straightforward implementation. Example: `openai-codex/gpt-5.6-
|
|
68
|
+
2. **Standard well-scoped** — a mid-tier model at medium thinking, for most delegations: routine multi-file edits, focused reviews, straightforward implementation. Example: `openai-codex/gpt-5.6-luna:max` on `worker`, `reviewer`, and a lightweight `delegate` agent.
|
|
63
69
|
3. **Deep but bounded** — a top reasoning model at high thinking, only for hard tasks that arrive with explicit goals and completion criteria. These models tend to loop on vague goals, so keep them off open-ended work. Example: `openai-codex/gpt-5.6-sol:high` on oracle-style agents.
|
|
64
70
|
4. **Taste and intent** — a model that reads human intent well and makes judgment calls without looping, for ambiguous work: UX and design decisions, product tradeoffs, planning from vague requirements, writing quality. Example: `anthropic/claude-fable-5` at `low` for lighter passes and `medium` for harder ones.
|
|
65
71
|
|
|
@@ -96,6 +102,21 @@ Set `subagents.defaultThinking` to give builtin, package, user, and project agen
|
|
|
96
102
|
|
|
97
103
|
If your provider rejects model IDs with thinking suffixes, set `subagents.disableThinking: true` in user or project settings. That clears bundled builtin thinking defaults in one place. An explicit higher-precedence `agentOverrides.<name>.thinking` value can opt a role back in. Existing custom-agent frontmatter remains authoritative.
|
|
98
104
|
|
|
105
|
+
### Thinking ceiling
|
|
106
|
+
|
|
107
|
+
Set `subagents.maxThinking` to enforce a hard maximum for every native Pi child. The supported levels, from least to most thinking, are `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, and `max`:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"subagents": {
|
|
112
|
+
"defaultThinking": "medium",
|
|
113
|
+
"maxThinking": "xhigh"
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Requests above the ceiling fail before child startup; the setting covers frontmatter, `agentOverrides`, per-run overrides, fallback models, parallel/chain children, nested launches, and resumed children. Project settings take precedence over user settings. External runners retain their existing behavior.
|
|
119
|
+
|
|
99
120
|
## Extension defaults
|
|
100
121
|
|
|
101
122
|
Set `subagents.defaultExtensions` to give builtin, package, user, and project agents without an `extensions` field a shared extension allowlist:
|
package/docs/observability.md
CHANGED
|
@@ -40,7 +40,7 @@ To inspect one background child in text, use `subagent({ action: "status", id: "
|
|
|
40
40
|
In the TUI, a persistent FleetView below the editor keeps active work visible as a compact summary. Set `fleetViewPlacement` to `"aboveEditor"` to move it above the editor.
|
|
41
41
|
|
|
42
42
|
```text
|
|
43
|
-
2 active agents · ↓ 4.2k tokens · ↓/← to inspect
|
|
43
|
+
2 active agents · 1 pane · ↓ 4.2k tokens · ↓/← to inspect
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
After you expand it:
|
|
@@ -53,7 +53,7 @@ After you expand it:
|
|
|
53
53
|
reviewer · running 38s · ↓ 1.4k tokens
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
When the focused editor is empty, press `↓` or `←` to expand the summary into `main` plus active children with agent name, state, elapsed time, and token totals. Then use `↑`/`↓` or `j`/`k` to select a child and `Enter` to inspect it. Printable navigation keys are never intercepted before activation.
|
|
56
|
+
When the focused editor is empty, press `↓` or `←` to expand the summary into `main` plus active children with agent name, state, elapsed time, and token totals. The compact line counts active current-session work and Herdr project panes. Then use `↑`/`↓` or `j`/`k` to select a child and `Enter` to inspect it. Printable navigation keys are never intercepted before activation.
|
|
57
57
|
|
|
58
58
|
FleetView replaces the legacy above-editor async widget by default. Successful background completions stay quiet so inactive Pi tabs are not marked unread, while failed or paused completions still notify the originating session. Parallel runs show every active child independently. Chains with parallel groups keep their grouped shape in progress and results, so failed or paused agents stay visible next to completed ones. When a child is explicitly allowed to fan out with `tools: subagent`, its nested runs appear under that parent child in the main status tree instead of being hidden inside the child process.
|
|
59
59
|
|
|
@@ -164,6 +164,17 @@ Nested fanout status is stored as compact sidecar event/registry metadata and me
|
|
|
164
164
|
|
|
165
165
|
Consumers should read these JSON files instead of scraping terminal output. Unknown fields and event types should be ignored for forward compatibility.
|
|
166
166
|
|
|
167
|
+
RPC hosts that need low-latency child-stop UI hints can subscribe to the
|
|
168
|
+
`subagent:child-status` event advertised by RPC `ping` as `events.childStatus`.
|
|
169
|
+
The payload uses `type: "subagent.child-status"`, `version: 1`, `runId`,
|
|
170
|
+
`childId`, `status` (`"stopping"` or `"stopped"`), `ts`, and optional child
|
|
171
|
+
metadata such as `stepIndex`, `agent`, `childRunId`, `workflowKey`, `phase`, and
|
|
172
|
+
`label`. These events are observer hints only. They can duplicate across RPC and
|
|
173
|
+
async replay paths, and they are not replayed after a host restart. Status
|
|
174
|
+
snapshots remain authoritative for recovery and final state. Child stop control
|
|
175
|
+
still uses the normal `stop` request with `childId`; there is no separate child
|
|
176
|
+
stop API.
|
|
177
|
+
|
|
167
178
|
### Status and result fields
|
|
168
179
|
|
|
169
180
|
The status/result fields are: `lifecycleArtifactVersion`, `runId`/`id`, `sessionId`, `mode`, `state`, `startedAt`, `lastUpdate`, `endedAt`, `durationMs`, `cwd`, `asyncDir`, `sessionFile`, `outputFile`, `workflowGraph`, `steps`, `results`, `totalTokens`, `totalCost`, `model`/`attemptedModels`/`modelAttempts`, `toolCount`, `turnCount`, optional `launchResolvedExtensions`, optional `runtimeAcknowledgedExtensions`, and nested `children` when a child is allowed to launch subagents.
|
|
@@ -210,7 +221,7 @@ Each scripted workflow stores runtime artifacts under a workflow artifact direct
|
|
|
210
221
|
|
|
211
222
|
A run directory may contain files such as `context.md`, `plan.md`, `progress.md`, and `parallel-{stepIndex}/.../output.md`. User-scoped temp workflow artifact directories older than 24 hours are cleaned up on extension startup; project-local and explicit persistent roots are not age-scanned.
|
|
212
223
|
|
|
213
|
-
Debug artifacts live under `{sessionDir}/subagent-artifacts/`, `.pi/subagents/artifacts/` for project-scoped runs, or a user-scoped temp artifact directory. Single-run relative `output` files are saved under `{artifactsDir}/outputs/{runId}/` unless `singleRunOutputBaseDir` is configured. Per task you may see:
|
|
224
|
+
Debug artifacts live under `{sessionDir}/subagent-artifacts/`, `.pi/subagents/artifacts/` for project-scoped runs, or a user-scoped temp artifact directory. Single-run relative `output` files are saved under `{artifactsDir}/outputs/{runId}/` unless `singleRunOutputBaseDir` is configured. For lane, review, council, and gate reports, prefer these managed artifacts or the aggregate workflow result instead of repo-root `reports/` files. Copy only final durable evidence to session memory, a mission artifact, a PR/comment, or an approved docs path. Per task you may see:
|
|
214
225
|
|
|
215
226
|
- `{runId}_{agent}_input.md`
|
|
216
227
|
- `{runId}_{agent}_output.md`
|
package/docs/tool-reference.md
CHANGED
|
@@ -4,7 +4,7 @@ Parameters and actions for the `subagent` tool. These are what the LLM passes wh
|
|
|
4
4
|
|
|
5
5
|
## Execution examples
|
|
6
6
|
|
|
7
|
-
Chaining is code-driven through `workflowScript`. Use `await runs.run(...)` for sequential steps and `await runs.all([{ key, agent, task }, ...])` for ordinary parallel fanout. Do not read `.output` from an unawaited `runs.run` launch. Stored `runs.run` promises are only for the advanced rolling fanout pattern under [Workflow steering](#workflow-steering), where every promise is later observed with direct `await`, `Promise.race`, or `Promise.all`. Legacy top-level `chain`, `tasks`, and `parallel` inputs are not supported. Helper functions must be plain functions or explicit Promise chains. Nested `async function` helpers, async arrows, and async methods are rejected so child-launch tracking stays portable across Node and Bun.
|
|
7
|
+
Chaining is code-driven through `workflowScript`. Use `await runs.run(...)` for sequential steps and `await runs.all([{ key, agent, task }, ...])` for ordinary parallel fanout. `runs.all` resolves to an ordered array, not a key map, so use indexes, destructuring, or `.map(...)`, not `results.<key>`. Do not read `.output` from an unawaited `runs.run` launch. Stored `runs.run` promises are only for the advanced rolling fanout pattern under [Workflow steering](#workflow-steering), where every promise is later observed with direct `await`, `Promise.race`, or `Promise.all`. Legacy top-level `chain`, `tasks`, and `parallel` inputs are not supported. Helper functions must be plain functions or explicit Promise chains. Nested `async function` helpers, async arrows, and async methods are rejected so child-launch tracking stays portable across Node and Bun.
|
|
8
8
|
|
|
9
9
|
```js
|
|
10
10
|
// One child; return the child promise explicitly
|
|
@@ -31,14 +31,14 @@ Chaining is code-driven through `workflowScript`. Use `await runs.run(...)` for
|
|
|
31
31
|
| Param | Type | Default | Description |
|
|
32
32
|
|-------|------|---------|-------------|
|
|
33
33
|
| `agent` | string | - | Agent target for management actions. Workflow child agents are set inside `runs.run` or `runs.all`. |
|
|
34
|
-
| `action` | string | - | Agent management (including `guide`, `children.list`, and `refine`/`refine.show`/`refine.rollback`), mission (`mission.create/list/show/update/resolve-decision/attach-run/close`), Herdr inspector (`inspector.open/status/close`), status/control, schedule, watchdog, or doctor action. |
|
|
34
|
+
| `action` | string | - | Agent management (including `guide`, `children.list`, and `refine`/`refine.show`/`refine.rollback`), mission (`mission.create/list/show/update/resolve-decision/attach-run/close`), Herdr inspector (`inspector.open/status/close`), Herdr project pane (`project.open/status/close`), status/control, schedule, watchdog, or doctor action. |
|
|
35
35
|
| `topic` | `overview \| workflows \| agents \| missions \| observability \| tool-reference \| configuration \| models \| watchdog \| extension-api` | `overview` | Packaged guide topic for `action: "guide"`. |
|
|
36
36
|
| `config` | object/string | - | Agent config for management create/update. |
|
|
37
37
|
| `context` | `fresh \| fork` | global or per-agent default, else `fresh` | Explicit `fresh` or `fork` overrides every workflow child. When omitted, [`defaultSubagentContext`](configuration.md#defaultsubagentcontext) wins over each agent's `defaultContext`; `"fork"` creates a real branched session when the parent session file and current leaf exist, otherwise it falls back to `fresh`. Packaged `worker`, `oracle`, and `advisor` default to `fork`. |
|
|
38
38
|
| `missionId` | string | - | Attach a workflow to an existing project mission instead of creating its default enclosing mission. |
|
|
39
39
|
| `mission` | object/false | auto-create | Override the default enclosing mission with `{ title \| summary, objective?, goal?, budget?, labels? }`. Set exactly one non-empty `title` or `summary`; `objective` and `labels` are optional. `goal` may only be `true`, requires `budget.tokens`, and enables continuation notices. Pass `false` for an intentionally ephemeral workflow with no mission for it or its children and no `state` global. Explicit mission persistence failures are strict. |
|
|
40
40
|
| `handoffPath` | string | - | Aggregate handoff manifest required by `action: "worktree.discard"`. |
|
|
41
|
-
| `focus` | boolean | false | Focus the newly split pane for `action: "inspector.open"` or `action: "project.open"`; not a standalone action. Panes open in the background unless you set `focus: true`. |
|
|
41
|
+
| `focus` | boolean | false | Focus the newly split pane for `action: "inspector.open"` or `action: "project.open"`; not a standalone action. Panes open in the background unless you set `focus: true`. Existing saved project panes can be focused through the public project-pane API when Herdr reports a tab or workspace id. |
|
|
42
42
|
| `view` | `fleet \| transcript` | - | Optional `status` view for the active fleet surface or transcript tail inspection. |
|
|
43
43
|
| `lines` | number | `80` | Maximum transcript lines for `action: "status", view: "transcript"`; capped at 500. |
|
|
44
44
|
| `agentScope` | `user \| project \| both` | `both` | Agent discovery scope. Project wins on collisions. |
|
|
@@ -226,6 +226,7 @@ subagent({ action: "doctor" })
|
|
|
226
226
|
|
|
227
227
|
- Multi-child async runs and remembered foreground single, parallel, or chain runs can be revived by passing `index` to choose the child.
|
|
228
228
|
- Nested runs can be resumed by nested id when their live route or persisted nested session metadata is available.
|
|
229
|
+
- Completed external-job runs can use the same `resume` action as a provider follow-up when the registered provider exposes `followUp(input)`. Running external-job parents fail closed with guidance to wait for completion. Unsupported providers fail with an update/reload message.
|
|
229
230
|
- Revive starts a new child process from the old session context; it does not restart the same OS process, and it requires the chosen child to have a persisted `.jsonl` session file.
|
|
230
231
|
- Direct revival takes an exclusive cross-process lease on the canonical session file until the new child finishes. A concurrent attempt fails before Pi is spawned and identifies the owning revived run; dead-owner leases are reclaimed only when staleness can be proved.
|
|
231
232
|
|
|
@@ -317,6 +318,20 @@ The parser canonicalizes known enum synonyms, snake_case report keys and wrapper
|
|
|
317
318
|
|
|
318
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.
|
|
319
320
|
|
|
321
|
+
## Herdr project panes
|
|
322
|
+
|
|
323
|
+
Herdr project panes are peer Pi sessions opened by this Pi session:
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
subagent({ action: "project.open", cwd: "/path/to/repo", message: "Start in this project." })
|
|
327
|
+
subagent({ action: "project.status", cwd: "/path/to/repo" })
|
|
328
|
+
subagent({ action: "project.close", cwd: "/path/to/repo" })
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
The saved pane binding is pane-level only. The parent can refresh status, focus the saved pane when Herdr reports a tab or workspace id, or close it after Herdr verifies ownership and `agent_status: "idle"`. It cannot inspect, steer, or stop subagents inside that peer session. Stale or opaque Herdr metadata stays unknown and fails closed.
|
|
332
|
+
|
|
333
|
+
Inline status counts active current-session work and Herdr project panes. Use Herdr itself or the project-pane API to focus or close project panes.
|
|
334
|
+
|
|
320
335
|
## Orca progress tabs (experimental observer)
|
|
321
336
|
|
|
322
337
|
Orca progress tabs are a global, opt-in observer, not an agent runner. Enable them in the extension config:
|
|
@@ -325,11 +340,11 @@ Orca progress tabs are a global, opt-in observer, not an agent runner. Enable th
|
|
|
325
340
|
{ "orcaProgressTabs": { "enabled": true } }
|
|
326
341
|
```
|
|
327
342
|
|
|
328
|
-
|
|
343
|
+
Foreground and background children keep running through their normal native Pi or `external-cli` path. For each top-level subagent call, the observer asks Orca to create one background terminal tab in the owning worktree and mirrors progress into it. Parallel and chain children share that tab and are separated by child headers. Titles receive a persistent worktree-local sequence number, including across separate workflow calls. Creates for the same worktree are serialized in that sequence so tabs appear to the right in order (`1`, then `2`, then `3`) instead of racing. Model/startup retries reuse the same observer. Attaching an already-running async root does not create a duplicate child tab. 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 run 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 runs with a known session append a safely quoted removal command for the exact verified session path; unsuccessful and sessionless runs append only their terminal status.
|
|
329
344
|
|
|
330
|
-
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
|
|
345
|
+
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 cwd. Availability and tab creation are best-effort: failures never fail, stop, or delay the subagent. When possible, the observer writes a passive manifest under `<worktree>/.pi/subagents/views/orca/`; the manifest is display metadata only, not a lifecycle or control source. Set `orcaProgressTabs.enabled` to `false` to guarantee that no Orca command or tab is created.
|
|
331
346
|
|
|
332
|
-
Agent profile `runner.type` supports native Pi (the default), `external-cli`, and `external-job`. Orca is intentionally not a profile runner and does not own subagent execution, completion, cancellation, artifacts, or result delivery.
|
|
347
|
+
Agent profile `runner.type` supports native Pi (the default), `external-cli`, and `external-job`. Orca is intentionally not a profile runner and does not own subagent execution, completion, cancellation, artifacts, or result delivery. External-job providers can optionally expose `followUp(input)` so a completed provider job can continue its parent conversation through `subagent({ action: "resume", id: "<run>", message: "..." })`.
|
|
333
348
|
|
|
334
349
|
## External CLI agent profiles
|
|
335
350
|
|
package/docs/workflows.md
CHANGED
|
@@ -35,7 +35,7 @@ Add `autofix` to `/parallel-review` or `/parallel-cleanup` to apply only the syn
|
|
|
35
35
|
|
|
36
36
|
## Scripted workflows (workflowScript)
|
|
37
37
|
|
|
38
|
-
All model-facing subagent execution is expressed through `workflowScript` in the `subagent` tool. Use stable keys and ordinary JavaScript for one child, sequence, and parallelism. For ordinary parallel fanout, use `await runs.all([{ key, agent, task }, ...])
|
|
38
|
+
All model-facing subagent execution is expressed through `workflowScript` in the `subagent` tool. Use stable keys and ordinary JavaScript for one child, sequence, and parallelism. For ordinary parallel fanout, use `await runs.all([{ key, agent, task }, ...])`. It resolves to an ordered array, not a key map, so use indexes, destructuring, or `.map(...)`, not `results.<key>`. Do not read `.output` from unawaited `runs.run` launches. Store a `runs.run` promise only when the script later observes it with `await`, `Promise.race`, or `Promise.all`, such as steering a live child before awaiting its result. Scripts are ordinary JavaScript statement bodies. Use an explicit `return` for a useful result:
|
|
39
39
|
|
|
40
40
|
Child results cross into the script as plain JSON data. Non-JSON host metadata is omitted, so use returned fields such as `runId`, `ok`, `output`, and `structuredOutput` for workflow control.
|
|
41
41
|
|
|
@@ -226,6 +226,12 @@ fresh: true
|
|
|
226
226
|
Review $@. Return concrete findings with source proof, or state that no issue was found.
|
|
227
227
|
```
|
|
228
228
|
|
|
229
|
+
For first-pass review prompts, filter by evidence rather than by severity. Ask the
|
|
230
|
+
reviewer to label concrete current findings P0/P1/P2 and end with `Merge verdict:
|
|
231
|
+
BLOCK`, `Merge verdict: OK`, or `Merge verdict: OK with notes`. Reserve
|
|
232
|
+
`blockers only` for final pre-merge re-checks after P1/P2 findings are already
|
|
233
|
+
known, or for explicit emergency hotfix lanes.
|
|
234
|
+
|
|
229
235
|
```text
|
|
230
236
|
/prompt-workflow review-release-candidate v0.51.0
|
|
231
237
|
```
|
package/package.json
CHANGED
package/prompts/council.md
CHANGED
|
@@ -36,6 +36,15 @@ question and scope provide the decision frame. If the user wants a specific lens
|
|
|
36
36
|
they should put it in the question, scope, or profile definition. Keep the roster
|
|
37
37
|
at 2–3 and never exceed 4.
|
|
38
38
|
|
|
39
|
+
Package advisors such as Surf's `gpt-pro` are valid only when the package Pi
|
|
40
|
+
extension is installed and its external-job provider is registered. For Surf,
|
|
41
|
+
that means the `surf-cli` Pi extension has loaded and `surf-oracle` appears in
|
|
42
|
+
`subagent({ action: "list" })` or the advisor is explicitly requested in
|
|
43
|
+
`--advisors` after that install. Treat them as external-runner advisors: omit
|
|
44
|
+
child `async` for normal attached council results, do not pass `outputSchema`,
|
|
45
|
+
include any needed evidence in the prompt, and use the fresh fallback cross-exam
|
|
46
|
+
path if the run is not resumable.
|
|
47
|
+
|
|
39
48
|
## Run the protocol
|
|
40
49
|
|
|
41
50
|
Use the canonical workflow, structured advisor contracts, aggregate pass receipts,
|
|
@@ -28,7 +28,11 @@ Choose or adapt angles when the work calls for it:
|
|
|
28
28
|
|
|
29
29
|
Prefer three strong reviewers over many vague reviewers.
|
|
30
30
|
|
|
31
|
-
Give every reviewer a specific task prompt naming its angle. Ask reviewers to return concise, evidence-backed findings with file/line references and suggested fixes. The response should be review feedback, not a context summary. Reviewers must not edit files unless I explicitly ask for a writer pass.
|
|
31
|
+
Give every reviewer a specific task prompt naming its angle. Ask reviewers to return concise, evidence-backed findings with file/line references and suggested fixes. Filter on evidence, not severity: a finding must be concrete, current, caused or made reachable by the target diff, and supported by source proof, a test or repro, or a contract contradiction. Label findings P0/P1/P2. P0 blocks merge. P1 should be fixed before release. P2 is report-only. End each review with `Merge verdict: BLOCK`, `Merge verdict: OK`, or `Merge verdict: OK with notes`. If nothing qualifies, ask the reviewer to say exactly `No issues found.` The response should be review feedback, not a context summary. Reviewers must not edit files unless I explicitly ask for a writer pass.
|
|
32
|
+
|
|
33
|
+
Do not default first-pass reviews to `blockers only`. That phrase is valid only for final pre-merge re-checks after P1/P2 findings are already inventoried, or for explicit emergency hotfix lanes where non-blocking findings are intentionally deferred.
|
|
34
|
+
|
|
35
|
+
For a targeted follow-up review, ask only whether the named finding was resolved, whether the fix introduced a new defect in the fix blast radius, and whether prior P1/P2 notes still stand. For bot or PR-comment triage, classify each comment as VALID, STALE, INVALID, or OUT-OF-POLICY against current HEAD, then assign P0/P1/P2 only to VALID comments.
|
|
32
36
|
|
|
33
37
|
While reviewers run, do your own narrow inspection if useful. After they return, synthesize the feedback into:
|
|
34
38
|
- fixes worth doing now
|
package/prompts/review-loop.md
CHANGED
|
@@ -6,7 +6,7 @@ Run a parent-orchestrated review loop for the requested work.
|
|
|
6
6
|
|
|
7
7
|
Use the `subagent` tool. Keep the parent session as the loop controller and final decision-maker. Child subagents must receive concrete role-specific tasks; they must not run subagents or manage the loop themselves unless the parent intentionally selected an explicit fanout agent whose builtin `tools` includes `subagent` for that assigned fanout.
|
|
8
8
|
|
|
9
|
-
Default to a maximum of 3 review rounds unless I specify a different cap. Count a review round each time fresh-context reviewers inspect the current diff after a worker pass. Stop early when reviewers find no
|
|
9
|
+
Default to a maximum of 3 review rounds unless I specify a different cap. Count a review round each time fresh-context reviewers inspect the current diff after a worker pass. Stop early when reviewers find no P0 findings, no P1 fixes worth doing now, and no approved P2 notes that should be handled in this loop.
|
|
10
10
|
|
|
11
11
|
If the invocation includes an implementation request, first launch one async `worker` to implement the approved scope. If the current diff is already the target, start with review. The sequence can be launched up front with `workflowScript` when it is already clear, or continued as follow-up single-agent runs after each async completion. For an initial workflowScript, pass `async: true` so the main chat is unblocked; do not set `clarify: true` unless I explicitly want the foreground clarify UI. Use only one writer against the active worktree at a time unless I explicitly ask for isolated worktrees.
|
|
12
12
|
|
|
@@ -14,12 +14,14 @@ As a conservative orchestration policy, do not set `turnBudget`, a hard `toolBud
|
|
|
14
14
|
|
|
15
15
|
For each review round, launch fresh-context `reviewer` agents in parallel. Reviewers must inspect the repository, relevant instructions, and current diff directly from files and commands. They must not rely on the main conversation history and must not edit files.
|
|
16
16
|
|
|
17
|
+
Tell reviewers to filter on evidence, not severity. They should report only concrete current issues caused or made reachable by the target diff, with source proof, a test or repro, or a contract contradiction. Ask them to label findings P0/P1/P2 and end with `Merge verdict: BLOCK`, `Merge verdict: OK`, or `Merge verdict: OK with notes`. P0 blocks merge. P1 should be fixed before release. P2 is report-only. Use `blockers only` only for final pre-merge re-checks after P1/P2 findings are already captured, or for explicit emergency hotfix lanes.
|
|
18
|
+
|
|
17
19
|
Choose review angles from the actual change. Common angles are correctness/regressions, tests/validation, and simplicity/maintainability. Add security, performance, docs/API contracts, or user-flow validation when the work calls for it. Prefer three strong reviewers over many vague reviewers.
|
|
18
20
|
|
|
19
21
|
After reviewers return, synthesize their feedback into:
|
|
20
|
-
- blockers or scope/product/architecture decisions that need user approval;
|
|
21
|
-
- fixes worth doing now;
|
|
22
|
-
- optional improvements;
|
|
22
|
+
- P0 blockers or scope/product/architecture decisions that need user approval;
|
|
23
|
+
- P1 fixes worth doing now;
|
|
24
|
+
- P2 report-only notes or optional improvements;
|
|
23
25
|
- feedback to ignore or defer, with a short reason.
|
|
24
26
|
|
|
25
27
|
Do not blindly apply every reviewer suggestion. If reviewers surface an unapproved product, scope, or architecture decision, pause and ask me before launching a fix worker.
|
|
@@ -30,8 +32,10 @@ When there are fixes worth doing now and the workflow is implementation-authoriz
|
|
|
30
32
|
|
|
31
33
|
After a fix worker returns, run another review round only when it made material changes or addressed non-trivial findings. Do not keep looping for optional polish, speculative improvements, or findings already deferred by the parent.
|
|
32
34
|
|
|
35
|
+
For a targeted follow-up review, ask only three questions: whether the named finding was resolved, whether the fix introduced a new concrete defect in the fix blast radius, and whether prior P1/P2 notes still stand. End with a fix verdict and the merge verdict.
|
|
36
|
+
|
|
33
37
|
Stop and summarize when one of these is true:
|
|
34
|
-
- reviewers find no blockers or fixes worth doing now;
|
|
38
|
+
- reviewers find no P0 blockers or P1 fixes worth doing now;
|
|
35
39
|
- remaining feedback is optional, speculative, or intentionally deferred;
|
|
36
40
|
- reviewers surface an unapproved decision that needs me;
|
|
37
41
|
- the max review-round cap is reached.
|
|
@@ -20,6 +20,17 @@ Use advisor profile names directly. A `council-*` profile defines model, tools,
|
|
|
20
20
|
context, output defaults, and any persistent stance in the profile body. Its
|
|
21
21
|
profile configuration or explicit invocation owns its context choice.
|
|
22
22
|
|
|
23
|
+
Package advisors can also join the roster only when their package Pi extension is
|
|
24
|
+
installed and their external-job provider is registered. For Surf, `gpt-pro` is
|
|
25
|
+
available only after the `surf-cli` Pi extension loads Surf's `surf-oracle`
|
|
26
|
+
provider. Treat it as a normal advisor name in `runs.all` after that provider is
|
|
27
|
+
visible. It is background-only, so omit `async` unless you explicitly want
|
|
28
|
+
detached receipt semantics; workflow execution will await the terminal provider
|
|
29
|
+
result. External runners can lack repo tools, structured-output support, or
|
|
30
|
+
resumability. For them, include the needed evidence or file excerpts in the task,
|
|
31
|
+
use the text JSON contract below instead of `outputSchema`, and use the
|
|
32
|
+
fresh-context fallback path for cross-exam when the run is not resumable.
|
|
33
|
+
|
|
23
34
|
Create model-based profiles in your user or project agent directory. Do not add
|
|
24
35
|
them to this package. This is a valid example:
|
|
25
36
|
|
|
@@ -73,7 +84,13 @@ be settled by evidence an advisor can produce. Never run an unbounded loop.
|
|
|
73
84
|
is known, omit `context` and disclose the unknown runtime default in the memo.
|
|
74
85
|
Each advisor is read-only and must not spawn children, edit files, run mutating
|
|
75
86
|
commands, commit, or push. Set `output: false` unless separate advisor artifacts
|
|
76
|
-
are explicitly requested or useful for the decision.
|
|
87
|
+
are explicitly requested or useful for the decision. When separate artifacts are
|
|
88
|
+
useful, give advisors relative output paths so the runtime stores them under its
|
|
89
|
+
managed artifact directory; do not ask them to write root-level council report
|
|
90
|
+
files. For installed
|
|
91
|
+
external-runner advisors such as Surf `gpt-pro` after `surf-oracle` is
|
|
92
|
+
registered, do not pass `outputSchema`; put the schema request in the task text
|
|
93
|
+
and accept `result.output` as the report.
|
|
77
94
|
4. Return one aggregate Pass 1 receipt. After it completes, tell the user the
|
|
78
95
|
completion count, agreement count, dispute count, and whether Pass 2 is needed.
|
|
79
96
|
5. The parent synthesizes a claim matrix in session. It contains agreements,
|
|
@@ -97,10 +114,12 @@ budgets on advisors. Bound work through the roster, pass cap, and report length.
|
|
|
97
114
|
|
|
98
115
|
## Advisor contracts and pass receipts
|
|
99
116
|
|
|
100
|
-
Pass-1 reports are at most about 600 words. Give
|
|
101
|
-
`outputSchema`, so reports are comparable without heading cleanup.
|
|
102
|
-
|
|
103
|
-
|
|
117
|
+
Pass-1 reports are at most about 600 words. Give native Pi advisors the same
|
|
118
|
+
`outputSchema`, so reports are comparable without heading cleanup. For
|
|
119
|
+
external-runner advisors, do not pass `outputSchema`; ask them to return compact
|
|
120
|
+
JSON text with the same fields. The following shape is a contract template. Use
|
|
121
|
+
the runtime schema syntax supported by the workflow for native advisors and keep
|
|
122
|
+
narrative fields as strings:
|
|
104
123
|
|
|
105
124
|
```js
|
|
106
125
|
const pass1OutputSchema = {
|
|
@@ -151,7 +170,9 @@ const pass1OutputSchema = {
|
|
|
151
170
|
|
|
152
171
|
Include this contract in each Pass 1 task: inspect supplied evidence directly; do
|
|
153
172
|
not see or ask about other advisors; stay read-only; do not spawn children; return
|
|
154
|
-
only the structured report.
|
|
173
|
+
only the structured report. For external-runner advisors, say `Return only JSON
|
|
174
|
+
matching this shape. Do not wrap it in Markdown.` and include any evidence they
|
|
175
|
+
cannot read through tools.
|
|
155
176
|
|
|
156
177
|
After `runs.all`, return one aggregate receipt rather than making the parent find
|
|
157
178
|
separate artifacts. Preserve the result order or map it by stable key so each row
|
|
@@ -165,7 +186,7 @@ return {
|
|
|
165
186
|
agent: result.agent,
|
|
166
187
|
requestedContext: roster[index].context ?? "runtime-default-unknown",
|
|
167
188
|
runId: result.runId,
|
|
168
|
-
report: result.structuredOutput
|
|
189
|
+
report: result.structuredOutput ?? result.output
|
|
169
190
|
}))
|
|
170
191
|
};
|
|
171
192
|
```
|
|
@@ -208,9 +229,11 @@ const pass2OutputSchema = {
|
|
|
208
229
|
```
|
|
209
230
|
|
|
210
231
|
Use stable resume keys such as `cross-oracle`, `phase: "Council pass 2"`, concise
|
|
211
|
-
labels, and `output: false` unless separate artifacts are requested or useful.
|
|
212
|
-
|
|
213
|
-
|
|
232
|
+
labels, and `output: false` unless separate artifacts are requested or useful. Keep
|
|
233
|
+
any artifact outputs under the managed run artifact directory. Do not pass
|
|
234
|
+
`outputSchema` to external-runner fallback launches; ask for compact JSON text
|
|
235
|
+
instead. The aggregate Pass 2 receipt uses the same row shape as Pass 1, with the
|
|
236
|
+
new `runId` and `structuredOutput ?? output`.
|
|
214
237
|
|
|
215
238
|
## Stop and memo
|
|
216
239
|
|