pi-subagents 0.70.0 → 0.70.1
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 +25 -0
- package/README.md +1 -1
- package/agents/claude-code-writer.md +1 -0
- package/agents/codex-exec-writer.md +1 -0
- package/agents/cursor-agent-writer.md +1 -0
- package/agents/worker.md +1 -0
- package/docs/agents.md +6 -7
- package/docs/configuration.md +2 -0
- package/docs/extension-api.md +2 -0
- package/docs/models.md +1 -1
- package/docs/observability.md +1 -1
- package/docs/standalone-background.md +4 -4
- package/docs/tool-reference.md +3 -7
- package/inspector-runner.mjs +1 -1
- package/package.json +1 -1
- package/skills/pi-subagents/SKILL.md +1 -0
- package/skills/pi-subagents/references/management-authoring-rpc.md +1 -1
- package/skills/pi-subagents/references/multi-lane-orchestration.md +8 -0
- package/skills/pi-subagents/references/prompting-and-roles.md +14 -13
- package/src/agents/agent-management.d.ts.map +1 -1
- package/src/agents/agent-management.js +11 -25
- package/src/agents/agent-management.js.map +1 -1
- package/src/agents/agent-serializer.d.ts.map +1 -1
- package/src/agents/agent-serializer.js +0 -4
- package/src/agents/agent-serializer.js.map +1 -1
- package/src/agents/agents.d.ts +17 -4
- package/src/agents/agents.d.ts.map +1 -1
- package/src/agents/agents.js +39 -22
- package/src/agents/agents.js.map +1 -1
- package/src/agents/runtime-agent-registry.d.ts +8 -3
- package/src/agents/runtime-agent-registry.d.ts.map +1 -1
- package/src/agents/runtime-agent-registry.js +14 -9
- package/src/agents/runtime-agent-registry.js.map +1 -1
- package/src/extension/index.js +1 -1
- package/src/extension/index.js.map +1 -1
- package/src/runs/background/async-execution.d.ts.map +1 -1
- package/src/runs/background/async-execution.js +0 -34
- package/src/runs/background/async-execution.js.map +1 -1
- package/src/runs/background/async-resume.d.ts.map +1 -1
- package/src/runs/background/async-resume.js +1 -4
- package/src/runs/background/async-resume.js.map +1 -1
- package/src/runs/background/run-status.d.ts.map +1 -1
- package/src/runs/background/run-status.js +6 -4
- package/src/runs/background/run-status.js.map +1 -1
- package/src/runs/background/runner-aliases.d.ts.map +1 -1
- package/src/runs/background/runner-aliases.js +26 -15
- package/src/runs/background/runner-aliases.js.map +1 -1
- package/src/runs/background/subagent-runner.d.ts +1 -5
- package/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/src/runs/background/subagent-runner.js +31 -113
- package/src/runs/background/subagent-runner.js.map +1 -1
- package/src/runs/foreground/execution.d.ts.map +1 -1
- package/src/runs/foreground/execution.js +0 -97
- package/src/runs/foreground/execution.js.map +1 -1
- package/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/src/runs/foreground/subagent-executor.js +0 -2
- package/src/runs/foreground/subagent-executor.js.map +1 -1
- package/src/runs/shared/acceptance.d.ts.map +1 -1
- package/src/runs/shared/acceptance.js +7 -40
- package/src/runs/shared/acceptance.js.map +1 -1
- package/src/runs/shared/child-hooks.d.ts +1 -3
- package/src/runs/shared/child-hooks.d.ts.map +1 -1
- package/src/runs/shared/child-hooks.js +1 -16
- package/src/runs/shared/child-hooks.js.map +1 -1
- package/src/runs/shared/child-launch.d.ts +0 -2
- package/src/runs/shared/child-launch.d.ts.map +1 -1
- package/src/runs/shared/child-launch.js +1 -2
- package/src/runs/shared/child-launch.js.map +1 -1
- package/src/runs/shared/child-session.d.ts +8 -9
- package/src/runs/shared/child-session.d.ts.map +1 -1
- package/src/runs/shared/child-session.js +67 -2
- package/src/runs/shared/child-session.js.map +1 -1
- package/src/runs/shared/dynamic-fanout.js +1 -1
- package/src/runs/shared/dynamic-fanout.js.map +1 -1
- package/src/runs/shared/parallel-utils.d.ts +0 -1
- package/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/src/runs/shared/parallel-utils.js.map +1 -1
- package/src/runs/shared/single-output.d.ts.map +1 -1
- package/src/runs/shared/single-output.js +10 -2
- package/src/runs/shared/single-output.js.map +1 -1
- package/src/runs/shared/subagent-control.d.ts.map +1 -1
- package/src/runs/shared/subagent-control.js +6 -19
- package/src/runs/shared/subagent-control.js.map +1 -1
- package/src/shared/launch-contract.d.ts.map +1 -1
- package/src/shared/launch-contract.js +0 -1
- package/src/shared/launch-contract.js.map +1 -1
- package/src/shared/pruned-fork.d.ts +1 -1
- package/src/shared/pruned-fork.d.ts.map +1 -1
- package/src/shared/pruned-fork.js +2 -9
- package/src/shared/pruned-fork.js.map +1 -1
- package/src/shared/types.d.ts +3 -10
- package/src/shared/types.d.ts.map +1 -1
- package/src/shared/types.js.map +1 -1
- package/src/slash/slash-commands.js +1 -1
- package/src/slash/slash-commands.js.map +1 -1
- package/src/slash/subagents-admin.d.ts.map +1 -1
- package/src/slash/subagents-admin.js +4 -5
- package/src/slash/subagents-admin.js.map +1 -1
- package/src/tui/render.d.ts.map +1 -1
- package/src/tui/render.js +8 -7
- package/src/tui/render.js.map +1 -1
- package/src/watchdog/permission-arbiter.d.ts.map +1 -1
- package/src/watchdog/permission-arbiter.js +13 -8
- package/src/watchdog/permission-arbiter.js.map +1 -1
- package/src/watchdog/review.d.ts +2 -1
- package/src/watchdog/review.d.ts.map +1 -1
- package/src/watchdog/review.js +13 -6
- package/src/watchdog/review.js.map +1 -1
- package/src/workflows/scripted-workflow.d.ts.map +1 -1
- package/src/workflows/scripted-workflow.js +1 -3
- package/src/workflows/scripted-workflow.js.map +1 -1
- package/src/runs/shared/completion-evidence.d.ts +0 -31
- package/src/runs/shared/completion-evidence.d.ts.map +0 -1
- package/src/runs/shared/completion-evidence.js +0 -54
- package/src/runs/shared/completion-evidence.js.map +0 -1
- package/src/runs/shared/completion-guard.d.ts +0 -35
- package/src/runs/shared/completion-guard.d.ts.map +0 -1
- package/src/runs/shared/completion-guard.js +0 -214
- package/src/runs/shared/completion-guard.js.map +0 -1
- package/src/runs/shared/llm-intent-arbiter.d.ts +0 -48
- package/src/runs/shared/llm-intent-arbiter.d.ts.map +0 -1
- package/src/runs/shared/llm-intent-arbiter.js +0 -235
- package/src/runs/shared/llm-intent-arbiter.js.map +0 -1
- package/src/runs/shared/task-intent.d.ts +0 -38
- package/src/runs/shared/task-intent.d.ts.map +0 -1
- package/src/runs/shared/task-intent.js +0 -213
- package/src/runs/shared/task-intent.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.70.1] - 2026-09-20
|
|
6
|
+
|
|
7
|
+
### Highlights
|
|
8
|
+
|
|
9
|
+
- Delegated tasks no longer fail solely because they finish without editing files.
|
|
10
|
+
- Runtime-added agents now honor configured model, provider, and thinking preferences.
|
|
11
|
+
- Foreground children launch reliably when Pi is installed outside the extension's own dependency tree.
|
|
12
|
+
- Pi 0.86.1 support improves watchdog checks, provider-backed summaries, packaging, and standalone use.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Stop guessing whether task wording requires file edits. Successful tasks now follow their process result and explicitly configured output and acceptance checks. The `completionGuard` setting and `PI_SUBAGENTS_LLM_INTENT_ARBITER` switch have been removed. Thanks to [@SuTang-vain](https://github.com/SuTang-vain) for the reproduction that led to this change in [#2351](https://github.com/nicobailon/pi-subagents/issues/2351).
|
|
17
|
+
- Clarify that a custom agent file fully replaces a bundled agent with the same name. Custom implementation agents must declare `acceptanceRole: writer` to receive writer acceptance defaults.
|
|
18
|
+
- Update delegation guidance so large changes are split only when they contain independently testable parts.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Apply `subagents.defaultModel`, `defaultProvider`, `defaultThinking`, and model-tier overrides to runtime-registered agents. Thanks to [@bioShaun](https://github.com/bioShaun) for [#2368](https://github.com/nicobailon/pi-subagents/pull/2368).
|
|
23
|
+
- Show each workflow child's resolved model and thinking level in parent status output. Thanks to [@grahama1970](https://github.com/grahama1970) for [#2364](https://github.com/nicobailon/pi-subagents/pull/2364).
|
|
24
|
+
- Preserve watchdog working-directory context and authenticated provider behavior for pruned-fork overflow summaries on Pi 0.86.1. Thanks to [@chem](https://github.com/chem) for [#2362](https://github.com/nicobailon/pi-subagents/issues/2362).
|
|
25
|
+
- Launch the packaged inspector bootstrap from its compiled JavaScript instead of an absent TypeScript source. Thanks to [@pablog12](https://github.com/pablog12) for [#2360](https://github.com/nicobailon/pi-subagents/issues/2360).
|
|
26
|
+
- Resolve the host `pi-coding-agent` package and its exports from the Pi installation that owns the session, so foreground children work across npm-hosted layouts without loading a second SDK instance. Thanks to [@nazerim](https://github.com/nazerim) for [#2348](https://github.com/nicobailon/pi-subagents/issues/2348).
|
|
27
|
+
- Show an actionable expand shortcut when a host cannot provide its configured keybinding label.
|
|
28
|
+
- Stop test-only background runners when their owning test process exits, and isolate test temporary data to reduce filesystem and Spotlight load.
|
|
29
|
+
|
|
5
30
|
## [0.70.0] - 2026-09-19
|
|
6
31
|
|
|
7
32
|
### Highlights
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
pi install npm:pi-subagents
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
That is the only required step. Background children use the host's SDK: npm Pi keeps its detached Node runner; the official Pi 0.
|
|
17
|
+
That is the only required step. Background children use the host's SDK: npm Pi keeps its detached Node runner; the official Pi 0.86.1 Linux x64 standalone release loads the same runner through Pi's embedded SDK, without a separate SDK install. See [Standalone background execution](docs/standalone-background.md) for the supported boundary and validation gate.
|
|
18
18
|
|
|
19
19
|
## Try this first
|
|
20
20
|
|
package/agents/worker.md
CHANGED
package/docs/agents.md
CHANGED
|
@@ -236,6 +236,8 @@ Disable and restore:
|
|
|
236
236
|
- `subagent({ action: "eject", agent: "reviewer" })` copies a bundled builtin or package agent verbatim into the user or project agent dir (default `user`) as an editable custom file that shadows the original.
|
|
237
237
|
- `subagent({ action: "reset", agent: "reviewer" })` deletes the scope's custom agent file and/or settings override entry, restoring the bundled default. It refuses if no bundled default exists (use `delete` for purely custom agents).
|
|
238
238
|
|
|
239
|
+
A custom agent file that shadows a bundled agent replaces the bundled definition wholesale; it does not inherit omitted frontmatter, including `acceptanceRole`. Custom implementation profiles must declare `acceptanceRole: writer` explicitly when writer acceptance inference is intended. Without it, automatic acceptance uses lightweight attestation as described in the [frontmatter reference](#frontmatter-reference).
|
|
240
|
+
|
|
239
241
|
`eject`, `disable`, `enable`, and `reset` accept `agentScope: "user" | "project"` and operate in one scope at a time. Project overrides still win over user ones, so a project-scope disable survives a user-scope `enable` until you target the project scope.
|
|
240
242
|
|
|
241
243
|
## Running external CLI agents on a Herdr saved machine
|
|
@@ -317,7 +319,6 @@ timeoutMs: 900000
|
|
|
317
319
|
toolTimeoutMs: 600000
|
|
318
320
|
acceptance: {"level":"none","reason":"lightweight lookup"}
|
|
319
321
|
acceptanceRole: read-only
|
|
320
|
-
completionGuard: false
|
|
321
322
|
interactive: true
|
|
322
323
|
maxSubagentDepth: 1
|
|
323
324
|
allowNestedSubagents: true
|
|
@@ -364,9 +365,8 @@ Field notes:
|
|
|
364
365
|
| `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. |
|
|
365
366
|
| `toolTimeoutMs` | Optional positive integer hard per-tool-call deadline in milliseconds. An explicit call value wins, then this agent default, global `toolTimeoutMs`, and `PI_SUBAGENT_TOOL_TIMEOUT_MS`. When omitted, known-fast built-in tools get a five-minute default; long-running tools get attention notices but no hard default. It does not extend the run-level deadline; `contact_supervisor`, `intercom`, and `bg_wait` are exempt. |
|
|
366
367
|
| `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. |
|
|
367
|
-
| `acceptanceRole` | Optional `read-only` or `writer` role for automatic acceptance inference.
|
|
368
|
-
| `mutationTools` | Comma-separated extension tool names
|
|
369
|
-
| `completionGuard` | Set `false` only for non-implementation agents that may mention implementation words while using mutation-capable tools such as `bash`. |
|
|
368
|
+
| `acceptanceRole` | Optional `read-only` or `writer` role for automatic acceptance inference. When omitted, automatic acceptance uses lightweight attestation; task wording and agent names do not escalate it. This does not grant or revoke tools. |
|
|
369
|
+
| `mutationTools` | Comma-separated extension tool names treated as mutating activity for runtime diagnostics, long-running-tool status, and timeout recovery. This is diagnostic only and never determines successful completion. List and load each tool through `tools` and its extension provider as usual. |
|
|
370
370
|
| `interactive` | Parsed for compatibility but not currently enforced. |
|
|
371
371
|
| `maxSubagentDepth` | Tightens nested delegation for this agent's children. |
|
|
372
372
|
| `memory` | Opt-in role-specific persistent memory. See below. |
|
|
@@ -377,7 +377,7 @@ Hosts can import `registerRequiredChildExtensions` from `pi-subagents/required-c
|
|
|
377
377
|
|
|
378
378
|
Required paths follow ordinary extension resolution and survive agent defaults and `extensions: []` across native foreground, detached, nested, and recovery launches. A `capabilityCeiling.denyExtensions` conflict or required load/provider-registration failure rejects before model resolution. External runners are excluded, and status/watch paths do not query the registry.
|
|
379
379
|
|
|
380
|
-
|
|
380
|
+
Successful completion is determined by observable gates such as process outcome, required outputs, explicit acceptance, verification commands, independent review, and staged-index integrity. Best-effort mutation observations remain diagnostic: unchanged or unknown evidence does not fail a run, and observed changes do not prove correctness.
|
|
381
381
|
|
|
382
382
|
## Per-agent persistent memory
|
|
383
383
|
|
|
@@ -449,8 +449,7 @@ More rules:
|
|
|
449
449
|
- `mcp:` entries are split out and forwarded as direct MCP selections without granting normal builtins unless those builtins are also listed.
|
|
450
450
|
- Path-like `tools` entries, such as extension paths or `.ts`/`.js` files, are treated as tool-extension paths rather than tool names.
|
|
451
451
|
- Internal runtime tools such as `structured_output` are added to an explicit allowlist only when their contract is active.
|
|
452
|
-
- Unknown extension tool calls
|
|
453
|
-
- Agents that declare only known read-only builtin tools skip the implementation completion guard. `bash`, unknown tools, and MCP tools stay mutation-capable. Use `completionGuard: false` for bash-enabled validators or advisors that should never be judged as implementation agents.
|
|
452
|
+
- Unknown extension tool calls are treated as mutating diagnostic activity only when their names are listed in `mutationTools`.
|
|
454
453
|
|
|
455
454
|
Examples:
|
|
456
455
|
|
package/docs/configuration.md
CHANGED
|
@@ -420,6 +420,8 @@ export PI_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT=/path/to/pi-coding-agent-packag
|
|
|
420
420
|
|
|
421
421
|
Overrides host-package discovery for spawned children. Foreground CLI resolution uses this root to locate the `pi` CLI script, and the detached background runner uses it for jiti host resolution and peer-package aliases, so both child kinds agree on one host. It is consulted when argv-based automatic discovery cannot identify the host, such as a wrapper install or a non-standard layout. The value must be the root of a canonical `@earendil-works/pi-coding-agent` installation (the directory containing its `package.json`, with that package name); both child kinds still validate the package name and its peer packages from that install tree, so a package whose manifest carries a different name is rejected even with the override set. Empty or whitespace-only values are ignored.
|
|
422
422
|
|
|
423
|
+
The default in-process child session loader consults the same discovery. Before falling back to a bare `@earendil-works/pi-coding-agent` import, it resolves the host package root (the running pi process's location, then this override, then pi-subagents' own install tree as a last fallback) and imports the host's entry file directly, so children share the host's single SDK instance instead of a second copy. Roots whose `package.json` name is not `@earendil-works/pi-coding-agent` are rejected. When this override is selected, an unimportable root is reported instead of falling back to a bare import from a different tree.
|
|
424
|
+
|
|
423
425
|
## `intercomBridge`
|
|
424
426
|
|
|
425
427
|
```json
|
package/docs/extension-api.md
CHANGED
|
@@ -188,6 +188,8 @@ const registration = request.result.registration;
|
|
|
188
188
|
|
|
189
189
|
If `pi-subagents` is a resolvable dependency of the consumer package, `pi-subagents/agents` exports `RUNTIME_AGENT_REGISTER_EVENT`, the request/result types, and `registerAgentViaEvents()` for the same contract. A separately installed Pi package is not automatically a Node dependency of another package. In that case, use the event contract directly instead of a runtime import. A type-only development dependency is optional.
|
|
190
190
|
|
|
191
|
+
A registered agent follows the operator's subagent model settings like any other agent: `subagents.defaultModel`, `defaultProvider`, and `defaultThinking` fill a definition that omits `model` or `thinking`, and the `model`, `defaultProvider`, `fast`, and `thinking` fields of `agentOverrides.<name>` win over the definition. Every other definition field stays extension-owned, and other override fields are ignored for runtime agents. Set `model` in the definition only when the agent must not follow operator model settings; `model: "inherit"` selects the parent session model explicitly.
|
|
192
|
+
|
|
191
193
|
The installed owner applies the existing runtime-agent validation, collision checks, limits, runtime source metadata, and cleanup. If more than one owner listens, the first handler that writes `request.result` wins. Unsupported versions, malformed requests, and registration failures return `{ ok: false, error }`. No result means no compatible owner handled the event.
|
|
192
194
|
|
|
193
195
|
This contract is process-local. It does not register agents in child sessions or other Pi processes, and it does not change package discovery or package resolution.
|
package/docs/models.md
CHANGED
|
@@ -82,7 +82,7 @@ For a persistent role override:
|
|
|
82
82
|
}
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
`subagents.defaultModel` and `subagents.defaultProvider` apply to builtin, package, user, and
|
|
85
|
+
`subagents.defaultModel` and `subagents.defaultProvider` apply to builtin, package, user, project, and runtime-registered agents. `defaultModel` fills only agents that do not set `model` in frontmatter or in their runtime definition. `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` win over frontmatter and the global default. The same `agentOverrides` block can change `tools`, `skills`, inherited context, prompt text, or disable an agent (see [agents.md](agents.md)); matching custom-agent frontmatter is replaced for any field set by the override. Runtime-registered agents take only `model`, `defaultProvider`, `fast`, and `thinking` from `agentOverrides.<name>`; their other definition fields stay owned by the registering extension.
|
|
86
86
|
|
|
87
87
|
## Fast mode
|
|
88
88
|
|
package/docs/observability.md
CHANGED
|
@@ -46,7 +46,7 @@ async subagent worker · background
|
|
|
46
46
|
|
|
47
47
|
To inspect one background child in text, use `subagent({ action: "status", id: "...", view: "transcript" })`; add `index` for a specific child in a parallel or chain run.
|
|
48
48
|
|
|
49
|
-
In Pi fullscreen mode with mouse dispatch
|
|
49
|
+
In Pi fullscreen mode with mouse dispatch, left-click
|
|
50
50
|
anywhere on the async widget's header row to fold it into a live one-line status
|
|
51
51
|
summary. Click again to restore the usual layout. No knowledge of extension commands
|
|
52
52
|
or keyboard shortcuts is needed. The summary counts the widget's tracked runs,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Standalone background execution
|
|
2
2
|
|
|
3
|
-
Supported standalone target: **official Pi 0.
|
|
3
|
+
Supported standalone target: **official Pi 0.86.1, Linux x64**. Keep its adjacent release assets with the executable. Other versions, operating systems, architectures and packagers are outside the fully validated support target; limited experimental Windows coverage is described below.
|
|
4
4
|
|
|
5
5
|
Pi's extension loader supplies its embedded SDK to `binary-bootstrap.ts`, which awaits the existing configured runner before exiting. Startup authorization, revival leases, controls, disposal and process-close observation remain shared with npm. Each independent run has its own host; native sessions inside that run share it. No per-session CLI protocol, runtime download/install, alternate SDK or foreground fallback is introduced. Npm Pi keeps its Node runner, peer aliases and detected npm `PI_PACKAGE_DIR` override (including refusal when no npm root exists).
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ Implementation and lifecycle fixtures derive from [@xz-dev](https://github.com/x
|
|
|
10
10
|
|
|
11
11
|
The resolver recognizes Bun's Windows virtual entrypoint prefixes, `B:/~BUN/` and `B:\~BUN\`, alongside `/$bunfs/`. It launches the real `process.execPath` (or the existing executable override). The `B:` prefix is virtual, not the installation drive; `pi-native.exe` is not a required executable name.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Windows remains **experimental**: the full standalone lifecycle matrix has not been validated there or for every Bun-compiled Pi host.
|
|
14
14
|
|
|
15
15
|
Node-hosted npm Pi keeps its existing runner path and is not affected by this virtual-entrypoint detection defect. Installing only the pi-subagents extension through npm does not change a Bun-compiled Pi host into an npm Pi host.
|
|
16
16
|
|
|
@@ -39,11 +39,11 @@ For a focused diagnostic, use `node test/smoke/standalone-background.mjs "$relea
|
|
|
39
39
|
|
|
40
40
|
## Npm regressions and local trial
|
|
41
41
|
|
|
42
|
-
Existing npm clean-install CI covers real SDK 0.
|
|
42
|
+
Existing npm clean-install CI covers real SDK 0.86.1. The standalone CI job also checks the public npm launch path without execution-time network:
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
npm_checks="$(mktemp -d)"
|
|
46
|
-
node test/smoke/clean-install.mjs "$npm_checks/sdk" 0.
|
|
46
|
+
node test/smoke/clean-install.mjs "$npm_checks/sdk" 0.86.1
|
|
47
47
|
node test/smoke/npm-background.mjs "$npm_checks/sdk" "$npm_checks/launch"
|
|
48
48
|
```
|
|
49
49
|
|
package/docs/tool-reference.md
CHANGED
|
@@ -242,7 +242,7 @@ Agent definitions are not loaded into context by default. Management actions let
|
|
|
242
242
|
|
|
243
243
|
{ action: "update", agent: "code-analysis.scout", config: { model: "openai/gpt-4o" } }
|
|
244
244
|
{ action: "update", agent: "code-analysis.scout", config: { acceptance: "" } } // clear the frontmatter default
|
|
245
|
-
{ action: "update", agent: "code-analysis.scout", config: { acceptanceRole: false } } // restore
|
|
245
|
+
{ action: "update", agent: "code-analysis.scout", config: { acceptanceRole: false } } // restore default lightweight attestation
|
|
246
246
|
{ action: "delete", agent: "scout" }
|
|
247
247
|
|
|
248
248
|
{ action: "eject", agent: "reviewer" }
|
|
@@ -431,13 +431,9 @@ A gate given as `{ command, output: "json" }` runs like a string gate, and then
|
|
|
431
431
|
|
|
432
432
|
Acceptance evidence levels are `auto`, `none`, `attested`, `checked`, and `verified`. `acceptance: "auto"` is the default.
|
|
433
433
|
|
|
434
|
-
|
|
434
|
+
Automatic inference uses only the declared structured role: `acceptanceRole: "writer"` infers checked evidence, with `review: { agent: "reviewer", required: true }` for async and dynamic writers; `"read-only"` infers none; and an omitted role infers lightweight attestation. Task wording, risk vocabulary, and agent names do not affect inference. Explicit acceptance can raise or add policy, while `{ level: "none", reason: "..." }` disables inferred gates according to the existing policy rules.
|
|
435
435
|
|
|
436
|
-
|
|
437
|
-
- Tasks classified as read-only infer no acceptance by default, including reviews of release, migration, or security work; those topics do not turn a read-only task into implementation. With role metadata omitted, unknown risk-topic tasks retain their gate even when the agent name suggests a reviewer. Explicit acceptance requests still apply.
|
|
438
|
-
- Normal writer tasks infer checked evidence without review.
|
|
439
|
-
|
|
440
|
-
Agent frontmatter or `subagents.agentOverrides` may set `acceptanceRole: "read-only" | "writer"` for ambiguous tasks. Explicit task mutation or no-edit intent wins over that role, while omitted metadata preserves the existing reviewer/scout/worker name heuristics. The role affects acceptance inference only and does not change tool access.
|
|
436
|
+
Agent frontmatter or `subagents.agentOverrides` may set `acceptanceRole`. The role affects acceptance inference only and does not change tool access. Review is a separate gate configured with `acceptance.review`.
|
|
441
437
|
|
|
442
438
|
Edge cases:
|
|
443
439
|
|
package/inspector-runner.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createJiti } from "jiti";
|
|
2
2
|
|
|
3
3
|
const jiti = createJiti(import.meta.url);
|
|
4
|
-
const { runInspector } = await jiti.import("./src/inspectors/inspector-runner.
|
|
4
|
+
const { runInspector } = await jiti.import("./src/inspectors/inspector-runner.js");
|
|
5
5
|
|
|
6
6
|
try {
|
|
7
7
|
runInspector();
|
package/package.json
CHANGED
|
@@ -101,6 +101,7 @@ For an authorized complex delegated workflow, read `prompting-and-roles.md` and
|
|
|
101
101
|
- Keep the parent on the ordinary strong default model. Route workers/scouts to a fast capable tier, serious reviews to a strong tier, and top reasoning to bounded read-only critique.
|
|
102
102
|
- Exact model names are deployment policy. Put them in user/project settings or profiles, not package guidance.
|
|
103
103
|
- Give every child a compact meta-prompt checklist: objective; repo/cwd/ref; authority/edit boundary; relevant files/contracts and constraints; success/acceptance criteria; validation; expected output/report; and stop/ask conditions. See `references/prompting-and-roles.md`.
|
|
104
|
+
- Before launching a writer for substantial mutation work, classify it as single-seam or multi-seam and partition multi-seam work across exclusive component owners, gates, and durable handoffs before an integration-only owner. See `references/multi-lane-orchestration.md`.
|
|
104
105
|
- For mutation work, use an isolated lane/worktree when isolation, overlap, or concurrent juggling matters; keep one writer per cwd/worktree. See `references/multi-lane-orchestration.md` for lane mechanics.
|
|
105
106
|
- Keep long/high-output validation out of chat: prefer `interactive_shell` dispatch/background monitors, bounded logs, or subagent-owned reports; return a concise summary plus report path unless same-turn output is required. Do not use `interactive_shell` as an implicit fallback for a failed `subagent` lane; see `references/execution-controls.md`.
|
|
106
107
|
- Treat subagent workflow, child launch, prompt runtime, extension load, and child tooling setup failures as lane infrastructure blockers. Stop, report the exact failure and run/worktree state, verify a clean worktree or capture a partial diff, and use only a clear same-protocol retry or an owner-approved execution-mode fallback.
|
|
@@ -131,7 +131,7 @@ That is only a starting point. Omit `package` for the traditional unqualified ru
|
|
|
131
131
|
|
|
132
132
|
`acceptance` is a single-agent launch default. Use a scalar level such as `checked` or an inline/block YAML map such as `{ level: "none", reason: "lightweight lookup" }`. An explicit tool-call value wins; scripted workflow child acceptance remains configured on the `runs.run` or `runs.all` item. Management create/update accepts the same policy object, and `acceptance: ""` clears the frontmatter default (`false` remains the deprecated disabled-policy shorthand).
|
|
133
133
|
|
|
134
|
-
`acceptanceRole` is `read-only` or `writer` and controls automatic acceptance inference only.
|
|
134
|
+
`acceptanceRole` is `read-only` or `writer` and controls automatic acceptance inference only. The structured role is authoritative; task wording and agent names do not escalate acceptance. Omission uses lightweight attestation. The field does not grant or revoke tools. Management accepts `false` or an empty string to clear it.
|
|
135
135
|
|
|
136
136
|
`tools` is a strict child allowlist, not an extension loader. For a named extension tool, keep its registered name in `tools` and load its provider through normal Pi discovery, `extensions`, a path-like `tools` entry, or `subagentOnlyExtensions`. For example, pair `tools: read, fixture_search` with `subagentOnlyExtensions: ./tools/fixture-search.ts` when the provider should exist only in that agent's child sessions. The child now fails with the unavailable names and provider-loading guidance instead of silently continuing when a requested tool is absent; internal `structured_output` is allowed automatically when an output schema requires it.
|
|
137
137
|
|
|
@@ -4,6 +4,14 @@ Use this reference when several independent tasks need coordinated workers, work
|
|
|
4
4
|
|
|
5
5
|
Create lanes only after delegation is operator-authorized and each lane materially improves evidence, independent review, specialization, useful parallelism, or isolated execution. Do not manufacture parallelism: keep dependent work serial, and only split work when each lane has a distinct decision and useful output.
|
|
6
6
|
|
|
7
|
+
## Mandatory implementation-topology preflight
|
|
8
|
+
|
|
9
|
+
Before launching a writer for substantial mutation work, classify the implementation as **single-seam** or **multi-seam**. Two or more independently testable contracts or source boundaries make it multi-seam. One PR does not imply one writer, and the one-writer-per-worktree rule prevents concurrent ownership conflicts; it does not authorize an issue-wide commission.
|
|
10
|
+
|
|
11
|
+
Record the classification and evidence on a lane board before writer launch. For multi-seam work, give each isolated component writer exclusive file or contract ownership and focused validation gates. Require every component to produce a committed or otherwise durable handoff, then start a separate integration-only owner after the component handoffs are ready. Mechanically reject and repartition a writer prompt if it owns all major outcomes across multiple independent boundaries.
|
|
12
|
+
|
|
13
|
+
A single complete writer remains valid only when the board records evidence that the work is genuinely one seam or that splitting it would create overlapping ownership or artificial handoffs. This preflight must not manufacture parallelism: do not split tightly coupled work merely to increase the lane count.
|
|
14
|
+
|
|
7
15
|
## Lane board and authority
|
|
8
16
|
|
|
9
17
|
Before multiple mutation-capable lanes start, record this board in the parent context:
|
|
@@ -118,7 +118,7 @@ Use this after implementation when the user or applicable instructions request d
|
|
|
118
118
|
|
|
119
119
|
### Staged fix orchestration technique
|
|
120
120
|
|
|
121
|
-
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
|
|
121
|
+
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 mutation ownership explicit in the `workflowScript`:
|
|
122
122
|
|
|
123
123
|
When staged seams are available, a low-tier writer should not receive the
|
|
124
124
|
end-to-end issue. Use `runs.lanes` inside `workflowScript` to keep stages narrow:
|
|
@@ -126,44 +126,45 @@ a scout/red test, helper-only change, one render seam, validation, minimality
|
|
|
126
126
|
challenge, or fresh review. Give the writer only its assigned implementation
|
|
127
127
|
stage; keep sequencing and synthesis with the parent.
|
|
128
128
|
|
|
129
|
-
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.
|
|
130
|
-
2.
|
|
131
|
-
3.
|
|
129
|
+
1. A parallel read-only planning fanout, one reviewer per issue cluster or review angle. Each child inspects the real diff and returns exact files, line refs, proposed fixes, and focused validation. They must not edit.
|
|
130
|
+
2. Classify the accepted fixes on the lane board before writer launch. If issue clusters are independently testable source or contract boundaries, use isolated component writers with exclusive file/contract ownership and focused gates. Each component must commit or produce another durable handoff; only after those handoffs are ready, start one integration-only owner.
|
|
131
|
+
3. Use one writer for the complete fix only when the accepted fixes are one tightly coupled existing diff/seam and the lane board records evidence that splitting would create overlapping ownership or artificial handoffs. Give that writer the planning summaries, accepted scope, stop rules, and verification contract.
|
|
132
|
+
4. Run fresh-context, read-only validation against the integrated or single-seam result. Validators use distinct angles and report pass/fail, remaining blockers, and missing verification.
|
|
132
133
|
|
|
133
134
|
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.
|
|
134
135
|
|
|
135
136
|
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.
|
|
136
137
|
|
|
137
|
-
|
|
138
|
+
Single-seam example shape (the lane board records that these are review angles on one tightly coupled deployment-lifecycle diff, not independent implementation contracts):
|
|
138
139
|
|
|
139
140
|
```typescript
|
|
140
141
|
subagent({
|
|
141
142
|
async: true,
|
|
142
143
|
context: "fresh",
|
|
143
144
|
workflowScript: `
|
|
144
|
-
// Stage 1: parallel read-only
|
|
145
|
+
// Stage 1: parallel read-only review angles on one recorded single seam
|
|
145
146
|
const plans = await runs.all([
|
|
146
|
-
{ key: "
|
|
147
|
-
{ key: "
|
|
148
|
-
{ key: "
|
|
147
|
+
{ key: "correctness-plan", agent: "reviewer", phase: "Planning", label: "Review lifecycle correctness", task: "Plan correctness fixes for the same deployment-lifecycle diff. Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "plans/correctness.md", outputMode: "file-only" },
|
|
148
|
+
{ key: "regression-plan", agent: "reviewer", phase: "Planning", label: "Review lifecycle regressions", task: "Plan regression coverage for the same deployment-lifecycle diff. Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "plans/regressions.md", outputMode: "file-only" },
|
|
149
|
+
{ key: "minimality-plan", agent: "reviewer", phase: "Planning", label: "Review lifecycle minimality", task: "Plan minimality fixes for the same deployment-lifecycle diff. Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "plans/minimality.md", outputMode: "file-only" }
|
|
149
150
|
]);
|
|
150
151
|
|
|
151
|
-
// Stage 2:
|
|
152
|
+
// Stage 2: one writer for this lane-board-recorded single seam.
|
|
152
153
|
// Under outputMode "file-only" the awaited .output is the saved-output
|
|
153
154
|
// reference, so pass those managed artifact references to the writer.
|
|
154
155
|
const worker = await runs.run("apply-fixes", {
|
|
155
156
|
agent: "worker",
|
|
156
157
|
phase: "Implementation",
|
|
157
158
|
label: "Apply accepted fixes",
|
|
158
|
-
task: "Apply only the accepted fixes
|
|
159
|
+
task: "Apply only the accepted fixes to the one deployment-lifecycle seam. The lane board records that splitting this existing diff would create overlapping ownership. You are the sole writer for this seam. Run focused validation and report changed files, commands, failures, and remaining issues.\\n\\nCorrectness plan: " + plans[0].output + "\\n\\nRegression plan: " + plans[1].output + "\\n\\nMinimality plan: " + plans[2].output,
|
|
159
160
|
output: "worker/fixes.md",
|
|
160
161
|
outputMode: "file-only"
|
|
161
162
|
});
|
|
162
163
|
|
|
163
164
|
// Stage 3: parallel read-only validation fanout
|
|
164
165
|
const validations = await runs.all([
|
|
165
|
-
{ key: "validate-
|
|
166
|
-
{ key: "validate-
|
|
166
|
+
{ key: "validate-behavior", agent: "reviewer", phase: "Validation", label: "Validate lifecycle behavior", task: "Validate behavior in the post-worker deployment-lifecycle diff. Start from the worker result: " + worker.output + ". Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "validation/behavior.md", outputMode: "file-only" },
|
|
167
|
+
{ key: "validate-minimality", agent: "reviewer", phase: "Validation", label: "Validate lifecycle minimality", task: "Validate minimality in the same post-worker deployment-lifecycle diff. Start from the worker result: " + worker.output + ". Do not modify project/source files; returning findings via the configured output artifact is allowed.", output: "validation/minimality.md", outputMode: "file-only" }
|
|
167
168
|
]);
|
|
168
169
|
|
|
169
170
|
return { worker: worker.output, validations: validations.map(v => v.output) };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-management.d.ts","sourceRoot":"","sources":["../../../src/agents/agent-management.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EACN,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"agent-management.d.ts","sourceRoot":"","sources":["../../../src/agents/agent-management.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EACN,KAAK,WAAW,EAiBhB,MAAM,aAAa,CAAC;AAcrB,OAAO,KAAK,EAAkE,OAAO,EAAE,eAAe,EAAoB,MAAM,oBAAoB,CAAC;AAIrJ,OAAO,EAAsB,KAAK,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAKzF,KAAK,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,eAAe,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC;AAE3O,UAAU,gBAAgB;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAoMD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CA8EnE;AAWD,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAsD7G;AA8jBD,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,iBAAiB,GAAG,eAAe,CAAC,OAAO,CAAC,CAuCrG;AAmID,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,iBAAiB,GAAG,eAAe,CAAC,OAAO,CAAC,CAiDvG;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,iBAAiB,GAAG,eAAe,CAAC,OAAO,CAAC,CA+DvG;AAoJD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,iBAAiB,GAAG,eAAe,CAAC,OAAO,CAAC,CAcjI"}
|
|
@@ -86,24 +86,24 @@ function parsePackageConfig(value) {
|
|
|
86
86
|
function allAgents(d) {
|
|
87
87
|
return [...d.builtin, ...d.package, ...d.user, ...d.project];
|
|
88
88
|
}
|
|
89
|
-
function effectiveAgentsForScope(scope, d, runtimeAgentOwner) {
|
|
89
|
+
function effectiveAgentsForScope(scope, d, runtimeAgentOwner, preferredModelProvider) {
|
|
90
90
|
let agents = mergeAgentsForScope(scope, d.user, d.project, d.builtin, d.package);
|
|
91
91
|
if (runtimeAgentOwner) {
|
|
92
|
-
agents = mergeRuntimeAgents(runtimeAgentOwner, { agents }, allAgents(d)).agents;
|
|
92
|
+
agents = mergeRuntimeAgents(runtimeAgentOwner, { agents }, allAgents(d), { cwd: d.cwd, scope, preferredModelProvider }).agents;
|
|
93
93
|
}
|
|
94
94
|
return agents;
|
|
95
95
|
}
|
|
96
|
-
function availableAgentNamesFromDiscovery(d, runtimeAgentOwner) {
|
|
97
|
-
const agents = runtimeAgentOwner ? effectiveAgentsForScope("both", d, runtimeAgentOwner) : allAgents(d);
|
|
96
|
+
function availableAgentNamesFromDiscovery(d, runtimeAgentOwner, preferredModelProvider) {
|
|
97
|
+
const agents = runtimeAgentOwner ? effectiveAgentsForScope("both", d, runtimeAgentOwner, preferredModelProvider) : allAgents(d);
|
|
98
98
|
return [...new Set(agents.map((agent) => agent.name))].sort((a, b) => a.localeCompare(b));
|
|
99
99
|
}
|
|
100
100
|
function availableAgentNames(cwd) {
|
|
101
101
|
return availableAgentNamesFromDiscovery(discoverAgentsAll(cwd));
|
|
102
102
|
}
|
|
103
|
-
function findAgentsInDiscovery(name, d, scope = "both", runtimeAgentOwner) {
|
|
103
|
+
function findAgentsInDiscovery(name, d, scope = "both", runtimeAgentOwner, preferredModelProvider) {
|
|
104
104
|
const raw = name.trim();
|
|
105
105
|
const sanitized = sanitizeName(raw);
|
|
106
|
-
const scoped = effectiveAgentsForScope(scope, d, runtimeAgentOwner);
|
|
106
|
+
const scoped = effectiveAgentsForScope(scope, d, runtimeAgentOwner, preferredModelProvider);
|
|
107
107
|
let resolved = resolveAgentName(raw, scoped);
|
|
108
108
|
if (!resolved.agent && !resolved.error && sanitized !== raw)
|
|
109
109
|
resolved = resolveAgentName(sanitized, scoped);
|
|
@@ -194,7 +194,7 @@ export function editableAgentConfig(agent) {
|
|
|
194
194
|
delete next.thinking;
|
|
195
195
|
return next;
|
|
196
196
|
};
|
|
197
|
-
const { override: _override, description: _description, output: _output, outputMode: _outputMode, defaultReads: _defaultReads, model: _model, fast: _fast, thinking: _thinking, systemPromptMode: _systemPromptMode, inheritProjectContext: _inheritProjectContext, inheritGlobalContext: _inheritGlobalContext, inheritSkills: _inheritSkills, defaultContext: _defaultContext, acceptanceRole: _acceptanceRole, disabled: _disabled, systemPrompt: _systemPrompt, skills: _skills, skillPath: _skillPath, tools: _tools, excludeTools: _excludeTools, mcpDirectTools: _mcpDirectTools, allowNestedSubagents: _allowNestedSubagents, allowedAgents: _allowedAgents, subagentOnlyExtensions: _subagentOnlyExtensions, mutationTools: _mutationTools,
|
|
197
|
+
const { override: _override, description: _description, output: _output, outputMode: _outputMode, defaultReads: _defaultReads, model: _model, fast: _fast, thinking: _thinking, systemPromptMode: _systemPromptMode, inheritProjectContext: _inheritProjectContext, inheritGlobalContext: _inheritGlobalContext, inheritSkills: _inheritSkills, defaultContext: _defaultContext, acceptanceRole: _acceptanceRole, disabled: _disabled, systemPrompt: _systemPrompt, skills: _skills, skillPath: _skillPath, tools: _tools, excludeTools: _excludeTools, mcpDirectTools: _mcpDirectTools, allowNestedSubagents: _allowNestedSubagents, allowedAgents: _allowedAgents, subagentOnlyExtensions: _subagentOnlyExtensions, mutationTools: _mutationTools, toolBudget: _toolBudget, ...editable } = withoutExtensions;
|
|
198
198
|
if (!base) {
|
|
199
199
|
return withDeclaredExtensionPaths(withoutSettingsDefaults({
|
|
200
200
|
...withoutExtensions,
|
|
@@ -228,7 +228,6 @@ export function editableAgentConfig(agent) {
|
|
|
228
228
|
...(base.extensions !== undefined ? { extensions: [...base.extensions] } : {}),
|
|
229
229
|
...(base.subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions: [...base.subagentOnlyExtensions] } : {}),
|
|
230
230
|
...(base.mutationTools !== undefined ? { mutationTools: [...base.mutationTools] } : {}),
|
|
231
|
-
...(base.completionGuard !== undefined ? { completionGuard: base.completionGuard } : {}),
|
|
232
231
|
...(base.toolBudget !== undefined ? { toolBudget: base.toolBudget } : {}),
|
|
233
232
|
}, agent.filePath);
|
|
234
233
|
}
|
|
@@ -318,11 +317,6 @@ export function preservedAgentFrontmatterFields(agent, cfg) {
|
|
|
318
317
|
changed("defaultProgress");
|
|
319
318
|
if (hasKey(cfg, "maxSubagentDepth"))
|
|
320
319
|
changed("maxSubagentDepth");
|
|
321
|
-
if (hasKey(cfg, "completionGuard")) {
|
|
322
|
-
changed("completionGuard");
|
|
323
|
-
if (cfg.completionGuard === true)
|
|
324
|
-
fields.add("completionGuard");
|
|
325
|
-
}
|
|
326
320
|
if (hasKey(cfg, "toolBudget"))
|
|
327
321
|
changed("toolBudget");
|
|
328
322
|
return fields;
|
|
@@ -642,11 +636,6 @@ function applyAgentConfig(target, cfg) {
|
|
|
642
636
|
else
|
|
643
637
|
return "config.maxSubagentDepth must be an integer >= 0 or false when provided.";
|
|
644
638
|
}
|
|
645
|
-
if (hasKey(cfg, "completionGuard")) {
|
|
646
|
-
if (typeof cfg.completionGuard !== "boolean")
|
|
647
|
-
return "config.completionGuard must be a boolean when provided.";
|
|
648
|
-
target.completionGuard = cfg.completionGuard;
|
|
649
|
-
}
|
|
650
639
|
if (hasKey(cfg, "toolBudget")) {
|
|
651
640
|
if (cfg.toolBudget === false || cfg.toolBudget === "")
|
|
652
641
|
delete target.toolBudget;
|
|
@@ -668,7 +657,6 @@ function applyAgentConfig(target, cfg) {
|
|
|
668
657
|
target.mutationTools?.length ? "mutationTools" : undefined,
|
|
669
658
|
target.skills?.length || target.skillPath?.length ? "skills" : undefined,
|
|
670
659
|
target.maxSubagentDepth !== undefined ? "maxSubagentDepth" : undefined,
|
|
671
|
-
target.completionGuard !== undefined ? "completionGuard" : undefined,
|
|
672
660
|
target.toolBudget ? "toolBudget" : undefined,
|
|
673
661
|
].filter((field) => Boolean(field));
|
|
674
662
|
if (unsupported.length > 0)
|
|
@@ -1019,8 +1007,6 @@ function formatAgentDetail(agent) {
|
|
|
1019
1007
|
lines.push("Progress: true");
|
|
1020
1008
|
if (agent.maxSubagentDepth !== undefined)
|
|
1021
1009
|
lines.push(`Max subagent depth: ${agent.maxSubagentDepth}`);
|
|
1022
|
-
if (agent.completionGuard === false)
|
|
1023
|
-
lines.push("Completion guard: false");
|
|
1024
1010
|
if (agent.toolBudget)
|
|
1025
1011
|
lines.push(`Tool budget: ${JSON.stringify(agent.toolBudget)}`);
|
|
1026
1012
|
if (agent.memory)
|
|
@@ -1032,7 +1018,7 @@ function formatAgentDetail(agent) {
|
|
|
1032
1018
|
export function handleList(params, ctx) {
|
|
1033
1019
|
const scope = normalizeListScope(params.agentScope) ?? "both";
|
|
1034
1020
|
const d = discoverAgentsAll(ctx.cwd, ctx.model?.provider);
|
|
1035
|
-
let scopedAgents = effectiveAgentsForScope(scope, d, ctx.runtimeAgentOwner);
|
|
1021
|
+
let scopedAgents = effectiveAgentsForScope(scope, d, ctx.runtimeAgentOwner, ctx.model?.provider);
|
|
1036
1022
|
scopedAgents = scopedAgents
|
|
1037
1023
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
1038
1024
|
const capabilityCeiling = resolveCurrentSubagentCapabilityCeiling(ctx.currentSessionId);
|
|
@@ -1089,7 +1075,7 @@ function handleModels(params, ctx) {
|
|
|
1089
1075
|
if (!scope)
|
|
1090
1076
|
return result("agentScope must be 'user', 'project', or 'both' for models.", true);
|
|
1091
1077
|
const discovered = discoverAgentsAll(ctx.cwd, ctx.model?.provider);
|
|
1092
|
-
const effectiveAgents = effectiveAgentsForScope(scope, discovered, ctx.runtimeAgentOwner)
|
|
1078
|
+
const effectiveAgents = effectiveAgentsForScope(scope, discovered, ctx.runtimeAgentOwner, ctx.model?.provider)
|
|
1093
1079
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
1094
1080
|
const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
1095
1081
|
const currentModel = ctx.model ? { provider: ctx.model.provider, id: ctx.model.id } : undefined;
|
|
@@ -1097,7 +1083,7 @@ function handleModels(params, ctx) {
|
|
|
1097
1083
|
const capabilityCeiling = resolveCurrentSubagentCapabilityCeiling(ctx.currentSessionId);
|
|
1098
1084
|
let selectedAgents = effectiveAgents;
|
|
1099
1085
|
if (requestedAgent) {
|
|
1100
|
-
const matches = findAgentsInDiscovery(requestedAgent, discovered, scope, ctx.runtimeAgentOwner);
|
|
1086
|
+
const matches = findAgentsInDiscovery(requestedAgent, discovered, scope, ctx.runtimeAgentOwner, ctx.model?.provider);
|
|
1101
1087
|
const diagnostics = diagnosticsForScope(discovered.agentDiagnostics, scope);
|
|
1102
1088
|
const normalizedName = sanitizeName(requestedAgent);
|
|
1103
1089
|
const diagnostic = findBlockingAgentDiagnostic(requestedAgent, matches, diagnostics)
|
|
@@ -1108,7 +1094,7 @@ function handleModels(params, ctx) {
|
|
|
1108
1094
|
if (distinctNames.length > 1)
|
|
1109
1095
|
return result(`Ambiguous agent alias or name '${params.agent}': ${distinctNames.sort((a, b) => a.localeCompare(b)).join(", ")}`, true);
|
|
1110
1096
|
if (!matches.length) {
|
|
1111
|
-
return result(`Agent '${params.agent}' not found. Available: ${availableAgentNamesFromDiscovery(discovered, ctx.runtimeAgentOwner).join(", ") || "none"}.`, true);
|
|
1097
|
+
return result(`Agent '${params.agent}' not found. Available: ${availableAgentNamesFromDiscovery(discovered, ctx.runtimeAgentOwner, ctx.model?.provider).join(", ") || "none"}.`, true);
|
|
1112
1098
|
}
|
|
1113
1099
|
selectedAgents = [matches[0]];
|
|
1114
1100
|
}
|