pi-subagents 0.62.0 → 0.63.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/docs/agents.md +5 -4
  3. package/docs/configuration.md +28 -2
  4. package/docs/models.md +5 -5
  5. package/docs/observability.md +4 -1
  6. package/docs/tool-reference.md +2 -2
  7. package/package.json +1 -1
  8. package/skills/pi-subagents/references/management-authoring-rpc.md +1 -1
  9. package/skills/pi-subagents/references/prompting-and-roles.md +3 -3
  10. package/src/agents/agent-management.ts +22 -4
  11. package/src/agents/agents.ts +107 -125
  12. package/src/api/shared-types.ts +3 -0
  13. package/src/extension/config.ts +20 -0
  14. package/src/inspectors/herdr/inspector-runner.ts +19 -13
  15. package/src/runs/background/active-async-capacity.ts +0 -1
  16. package/src/runs/background/async-execution.ts +53 -7
  17. package/src/runs/background/async-resume.ts +3 -0
  18. package/src/runs/background/async-status.ts +18 -2
  19. package/src/runs/background/notify.ts +13 -1
  20. package/src/runs/background/run-status.ts +22 -2
  21. package/src/runs/background/subagent-runner.ts +30 -2
  22. package/src/runs/background/wait-completions.ts +13 -0
  23. package/src/runs/foreground/subagent-executor.ts +35 -3
  24. package/src/runs/shared/acceptance.ts +15 -9
  25. package/src/runs/shared/lane-metadata.ts +24 -3
  26. package/src/runs/shared/parallel-handoff.ts +4 -0
  27. package/src/runs/shared/pi-args.ts +8 -2
  28. package/src/runs/shared/task-intent.ts +5 -2
  29. package/src/runs/shared/worktree.ts +467 -63
  30. package/src/shared/types.ts +29 -0
  31. package/src/shared/utils.ts +18 -7
  32. package/src/slash/subagents-admin.ts +24 -12
  33. package/src/tui/fleet-status.ts +61 -2
  34. package/src/tui/fleet.ts +12 -7
  35. package/src/tui/render.ts +222 -14
  36. package/src/workflows/workflow-checklist.ts +441 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,34 @@
3
3
 
4
4
  ## [Unreleased]
5
5
 
