pi-subagents 0.57.0 → 0.58.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 +39 -0
- package/docs/agents.md +13 -6
- package/docs/extension-api.md +39 -0
- package/docs/models.md +3 -3
- package/docs/tool-reference.md +3 -2
- package/docs/workflows.md +24 -0
- package/package.json +1 -1
- package/skills/pi-subagents/SKILL.md +2 -0
- package/skills/pi-subagents/references/execution-controls.md +1 -1
- package/skills/pi-subagents/references/management-authoring-rpc.md +1 -0
- package/skills/pi-subagents/references/prompting-and-roles.md +2 -2
- package/src/agents/agent-management.ts +23 -0
- package/src/agents/agent-serializer.ts +5 -0
- package/src/agents/agents.ts +38 -3
- package/src/agents/runtime-agent-events.ts +70 -0
- package/src/agents/runtime-agent-registry.ts +10 -2
- package/src/api/agents.ts +10 -5
- package/src/api/preflight.ts +26 -1
- package/src/extension/index.ts +15 -4
- package/src/extension/rpc.ts +35 -14
- package/src/extension/schemas.ts +2 -2
- package/src/extension/tool-description.ts +8 -4
- package/src/integrations/herdr-status.ts +5 -0
- package/src/runs/background/async-execution.ts +29 -12
- package/src/runs/background/async-resume.ts +6 -2
- package/src/runs/background/async-status.ts +2 -0
- package/src/runs/background/chain-append.ts +2 -0
- package/src/runs/background/notify.ts +26 -3
- package/src/runs/background/result-delivery-ownership.ts +45 -0
- package/src/runs/background/result-watcher.ts +27 -10
- package/src/runs/background/subagent-runner.ts +71 -21
- package/src/runs/foreground/execution.ts +20 -1
- package/src/runs/foreground/subagent-executor.ts +57 -26
- package/src/runs/foreground/workflow-detach-reconcile.ts +128 -17
- package/src/runs/shared/completion-guard.ts +4 -3
- package/src/runs/shared/dynamic-fanout.ts +3 -3
- package/src/runs/shared/fast-mode-extension.ts +5 -5
- package/src/runs/shared/launch-cwd.ts +16 -0
- package/src/runs/shared/long-running-guard.ts +2 -1
- package/src/runs/shared/mcp-config-sources.ts +386 -0
- package/src/runs/shared/mcp-direct-tool-allowlist.ts +155 -42
- package/src/runs/shared/model-exclusions.ts +12 -0
- package/src/runs/shared/model-fallback.ts +16 -4
- package/src/runs/shared/parallel-utils.ts +8 -1
- package/src/runs/shared/pi-args.ts +61 -6
- package/src/runs/shared/single-output.ts +17 -0
- package/src/runs/shared/subagent-prompt-runtime.ts +85 -9
- package/src/shared/formatters.ts +6 -0
- package/src/shared/launch-contract.ts +4 -0
- package/src/shared/types.ts +42 -1
- package/src/shared/utils.ts +6 -29
- package/src/slash/subagents-admin.ts +3 -0
- package/src/tui/render.ts +14 -6
- package/src/workflows/scripted-workflow.ts +52 -5
- package/src/workflows/workflow-receipt.ts +39 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,45 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.58.0] - 2026-08-27
|
|
6
|
+
|
|
7
|
+
### Highlights
|
|
8
|
+
- Launch MCP tools from more places, including runtime-registered servers, Pi package manifests, and Agent Plugin configs.
|
|
9
|
+
- Keep agent context smaller by default, with an explicit `inheritGlobalContext` opt-in when a child needs the operator's global context.
|
|
10
|
+
- Make detached and recovered workflow results more reliable, with clearer terminal handoffs and recovery actions.
|
|
11
|
+
- Show better launch and status diagnostics for workspace, authority, context-window, and missing-directory problems.
|
|
12
|
+
- Keep fast OpenAI-Codex launches compatible with priority service tier without losing provider request fields.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- Support direct MCP tool launches from runtime-registered servers.
|
|
16
|
+
- Add `inheritGlobalContext` agent configuration so children can opt into the operator's global context file separately from repository context. Thanks to [@hknatm](https://github.com/hknatm) for #1560.
|
|
17
|
+
- Add process-local event registration so independent Pi extensions can register runtime agents through the installed owner. Thanks to [@fmoda3](https://github.com/fmoda3) for #1533.
|
|
18
|
+
- Add advisory launch preflight diagnostics for likely workspace scope and authority mismatches.
|
|
19
|
+
- Document per-run thinking suffixes in model-facing subagent guidance. Thanks to [@yanqianglu](https://github.com/yanqianglu) for #1565.
|
|
20
|
+
- Document unsupported native child options for external CLI agents in the subagent tool help, packaged guide, and packaged skill.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- Agents now omit the operator's global context file by default, including existing agents with `inheritProjectContext: true`; set `inheritGlobalContext: true` to preserve the previous behavior. Thanks to [@hknatm](https://github.com/hknatm) for #1560.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- Fail explicitly requested models closed when a cached model exclusion is active, instead of silently selecting a fallback. Thanks to [@harpsychord](https://github.com/harpsychord) for #1556.
|
|
27
|
+
- Preserve fast-mode provider request root fields when adding OpenAI's priority service tier. Thanks to [@nothingrotf](https://github.com/nothingrotf) for #1570.
|
|
28
|
+
- Classify workflow budget and timeout stops as partial terminal outcomes while preserving settled child evidence. Thanks to [@yceachan](https://github.com/yceachan) for #1530.
|
|
29
|
+
- Publish a deterministic terminal handoff with settled child evidence and keyed recovery actions when detached workflow lanes settle. Thanks to [@yceachan](https://github.com/yceachan) for #1530.
|
|
30
|
+
- Resolve direct MCP tool selections from Pi package manifests and Agent Plugin configs. Thanks to [@fmoda3](https://github.com/fmoda3) for #1541.
|
|
31
|
+
- Fail closed with a launch diagnostic when configured runtime-style MCP direct-tool selectors cannot be resolved.
|
|
32
|
+
- Sync Herdr status after restoring active async jobs, so recovered work appears without waiting for another lifecycle event. Thanks to [@vicocamacho](https://github.com/vicocamacho) for #1553.
|
|
33
|
+
- Show task intent and context-window use in compact in-progress async status rows.
|
|
34
|
+
- Report deterministic settlement diagnostics when background children fail before required output handoff.
|
|
35
|
+
- Auto-resume workflow children once after setup-phase aborts that produce zero usage, preserving the retained transcript instead of rerunning the whole task.
|
|
36
|
+
- Finalize detached foreground worktree handoffs after terminal child completion, preserving captured changes before cleanup. Thanks to [@jpriverar](https://github.com/jpriverar) for #1562.
|
|
37
|
+
- Fail native child launches before spawn when the requested local working directory is missing or not a directory, with the requested and resolved paths in the error.
|
|
38
|
+
- Map report paths requested in workflow child tasks to the actual saved child output when workflow output routing overrides them.
|
|
39
|
+
- Stop same-session workflows recovered after extension reload through the durable control channel.
|
|
40
|
+
- Let agents declare extension mutation tools so real non-Git or untracked edits satisfy the implementation completion guard. Thanks to [@AlphaGodzilla](https://github.com/AlphaGodzilla) for #1532.
|
|
41
|
+
- Deliver async results from an explicitly replaced predecessor session without accepting unrelated session results. Thanks to [@DresvyanskiyDenis](https://github.com/DresvyanskiyDenis) for #1531.
|
|
42
|
+
- Avoid attributing assistant-issued workflow stops to the user.
|
|
43
|
+
|
|
5
44
|
## [0.57.0] - 2026-08-26
|
|
6
45
|
|
|
7
46
|
### Highlights
|
package/docs/agents.md
CHANGED
|
@@ -57,6 +57,8 @@ The Pi async run remains the source of truth for status, artifacts, wake/wait, m
|
|
|
57
57
|
|
|
58
58
|
### Advisory runner data boundary
|
|
59
59
|
|
|
60
|
+
External CLI agents use their own runner contract. Do not pass native Pi child options such as model override, structured output, acceptance/agent contract, tool budgets, fast mode, fork context, skills, or native Pi tools unless the adapter explicitly implements them.
|
|
61
|
+
|
|
60
62
|
The built-in `codex-exec` and `codex-exec-writer` profiles are the supported Codex one-shot modes. Both require an installed and authenticated Codex CLI. The adapters own `codex exec --json` argv with ignored user config and rules, ephemeral sessions, approval policy `never`, and a final-message artifact.
|
|
61
63
|
|
|
62
64
|
| Profile | Access | Sandbox |
|
|
@@ -207,7 +209,7 @@ You can override selected builtin fields without copying the whole agent. Overri
|
|
|
207
209
|
}
|
|
208
210
|
```
|
|
209
211
|
|
|
210
|
-
Supported override fields: `description`, `output`, `outputMode`, `defaultReads`, `model`, `defaultProvider`, `fallbackModels`, `thinking`, `systemPromptMode`, `inheritProjectContext`, `inheritSkills`, `defaultContext`, `acceptanceRole`, `disabled`, `skills`, `tools`, and `systemPrompt`.
|
|
212
|
+
Supported override fields: `description`, `output`, `outputMode`, `defaultReads`, `model`, `defaultProvider`, `fallbackModels`, `thinking`, `systemPromptMode`, `inheritProjectContext`, `inheritGlobalContext`, `inheritSkills`, `defaultContext`, `acceptanceRole`, `disabled`, `skills`, `tools`, and `systemPrompt`.
|
|
211
213
|
|
|
212
214
|
- `description` replaces the discovered description for builtin and custom agents, which lets list output show deployment-specific routing or model metadata.
|
|
213
215
|
- Use `output: false`, `defaultReads: false`, `defaultContext: false`, or `acceptanceRole: false` to clear an inherited value.
|
|
@@ -234,11 +236,12 @@ Use these fields when an agent should see more:
|
|
|
234
236
|
| Field | Effect |
|
|
235
237
|
|-------|--------|
|
|
236
238
|
| `systemPromptMode: append` | Append the agent prompt to Pi's normal base prompt. |
|
|
237
|
-
| `inheritProjectContext: true` | Keep inherited
|
|
239
|
+
| `inheritProjectContext: true` | Keep inherited repository instructions from files like `AGENTS.md` and `CLAUDE.md`. |
|
|
240
|
+
| `inheritGlobalContext: true` | Also keep the operator's global context file from the Pi config agent directory (such as `~/.pi/agent/AGENTS.md`). Defaults to `false`. |
|
|
238
241
|
| `inheritSkills: true` | Let the child see Pi's discovered skills catalog. |
|
|
239
242
|
| `defaultContext: fork` | Prefer forked session context when a launch omits `context`; if the parent has no persisted session file or current leaf yet, the implicit default falls back to `fresh` without a failed first attempt. Explicit `context: "fork"` remains strict, and explicit `context: "fresh"` still wins. |
|
|
240
243
|
|
|
241
|
-
Builtin agents opt into
|
|
244
|
+
Builtin agents opt into repository instruction inheritance by default so they follow repo-specific rules out of the box, but global context remains excluded unless `inheritGlobalContext: true` is set. This changes the behavior of existing agents that previously received global context as part of `inheritProjectContext: true`. `delegate` also uses append mode because its job is orchestration inside the parent workflow.
|
|
242
245
|
|
|
243
246
|
## Frontmatter reference
|
|
244
247
|
|
|
@@ -255,10 +258,11 @@ tools: read, grep, find, ls, bash, mcp:chrome-devtools
|
|
|
255
258
|
extensions:
|
|
256
259
|
subagentOnlyExtensions: ./tools/child-only-search.ts
|
|
257
260
|
model: claude-haiku-4-5
|
|
258
|
-
fallbackModels: openai/gpt-5-
|
|
261
|
+
fallbackModels: openai-codex/gpt-5.6-luna:low, anthropic/claude-sonnet-4
|
|
259
262
|
thinking: high
|
|
260
263
|
systemPromptMode: replace
|
|
261
264
|
inheritProjectContext: false
|
|
265
|
+
inheritGlobalContext: false
|
|
262
266
|
inheritSkills: false
|
|
263
267
|
skills: safe-bash, review-checklist
|
|
264
268
|
skillPath: ./skills, ../shared-skills
|
|
@@ -286,7 +290,7 @@ tools:
|
|
|
286
290
|
- read
|
|
287
291
|
- mcp:github/search_repositories
|
|
288
292
|
fallbackModels:
|
|
289
|
-
- openai/gpt-5-
|
|
293
|
+
- openai-codex/gpt-5.6-luna:low
|
|
290
294
|
- anthropic/claude-sonnet-4
|
|
291
295
|
```
|
|
292
296
|
|
|
@@ -303,7 +307,8 @@ Field notes:
|
|
|
303
307
|
| `fallbackModels` | Ordered backup models for provider/model failures such as quota, auth, timeout, or unavailable model. Ordinary task failures do not trigger fallback. |
|
|
304
308
|
| `thinking` | Appended as a `:level` suffix at runtime unless a suffix is already present. |
|
|
305
309
|
| `systemPromptMode` | `replace` by default; `append` keeps Pi's base prompt. |
|
|
306
|
-
| `inheritProjectContext` | Keeps or strips inherited
|
|
310
|
+
| `inheritProjectContext` | Keeps or strips inherited repository instruction blocks. |
|
|
311
|
+
| `inheritGlobalContext` | Keeps or strips the operator's global context file from the Pi config agent directory (e.g. `~/.pi/agent/AGENTS.md`). It has an effect only when `inheritProjectContext` is `true`; otherwise all context files are already disabled. Defaults to `false`. |
|
|
307
312
|
| `inheritSkills` | Keeps or strips Pi's discovered skills catalog. |
|
|
308
313
|
| `defaultContext` | Optional `fresh` or `fork` launch-context preference. An implicit `fork` falls back to `fresh` when the parent has no persisted session file or current leaf; an explicit launch `context: "fork"` remains strict. |
|
|
309
314
|
| `skills` | Selects specific skills for the child, regardless of `inheritSkills`. |
|
|
@@ -317,6 +322,7 @@ Field notes:
|
|
|
317
322
|
| `turnBudget` | JSON object default such as `{"maxTurns":20,"graceTurns":2}` for single-agent launches. An explicit call value wins, followed by this agent default, then global `turnBudget` config. |
|
|
318
323
|
| `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. |
|
|
319
324
|
| `acceptanceRole` | Optional `read-only` or `writer` role for automatic acceptance inference. Explicit task mutation or no-edit intent wins; otherwise the declared role replaces agent-name guessing. This does not grant or revoke tools. |
|
|
325
|
+
| `mutationTools` | Comma-separated extension tool names whose calls count as mutation attempts for the completion guard. This declares evidence only; list and load each tool through `tools` and its extension provider as usual. |
|
|
320
326
|
| `completionGuard` | Set `false` only for non-implementation agents that may mention implementation words while using mutation-capable tools such as `bash`. |
|
|
321
327
|
| `interactive` | Parsed for compatibility but not currently enforced. |
|
|
322
328
|
| `maxSubagentDepth` | Tightens nested delegation for this agent's children. |
|
|
@@ -385,6 +391,7 @@ More rules:
|
|
|
385
391
|
- `mcp:` entries are split out and forwarded as direct MCP selections without granting normal builtins unless those builtins are also listed.
|
|
386
392
|
- Path-like `tools` entries, such as extension paths or `.ts`/`.js` files, are treated as tool-extension paths rather than tool names.
|
|
387
393
|
- Internal runtime tools such as `structured_output` are added to an explicit allowlist only when their contract is active.
|
|
394
|
+
- Unknown extension tool calls count as mutation attempts only when their names are listed in `mutationTools`; undeclared unknown tools keep the no-edit guard active.
|
|
388
395
|
- 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.
|
|
389
396
|
|
|
390
397
|
Examples:
|
package/docs/extension-api.md
CHANGED
|
@@ -58,6 +58,45 @@ The DTO intentionally never exposes run, async, or tool IDs. Clients must ignore
|
|
|
58
58
|
|
|
59
59
|
`pi.events` is in-process only. It does not reach separate Pi processes or child subagents; use the file lifecycle artifacts or `pi-intercom` for cross-process coordination.
|
|
60
60
|
|
|
61
|
+
## Runtime agent registration from independent extensions
|
|
62
|
+
|
|
63
|
+
An independently installed Pi extension can register an agent with the installed `pi-subagents` owner through the process-local `pi-subagents:runtime-agent-register:v1` event. Emit after extension setup, such as during `session_start`. Event delivery is synchronous, so the owner writes the result onto the request before `emit()` returns.
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
const request: {
|
|
67
|
+
version: 1;
|
|
68
|
+
name: string;
|
|
69
|
+
definition: {
|
|
70
|
+
description: string;
|
|
71
|
+
systemPrompt: string;
|
|
72
|
+
tools?: readonly string[];
|
|
73
|
+
};
|
|
74
|
+
result?:
|
|
75
|
+
| { ok: true; registration: { dispose(): void } }
|
|
76
|
+
| { ok: false; error: Error };
|
|
77
|
+
} = {
|
|
78
|
+
version: 1,
|
|
79
|
+
name: "runtime-probe-agent",
|
|
80
|
+
definition: {
|
|
81
|
+
description: "Agent registered by an independent extension",
|
|
82
|
+
systemPrompt: "Return the words runtime probe.",
|
|
83
|
+
tools: [],
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
pi.events.emit("pi-subagents:runtime-agent-register:v1", request);
|
|
88
|
+
if (!request.result) throw new Error("pi-subagents is not installed or not ready");
|
|
89
|
+
if (!request.result.ok) throw request.result.error;
|
|
90
|
+
const registration = request.result.registration;
|
|
91
|
+
// Call registration.dispose() during your extension cleanup.
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
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.
|
|
95
|
+
|
|
96
|
+
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.
|
|
97
|
+
|
|
98
|
+
This contract is process-local. It does not register agents in child processes or other Pi processes, and it does not change package discovery or package resolution.
|
|
99
|
+
|
|
61
100
|
## External jobs in FleetView
|
|
62
101
|
|
|
63
102
|
Use `pi-subagents/external-runs` to publish display-only current-session jobs owned by another extension:
|
package/docs/models.md
CHANGED
|
@@ -51,7 +51,7 @@ For a persistent role override with a backup model for provider failures:
|
|
|
51
51
|
"reviewer": {
|
|
52
52
|
"model": "anthropic/claude-sonnet-4",
|
|
53
53
|
"thinking": "high",
|
|
54
|
-
"fallbackModels": ["openai/gpt-5-
|
|
54
|
+
"fallbackModels": ["openai-codex/gpt-5.6-luna:low"]
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -182,9 +182,9 @@ To keep subagents inside a budget or compliance profile, enforce a model scope.
|
|
|
182
182
|
"modelScope": {
|
|
183
183
|
"enforce": true,
|
|
184
184
|
"strict": true,
|
|
185
|
-
"allow": ["inherit", "openai/gpt-5-*"],
|
|
185
|
+
"allow": ["inherit", "openai/gpt-5-*", "openai-codex/gpt-5.6-*"],
|
|
186
186
|
"agents": {
|
|
187
|
-
"worker": { "allow": ["openai/gpt-5-
|
|
187
|
+
"worker": { "allow": ["openai-codex/gpt-5.6-luna"] },
|
|
188
188
|
"reviewer": { "allow": ["inherit"] }
|
|
189
189
|
}
|
|
190
190
|
}
|
package/docs/tool-reference.md
CHANGED
|
@@ -159,9 +159,10 @@ Agent definitions are not loaded into context by default. Management actions let
|
|
|
159
159
|
systemPrompt: "You are a code scout...",
|
|
160
160
|
systemPromptMode: "replace",
|
|
161
161
|
inheritProjectContext: false,
|
|
162
|
+
inheritGlobalContext: false,
|
|
162
163
|
inheritSkills: false,
|
|
163
164
|
model: "anthropic/claude-sonnet-4",
|
|
164
|
-
fallbackModels: ["openai/gpt-5-
|
|
165
|
+
fallbackModels: ["openai-codex/gpt-5.6-luna:low", "anthropic/claude-haiku-4-5"],
|
|
165
166
|
tools: "read, bash, mcp:github/search_repositories",
|
|
166
167
|
extensions: "",
|
|
167
168
|
skills: "parallel-scout",
|
|
@@ -371,7 +372,7 @@ async: true
|
|
|
371
372
|
|
|
372
373
|
Supported: status artifacts, stdout/stderr logs, timeout, and stop. Full stdout and stderr are written to log files, while the in-memory final stdout response and stderr error are limited to their last 64 KiB.
|
|
373
374
|
|
|
374
|
-
Intentionally unsupported:
|
|
375
|
+
Intentionally unsupported: native Pi child options such as model override, structured output, acceptance/agent contract, tool budgets, fast mode, fork context, skills, or native Pi tools unless the runner explicitly implements them. Foreground/clarify, steer/resume/interrupt-as-pause, nested subagents, and fallback models are also unsupported.
|
|
375
376
|
|
|
376
377
|
## Session sharing
|
|
377
378
|
|
package/docs/workflows.md
CHANGED
|
@@ -57,6 +57,30 @@ subagent({ action: "validate", workflowScriptPath: "workflows/review.js" });
|
|
|
57
57
|
|
|
58
58
|
The fields are mutually exclusive. Relative paths resolve against the request `cwd`; absolute paths pass through. The host reads the file before validation, schedule creation, or workflow sandbox execution. The sandbox still has no filesystem access. Missing, unreadable, and empty files return file input errors instead of script syntax errors.
|
|
59
59
|
|
|
60
|
+
### Opt-in bounded workflows
|
|
61
|
+
|
|
62
|
+
Composite workflows have no default parent deadline. Add bounds only when the workflow contract calls for them:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
subagent({
|
|
66
|
+
workflowScript: `
|
|
67
|
+
const scan = await runs.run("scan", { agent: "scout", task: "Inspect the named files." });
|
|
68
|
+
return runs.run("review", { agent: "reviewer", task: "Review:\n" + scan.output });
|
|
69
|
+
`,
|
|
70
|
+
timeoutMs: 900000,
|
|
71
|
+
turnBudget: { maxTurns: 30, graceTurns: 2 },
|
|
72
|
+
toolBudget: { soft: 40, hard: 60 },
|
|
73
|
+
usageBudget: { tokens: { soft: 100000, hard: 150000 } }
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- `timeoutMs` sets the workflow deadline and bounds child deadlines to the remaining time.
|
|
78
|
+
- `turnBudget` and `toolBudget` become defaults for each child unless that child supplies a narrower value.
|
|
79
|
+
- `usageBudget` accounts for reported usage across completed workflow children. Once exhausted, it rejects later child launches but does not stop children that are already running.
|
|
80
|
+
- Budget and timeout stops return a structured `terminalOutcome` with `state: "partial"` and reason `budget_exhausted` or `timeout`. Workflow receipts keep settled child evidence for recovery.
|
|
81
|
+
|
|
82
|
+
These controls are opt-in. Avoid tight hard budgets for mutation-capable workers unless the workflow has an explicit checkpoint and handoff path.
|
|
83
|
+
|
|
60
84
|
The result is `{ ok, errors }`. Invalid scripts return a tool error and include line and column data when available. Validation checks syntax, portable nested-async rules, literal `runs.run` and `runs.all` keys, duplicate literal keys in one `runs.all` group, direct keyed access to a known `runs.all` result, and statically clear non-JSON boundary values. Dynamic keys and other runtime-only values are accepted without a warning. Validation does not discover agents, launch children, or create run artifacts.
|
|
61
85
|
|
|
62
86
|
```js
|
package/package.json
CHANGED
|
@@ -31,6 +31,8 @@ Read the matching reference file before acting. Paths are relative to this `SKIL
|
|
|
31
31
|
|
|
32
32
|
For broad or uncertain requests, read more than one reference. For complex work, start with `references/prompting-and-roles.md` and `references/execution-controls.md`, then consult `references/constraints-and-recipes.md` before launching or reviewing child work.
|
|
33
33
|
|
|
34
|
+
External CLI agents such as `codex-exec`, `codex-exec-writer`, `claude-code`, and `cursor-agent` use their own runner contract. Do not pass native Pi child options such as model override, structured output, acceptance/agent contract, tool budgets, fast mode, fork context, skills, or native Pi tools unless that runner explicitly implements them.
|
|
35
|
+
|
|
34
36
|
## Always-on constraints
|
|
35
37
|
|
|
36
38
|
- Keep the parent as orchestrator and final decision-maker.
|
|
@@ -24,7 +24,7 @@ Project settings resolve from the nearest parent directory containing `.pi` or `
|
|
|
24
24
|
|
|
25
25
|
An agent may set `runner.type: external-cli` with a non-empty `command`, optional string `args`, and `promptDelivery: stdin` (the default). The command runs with `shell: false`, inherits the resolved cwd and environment, and receives the combined agent instructions and task through stdin. It must already be installed; pi-subagents adds no CLI dependency.
|
|
26
26
|
|
|
27
|
-
External CLI profiles are async-only and one-shot. They support lifecycle artifacts, stdout/stderr logs, timeout, and stop. Full stdout and stderr are retained in their log files, while the final stdout response and stderr error kept in memory are each limited to their last 64 KiB. They do not support
|
|
27
|
+
External CLI profiles are async-only and one-shot. They support lifecycle artifacts, stdout/stderr logs, timeout, and stop. Full stdout and stderr are retained in their log files, while the final stdout response and stderr error kept in memory are each limited to their last 64 KiB. They do not support native Pi child options such as model override, structured output, acceptance/agent contract, tool budgets, fast mode, fork context, skills, or native Pi tools unless the runner explicitly implements them. Foreground/clarify, steer/resume/interrupt-as-pause, nested subagents, fallbacks, and sessions are also unsupported.
|
|
28
28
|
|
|
29
29
|
### External job profiles
|
|
30
30
|
|
|
@@ -230,7 +230,7 @@ Direct settings example:
|
|
|
230
230
|
"reviewer": {
|
|
231
231
|
"model": "anthropic/claude-sonnet-4",
|
|
232
232
|
"thinking": "high",
|
|
233
|
-
"fallbackModels": ["openai/gpt-5-
|
|
233
|
+
"fallbackModels": ["openai-codex/gpt-5.6-luna:low"],
|
|
234
234
|
"acceptanceRole": "read-only"
|
|
235
235
|
}
|
|
236
236
|
}
|
|
@@ -239,7 +239,7 @@ Direct settings example:
|
|
|
239
239
|
```
|
|
240
240
|
|
|
241
241
|
Useful override fields: `description`, `model`, `fallbackModels`, `thinking`,
|
|
242
|
-
`systemPromptMode`, `inheritProjectContext`, `inheritSkills`, `defaultContext`,
|
|
242
|
+
`systemPromptMode`, `inheritProjectContext`, `inheritGlobalContext`, `inheritSkills`, `defaultContext`,
|
|
243
243
|
`acceptanceRole`, `disabled`, `skills`, `tools`, `extensions`, and `systemPrompt`.
|
|
244
244
|
`description` replaces the discovered description for builtin and custom agents
|
|
245
245
|
in `list` output, which is useful for deployment-specific routing notes.
|
|
@@ -230,6 +230,7 @@ export function editableAgentConfig(agent: AgentConfig): AgentConfig {
|
|
|
230
230
|
thinking: _thinking,
|
|
231
231
|
systemPromptMode: _systemPromptMode,
|
|
232
232
|
inheritProjectContext: _inheritProjectContext,
|
|
233
|
+
inheritGlobalContext: _inheritGlobalContext,
|
|
233
234
|
inheritSkills: _inheritSkills,
|
|
234
235
|
defaultContext: _defaultContext,
|
|
235
236
|
acceptanceRole: _acceptanceRole,
|
|
@@ -240,6 +241,7 @@ export function editableAgentConfig(agent: AgentConfig): AgentConfig {
|
|
|
240
241
|
tools: _tools,
|
|
241
242
|
mcpDirectTools: _mcpDirectTools,
|
|
242
243
|
subagentOnlyExtensions: _subagentOnlyExtensions,
|
|
244
|
+
mutationTools: _mutationTools,
|
|
243
245
|
completionGuard: _completionGuard,
|
|
244
246
|
...editable
|
|
245
247
|
} = withoutExtensions;
|
|
@@ -260,6 +262,7 @@ export function editableAgentConfig(agent: AgentConfig): AgentConfig {
|
|
|
260
262
|
...(base.thinking !== undefined ? { thinking: base.thinking } : {}),
|
|
261
263
|
systemPromptMode: base.systemPromptMode,
|
|
262
264
|
inheritProjectContext: base.inheritProjectContext,
|
|
265
|
+
inheritGlobalContext: base.inheritGlobalContext,
|
|
263
266
|
inheritSkills: base.inheritSkills,
|
|
264
267
|
...(base.defaultContext !== undefined ? { defaultContext: base.defaultContext } : {}),
|
|
265
268
|
...(base.acceptanceRole !== undefined ? { acceptanceRole: base.acceptanceRole } : {}),
|
|
@@ -271,6 +274,7 @@ export function editableAgentConfig(agent: AgentConfig): AgentConfig {
|
|
|
271
274
|
...(base.mcpDirectTools !== undefined ? { mcpDirectTools: [...base.mcpDirectTools] } : {}),
|
|
272
275
|
...(base.extensions !== undefined ? { extensions: [...base.extensions] } : {}),
|
|
273
276
|
...(base.subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions: [...base.subagentOnlyExtensions] } : {}),
|
|
277
|
+
...(base.mutationTools !== undefined ? { mutationTools: [...base.mutationTools] } : {}),
|
|
274
278
|
...(base.completionGuard !== undefined ? { completionGuard: base.completionGuard } : {}),
|
|
275
279
|
}, agent.filePath);
|
|
276
280
|
}
|
|
@@ -303,6 +307,7 @@ export function preservedAgentFrontmatterFields(agent: AgentConfig, cfg: Record<
|
|
|
303
307
|
if (hasKey(cfg, "skillPath")) changed("skillPath");
|
|
304
308
|
if (hasKey(cfg, "extensions")) changed("extensions");
|
|
305
309
|
if (hasKey(cfg, "subagentOnlyExtensions")) changed("subagentOnlyExtensions");
|
|
310
|
+
if (hasKey(cfg, "mutationTools")) changed("mutationTools");
|
|
306
311
|
if (hasKey(cfg, "thinking")) {
|
|
307
312
|
changed("thinking");
|
|
308
313
|
if (cfg.thinking === "off") fields.add("thinking");
|
|
@@ -315,6 +320,10 @@ export function preservedAgentFrontmatterFields(agent: AgentConfig, cfg: Record<
|
|
|
315
320
|
changed("inheritProjectContext");
|
|
316
321
|
fields.add("inheritProjectContext");
|
|
317
322
|
}
|
|
323
|
+
if (hasKey(cfg, "inheritGlobalContext")) {
|
|
324
|
+
changed("inheritGlobalContext");
|
|
325
|
+
fields.add("inheritGlobalContext");
|
|
326
|
+
}
|
|
318
327
|
if (hasKey(cfg, "inheritSkills")) {
|
|
319
328
|
changed("inheritSkills");
|
|
320
329
|
fields.add("inheritSkills");
|
|
@@ -457,6 +466,12 @@ function applyAgentConfig(target: AgentConfig, cfg: Record<string, unknown>): st
|
|
|
457
466
|
else if (typeof cfg.subagentOnlyExtensions === "string") target.subagentOnlyExtensions = parseCsv(cfg.subagentOnlyExtensions);
|
|
458
467
|
else return "config.subagentOnlyExtensions must be a comma-separated string, empty string, or false when provided.";
|
|
459
468
|
}
|
|
469
|
+
if (hasKey(cfg, "mutationTools")) {
|
|
470
|
+
if (cfg.mutationTools === false) delete target.mutationTools;
|
|
471
|
+
else if (cfg.mutationTools === "") target.mutationTools = [];
|
|
472
|
+
else if (typeof cfg.mutationTools === "string") target.mutationTools = parseCsv(cfg.mutationTools);
|
|
473
|
+
else return "config.mutationTools must be a comma-separated string, empty string, or false when provided.";
|
|
474
|
+
}
|
|
460
475
|
if (hasKey(cfg, "thinking")) {
|
|
461
476
|
if (cfg.thinking === false || cfg.thinking === "") delete target.thinking;
|
|
462
477
|
else if (typeof cfg.thinking === "string") {
|
|
@@ -473,6 +488,10 @@ function applyAgentConfig(target: AgentConfig, cfg: Record<string, unknown>): st
|
|
|
473
488
|
if (typeof cfg.inheritProjectContext !== "boolean") return "config.inheritProjectContext must be a boolean when provided.";
|
|
474
489
|
target.inheritProjectContext = cfg.inheritProjectContext;
|
|
475
490
|
}
|
|
491
|
+
if (hasKey(cfg, "inheritGlobalContext")) {
|
|
492
|
+
if (typeof cfg.inheritGlobalContext !== "boolean") return "config.inheritGlobalContext must be a boolean when provided.";
|
|
493
|
+
target.inheritGlobalContext = cfg.inheritGlobalContext;
|
|
494
|
+
}
|
|
476
495
|
if (hasKey(cfg, "inheritSkills")) {
|
|
477
496
|
if (typeof cfg.inheritSkills !== "boolean") return "config.inheritSkills must be a boolean when provided.";
|
|
478
497
|
target.inheritSkills = cfg.inheritSkills;
|
|
@@ -561,6 +580,7 @@ function applyAgentConfig(target: AgentConfig, cfg: Record<string, unknown>): st
|
|
|
561
580
|
target.thinking ? "thinking" : undefined,
|
|
562
581
|
target.extensions?.length ? "extensions" : undefined,
|
|
563
582
|
target.subagentOnlyExtensions?.length ? "subagentOnlyExtensions" : undefined,
|
|
583
|
+
target.mutationTools?.length ? "mutationTools" : undefined,
|
|
564
584
|
target.skills?.length || target.skillPath?.length ? "skills" : undefined,
|
|
565
585
|
target.maxSubagentDepth !== undefined ? "maxSubagentDepth" : undefined,
|
|
566
586
|
target.completionGuard !== undefined ? "completionGuard" : undefined,
|
|
@@ -699,6 +719,7 @@ function formatAgentDetail(agent: AgentConfig): string {
|
|
|
699
719
|
if (agent.runner?.type === "external-job" && agent.runner.options) lines.push(`Runner options: ${JSON.stringify(agent.runner.options)}`);
|
|
700
720
|
}
|
|
701
721
|
lines.push(`Inherit project context: ${agent.inheritProjectContext ? "true" : "false"}`);
|
|
722
|
+
lines.push(`Inherit global context: ${agent.inheritGlobalContext ? "true" : "false"}`);
|
|
702
723
|
lines.push(`Inherit skills: ${agent.inheritSkills ? "true" : "false"}`);
|
|
703
724
|
if (agent.defaultContext) lines.push(`Default context: ${agent.defaultContext}`);
|
|
704
725
|
if (agent.defaultAsync !== undefined) lines.push(`Async: ${agent.defaultAsync ? "true" : "false"}`);
|
|
@@ -709,6 +730,7 @@ function formatAgentDetail(agent: AgentConfig): string {
|
|
|
709
730
|
if (agent.source === "builtin") lines.push(`Disabled: ${agent.disabled ? "true" : "false"}`);
|
|
710
731
|
if (agent.extensions !== undefined) lines.push(`Extensions: ${agent.extensions.length ? agent.extensions.join(", ") : "(none)"}`);
|
|
711
732
|
if (agent.subagentOnlyExtensions !== undefined) lines.push(`Subagent-only extensions: ${agent.subagentOnlyExtensions.length ? agent.subagentOnlyExtensions.join(", ") : "(none)"}`);
|
|
733
|
+
if (agent.mutationTools !== undefined) lines.push(`Mutation tools: ${agent.mutationTools.length ? agent.mutationTools.join(", ") : "(none)"}`);
|
|
712
734
|
if (agent.thinking) lines.push(`Thinking: ${agent.thinking}`);
|
|
713
735
|
if (agent.output) lines.push(`Output: ${agent.output}`);
|
|
714
736
|
if (agent.outputMode) lines.push(`Output mode: ${agent.outputMode}`);
|
|
@@ -915,6 +937,7 @@ export function handleCreate(params: ManagementParams, ctx: ManagementContext):
|
|
|
915
937
|
systemPrompt: "",
|
|
916
938
|
systemPromptMode: defaultSystemPromptMode(name),
|
|
917
939
|
inheritProjectContext: defaultInheritProjectContext(name),
|
|
940
|
+
inheritGlobalContext: false,
|
|
918
941
|
inheritSkills: defaultInheritSkills(),
|
|
919
942
|
};
|
|
920
943
|
const applyError = applyAgentConfig(agent, cfg);
|
|
@@ -15,6 +15,7 @@ export const KNOWN_FIELDS = new Set([
|
|
|
15
15
|
"thinking",
|
|
16
16
|
"systemPromptMode",
|
|
17
17
|
"inheritProjectContext",
|
|
18
|
+
"inheritGlobalContext",
|
|
18
19
|
"inheritSkills",
|
|
19
20
|
"defaultContext",
|
|
20
21
|
"async",
|
|
@@ -28,6 +29,7 @@ export const KNOWN_FIELDS = new Set([
|
|
|
28
29
|
"skillPath",
|
|
29
30
|
"extensions",
|
|
30
31
|
"subagentOnlyExtensions",
|
|
32
|
+
"mutationTools",
|
|
31
33
|
"output",
|
|
32
34
|
"outputMode",
|
|
33
35
|
"defaultReads",
|
|
@@ -78,6 +80,7 @@ export function serializeAgent(config: AgentConfig, options: SerializeAgentOptio
|
|
|
78
80
|
}
|
|
79
81
|
if (!preservingExistingFrontmatter || preserve("systemPromptMode")) lines.push(`systemPromptMode: ${config.systemPromptMode}`);
|
|
80
82
|
if (!preservingExistingFrontmatter || preserve("inheritProjectContext")) lines.push(`inheritProjectContext: ${config.inheritProjectContext ? "true" : "false"}`);
|
|
83
|
+
if (config.inheritGlobalContext || preserve("inheritGlobalContext")) lines.push(`inheritGlobalContext: ${config.inheritGlobalContext ? "true" : "false"}`);
|
|
81
84
|
if (!preservingExistingFrontmatter || preserve("inheritSkills")) lines.push(`inheritSkills: ${config.inheritSkills ? "true" : "false"}`);
|
|
82
85
|
if (config.defaultContext || preserve("defaultContext")) lines.push(`defaultContext: ${config.defaultContext ?? ""}`);
|
|
83
86
|
if (config.runner || preserve("runner")) {
|
|
@@ -114,6 +117,8 @@ export function serializeAgent(config: AgentConfig, options: SerializeAgentOptio
|
|
|
114
117
|
const subagentOnlyExtensionsValue = joinComma(config.subagentOnlyExtensions);
|
|
115
118
|
lines.push(`subagentOnlyExtensions: ${subagentOnlyExtensionsValue ?? ""}`);
|
|
116
119
|
}
|
|
120
|
+
const mutationToolsValue = joinComma(config.mutationTools);
|
|
121
|
+
if (mutationToolsValue || preserve("mutationTools")) lines.push(`mutationTools: ${mutationToolsValue ?? ""}`);
|
|
117
122
|
|
|
118
123
|
if (config.output || preserve("output")) lines.push(`output: ${config.output ?? ""}`);
|
|
119
124
|
if (config.outputMode || preserve("outputMode")) lines.push(`outputMode: ${config.outputMode ?? ""}`);
|