@narumitw/pi-subagents 0.49.3 → 0.51.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/README.md +313 -53
- package/package.json +10 -7
- package/src/adaptive-scheduler.ts +196 -0
- package/src/admission-benchmark.ts +95 -0
- package/src/admission-policy.ts +78 -0
- package/src/agent-projection.ts +53 -0
- package/src/agents.ts +58 -1
- package/src/auto-transport.ts +114 -0
- package/src/blocking-status.ts +63 -0
- package/src/capabilities.ts +145 -0
- package/src/capability-grant.ts +115 -0
- package/src/capability-router.ts +107 -0
- package/src/completion-delivery.ts +257 -0
- package/src/config-status.ts +221 -0
- package/src/config-ui.ts +215 -236
- package/src/consult-resources.ts +4 -27
- package/src/consult.ts +9 -1
- package/src/create-stateful-transport.ts +55 -0
- package/src/delegation-contract.ts +417 -0
- package/src/execution-plan.ts +322 -0
- package/src/execution-profiles.ts +95 -0
- package/src/execution-ui.ts +320 -0
- package/src/execution.ts +848 -158
- package/src/in-process-transport.ts +269 -25
- package/src/inspect-render.ts +101 -1
- package/src/inspect.ts +296 -3
- package/src/integration-controller.ts +98 -0
- package/src/limits.ts +3 -0
- package/src/orchestration-metrics.ts +78 -0
- package/src/outcome.ts +61 -0
- package/src/panel-child-group.ts +35 -0
- package/src/panel-contract.ts +343 -0
- package/src/panel-evidence.ts +59 -0
- package/src/panel-execution.ts +772 -0
- package/src/panel-failure.ts +56 -0
- package/src/panel-planning.ts +175 -0
- package/src/panel-prompts.ts +132 -0
- package/src/panel-reconciliation.ts +57 -0
- package/src/panel-render.ts +103 -0
- package/src/parallel-limit-ui.ts +112 -0
- package/src/params.ts +172 -3
- package/src/persistence.ts +182 -32
- package/src/prompt-resources.ts +38 -0
- package/src/registry-types.ts +175 -0
- package/src/registry.ts +466 -143
- package/src/render.ts +72 -6
- package/src/result-contract.ts +416 -0
- package/src/retained-semantic-state.ts +100 -0
- package/src/rpc-timeout-finalization.ts +207 -0
- package/src/rpc-transport-metadata.ts +65 -0
- package/src/rpc-transport.ts +990 -0
- package/src/rpc-turn-capture.ts +142 -0
- package/src/runner-result.ts +55 -0
- package/src/runner-usage.ts +48 -0
- package/src/runner.ts +325 -73
- package/src/semantic-snapshot.ts +214 -0
- package/src/settings.ts +254 -35
- package/src/spawn-idempotency.ts +61 -0
- package/src/stateful-config.ts +13 -0
- package/src/stateful-guidance.ts +1 -0
- package/src/stateful-lifecycle.ts +45 -2
- package/src/stateful-limit-ui.ts +246 -0
- package/src/stateful-limits.ts +96 -0
- package/src/stateful-prompt.ts +11 -2
- package/src/stateful-render.ts +48 -3
- package/src/stateful.ts +467 -357
- package/src/subagents.ts +114 -46
- package/src/subprocess-transport.ts +64 -5
- package/src/supervision.ts +103 -0
- package/src/timeout-checkpoint.ts +305 -0
- package/src/timeout-finalization.ts +75 -0
- package/src/transport-types.ts +68 -0
- package/src/transport-ui.ts +169 -0
- package/src/transport.ts +16 -4
- package/src/turn-budget.ts +109 -0
- package/src/verification-policy.ts +17 -0
- package/src/work-item-ledger.ts +682 -0
- package/src/work-item-persistence.ts +218 -0
- package/src/workflow-planning.ts +150 -0
- package/src/workflow-ui.ts +61 -0
- package/src/workspace.ts +69 -12
package/README.md
CHANGED
|
@@ -12,17 +12,25 @@ Use it to split independent research, planning, implementation, and review work
|
|
|
12
12
|
- Adds `subagent_inspect` for bounded metadata without child launch, mailbox-content access, acknowledgement, or mutation.
|
|
13
13
|
- Adds `subagent_consult` for one synchronous ephemeral child constrained to built-in `read`, `grep`, `find`, and `ls` tools (or a narrower agent allow-list).
|
|
14
14
|
- Keeps batch workers isolated in `pi --mode json -p --no-session` subprocesses.
|
|
15
|
+
- Lets users set a blocking parallel call's maximum worker count from 1 through 64 while keeping four-at-a-time execution.
|
|
15
16
|
- Registers detached stateful lifecycle tools by default; completion can stay queued for the next turn or opt into an idle root synthesis turn.
|
|
16
17
|
- Supports an opt-in public-SDK `in-process` stateful transport with one reusable child `AgentSession` per `agentId`.
|
|
18
|
+
- Supports an opt-in persistent `rpc` transport with one isolated Pi RPC process per active retained agent and `pi-subagents:v1` lifecycle metadata.
|
|
19
|
+
- Supports deterministic opt-in `auto` routing: read-only built-ins use in-process, write-capable built-ins use RPC, and custom tools use the compatibility subprocess path.
|
|
17
20
|
- Supports built-in `scout`, `planner`, `reviewer`, and `worker` agents.
|
|
18
21
|
- Loads custom user agents from `~/.pi/agent/agents/*.md`.
|
|
19
22
|
- Optionally loads project agents from `.pi/agents/*.md` with confirmation.
|
|
20
23
|
- Provides a current-session-first `/subagents` manager, direct `settings|status|help` routes, and compatibility aliases for agent tools and retained agents.
|
|
21
|
-
- Supports trust-aware per-task `cwd` policies,
|
|
24
|
+
- Supports trust-aware per-task `cwd` policies, task-selected work, workflow, idle, turn, and tool-call budgets, deterministic timeout checkpoints, bounded abort-then-summary recovery, progress telemetry, and explicit Fast, Balanced, or Deep thinking profiles.
|
|
22
25
|
- Renders all seven tools with Pi-native compact/expanded transcript rows; long-running blocking and consultation calls show bounded live activity.
|
|
23
26
|
- Bounds JSON lines, captured messages, stderr, final output, chain substitution, and fan-in context.
|
|
24
27
|
- Enforces a recursion-depth guard and deterministic process-group termination.
|
|
25
|
-
- Provides addressable stateful agents with follow-up, consolidated mailbox/management actions, context selection, and persistence.
|
|
28
|
+
- Provides addressable stateful agents with follow-up, consolidated mailbox/management actions, idempotent spawn retries, context selection and preview, versioned structured outcomes, and persistence.
|
|
29
|
+
- Publishes built-in and custom agent capability manifests, then records the executor-owned `ExecutionPlan` that resolves requested authority to effective tools, model, thinking, timeout, transport, trust, and workspace controls.
|
|
30
|
+
- Runs explicit dependency workflows through a persistent `WorkItem` ledger, dependency-aware scheduler, declared scope-conflict checks, artifact provenance, stale-result invalidation, and bounded overall deadlines.
|
|
31
|
+
- Runs first-class blocking panels with two or more independent reviewers, incremental bounded evidence artifacts, preserved blockers and dissent, a minimum-valid-review barrier, reserved synthesis and cleanup budgets, and one evidence-preserving synthesis.
|
|
32
|
+
- Supports bounded retries only for explicitly idempotent work and hedged execution only for explicitly read-only work.
|
|
33
|
+
- Detects retained-agent semantic skew across agent definitions, role prompts, tools, model resolution, transport, trust, repository generation, artifacts, and scheduler policy before follow-up work starts.
|
|
26
34
|
- Publishes transient runtime status through Pi's generic extension status API while subagents are running.
|
|
27
35
|
- Returns complete bounded worker output in tool details and a concise result for the main agent.
|
|
28
36
|
|
|
@@ -41,7 +49,7 @@ pi -e npm:@narumitw/pi-subagents
|
|
|
41
49
|
Try this package locally from the repository root:
|
|
42
50
|
|
|
43
51
|
```bash
|
|
44
|
-
pi -e ./
|
|
52
|
+
pi -e ./packages/pi-subagents
|
|
45
53
|
```
|
|
46
54
|
|
|
47
55
|
## 🛠️ Pi tool
|
|
@@ -59,7 +67,7 @@ The preview compares the selection with the tools registered in the current sess
|
|
|
59
67
|
|
|
60
68
|
The available tools are:
|
|
61
69
|
|
|
62
|
-
- `subagent` — delegate blocking single, parallel, fan-in, or
|
|
70
|
+
- `subagent` — delegate blocking single, parallel, fan-in, chained, panel-review, or explicit dependency-workflow tasks. The main agent cannot process queued steering until the call returns.
|
|
63
71
|
- `subagent_spawn` and related lifecycle tools — when enabled, start reusable detached work, return immediately, and receive bounded completion messages automatically.
|
|
64
72
|
- `subagent_inspect` — inspect agent/model/run/runtime metadata without launching work or changing state.
|
|
65
73
|
- `subagent_consult` — run one ephemeral read-only consultation and wait for its answer.
|
|
@@ -102,14 +110,22 @@ Execution modes:
|
|
|
102
110
|
- **parallel** — run multiple `{ agent, task }` jobs independently.
|
|
103
111
|
- **parallel + aggregator** — run parallel jobs, then pass all outputs into one fan-in agent.
|
|
104
112
|
- **chain** — run sequential steps, passing prior output with `{previous}`.
|
|
113
|
+
- **workflow** — run named tasks only after declared `dependsOn` tasks and required `inputArtifacts` are ready; independent conflict-free tasks may run concurrently.
|
|
114
|
+
- **panel** — run at least two independent reviewers over one shared task and snapshot, then run one synthesizer only when `minValidReviews` valid evidence artifacts remain.
|
|
105
115
|
|
|
106
116
|
Common controls:
|
|
107
117
|
|
|
108
118
|
- `cwd` — choose a launch directory subject to the user-owned trust-aware target policy described below.
|
|
109
|
-
- `timeoutMs` —
|
|
110
|
-
- `
|
|
119
|
+
- `timeoutMs` — choose the per-turn work deadline for the task difficulty.
|
|
120
|
+
- `totalTimeoutMs` — cap an entire blocking single, parallel, chain, panel, or fan-in workflow, including queued work and reserved panel phases.
|
|
121
|
+
- `idleTimeoutMs` — stop work that produces no completed assistant turn or tool result within the selected interval.
|
|
122
|
+
- `maxTurns` / `maxToolCalls` — stop unfinished repeated work after bounded assistant turns or tool calls.
|
|
123
|
+
- `thinkingLevel` — request `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max` thinking for the spawned Pi process or retained child.
|
|
124
|
+
- `idempotencyKey` — make an exact `subagent_spawn` retry return the existing retained `agentId`; reuse with different parameters fails before confirmation, worktree creation, or child launch.
|
|
125
|
+
- `resultFormat` — keep bounded text by default, request legacy `structured-v1`, or request `structured-v2` with explicit outcome status, reason code, claims, artifacts, verification, limitations, and unresolved dependencies.
|
|
126
|
+
- `totalTimeoutMs` — bound a whole explicit blocking workflow; no new task starts after the budget is exhausted.
|
|
111
127
|
|
|
112
|
-
For `subagent_spawn`, the root agent selects the lowest thinking level sufficient for the delegated task.
|
|
128
|
+
For `subagent_spawn`, the root agent selects the lowest thinking level and shortest realistic work deadline sufficient for the delegated task. These are tool-argument decisions made from the task already in context; `pi-subagents` does not run a string heuristic or an extra classifier model call.
|
|
113
129
|
|
|
114
130
|
## 🔐 Working-directory trust policy
|
|
115
131
|
|
|
@@ -122,7 +138,7 @@ The default target policies are:
|
|
|
122
138
|
| `cwdPolicy.consultation` | `"anywhere"`, `"current-workspace"` | `"anywhere"`: consultation may start in any existing directory, but a target without effective trust is forced to `resources: "none"` |
|
|
123
139
|
| `cwdPolicy.delegation` | `"trusted-targets"`, `"current-workspace"`, `"anywhere"` | `"trusted-targets"`: blocking and detached delegation may target the current workspace or an external folder covered by a saved `true` decision |
|
|
124
140
|
|
|
125
|
-
All paths are resolved relative to the current session workspace and canonicalized before containment and trust checks. Missing paths, non-directories, sibling paths, and symlink escapes cannot bypass the policy. Blocking parallel, chain, and fan-in calls preflight every target before any child starts. A generated `workspaceMode: "worktree"` inherits the resolved trust of its approved base cwd.
|
|
141
|
+
All paths are resolved relative to the current session workspace and canonicalized before containment and trust checks. Missing paths, non-directories, sibling paths, and symlink escapes cannot bypass the policy. Blocking parallel, chain, panel, and fan-in calls preflight every target before any child starts. A generated `workspaceMode: "worktree"` inherits the resolved trust of its approved base cwd.
|
|
126
142
|
|
|
127
143
|
`"anywhere"` for general delegation restores the previous external-target flexibility. An external target without effective trust starts with `projectTrusted: false`, so Pi-protected project settings, packages, extensions, skills, prompts, and system resources stay disabled. General agents still have their configured tools and ordinary Pi/OS permissions, and Pi may still load `AGENTS.md` or `CLAUDE.md` because those context files are not protected by project trust. Resource-free consultation is stricter: it also passes `--no-context-files`, `--no-skills`, `--no-prompt-templates`, `--no-approve`, and `--no-extensions`.
|
|
128
144
|
|
|
@@ -163,10 +179,9 @@ Count-selection guidance:
|
|
|
163
179
|
- Use detached `subagent_spawn` only when lifecycle tools are enabled and a bounded independent task
|
|
164
180
|
has a concrete isolation or specialization benefit. After spawning, do useful non-overlapping work
|
|
165
181
|
immediately. Do not poll lifecycle tools for progress or duplicate the delegated work.
|
|
166
|
-
- Add another detached agent only for truly independent work with safe workspace concurrency.
|
|
167
|
-
synchronous parallel or fan-in output is genuinely required, keep blocking `subagent` tasks
|
|
168
|
-
|
|
169
|
-
the same files or shared state.
|
|
182
|
+
- Add another detached agent only for truly independent work with safe workspace concurrency.
|
|
183
|
+
If synchronous parallel or fan-in output is genuinely required, keep blocking `subagent` tasks independent, stay within the configured `blocking.maxParallelTasks` limit, and do not parallelize implementation that may edit the same files or shared state.
|
|
184
|
+
The limit defaults to 8, accepts 1 through 64, and bounds total worker tasks in one call rather than the four-at-a-time execution concurrency.
|
|
170
185
|
- Do not use project-local agents unless the user explicitly opts into them with
|
|
171
186
|
`agentScope: "project"` or `"both"`; keep confirmation enabled for untrusted repositories.
|
|
172
187
|
|
|
@@ -218,12 +233,15 @@ A blocking fan-out is reserved for output that must be synthesized before the ro
|
|
|
218
233
|
| `list_agents` | Optional `agentScope` (default `user`) and `limit` (default 32, maximum 100) | Bounded agent metadata and omission counts |
|
|
219
234
|
| `get_agent` | Required `agent`; optional `agentScope` | One resolved definition, safe source path, configured tools, and consultation-effective tools; never the system prompt |
|
|
220
235
|
| `list_runs` | Optional `includeClosed` and `limit` (default 50, maximum 100) | Metadata-only retained-run summaries and unread counts |
|
|
221
|
-
| `get_run` | Required `agentId` | Safe `cwd`, current-task/error summaries, thinking level, policy, history count, and unread count |
|
|
236
|
+
| `get_run` | Required `agentId` | Safe `cwd`, current-task/error summaries, thinking level, context footprint, protocol, effective transport, bounded timing/usage telemetry, structured result when valid, policy, history count, and unread count |
|
|
237
|
+
| `list_workflows` | Optional `limit` (default 50, maximum 100) | Metadata-only persisted blocking-workflow summaries for the current session |
|
|
238
|
+
| `get_workflow` | Required `workflowId` | Bounded task states, generations, dependencies, plan identities, artifact metadata, verification state, and outcome reasons without artifact contents |
|
|
222
239
|
| `list_models` | Optional `limit` (default 50, maximum 100) | Session-scoped models, or the already-loaded available snapshot |
|
|
223
|
-
| `
|
|
240
|
+
| `preview_context` | Optional `context` and `contextEntryIds` | Selected mode, user turns, source count, UTF-8 bytes, and truncation without returning context text |
|
|
241
|
+
| `status` | No additional fields | Effective workflow, runtime counts/transport, detached limit values, completion delivery, consultation resources, and configured/runtime settings with per-field sources |
|
|
224
242
|
| `diagnose` | No additional fields | Structured `pass`, `warning`, and `fail` checks; failed checks are report data rather than a tool error |
|
|
225
243
|
|
|
226
|
-
The schema rejects fields that do not belong to the selected action. Explicit `project` or `both` scope fails before project-agent discovery unless Pi already trusts the project. Run inspection never returns history output, stored context, or mailbox content; unread counts come from a metadata-only snapshot and do not acknowledge messages. Paths beneath the Pi agent directory use `~`, project paths are workspace-relative, model objects are projected through an allow-list, and model-facing text is bounded to 50 KiB or 2,000 lines.
|
|
244
|
+
The schema rejects fields that do not belong to the selected action. Explicit `project` or `both` scope fails before project-agent discovery unless Pi already trusts the project. Run inspection never returns history output, stored context, or mailbox content; unread counts come from a metadata-only snapshot and do not acknowledge messages. Workflow inspection reads validated, redacted snapshots without quarantining or rewriting invalid files. Paths beneath the Pi agent directory use `~`, project paths are workspace-relative, model objects are projected through an allow-list, and model-facing text is bounded to 50 KiB or 2,000 lines.
|
|
227
245
|
|
|
228
246
|
Compatibility: `subagent_manage({ "action": "list" })` remains supported with its existing behavior. Prefer `subagent_inspect` when a whole tool must be safe to activate on a read-only surface.
|
|
229
247
|
|
|
@@ -261,7 +279,7 @@ Extensions remain disabled for all three values. Pi core owns system-prompt sour
|
|
|
261
279
|
|
|
262
280
|
Both settings are user-owned in `~/.pi/agent/pi-subagents.json`; projects cannot override them. `cwdPolicy.consultation: "current-workspace"` rejects every canonical external target before agent discovery or launch even when that target is saved-trusted. This is not a path sandbox: read-only tools can still read an explicitly requested accessible absolute path.
|
|
263
281
|
|
|
264
|
-
Result details report the canonical safe cwd, current/external boundary, bounded target-trust decision/source/warning, requested and effective tools/resources, downgrade reason, agent/model/thinking/timeout metadata, and the facts that extensions, session persistence, and retained-agent state are disabled. They never dump prompt contents or the full trust store. Nested model usage is returned through Pi's usage field, so footer, `/session`, and RPC totals include consultation cost. Validation, disallowed targets, and launch failures throw. Failures after model launch preserve bounded partial evidence and usage while the finalized Pi tool result is marked as an error.
|
|
282
|
+
Result details report the canonical safe cwd, current/external boundary, bounded target-trust decision/source/warning, requested and effective tools/resources, downgrade reason, agent/model/thinking/timeout metadata, and the facts that extensions, session persistence, and retained-agent state are disabled. They never dump prompt contents or the full trust store. Nested model usage is returned through Pi's usage field, so footer, `/session`, and RPC totals include consultation cost. Validation, disallowed targets, and launch failures throw. Failures after model launch preserve bounded partial evidence and usage while the finalized Pi tool result is marked as an error. Explicit abort, session replacement, and shutdown use the existing process-tree termination and temporary-file cleanup path; a work timeout additionally makes one separately bounded, tool-less summary attempt after abort.
|
|
265
283
|
|
|
266
284
|
## 🚀 Blocking batch examples
|
|
267
285
|
|
|
@@ -334,6 +352,73 @@ Run a chain where each step receives the previous output:
|
|
|
334
352
|
}
|
|
335
353
|
```
|
|
336
354
|
|
|
355
|
+
Run an evidence-preserving panel:
|
|
356
|
+
|
|
357
|
+
```json
|
|
358
|
+
{
|
|
359
|
+
"panel": {
|
|
360
|
+
"id": "auth-panel",
|
|
361
|
+
"preset": "code-review",
|
|
362
|
+
"task": "Review the authentication change for correctness and regressions.",
|
|
363
|
+
"context": "Inspect the current repository snapshot and existing test evidence.",
|
|
364
|
+
"reviewers": [
|
|
365
|
+
{ "id": "correctness", "agent": "reviewer", "focus": "Control flow and edge cases" },
|
|
366
|
+
{ "id": "tests", "agent": "reviewer", "focus": "Coverage and regression risk" }
|
|
367
|
+
],
|
|
368
|
+
"synthesizer": { "agent": "reviewer" },
|
|
369
|
+
"minValidReviews": 2
|
|
370
|
+
},
|
|
371
|
+
"totalTimeoutMs": 120000
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Every reviewer receives the same shared task, context, target snapshot, and scope, but never receives sibling output.
|
|
376
|
+
Reviewer-specific `focus` text is appended after the shared block.
|
|
377
|
+
The executor accepts only strict `pi-subagents:panel-review:v1` artifacts, stamps reviewer provenance, and starts synthesis only after the valid-review barrier.
|
|
378
|
+
Agreement is corroboration rather than proof, and a vote cannot clear a correctness, safety, security, or explicit-requirement blocker.
|
|
379
|
+
If too few valid reviews remain, the tool returns `insufficient-panel` with bounded partial evidence and failure classes without running synthesis or claiming consensus.
|
|
380
|
+
Review, evidence-finalization, synthesis, and cleanup receive explicit phase allocations, and reviewer work cannot consume the synthesis or cleanup reserve.
|
|
381
|
+
Only transient launch or transport failures receive one bounded retry; invalid contracts, semantic stalls, permission failures, exhausted budgets, cancellation, and deterministic task failures do not.
|
|
382
|
+
Read-only reviewers share the approved target, while conservatively write-capable reviewers receive separate disposable Git worktrees from one clean base.
|
|
383
|
+
Worktrees isolate repository writes but do not isolate processes, the network, secrets, credentials, or the rest of the filesystem.
|
|
384
|
+
The blocking panel owns every reviewer, synthesizer, timer, generation, transport, and worktree and closes them when the call settles or Pi emits graceful session replacement or shutdown.
|
|
385
|
+
An uncatchable host kill or forced process termination cannot guarantee cleanup; inspect `git worktree list`, remove any confirmed generated `pi-subagent-worktree-*` entry, and run `git worktree prune` if the host terminated before Pi dispatched lifecycle cleanup.
|
|
386
|
+
Panel WorkItem snapshots persist metadata and artifact references for current-session inspection without storing raw review bodies.
|
|
387
|
+
|
|
388
|
+
Run an explicit dependency workflow:
|
|
389
|
+
|
|
390
|
+
```json
|
|
391
|
+
{
|
|
392
|
+
"workflow": {
|
|
393
|
+
"id": "auth-review",
|
|
394
|
+
"tasks": [
|
|
395
|
+
{
|
|
396
|
+
"id": "inventory",
|
|
397
|
+
"agent": "scout",
|
|
398
|
+
"task": "Produce the auth inventory artifact.",
|
|
399
|
+
"resultFormat": "structured-v2",
|
|
400
|
+
"readPaths": ["src/auth"]
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
"id": "review",
|
|
404
|
+
"agent": "reviewer",
|
|
405
|
+
"task": "Review the inventory and report verification evidence.",
|
|
406
|
+
"dependsOn": ["inventory"],
|
|
407
|
+
"inputArtifacts": ["auth-inventory"],
|
|
408
|
+
"resultFormat": "structured-v2"
|
|
409
|
+
}
|
|
410
|
+
]
|
|
411
|
+
},
|
|
412
|
+
"totalTimeoutMs": 120000
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Cycles, missing dependencies, conflicting integration owners, recursive workflow grandchildren, and unsafe retry or hedge policies fail before child launch.
|
|
417
|
+
Workflow scheduling starts at most two mutating tasks concurrently, while declared read-only work may use the existing four-child ceiling.
|
|
418
|
+
Set `workflow.honorAdmission: true` only when explicit contract admission metadata should be allowed to decline parent-owned or insufficient-evidence work before launch; admission never silently widens the requested architecture.
|
|
419
|
+
Workflow result details include the final ledger, scheduling decisions, artifact versions, task generations, attempts, hedge use, accepted plan identity, and bounded capability-grant metadata.
|
|
420
|
+
Explicit workflow transitions are also atomically persisted as mode-0600, private-text-redacted snapshots for current-session `list_workflows` and `get_workflow` inspection; in-flight tasks inspect as `interrupted`, and no prior side effect is automatically resumed.
|
|
421
|
+
|
|
337
422
|
## 🔁 Stateful agents
|
|
338
423
|
|
|
339
424
|
Stateful lifecycle tools are available by default. `subagent_spawn` is detached: it schedules work, returns immediately with an opaque `agentId`, and later injects a bounded `pi-subagent-completion` custom message. Completions that settle in the same dispatch window are batched, and the broker allows at most one in-flight root wake until that parent turn starts.
|
|
@@ -349,24 +434,35 @@ A detached agent additionally needs a concrete isolation or specialization benef
|
|
|
349
434
|
|
|
350
435
|
Auto-resume is best-effort because Pi's custom-message API is fire-and-forget. Session-generation checks, shutdown cleanup, batching, and the in-flight wake guard prevent stale or duplicate scheduling pressure, but they do not make completion delivery durable across process exit.
|
|
351
436
|
|
|
352
|
-
The default `subprocess` transport preserves compatibility: each turn starts a fresh isolated `pi --mode json -p --no-session` child and receives sanitized, bounded history.
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
437
|
+
The default `subprocess` transport preserves compatibility: each turn starts a fresh isolated `pi --mode json -p --no-session` child and receives sanitized, bounded history.
|
|
438
|
+
Set `transport` to `in-process` to retain one public Pi SDK `AgentSession` per stateful `agentId`, avoiding repeated process startup while preserving native child history in memory.
|
|
439
|
+
Set it to `rpc` to retain one `pi --mode rpc --no-session --no-extensions` process per active retained agent, preserving native child history with a separate process boundary.
|
|
440
|
+
Set it to `auto` for deterministic preflight selection: read-only built-in tools use in-process, write-capable built-in tools use RPC, and extension/custom tools use subprocess.
|
|
441
|
+
Automatic selection never falls back after child creation or prompt acceptance.
|
|
442
|
+
|
|
443
|
+
Run `/subagents` in TUI mode to open the standard primary manager.
|
|
444
|
+
It leads with the current delegation workflow, human-readable async completion behavior, consultation/delegation target policies, consultation-resource policy, parallel-worker limit, and active/retained counts.
|
|
445
|
+
**Change delegation**, **Current agents**, and **Settings** cover the common workflows.
|
|
446
|
+
Agent permissions, **Maximum parallel workers**, **Detached agent limits**, **Performance and execution**, transport/runtime details, source, and settings path remain under **Advanced settings**.
|
|
447
|
+
**Performance and execution** provides responsiveness guidance, transport previews, Fast/Balanced/Deep thinking profiles, and per-agent model/thinking/timeout defaults.
|
|
448
|
+
Profiles are explicit atomic thinking patches, preserve model/tool/timeout/context settings, never select `max`, and can be customized afterward.
|
|
449
|
+
The parallel-worker input rejects invalid values without discarding the draft and applies a successful save immediately.
|
|
450
|
+
The detached-limit screen edits retained capacity, active-turn concurrency, direct children, tree depth, and stored-record capacity.
|
|
451
|
+
Detached-limit saves are durable immediately but apply to the runtime after `/reload` or the next Pi session.
|
|
452
|
+
Escape returns from a nested screen to a newly refreshed manager, while Ctrl+C closes the full flow.
|
|
453
|
+
Exact workflow/reload and project-agent safety confirmations remain extension-owned because they guard live agent and trust-boundary policy rather than ordinary navigation.
|
|
359
454
|
|
|
360
455
|
The direct routes remain predictable: `/subagents settings` changes both target policies, consultation resources, and completion delivery and applies them immediately, including refreshing model-facing tool guidance; `/subagents status` reports current-session runtime values separately from configured values, per-field sources, and path; `/subagents help` summarizes the single-command interface and the non-sandbox limitation. In RPC mode, bare `/subagents` emits the same bounded status through Pi's notification protocol instead of opening a custom TUI. JSON and print modes do not emit ad hoc command output. Manual edits use `~/.pi/agent/pi-subagents.json` and take effect after reloading Pi:
|
|
361
456
|
|
|
362
457
|
```json
|
|
363
458
|
{
|
|
364
459
|
"blocking": {
|
|
365
|
-
"enabled": false
|
|
460
|
+
"enabled": false,
|
|
461
|
+
"maxParallelTasks": 8
|
|
366
462
|
},
|
|
367
463
|
"stateful": {
|
|
368
464
|
"enabled": true,
|
|
369
|
-
"transport": "
|
|
465
|
+
"transport": "auto",
|
|
370
466
|
"completionDelivery": "auto-resume",
|
|
371
467
|
"maxAgents": 16,
|
|
372
468
|
"maxActiveTurns": 4,
|
|
@@ -388,12 +484,31 @@ The direct routes remain predictable: `/subagents settings` changes both target
|
|
|
388
484
|
}
|
|
389
485
|
```
|
|
390
486
|
|
|
391
|
-
The settings UI patches the raw JSON atomically and preserves unknown fields
|
|
487
|
+
The settings UI patches the raw JSON atomically and preserves unknown fields.
|
|
488
|
+
It refuses to overwrite malformed or invalid settings.
|
|
489
|
+
Supported Pi writers serialize the latest-document read and same-directory temporary-file rename through `pi-subagents.json.mutation-lock`.
|
|
490
|
+
Editors and older extension versions do not participate in that lock, so avoid manual edits while a settings save is in progress.
|
|
491
|
+
`blocking.enabled` defaults to `true`; set it to `false` for async-only delegation.
|
|
492
|
+
`blocking.maxParallelTasks` defaults to `8` and accepts positive integers from `1` through `64`.
|
|
493
|
+
It limits worker tasks in one blocking parallel call, while execution still starts at most four workers at once and treats an optional aggregator separately.
|
|
494
|
+
`stateful.enabled` also defaults to `true`; its existing `false` value remains the blocking-only workflow.
|
|
495
|
+
The detached defaults are `maxAgents: 16`, `maxActiveTurns: 4`, `maxChildrenPerAgent: 8`, `maxDepth: 3`, and `maxStoredAgents: 50`.
|
|
496
|
+
`maxDepth` accepts zero or a positive safe integer, while the other four detached limits accept positive safe integers.
|
|
497
|
+
Use `/subagents` → **Advanced settings** → **Detached agent limits** to edit them without replacing unknown JSON fields.
|
|
498
|
+
The screen shows current-session and configured values separately because changes apply after `/reload`.
|
|
499
|
+
It never reloads automatically, because reload can interrupt retained detached work.
|
|
500
|
+
Lowering retained, depth, or stored capacity shows a projected recovery warning when current records would be omitted.
|
|
501
|
+
Restored parents that already exceed a lowered `maxChildrenPerAgent` remain available, but they cannot gain another child until they fall below the configured limit.
|
|
502
|
+
`cwdPolicy.consultation` defaults to `"anywhere"`, `cwdPolicy.delegation` defaults to `"trusted-targets"`, and `consult.resources` defaults to `"project-context"`.
|
|
503
|
+
The Settings UI applies a saved change immediately to subsequent launches and refreshes the affected tool descriptions; manual edits take effect on session start or `/reload`.
|
|
504
|
+
The UI explicitly states that target/trust settings are not filesystem sandboxing and directs trust changes to Pi `/trust`.
|
|
505
|
+
When stateful tools are enabled, their membership stays fixed across spawn, completion, interrupt, close, and mailbox transitions.
|
|
506
|
+
This avoids lifecycle-driven tool-schema churn and preserves a stable provider prompt prefix for KV caching.
|
|
392
507
|
|
|
393
508
|
| Tool | Purpose |
|
|
394
509
|
| --- | --- |
|
|
395
|
-
| `subagent_spawn` | Start detached work with
|
|
396
|
-
| `subagent_send` | Send follow-up work and trigger a new turn on a reusable agent; shared-workspace write conflicts are guarded unless explicitly overridden. |
|
|
510
|
+
| `subagent_spawn` | Start detached work with optional task-selected thinking and retained timeout, exact-retry `idempotencyKey`, and `text`, `structured-v1`, or `structured-v2` result format; return an opaque `agentId` immediately and deliver completion asynchronously. |
|
|
511
|
+
| `subagent_send` | Send follow-up work with an optional one-turn timeout override and trigger a new turn on a reusable agent; semantic skew requires explicit `revalidate: true`, and shared-workspace write conflicts are guarded unless explicitly overridden. |
|
|
397
512
|
| `subagent_manage` | Use `action: "list"` to inspect agents, `"interrupt"` to retain an agent after aborting active work, or `"close"` to release it; interrupt/close accept optional `subtree`. |
|
|
398
513
|
| `subagent_mailbox` | Use `action: "send"` for queue-only messages that do not start a turn, or `"read"` to read and optionally acknowledge unread messages. |
|
|
399
514
|
|
|
@@ -415,7 +530,12 @@ The action schemas are flat for provider compatibility and reject parameters tha
|
|
|
415
530
|
}
|
|
416
531
|
```
|
|
417
532
|
|
|
418
|
-
Use the **Current agents** action in `/subagents` to inspect the indented agent tree, lifecycle state, unread count, and available actions, or to confirm clearing retained agents.
|
|
533
|
+
Use the **Current agents** action in `/subagents` to inspect the indented agent tree, lifecycle state, unread count, and available actions, or to confirm clearing retained agents.
|
|
534
|
+
Active turns are FIFO-limited by `maxActiveTurns`; excess retained work remains in `starting` state until a slot is available.
|
|
535
|
+
`maxAgents` separately bounds running, queued, and idle records.
|
|
536
|
+
`maxChildrenPerAgent` bounds direct children, while `maxDepth` counts nested levels below a depth-zero root.
|
|
537
|
+
`maxStoredAgents` bounds sanitized records persisted per session and does not increase live runtime capacity.
|
|
538
|
+
`parentId` creates a bounded child relationship; subtree interrupt and close operate child-first.
|
|
419
539
|
|
|
420
540
|
### Migrating from the previous seven-tool lifecycle surface
|
|
421
541
|
|
|
@@ -441,7 +561,26 @@ A spawn can request a thinking level explicitly:
|
|
|
441
561
|
}
|
|
442
562
|
```
|
|
443
563
|
|
|
444
|
-
The requested level
|
|
564
|
+
The requested level and spawn `timeoutMs`, `idleTimeoutMs`, `maxTurns`, and `maxToolCalls` are stored with the stateful agent and remain in effect for all follow-ups and after persisted restore. The same fields on `subagent_send` override only that follow-up turn. `subagent_send` does not provide a per-turn thinking override; create a new agent when a later task needs a different level.
|
|
565
|
+
|
|
566
|
+
An exact retry can use a bounded session-owned idempotency key:
|
|
567
|
+
|
|
568
|
+
```json
|
|
569
|
+
{
|
|
570
|
+
"agent": "worker",
|
|
571
|
+
"task": "Implement the approved change",
|
|
572
|
+
"idempotencyKey": "approved-change-1"
|
|
573
|
+
}
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
The same key and canonical request returns the existing retained `agentId` without another confirmation, worktree, or child.
|
|
577
|
+
Reusing the key with different behavior-affecting parameters fails.
|
|
578
|
+
Closing the retained record releases the key.
|
|
579
|
+
|
|
580
|
+
Set `resultFormat: "structured-v1"` to ask for legacy `summary`, `evidence`, `changes`, `verification`, and `risks` fields.
|
|
581
|
+
Prefer `resultFormat: "structured-v2"` when orchestration must distinguish `completed`, `partial`, `blocked`, `needs-input`, `failed`, `interrupted`, `abstained`, `stale`, or `contract-invalid` outcomes and consume typed artifact evidence.
|
|
582
|
+
Valid structured data and deterministic recovery classification appear in completion and inspection details, while malformed structured output becomes `contract-invalid` instead of being treated as success.
|
|
583
|
+
The executor stamps task generation, cancellation lineage, and accepted `ExecutionPlan` identity after parsing, so model output cannot forge the provenance used for stale-result containment.
|
|
445
584
|
|
|
446
585
|
`subagent_spawn.context` accepts:
|
|
447
586
|
|
|
@@ -450,21 +589,31 @@ The requested level is stored with the stateful agent and remains in effect for
|
|
|
450
589
|
- `"summary"` — a bounded earlier-context checkpoint plus recent messages verbatim.
|
|
451
590
|
- A positive number — the most recent N user turns and related assistant text.
|
|
452
591
|
|
|
453
|
-
Use `contextEntryIds` to select exact session entries.
|
|
592
|
+
Use `contextEntryIds` to select exact session entries.
|
|
593
|
+
Supplying IDs without `context` implies `context: "all"`; an explicit `context: "none"` still disables parent context.
|
|
594
|
+
Stable source IDs are retained so repeated follow-ups do not need to duplicate parent context.
|
|
595
|
+
Use `subagent_inspect` with `action: "preview_context"` to inspect selected turns, source count, UTF-8 bytes, and truncation before spawning without returning the context text.
|
|
596
|
+
The byte count is not a provider token estimate.
|
|
454
597
|
|
|
455
598
|
Reasoning, tool results, custom transport messages, and non-text parts are excluded. Text inside `<private>...</private>` and lines containing `[subagent-private]` are omitted before context, mailbox content, or history is persisted.
|
|
456
599
|
|
|
457
600
|
Stateful execution uses a transport boundary:
|
|
458
601
|
|
|
459
|
-
- `subprocess` is the default compatibility and rollback path.
|
|
602
|
+
- `subprocess` is the default compatibility and rollback path and starts a fresh child for every turn.
|
|
460
603
|
- `in-process` uses only public Pi SDK APIs: `createAgentSessionServices()`, `createAgentSessionFromServices()`, `SessionManager.inMemory()`, and normal session lifecycle methods. It isolates conversation/tool selection, not memory or crashes; child failures share the parent Node.js process.
|
|
461
|
-
-
|
|
604
|
+
- `rpc` uses strict bounded JSONL over one lazy child process per active retained agent. A `get_state` response proves readiness, prompt response means accepted only, and `agent_settled` is the completion boundary after retry or compaction.
|
|
605
|
+
- `auto` selects one transport before launch and retains the choice for that agent's runtime lifetime. It never retries through another transport after startup or accepted work.
|
|
606
|
+
- In-process and RPC child resource loading disables extensions to prevent recursive `pi-subagents` loading and duplicate extension side effects while retaining trust-eligible context/skill resources and the selected agent prompt. The compatibility subprocess path retains its recursion-depth guard and configured tool behavior. Transports receive the same resolved target-trust boolean through their public SDK or explicit CLI trust controls.
|
|
462
607
|
- Agent model strings use Pi core's CLI resolver, including provider/model patterns, fuzzy matching, custom provider model IDs, and `:<thinking>` suffixes. Thinking level and built-in tool allow-list overrides are applied when the child is created. Parent model/thinking changes are snapshotted for subsequently created children; an existing child keeps its own session configuration.
|
|
463
|
-
- Extension/custom tool names are rejected in-process
|
|
464
|
-
- Timeout, parent abort, close, expiry, and session shutdown abort/dispose owned child sessions. A child that does not settle after abort grace is discarded rather than reused.
|
|
608
|
+
- Extension/custom tool names are rejected by in-process and RPC v1 before child creation; automatic mode selects `subprocess` for them, and permissions are never silently widened.
|
|
609
|
+
- Timeout, parent abort, close, expiry, and session shutdown abort/dispose owned child sessions or process groups. A child that does not settle after abort grace is discarded rather than reused.
|
|
610
|
+
- RPC progress uses `pi-subagents:v1` metadata and reports only bounded phase, queue, timing, effective model/thinking, and validated usage fields; it never exposes raw prompts, reasoning, credentials, environment values, or full RPC events.
|
|
611
|
+
- A successful RPC prompt response is never treated as completion, and accepted or ambiguously accepted work is never replayed automatically.
|
|
465
612
|
- In-process startup failures do not silently retry through subprocesses, preventing duplicate side effects. If the loaded Pi core lacks public `createAgentSessionServices()`, `createAgentSessionFromServices()`, or `resolveCliModel()` support, startup fails with an actionable instruction to select `stateful.transport: "subprocess"`.
|
|
466
613
|
|
|
467
|
-
No private Pi imports, runtime casts, or `ExtensionAPI` monkey-patching are used.
|
|
614
|
+
No private Pi imports, runtime casts, or `ExtensionAPI` monkey-patching are used.
|
|
615
|
+
The package uses public Pi root RPC types but owns exact CLI resolution, bounded framing, readiness, stderr, cancellation, and process-group cleanup because the stock client does not provide those package-specific guarantees.
|
|
616
|
+
Approval policy, sandbox profile, provider-header hooks, extension state, global scheduling, and parent/child transcript switching are not inherited or provided by in-process or RPC transport.
|
|
468
617
|
|
|
469
618
|
Write-capable agents share the workspace by default. Concurrent write-capable starts in the same cwd are rejected unless `allowConcurrentWrites` is explicitly set. Classification is intentionally conservative: an agent with `bash`, `write`, or `edit` is write-capable even when its task prompt says “read only,” because prompt wording is not a filesystem sandbox. Prefer one detached agent when asynchronous work can be combined. If concurrent work is genuinely required, use the blocking batch only when synchronous outputs justify making the root unavailable, explicitly accept safe detached overlap with `allowConcurrentWrites`, or use isolated worktrees when repository isolation is needed.
|
|
470
619
|
|
|
@@ -472,19 +621,26 @@ Set `workspaceMode: "worktree"` to opt into a disposable detached Git worktree;
|
|
|
472
621
|
|
|
473
622
|
## 📜 Compatibility and failure contract
|
|
474
623
|
|
|
475
|
-
Existing `subagent`
|
|
624
|
+
Existing accepted `subagent` payload shapes remain unchanged.
|
|
625
|
+
`subagent_spawn` adds optional `idempotencyKey` and `resultFormat` fields without changing omitted behavior.
|
|
626
|
+
Older releases do not recognize `stateful.transport: "rpc"` or `"auto"`; change the value to `"subprocess"` and reload before downgrading.
|
|
627
|
+
Retained records remain transport-neutral, and older readers ignore the additive idempotency and context-footprint fields while the state version remains compatible.
|
|
628
|
+
The `tasks` schema now advertises the absolute 64-item safety bound, while the effective `blocking.maxParallelTasks` value may be lower.
|
|
629
|
+
The intentional compatibility change is that an external target without saved trust is rejected by the new default `cwdPolicy.delegation: "trusted-targets"`; set the user-owned policy to `"anywhere"` to restore the preceding target flexibility.
|
|
476
630
|
|
|
477
631
|
| Mode | Ordering | Failure behavior |
|
|
478
632
|
| --- | --- | --- |
|
|
479
633
|
| Single | One result. | A failed/aborted/timed-out worker is marked as a tool error while preserving bounded details. |
|
|
480
634
|
| Chain | Input order. | Stops at the first failed step; completed steps remain in details. |
|
|
481
|
-
| Parallel | Input order,
|
|
482
|
-
| Parallel + aggregator | Source input order, then aggregator. | The aggregator runs with
|
|
635
|
+
| Parallel | Input order, up to `blocking.maxParallelTasks` total workers and at most four active children. | Rejects calls above the configured limit; otherwise collects all task results, and partial worker failure does not discard successful results. |
|
|
636
|
+
| Parallel + aggregator | Source input order, then aggregator. | The aggregator runs with successful outputs and failure descriptions only when total budget remains; aggregator failure or orchestration expiry marks the tool result as an error. |
|
|
637
|
+
| Workflow | Deterministic dependency-ready and critical-path order, with results returned in declared task order. | Invalid graphs fail before launch; blocked or failed dependencies prevent downstream start; bounded retry and hedging require explicit side-effect contracts. |
|
|
638
|
+
| Panel | Reviewer declaration order, then at most one synthesizer. | Invalid or failed reviews remain visible; synthesis requires `minValidReviews`; insufficient panels preserve partial evidence without a consensus claim; synthesis contract failure marks the tool result as an error. |
|
|
483
639
|
|
|
484
640
|
An aggregator whose `agent` or `task` is empty or whitespace-only is treated as absent, so successful
|
|
485
641
|
parallel outputs remain available instead of being replaced by a malformed fan-in failure.
|
|
486
642
|
|
|
487
|
-
|
|
643
|
+
Blocking work-timeout precedence remains: task/step/aggregator → call → agent setting → `PI_SUBAGENT_TIMEOUT_MS` → 600000 ms, then `totalTimeoutMs` caps the effective remaining time. Blocking idle, turn, and tool-call precedence is task/step/aggregator → call → omitted. Stateful budget precedence is the explicit `subagent_send` field for one follow-up → retained `subagent_spawn` field → timeout-only agent/environment fallback where applicable. Blocking thinking precedence remains: task/step/aggregator → call → agent setting → child default. Stateful spawn thinking precedence is: `subagent_spawn.thinkingLevel` → agent setting → transport fallback. Project-agent resolution and confirmation behavior is unchanged after target preflight. Blocking and retained result/inspection details add bounded target, budget, termination, and effective trust metadata.
|
|
488
644
|
|
|
489
645
|
## 🤖 Built-in agents
|
|
490
646
|
|
|
@@ -500,12 +656,24 @@ Built-in agents are available without setup and can be overridden by user or pro
|
|
|
500
656
|
|
|
501
657
|
The built-in `reviewer` does not run tests, builds, benchmarks, or formatters. It recommends additional verification commands for the main agent to run instead. Custom agents can override this behavior.
|
|
502
658
|
|
|
503
|
-
Built-in agents inherit the active/default Pi model instead of forcing a provider-specific model alias, which keeps
|
|
659
|
+
Built-in agents inherit the active/default Pi model instead of forcing a provider-specific model alias, which keeps every transport usable across different Pi setups.
|
|
660
|
+
Built-ins also have no fixed thinking override until a caller, frontmatter, per-agent setting, or execution profile selects one.
|
|
661
|
+
|
|
662
|
+
The optional profiles apply these provider-neutral thinking defaults:
|
|
663
|
+
|
|
664
|
+
| Profile | `scout` | `planner` | `reviewer` | `worker` and aliases |
|
|
665
|
+
| --- | --- | --- | --- | --- |
|
|
666
|
+
| Fast | `low` | `low` | `medium` | `low` |
|
|
667
|
+
| Balanced | `low` | `medium` | `medium` | `medium` |
|
|
668
|
+
| Deep | `medium` | `high` | `high` | `high` |
|
|
669
|
+
|
|
670
|
+
Profiles preserve model, timeout, tools, transport, completion delivery, and parent-context behavior.
|
|
504
671
|
|
|
505
672
|
## ⚙️ Configure agent tools
|
|
506
673
|
|
|
507
674
|
Open `/subagents`, choose **Advanced settings**, then **Agent tool permissions** in an interactive
|
|
508
|
-
Pi session to edit the tools each subagent may use.
|
|
675
|
+
Pi session to edit the tools each subagent may use.
|
|
676
|
+
Choose **Performance and execution** → **Agent execution defaults** to edit provider-neutral inherited model patterns, thinking levels, and timeouts without changing tools. The standard bounded multi-select keeps a
|
|
509
677
|
one-save draft: toggles do not write until **Save changes**, Escape leaves the draft without writing,
|
|
510
678
|
and unavailable configured tool names remain visible and preserved. In TUI mode, type to fuzzy-search
|
|
511
679
|
tool names and availability metadata; Save and Discard remain pinned below the matches. These are user
|
|
@@ -538,6 +706,17 @@ description: Review API changes for compatibility and tests
|
|
|
538
706
|
tools: read, grep, find, ls, bash
|
|
539
707
|
model: sonnet
|
|
540
708
|
thinkingLevel: high
|
|
709
|
+
capabilityManifest:
|
|
710
|
+
version: pi-subagents:capabilities:v1
|
|
711
|
+
capabilities: [code-review, evidence-review]
|
|
712
|
+
modalities: [text]
|
|
713
|
+
resultFormats: [text, structured-v2]
|
|
714
|
+
authority:
|
|
715
|
+
filesystem: read
|
|
716
|
+
verificationRoles: [independent-review]
|
|
717
|
+
contextStrengths: [repository]
|
|
718
|
+
costHint: medium
|
|
719
|
+
latencyHint: medium
|
|
541
720
|
---
|
|
542
721
|
|
|
543
722
|
You are an API review subagent. Do not edit files. Check compatibility,
|
|
@@ -546,6 +725,10 @@ test coverage, and migration risks. Report PASS/FAIL/PARTIAL with evidence.
|
|
|
546
725
|
|
|
547
726
|
`tools` accepts either the comma-separated form above or a YAML string array such as `tools: [read, grep]`. An omitted field keeps the agent's default tools; blank, `null`, or `[]` explicitly selects no tools.
|
|
548
727
|
|
|
728
|
+
`capabilityManifest` is optional for legacy custom agents and never grants authority by itself.
|
|
729
|
+
Explicit workflow routing can match declared capabilities, configured tools, filesystem authority, verification roles, and low/medium/high cost or latency hints.
|
|
730
|
+
A missing or malformed manifest remains unknown and cannot satisfy a capability-routed task.
|
|
731
|
+
|
|
549
732
|
`agentScope` is a top-level tool argument supplied per invocation. It is not a setting in
|
|
550
733
|
`~/.pi/agent/pi-subagents.json` and does not belong in agent frontmatter. The parent-facing tool
|
|
551
734
|
metadata discovers these definitions after session start and labels their source and required scope.
|
|
@@ -588,12 +771,21 @@ argument skips that confirmation dialog, but it does not bypass the project trus
|
|
|
588
771
|
|
|
589
772
|
## ⏱️ Runtime limits and thinking levels
|
|
590
773
|
|
|
591
|
-
|
|
774
|
+
Every turn can combine main-agent-selected wall-clock, idle, assistant-turn, and tool-call budgets with an extension-owned hard-bounded finalization deadline.
|
|
592
775
|
|
|
593
|
-
- Set `
|
|
776
|
+
- Set `blocking.maxParallelTasks` in `~/.pi/agent/pi-subagents.json`, or use `/subagents` → **Advanced settings** → **Maximum parallel workers**, to allow 1 through 64 worker tasks in one blocking parallel call.
|
|
777
|
+
- The worker-count limit defaults to 8 and does not change the fixed four-at-a-time execution concurrency.
|
|
778
|
+
- Set `timeoutMs` on the top-level blocking call to apply a work deadline to all jobs.
|
|
594
779
|
- Set `timeoutMs` on a task, chain step, or aggregator to override it locally.
|
|
595
|
-
-
|
|
596
|
-
-
|
|
780
|
+
- Set top-level blocking `totalTimeoutMs` to cap model work across the whole call; each child receives at most the remaining budget, queued work is not started after expiry, fan-in receives only remaining time, and an orchestration-expired child skips model finalization. Bounded process-cleanup grace may follow the deadline.
|
|
781
|
+
- Set `idleTimeoutMs` to stop a turn that has produced no completed assistant turn or tool result within that interval.
|
|
782
|
+
- Set `maxTurns` or `maxToolCalls` to stop unfinished repeated work; a terminal answer at the exact turn limit remains successful.
|
|
783
|
+
- Set spawn budgets as retained defaults, or the same fields on `subagent_send` to override one follow-up turn.
|
|
784
|
+
- Top-level blocking turn budgets apply to every job, while a task, chain step, or aggregator can override them locally.
|
|
785
|
+
- Choose the shortest realistic budgets for the task difficulty; split an oversized task instead of extending limits merely to compensate for broad scope.
|
|
786
|
+
- Valid time values range from 1 to 2,147,483,647 milliseconds, matching the runtime timer limit.
|
|
787
|
+
- `maxTurns` and `maxToolCalls` accept integers from 1 through 1,000,000.
|
|
788
|
+
- If `timeoutMs` is omitted, the default is the retained or agent setting, then `PI_SUBAGENT_TIMEOUT_MS`, or `600000` milliseconds (10 minutes) when unset; the other new budgets remain opt-in.
|
|
597
789
|
|
|
598
790
|
Set `thinkingLevel` to request one of Pi's supported levels: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`. Blocking subprocess calls pass the resolved value through `--thinking <level>`.
|
|
599
791
|
|
|
@@ -610,11 +802,17 @@ For `subagent_spawn`, the root agent should choose the lowest sufficient level:
|
|
|
610
802
|
|
|
611
803
|
Blocking thinking precedence is: task/chain step/aggregator `thinkingLevel` → top-level `thinkingLevel` → agent default from config or frontmatter → Pi subprocess default.
|
|
612
804
|
|
|
613
|
-
Stateful spawn precedence is: `subagent_spawn.thinkingLevel` → agent default from
|
|
805
|
+
Stateful spawn precedence is: `subagent_spawn.thinkingLevel` → agent default from settings or frontmatter → model suffix → transport fallback.
|
|
806
|
+
Subprocess uses spawned Pi model/default resolution.
|
|
807
|
+
In-process delegates configured model parsing to loaded Pi core and then uses the parent thinking snapshot captured at child creation.
|
|
808
|
+
RPC passes the selected CLI model and thinking controls before its readiness handshake and reports the effective state returned by Pi.
|
|
809
|
+
An explicit spawn value is retained for the agent lifecycle and wins over every fallback.
|
|
614
810
|
|
|
615
811
|
Omit `thinkingLevel` to preserve existing behavior. Reported stateful details show the requested level, not a guarantee of the provider's effective value. Pi still owns model capability clamping; `pi-subagents` does not duplicate capability detection.
|
|
616
812
|
|
|
617
|
-
|
|
813
|
+
When any execution budget expires, the extension aborts the active run first and creates a versioned, bounded, redacted checkpoint containing partial assistant notes, completed tool evidence, changed-file hints, and whether side effects may already have occurred. After authoritative settlement it may make one concise summary attempt over that checkpoint without replaying the stopped task. The summary attempt has its own extension-owned model-work deadline of at most 45 seconds, followed only by bounded abort and process-cleanup grace. Fresh subprocess summaries run with no tools or project resources. Retained RPC and in-process summaries reuse their child context and are explicitly instructed not to call tools; the current child APIs do not support replacing an existing session's tool set for one turn, so their separate deadline and abort path remain the enforcement boundary. The deterministic checkpoint remains available when finalization or the provider fails, and results retain exit `124` plus a structured termination reason and finalization status. Explicit parent or user abort stops immediately, never starts finalization, and is not mislabeled as a budget stop.
|
|
814
|
+
|
|
815
|
+
This release does not claim a cooperative soft-wrap-up phase because print-mode subprocess children cannot receive steering while they are running. It also does not retry budget-stopped work automatically because file or external side effects may already have occurred.
|
|
618
816
|
|
|
619
817
|
The child event protocol limits each JSON line to 256 KiB. Captured output uses these defaults:
|
|
620
818
|
|
|
@@ -626,11 +824,26 @@ Truncated text includes a `truncated by pi-subagents` marker and details expose
|
|
|
626
824
|
|
|
627
825
|
## 📡 Runtime status
|
|
628
826
|
|
|
827
|
+
Run the offline transport benchmark from the repository root when comparing startup overhead:
|
|
828
|
+
|
|
829
|
+
```bash
|
|
830
|
+
just benchmark-subagents
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
It reports serial median and median absolute deviation for deterministic fake fresh-subprocess and retained-RPC turns plus isolated real Pi RPC readiness, retained commands, in-process session creation, and retained in-process state access without making a provider request.
|
|
834
|
+
Queue time starts when the registry accepts work, transport startup starts when execution begins, RPC readiness comes from `get_state`, RPC acceptance comes from the correlated `prompt` response, first activity comes from a bounded lifecycle event, settlement comes from `agent_settled`, and delivery is recorded after the parent accepts the completion message.
|
|
835
|
+
Subprocess and in-process timing fields use the nearest public lifecycle boundary and may be coarser than RPC.
|
|
836
|
+
Timing and progress are current-session diagnostics and are not persisted.
|
|
837
|
+
The benchmark measures transport overhead rather than model latency or output quality.
|
|
838
|
+
|
|
629
839
|
While the `subagent` tool is running, `pi-subagents` publishes compact activity status with `ctx.ui.setStatus("subagents", "...")`. Any statusline extension that reads Pi's generic extension status API can display it; no package-to-package dependency is required.
|
|
630
840
|
|
|
631
841
|
## 🔒 Safety notes
|
|
632
842
|
|
|
633
|
-
Subagents have separate processes and context windows, but they are **not security sandboxes**. They run as the same OS user, share the host filesystem and network access, and may conflict if they edit the same files. Tool allow-lists reduce available Pi tools but do not reduce operating-system permissions. `subagent_consult` prevents writes through its Pi tool surface and disables extensions, but it can read accessible paths, call the configured model over the network, and incur cost; its instruction-resource policy is not a filesystem or confidentiality boundary.
|
|
843
|
+
Subagents have separate processes and context windows, but they are **not security sandboxes**. They run as the same OS user, share the host filesystem and network access, and may conflict if they edit the same files. Tool allow-lists reduce available Pi tools but do not reduce operating-system permissions. `subagent_consult` prevents writes through its Pi tool surface and disables extensions, but it can read accessible paths, call the configured model over the network, and incur cost; its instruction-resource policy is not a filesystem or confidentiality boundary. Panel write-capable reviewers use separate disposable Git worktrees, but those worktrees provide repository-write isolation only.
|
|
844
|
+
|
|
845
|
+
Every contracted execution records a hashed immutable `ExecutionPlan` and an executor-owned capability grant bound to its task generation, effective tools, issuance time, and expiry.
|
|
846
|
+
Interrupt, close, shutdown, replacement, persistence, and restore revoke active grants before signalling work or accepting another generation, and late old-plan results become `stale` diagnostic evidence.
|
|
634
847
|
|
|
635
848
|
The runner explicitly reports policy continuity in result details:
|
|
636
849
|
|
|
@@ -640,12 +853,21 @@ The runner explicitly reports policy continuity in result details:
|
|
|
640
853
|
|
|
641
854
|
Treat project-local agent prompts like executable project configuration: only enable them in trusted repositories. Stateful project agents require Pi's project trust; interactive use also keeps confirmation enabled by default.
|
|
642
855
|
|
|
643
|
-
Stateful records are stored as versioned mode-0600 JSON under `~/.pi/agent/pi-subagents-state/` (or the configured Pi agent directory).
|
|
856
|
+
Stateful records are stored as versioned mode-0600 JSON under `~/.pi/agent/pi-subagents-state/` (or the configured Pi agent directory).
|
|
857
|
+
Explicit blocking-workflow snapshots use separate mode-0600 files under `~/.pi/agent/pi-subagents-workflows/`, retain at most 64 workflows per session for 30 days, and are available only through current-session workflow inspection.
|
|
858
|
+
Records contain sanitized logical history, never process IDs or credentials.
|
|
859
|
+
Corrupt or unsupported state is quarantined, completed and actionable terminal outcomes are preserved, in-flight records restore as `interrupted`, and no prior side effect is automatically resumed.
|
|
860
|
+
Retained follow-ups compare a privacy-safe hashed semantic snapshot before model work; incompatible resource changes require explicit `revalidate: true`, while unknown snapshot versions fail closed.
|
|
861
|
+
Snapshots hash agent manifests, prompts, effective tools, model/thinking, transport, trust, Git tracked and untracked state, and bounded user/project skill and prompt resources without persisting their contents.
|
|
862
|
+
A non-Git target has no stable repository generation proof, so each later follow-up requires explicit revalidation.
|
|
863
|
+
Count projection keeps complete ancestor chains together when stored or restored limits omit older trees.
|
|
864
|
+
Retention and count limits are configurable.
|
|
865
|
+
Downgrading is safe: older extension versions ignore this separate state directory; clear **Current agents** from `/subagents` before downgrade if the histories should be removed.
|
|
644
866
|
|
|
645
867
|
## 🗂️ Package layout
|
|
646
868
|
|
|
647
869
|
```txt
|
|
648
|
-
|
|
870
|
+
packages/pi-subagents/
|
|
649
871
|
├── src/
|
|
650
872
|
│ ├── index.ts # Pi package entrypoint
|
|
651
873
|
│ ├── subagents.ts # Extension registration and blocking tool schema
|
|
@@ -653,10 +875,44 @@ extensions/pi-subagents/
|
|
|
653
875
|
│ ├── consult.ts # Synchronous read-only consultation tool
|
|
654
876
|
│ ├── consult-policy.ts # Enforced read-only tool intersection
|
|
655
877
|
│ ├── cwd-policy.ts # Canonical target and saved-trust resolution
|
|
878
|
+
│ ├── prompt-resources.ts # Core-selected SYSTEM and APPEND_SYSTEM resources
|
|
656
879
|
│ ├── safe-text.ts # Shared byte/line/path sanitization
|
|
657
880
|
│ ├── stateful.ts # Detached lifecycle registration and dispatch
|
|
881
|
+
│ ├── rpc-transport.ts # Persistent strict-JSONL Pi RPC child transport
|
|
882
|
+
│ ├── rpc-timeout-finalization.ts # RPC abort-settle-summary recovery
|
|
883
|
+
│ ├── rpc-transport-metadata.ts # RPC result policy and bounded metadata helpers
|
|
884
|
+
│ ├── rpc-turn-capture.ts # RPC evidence capture, usage, and budget events
|
|
885
|
+
│ ├── auto-transport.ts # Deterministic preflight transport routing
|
|
886
|
+
│ ├── transport-types.ts # Bounded pi-subagents:v1 progress and telemetry contract
|
|
887
|
+
│ ├── completion-delivery.ts # Completion batching and optional idle-root wake
|
|
888
|
+
│ ├── admission-policy.ts # Audit-only deterministic delegation admission
|
|
889
|
+
│ ├── capability-grant.ts # Generation-bound authority lifetime and revocation
|
|
890
|
+
│ ├── execution-plan.ts # Executor-owned authority and resource resolution
|
|
891
|
+
│ ├── work-item-ledger.ts # Persistent dependency and artifact state machine
|
|
892
|
+
│ ├── work-item-persistence.ts # Atomic redacted workflow state and inspection
|
|
893
|
+
│ ├── integration-controller.ts # Fail-closed canonical integration admission
|
|
894
|
+
│ ├── adaptive-scheduler.ts # Dependency, capacity, budget, and conflict scheduling
|
|
895
|
+
│ ├── semantic-snapshot.ts # Privacy-safe continuation compatibility checks
|
|
896
|
+
│ ├── supervision.ts # Bounded idempotent retries and read-only hedging
|
|
897
|
+
│ ├── panel-execution.ts # Blocking review barrier, synthesis, and lifecycle owner
|
|
898
|
+
│ ├── panel-contract.ts # Strict review and synthesis evidence contracts
|
|
899
|
+
│ ├── panel-evidence.ts # Bounded monotonic reviewer evidence ledger
|
|
900
|
+
│ ├── panel-planning.ts # Panel validation, phase budgets, and WorkItems
|
|
901
|
+
│ ├── panel-prompts.ts # Shared-task reviewer and synthesis prompts
|
|
902
|
+
│ ├── panel-reconciliation.ts # Objection-preserving valid-review barrier
|
|
903
|
+
│ ├── panel-child-group.ts # Child signals and disposable-worktree cleanup
|
|
904
|
+
│ ├── panel-render.ts # Compact and expanded sanitized panel rows
|
|
905
|
+
│ ├── execution-profiles.ts # Provider-neutral thinking profile patches
|
|
906
|
+
│ ├── execution-ui.ts # Profile and per-agent execution settings screens
|
|
658
907
|
│ ├── stateful-guidance.ts # Detached model-facing workflow guidance
|
|
659
908
|
│ ├── stateful-lifecycle.ts # Runtime disposal and spawn ownership guards
|
|
909
|
+
│ ├── timeout-finalization.ts # Abort-time bounded summary prompts and deadlines
|
|
910
|
+
│ ├── timeout-checkpoint.ts # Redacted deterministic termination evidence
|
|
911
|
+
│ ├── turn-budget.ts # Idle, assistant-turn, and tool-call enforcement
|
|
912
|
+
│ ├── runner-usage.ts # Bounded subprocess usage accumulation
|
|
913
|
+
│ ├── runner-result.ts # Shared subprocess result interpretation
|
|
914
|
+
│ ├── stateful-limit-ui.ts # Detached capacity settings and recovery previews
|
|
915
|
+
│ ├── stateful-limits.ts # Shared detached defaults, labels, and validation
|
|
660
916
|
│ ├── stateful-safety.ts # Project-agent and shared-write safety checks
|
|
661
917
|
│ ├── stateful-tool-params.ts # Consolidated action schemas and validation
|
|
662
918
|
│ └── *.ts # Package-local discovery, execution, rendering, and settings modules
|
|
@@ -666,7 +922,11 @@ extensions/pi-subagents/
|
|
|
666
922
|
└── package.json
|
|
667
923
|
```
|
|
668
924
|
|
|
669
|
-
`index.ts` is the Pi entrypoint and forwards to `subagents.ts`; the other source modules are internal.
|
|
925
|
+
`index.ts` is the Pi entrypoint and forwards to `subagents.ts`; the other source modules are internal.
|
|
926
|
+
Workflow settings remain backward compatible: older files without `blocking.enabled` receive the seven-tool default, and an absent `blocking.maxParallelTasks` keeps the previous eight-worker limit.
|
|
927
|
+
Existing `stateful.enabled: false` files expose blocking delegation plus inspection/consultation.
|
|
928
|
+
Older package releases ignore and preserve the optional `blocking.maxParallelTasks`, `consult`, and `cwdPolicy` fields.
|
|
929
|
+
The package exposes its Pi extension through `package.json`:
|
|
670
930
|
|
|
671
931
|
```json
|
|
672
932
|
{
|
|
@@ -678,7 +938,7 @@ extensions/pi-subagents/
|
|
|
678
938
|
|
|
679
939
|
## 🔎 Keywords
|
|
680
940
|
|
|
681
|
-
Pi extension, Pi coding agent, subagents, agent delegation, parallel agents, fan-in aggregation, chained agents, isolated subprocesses, AI coding workflow, TypeScript Pi package.
|
|
941
|
+
Pi extension, Pi coding agent, subagents, agent delegation, parallel agents, review panels, evidence synthesis, fan-in aggregation, chained agents, isolated subprocesses, AI coding workflow, TypeScript Pi package.
|
|
682
942
|
|
|
683
943
|
## 📄 License
|
|
684
944
|
|