6
+ ## [0.63.0] - 2026-09-01
7
+
8
+ ### Highlights
9
+ - Workflow progress is easier to scan in status, Fleet, and live widgets.
10
+ - Additional agent folders can now be configured without copying definitions into one directory.
11
+ - Worktrunk users get managed worktrees automatically, with native Git available as the fallback.
12
+ - Fleet can jump straight into the selected child run's Herdr inspector.
13
+ - Async runs clean up and report edge cases more reliably.
14
+
15
+ ### Added
16
+ - Show workflow progress as stacked checklist summaries in status, Fleet, and live widget views (#1806).
17
+ - Add configurable extra agent scan directories with one-segment wildcard expansion. Thanks to [@mystery4f](https://github.com/mystery4f) for #1801.
18
+ - Make Worktrunk a first-class managed worktree provider, selected automatically when available with native Git as the fallback (#1800).
19
+ - Let Fleet open the selected async child in its child-specific Herdr inspector. Thanks to [@stekman08](https://github.com/stekman08) for #1790.
20
+
21
+ ### Changed
22
+ - Show workflow checklist phases first in collapsed views, while keeping child details available when expanded (#1810).
23
+
24
+ ### Fixed
25
+ - Keep isolated test runs from writing agent definitions into an inherited `PI_CODING_AGENT_DIR`. Thanks to [@mapleluvr](https://github.com/mapleluvr) for #1809.
26
+ - Prevent nested tool-availability diagnostics from failing an otherwise valid parent result. Thanks to [@robertvangor](https://github.com/robertvangor) for #1802.
27
+ - Free async capacity correctly after workflows finish, even when saved step status is stale. Thanks to [@boggylp](https://github.com/boggylp) for #1804.
28
+ - Make `subagents.agentOverrides.<name>` replace matching custom-agent frontmatter fields, consistently with builtin agents. Thanks to [@expoli](https://github.com/expoli) for #1796.
29
+ - Strip the trailing Pi turn-timing footer from child output. Thanks to [@fkhawajagh](https://github.com/fkhawajagh) for #1792.
30
+ - Keep inferred acceptance reports out of reviewer and read-only child prompts. Thanks to [@expoli](https://github.com/expoli) for #1797.
31
+ - Preserve coordinated read-only intent when direct async children resume, and show captured structured output in completion and status evidence. Thanks to [@fkhawajagh](https://github.com/fkhawajagh) for #1788.
32
+ - Keep macOS subagent tasks out of argv by delivering them through temporary files. Thanks to [@josephkallas](https://github.com/josephkallas) for #1793.
33
+
6
34
  ## [0.62.0] - 2026-08-31
7
35
 
8
36
  ### Highlights
package/docs/agents.md CHANGED
@@ -27,6 +27,7 @@ Discovery notes:
27
27
 
28
28
  - Project discovery also reads legacy `.agents/**/*.md` files. If both `.agents/` and the project config agents directory define the same parsed runtime agent name, the project config directory wins.
29
29
  - Nested subdirectories are discovered recursively. `.chain.md` files do not define agents.
30
+ - User and project settings can add extra recursive scan roots with `subagents.agentScanDirs`; fixed user/project agent directories keep higher priority than same-name agents from scan roots.
30
31
  - Installed Pi packages can expose agent directories from either `{"pi-subagents":{"agents":["./agents"]}}` or `{"pi":{"subagents":{"agents":["./agents"]}}}` in their package manifest. Package agents load above builtins and below user/project agents.
31
32
  - Use `agentScope: "user" | "project" | "both"` to control discovery. `both` is the default, and project definitions win runtime-name collisions.
32
33
 
@@ -189,9 +190,9 @@ The `researcher` builtin uses `web_search`, `fetch_content`, and `get_search_con
189
190
  pi install npm:pi-web-access
190
191
  ```
191
192
 
192
- ## Overriding builtins
193
+ ## Overriding builtins and custom agents
193
194
 
194
- You can override selected builtin fields without copying the whole agent. Overrides live in settings:
195
+ You can override selected agent fields without copying the whole agent. Overrides live in settings:
195
196
 
196
197
  - User: `~/.pi/agent/settings.json`
197
198
  - Project: project config settings file (`.pi/settings.json` in standard Pi)
@@ -213,9 +214,9 @@ Supported override fields: `description`, `output`, `outputMode`, `defaultReads`
213
214
 
214
215
  - `description` replaces the discovered description for builtin and custom agents, which lets list output show deployment-specific routing or model metadata.
215
216
  - Use `output: false`, `defaultReads: false`, `defaultContext: false`, or `acceptanceRole: false` to clear an inherited value.
216
- - 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.
217
+ - Use `tools: "inherit"` when that one role should omit its bundled or frontmatter tool allowlist and receive Pi's normal builtins and ambient extensions.
217
218
  - Project overrides beat user overrides.
218
- - 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.
219
+ - Matching package, user, and project agents also receive override fields, which replace the same fields declared in their frontmatter. This lets a shared agent keep its persona while local settings choose the effective model, context, tools, or other supported options.
219
220
 
220
221
  Disable and restore:
221
222
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  `pi-subagents` reads optional JSON config from `~/.pi/agent/extensions/subagent/config.json`. This page lists every key, plus the environment variables and the settings-file keys that affect config resolution.
4
4
 
5
- Settings-level keys (`subagents.defaultModel`, `defaultProvider`, `defaultThinking`, `defaultExtensions`, `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`, `agentScanDirs`, `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
 
@@ -18,6 +18,20 @@ By default, project settings resolve from the nearest parent directory that cont
18
18
 
19
19
  `"git-root"` keeps package discovery, project agents, chains, and `agentOverrides` anchored to the git worktree root when that root also has Pi project config. A nested project can still opt back into nearest-root behavior by setting `"projectRootResolution": "nearest"` in its own `.pi/settings.json`.
20
20
 
21
+ ## Extra agent scan directories (settings)
22
+
23
+ Add recursive user or project agent roots with `subagents.agentScanDirs` in Pi settings:
24
+
25
+ ```json
26
+ {
27
+ "subagents": {
28
+ "agentScanDirs": ["~/.pi/flows/*/agents"]
29
+ }
30
+ }
31
+ ```
32
+
33
+ Entries support `~` expansion. A single `*` path segment expands one directory level, so package-like folders can each expose an `agents/` directory. Missing directories are ignored. Fixed user/project agent directories still win over same-name agents from scan roots.
34
+
21
35
  ## `modelExclusions`
22
36
 
23
37
  ```json
@@ -356,7 +370,7 @@ Overrides the command used to launch child Pi processes. Package wrappers can se
356
370
  export PI_SUBAGENT_TASK_DELIVERY=file # auto | file (default: auto)
357
371
  ```
358
372
 
359
- Controls how the task text reaches the child Pi process. `auto` (default) passes short tasks as an inline argv token and writes tasks longer than 8000 characters to a temp `task.md` referenced as `@<path>`. `file` always uses a temp file, keeping the task out of argv entirely.
373
+ Controls how the task text reaches the child Pi process. `auto` (default) passes short non-macOS tasks as an inline argv token, and writes macOS tasks plus tasks longer than 8000 characters to a temp `task.md` referenced as `@<path>`. `file` always uses a temp file, keeping the task out of argv entirely.
360
374
 
361
375
  Use `file` on hosts where endpoint protection (EDR) pre-execution scanning denies child processes whose command line embeds a long natural-language task — that denial surfaces as an immediate zero-activity `SIGKILL`. Independently of this setting, startup retries automatically escalate to file delivery after an unexplained zero-activity `SIGKILL`. Empty, whitespace-only, or unrecognized values fall back to `auto`.
362
376
 
@@ -392,6 +406,18 @@ The default injected guidance tells children to use `contact_supervisor` with `r
392
406
 
393
407
  Sets the base directory for `worktree: true` runs. Relative paths resolve from the repository root, `~/...` expands to your home directory, and `PI_SUBAGENTS_WORKTREE_DIR` is used when config is unset. The default remains the system temp directory.
394
408
 
409
+ ## `worktreeProvider`
410
+
411
+ ```json
412
+ { "worktreeProvider": "auto", "worktreeBranchPrefix": "pi-subagents/" }
413
+ ```
414
+
415
+ Selects the managed worktree allocator: `auto` (the default) uses Worktrunk when its machine-readable interface is available and otherwise falls back to Pi's native Git worktrees; `native` always uses Pi's Git implementation; and `worktrunk` fails closed when Worktrunk is unavailable or incompatible. A configured `worktreeBaseDir` (or `PI_SUBAGENTS_WORKTREE_DIR`) selects native allocation and cannot be combined with explicit `worktrunk`.
416
+
417
+ `worktreeBranchPrefix` is normalized as a Git ref namespace and defaults to `pi-subagents/`. Branch names include readable task/lane identity plus run and fan-out indexes. Pi continues to own setup hooks, launch, handoff/diff evidence, resume, and cleanup; Worktrunk is used only to allocate and report the worktree path.
418
+
419
+ Set `worktree` to `true` to make managed worktree isolation the default for launches that omit the per-call `worktree` flag. A per-call value still takes precedence.
420
+
395
421
  ## `worktreeSetupHook`
396
422
 
397
423
  ```json
package/docs/models.md CHANGED
@@ -11,7 +11,7 @@ Builtin agents inherit your current Pi default model. This keeps new installs fr
11
11
  - `subagents.agentOverridesByProvider.<provider>.<name>` — layer role fields for the active parent provider.
12
12
  - Per-run overrides — for one launch only.
13
13
 
14
- Precedence, strongest first: per-run override → agent frontmatter `model` → provider-scoped role override → `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.
14
+ Precedence, strongest first: per-run override → provider-scoped role override → `agentOverrides.<name>.model` → agent frontmatter `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.
15
15
 
16
16
  Use `model: "inherit"` in agent frontmatter or `agentOverrides.<name>.model` to select the current parent session model explicitly.
17
17
 
@@ -81,7 +81,7 @@ For a persistent role override with a backup model for provider failures:
81
81
  }
82
82
  ```
83
83
 
84
- `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.
84
+ `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` 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.
85
85
 
86
86
  ## Fast mode
87
87
 
@@ -116,7 +116,7 @@ One interaction worth knowing for tier 4: forked context over an Anthropic paren
116
116
 
117
117
  ## Thinking level defaults
118
118
 
119
- Set `subagents.defaultThinking` to give builtin, package, user, and project agents without a `thinking` value a shared thinking level, independent of the parent session's default. Project settings win over user settings. Explicit frontmatter, `agentOverrides.<name>.thinking`, and per-run thinking overrides still win. `thinking: false` remains an explicit opt-out:
119
+ Set `subagents.defaultThinking` to give builtin, package, user, and project agents without a `thinking` value a shared thinking level, independent of the parent session's default. Project settings win over user settings. Matching `agentOverrides.<name>.thinking` and per-run thinking overrides replace frontmatter; otherwise explicit frontmatter remains in effect. `thinking: false` remains an explicit opt-out:
120
120
 
121
121
  ```json
122
122
  {
@@ -129,7 +129,7 @@ Set `subagents.defaultThinking` to give builtin, package, user, and project agen
129
129
  }
130
130
  ```
131
131
 
132
- 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.
132
+ 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 or replace custom-agent frontmatter thinking.
133
133
 
134
134
  ### Thinking ceiling
135
135
 
@@ -154,7 +154,7 @@ Set `subagents.defaultExtensions` to give builtin, package, user, and project ag
154
154
  - Empty array: sets `extensions: []` for agents that do not explicitly define it, disabling ambient extension loading.
155
155
  - Non-empty array: supplies that allowlist to agents that do not explicitly define one.
156
156
 
157
- Project settings win over user settings. Use `agentOverrides.<name>.extensions` for per-agent settings; explicit custom-agent frontmatter remains authoritative.
157
+ Project settings win over user settings. Use `agentOverrides.<name>.extensions` for per-agent settings; a matching override replaces custom-agent frontmatter for that field.
158
158
 
159
159
  ```json
160
160
  {
@@ -54,7 +54,7 @@ After you expand it:
54
54
  reviewer · running 38s · ↓ 1.1k window · 1.4k spent
55
55
  ```
56
56
 
57
- 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 usage. When providers report usage, `window` is the latest assistant turn's input plus cache-read tokens, while `spent` keeps the cumulative input-plus-output total. Old run artifacts without window data keep the existing token-total label. 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
+ 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 usage. When providers report usage, `window` is the latest assistant turn's input plus cache-read tokens, while `spent` keeps the cumulative input-plus-output total. Old run artifacts without window data keep the existing token-total label. The compact line counts active current-session work and Herdr project panes. Then use `↑`/`↓` or `j`/`k` to select a child and `Enter` to open the Fleet lobby; press `Enter` or `H` there to open its child-specific Herdr inspector. Printable navigation keys are never intercepted before activation.
58
58
 
59
59
  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` or `allowNestedSubagents: true`, its nested runs appear under that parent child in the main status tree instead of being hidden inside the child process.
60
60
 
@@ -70,6 +70,7 @@ Default keys:
70
70
  - `x`/`Ctrl+O` — toggle tool details
71
71
  - `r` — refresh
72
72
  - `Esc` — close
73
+ - `Enter` — open the selected inspectable async child in its child-specific Herdr inspector
73
74
  - `s` — compose an acknowledged message to a selected live async child; Tab cycles `steer`, `follow_up`, and `auto`
74
75
  - `D` — stop a selected child's top-level async run after confirmation
75
76
  - `H` — open the selected active async child in a Herdr inspector pane (Herdr 0.7.5+)
@@ -78,6 +79,8 @@ Set `fleetKeybindings` in the extension config to replace inspector-level keys w
78
79
 
79
80
  `Ctrl+Alt+F` opens the same inspector even while a foreground turn is active and slash input is queued.
80
81
 
82
+ Enter and `H` use the existing Herdr pane path. In a child-specific Herdr inspector, type ordinary guidance and press Enter to send it through the acknowledged steer channel; `steer <message>`, `status`, and `stop` remain available as explicit controls.
83
+
81
84
  Without a TUI, `/subagents-fleet` retains the textual `subagent({ action: "status", view: "fleet" })` fallback, and mutations use explicit commands: run `/subagents-stop` and pick from the selector, or use `/subagents-stop <run-id>` / `subagent({ action: "stop", id: "..." })` when you already know the id.
82
85
 
83
86
  Use `/subagents-detach [run-id]` only for an active foreground single-subagent run you want to leave running without terminating; the eventual result remains available through status/wait.
@@ -393,7 +393,7 @@ Acceptance evidence levels are `auto`, `none`, `attested`, `checked`, and `verif
393
393
  Review is a separate gate configured with `acceptance.review`:
394
394
 
395
395
  - Async, risky, and dynamic writer contexts infer checked evidence plus `review: { agent: "reviewer", required: true }`.
396
- - Read-only tasks infer lightweight attestation.
396
+ - Reviewer/read-only calls infer no acceptance by default; explicit acceptance requests still apply.
397
397
  - Normal writer tasks infer checked evidence without review.
398
398
 
399
399
  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.
@@ -420,7 +420,7 @@ Acceptance provenance is stored separately from child prose. `evidenceStatus` pr
420
420
 
421
421
  ### The acceptance report
422
422
 
423
- For `attested` or stricter levels, the child prompt includes a standardized acceptance section and asks for a fenced `acceptance-report` JSON block. With `outputSchema`, set `acceptance.report: "on"` to require the same report in the final `structured_output` call, or `"off"` to keep the fenced-report path. Omitting `report` preserves the default behavior. Runs without `outputSchema` never gain a standalone structured-output tool from this option.
423
+ For `attested` or stricter levels, the child prompt includes a standardized acceptance section and asks for a fenced `acceptance-report` JSON block. Reviewer/read-only inference resolves to `none`, so it does not add this section; explicit acceptance still does. With `outputSchema`, set `acceptance.report: "on"` to require the same report in the final `structured_output` call, or `"off"` to keep the fenced-report path. Omitting `report` preserves the default behavior. Runs without `outputSchema` never gain a standalone structured-output tool from this option.
424
424
 
425
425
  The parser canonicalizes known enum synonyms, snake_case report keys and wrappers, underscore fence tags, unambiguous scalar arrays, string booleans, and criterion-id separators. Unknown or ambiguous keys and enum values fail with field-level diagnostics. Explicit empty `changedFiles` and `testsAddedOrUpdated` arrays are recorded as not applicable; missing fields and empty required command or validation evidence still fail.
426
426
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-subagents",
3
- "version": "0.62.0",
3
+ "version": "0.63.0",
4
4
  "description": "Pi extension for single-agent delegation and scripted multi-agent workflows",
5
5
  "author": "Nico Bailon",
6
6
  "license": "MIT",
@@ -85,7 +85,7 @@ subagent({ action: "reset", agent: "reviewer" })
85
85
  Use management actions when the system needs to create or edit subagents on
86
86
  demand without dropping into raw file editing.
87
87
 
88
- Management actions create or update user/project agent files. `config.name` is the local frontmatter name; optional `config.package` registers and looks up the runtime name as `{package}.{name}`. Use the dotted runtime name for `get`, `update`, `delete`, slash commands, and scripted workflow steps. For small builtin changes such as a model swap, prefer `subagents.agentOverrides` in settings. Durable `.chain.md` definitions are legacy records, not a current authoring target; use `workflowScript` or `/prompt-workflow` for repeatable orchestration.
88
+ Management actions create or update user/project agent files. `config.name` is the local frontmatter name; optional `config.package` registers and looks up the runtime name as `{package}.{name}`. Use the dotted runtime name for `get`, `update`, `delete`, slash commands, and scripted workflow steps. For small agent changes such as a model swap, prefer `subagents.agentOverrides` in settings. Durable `.chain.md` definitions are legacy records, not a current authoring target; use `workflowScript` or `/prompt-workflow` for repeatable orchestration.
89
89
 
90
90
  ## Creating and Editing Agents by File
91
91
 
@@ -185,7 +185,7 @@ Builtin `worker` and `delegate` use strict tool allowlists and do not inherit am
185
185
 
186
186
  Builtin agents inherit the current Pi default model unless a run, user setting, project setting, or `subagents.defaultModel` overrides `model`. The table records recommended tier routing, not shipped hard defaults; explicit run, user, or project settings still win. Keep the parent/orchestrator on the ordinary strong default model unless parent/user policy says otherwise. Override builtin defaults before copying full agent files when a small tweak is enough.
187
187
 
188
- Set `subagents.defaultThinking` to apply a shared thinking level to builtin, package, user, and project agents whose frontmatter leaves `thinking` unset. Project settings win over user settings; explicit frontmatter (including `thinking: false`), `agentOverrides.<name>.thinking`, and per-run overrides remain more specific. This setting affects child agents only and does not change the parent session's default thinking level.
188
+ Set `subagents.defaultThinking` to apply a shared thinking level to builtin, package, user, and project agents whose frontmatter leaves `thinking` unset. Project settings win over user settings; matching `agentOverrides.<name>.thinking` and per-run overrides replace frontmatter, while an explicit frontmatter value remains in effect when no matching override is set. This setting affects child agents only and does not change the parent session's default thinking level.
189
189
 
190
190
  ```json
191
191
  {
@@ -288,8 +288,8 @@ Use `fallbackModels` when a tier has provider quota or availability risk. Prefer
288
288
  If a provider rejects model IDs with thinking suffixes, use
289
289
  `subagents.disableThinking: true` in user or project settings to clear bundled
290
290
  builtin thinking defaults globally. A higher-precedence per-agent `thinking`
291
- override can opt one builtin back in. Existing custom-agent frontmatter remains authoritative.
291
+ override can opt one builtin back in or replace custom-agent frontmatter thinking.
292
292
 
293
- Set `subagents.defaultExtensions` to give agents without an `extensions` field a shared child extension allowlist. Omit it to preserve ambient extension discovery, set it to `[]` to disable ambient extensions by default, or use `agentOverrides.<name>.extensions` for one agent. Explicit custom-agent frontmatter still wins.
293
+ Set `subagents.defaultExtensions` to give agents without an `extensions` field a shared child extension allowlist. Omit it to preserve ambient extension discovery, set it to `[]` to disable ambient extensions by default, or use `agentOverrides.<name>.extensions` for one agent. A matching override replaces custom-agent frontmatter for that field.
294
294
 
295
295
  Tool description modes live in `~/.pi/agent/extensions/subagent/config.json`, not `subagents` settings. The default uses split prompt metadata: a short tool description plus active `promptSnippet` and `promptGuidelines`. Set `toolDescriptionMode` to `full` or `compact` to force one description string, or `custom` to read `subagent-tool-description.md` from the project config dir or agent dir; invalid custom files fall back to full mode and the safety guidance is still appended.
@@ -250,13 +250,25 @@ function withDeclaredExtensionPaths(config: AgentConfig, filePath: string): Agen
250
250
  export function editableAgentConfig(agent: AgentConfig): AgentConfig {
251
251
  const { extensions: _extensions, ...withoutExtensions } = agent;
252
252
  const base = agent.override?.base;
253
+ const description = base?.description ?? agent.description;
254
+ const frontmatterFields = agent.source === "builtin" || agent.source === "runtime" ? undefined : readAgentFrontmatterFields(agent.filePath);
255
+ const hasDeclaredField = (...fields: string[]) => frontmatterFields === undefined || fields.some((field) => frontmatterFields.has(field));
256
+ const withoutSettingsDefaults = (config: AgentConfig): AgentConfig => {
257
+ if (!frontmatterFields) return config;
258
+ const next = { ...config };
259
+ if (!hasDeclaredField("model")) delete next.model;
260
+ if (!hasDeclaredField("thinking")) delete next.thinking;
261
+ return next;
262
+ };
253
263
  const {
254
264
  override: _override,
265
+ description: _description,
255
266
  output: _output,
256
267
  outputMode: _outputMode,
257
268
  defaultReads: _defaultReads,
258
269
  model: _model,
259
270
  fallbackModels: _fallbackModels,
271
+ fast: _fast,
260
272
  thinking: _thinking,
261
273
  systemPromptMode: _systemPromptMode,
262
274
  inheritProjectContext: _inheritProjectContext,
@@ -271,26 +283,30 @@ export function editableAgentConfig(agent: AgentConfig): AgentConfig {
271
283
  tools: _tools,
272
284
  excludeTools: _excludeTools,
273
285
  mcpDirectTools: _mcpDirectTools,
286
+ allowNestedSubagents: _allowNestedSubagents,
274
287
  subagentOnlyExtensions: _subagentOnlyExtensions,
275
288
  mutationTools: _mutationTools,
276
289
  completionGuard: _completionGuard,
290
+ toolBudget: _toolBudget,
277
291
  ...editable
278
292
  } = withoutExtensions;
279
293
  if (!base) {
280
- return withDeclaredExtensionPaths({
294
+ return withDeclaredExtensionPaths(withoutSettingsDefaults({
281
295
  ...withoutExtensions,
282
296
  ...(agent.extensionsFromDefault ? {} : agent.extensions !== undefined ? { extensions: [...agent.extensions] } : {}),
283
- }, agent.filePath);
297
+ }), agent.filePath);
284
298
  }
285
299
 
286
300
  return withDeclaredExtensionPaths({
287
301
  ...editable,
302
+ description,
288
303
  ...(base.output !== undefined ? { output: base.output } : {}),
289
304
  ...(base.outputMode !== undefined ? { outputMode: base.outputMode } : {}),
290
305
  ...(base.defaultReads !== undefined ? { defaultReads: [...base.defaultReads] } : {}),
291
- ...(base.model !== undefined ? { model: base.model } : {}),
306
+ ...(base.model !== undefined && hasDeclaredField("model") ? { model: base.model } : {}),
292
307
  ...(base.fallbackModels !== undefined ? { fallbackModels: [...base.fallbackModels] } : {}),
293
- ...(base.thinking !== undefined ? { thinking: base.thinking } : {}),
308
+ ...(base.fast !== undefined ? { fast: base.fast } : {}),
309
+ ...(base.thinking !== undefined && hasDeclaredField("thinking") ? { thinking: base.thinking } : {}),
294
310
  systemPromptMode: base.systemPromptMode,
295
311
  inheritProjectContext: base.inheritProjectContext,
296
312
  inheritGlobalContext: base.inheritGlobalContext,
@@ -304,10 +320,12 @@ export function editableAgentConfig(agent: AgentConfig): AgentConfig {
304
320
  ...(base.tools !== undefined ? { tools: [...base.tools] } : {}),
305
321
  ...(base.excludeTools !== undefined ? { excludeTools: [...base.excludeTools] } : {}),
306
322
  ...(base.mcpDirectTools !== undefined ? { mcpDirectTools: [...base.mcpDirectTools] } : {}),
323
+ ...(base.allowNestedSubagents !== undefined ? { allowNestedSubagents: base.allowNestedSubagents } : {}),
307
324
  ...(base.extensions !== undefined ? { extensions: [...base.extensions] } : {}),
308
325
  ...(base.subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions: [...base.subagentOnlyExtensions] } : {}),
309
326
  ...(base.mutationTools !== undefined ? { mutationTools: [...base.mutationTools] } : {}),
310
327
  ...(base.completionGuard !== undefined ? { completionGuard: base.completionGuard } : {}),
328
+ ...(base.toolBudget !== undefined ? { toolBudget: base.toolBudget } : {}),
311
329
  }, agent.filePath);
312
330
  }
313
331