pi-subagents 0.24.4 → 0.27.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 +29 -0
- package/README.md +145 -27
- package/package.json +1 -1
- package/prompts/parallel-context-build.md +3 -1
- package/prompts/parallel-handoff-plan.md +3 -1
- package/prompts/review-loop.md +1 -1
- package/skills/pi-subagents/SKILL.md +71 -20
- package/src/agents/agent-management.ts +57 -15
- package/src/agents/agent-serializer.ts +3 -2
- package/src/agents/agents.ts +47 -16
- package/src/agents/chain-serializer.ts +120 -0
- package/src/extension/fanout-child.ts +171 -0
- package/src/extension/index.ts +7 -2
- package/src/extension/schemas.ts +138 -5
- package/src/intercom/result-intercom.ts +108 -0
- package/src/runs/background/async-execution.ts +185 -10
- package/src/runs/background/async-job-tracker.ts +41 -6
- package/src/runs/background/async-resume.ts +28 -15
- package/src/runs/background/async-status.ts +71 -31
- package/src/runs/background/result-watcher.ts +111 -54
- package/src/runs/background/run-id-resolver.ts +83 -0
- package/src/runs/background/run-status.ts +89 -4
- package/src/runs/background/stale-run-reconciler.ts +46 -1
- package/src/runs/background/subagent-runner.ts +648 -42
- package/src/runs/foreground/chain-execution.ts +331 -118
- package/src/runs/foreground/execution.ts +226 -10
- package/src/runs/foreground/subagent-executor.ts +377 -14
- package/src/runs/shared/acceptance-contract.ts +291 -0
- package/src/runs/shared/acceptance-evaluation.ts +221 -0
- package/src/runs/shared/acceptance-finalization.ts +161 -0
- package/src/runs/shared/acceptance-reports.ts +127 -0
- package/src/runs/shared/acceptance.ts +22 -0
- package/src/runs/shared/chain-outputs.ts +101 -0
- package/src/runs/shared/completion-guard.ts +26 -3
- package/src/runs/shared/dynamic-fanout.ts +293 -0
- package/src/runs/shared/nested-events.ts +819 -0
- package/src/runs/shared/nested-path.ts +52 -0
- package/src/runs/shared/nested-render.ts +115 -0
- package/src/runs/shared/parallel-utils.ts +31 -1
- package/src/runs/shared/pi-args.ts +73 -5
- package/src/runs/shared/structured-output.ts +77 -0
- package/src/runs/shared/subagent-prompt-runtime.ts +77 -7
- package/src/runs/shared/workflow-graph.ts +206 -0
- package/src/shared/formatters.ts +2 -2
- package/src/shared/settings.ts +53 -4
- package/src/shared/types.ts +345 -0
- package/src/slash/slash-commands.ts +41 -3
- package/src/tui/render.ts +268 -43
package/CHANGELOG.md
CHANGED
|
@@ -2,9 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.27.0] - 2026-05-30
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- Reworked public acceptance config to be object-only and evidence-driven, removing public `level`/disable shorthands. Explicit acceptance now triggers a same-session self-review/repair finalization loop, with `maxFinalizationTurns` controlling the cap.
|
|
9
|
+
- Documented goal-style acceptance guidance so `/goal`, “active goal”, and “work until evidence says done” requests map to run-scoped `acceptance` contracts.
|
|
10
|
+
- Refined acceptance finalization prompts and status output to emphasize evidence, blockers, stop rules, and finalization progress such as `completed after 1/3 turns`.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Treat explicit acceptance as the completion contract for acceptance-enabled runs, avoiding implementation completion-guard false positives when the visible output is only an `acceptance-report` or a finalization self-review turn does not need a repair edit.
|
|
14
|
+
|
|
15
|
+
## [0.26.0] - 2026-05-29
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- Added first-wave acceptance gates with optional public `acceptance` config, inferred effective policies, structured child reports, provenance ledgers, checked evidence gates, explicit runtime verification commands, async/status persistence, and saved `.chain.json` validation.
|
|
19
|
+
- Added chain step metadata (`phase`, `label`), named outputs (`as` with `{outputs.name}`), workflow graph snapshots, and strict `outputSchema` structured-output contracts across foreground and async chain execution.
|
|
20
|
+
- Added dynamic chain fanout with `expand`/single-template `parallel`/`collect`, structured named-output sources, bounded item expansion, collected result outputs, async status graph persistence, and saved `.chain.json` support.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- Fixed dynamic fanout acceptance blockers around real `structured_output` tool validation, malformed dynamic-like chain rejection, async dynamic failure status/details, dynamic child intercom target indexing, and saved `.chain.json` management diagnostics.
|
|
24
|
+
- Fixed acceptance-gate semantics so reviewed status requires an independent reviewer result, required criteria must be reported as satisfied, only fenced `acceptance-report` blocks satisfy attestation, malformed reports preserve parse errors, `{ level: "none", reason }` disables inferred gates, and zero-child dynamic aggregates no longer fabricate evidence.
|
|
25
|
+
|
|
26
|
+
## [0.25.0] - 2026-05-21
|
|
27
|
+
|
|
5
28
|
### Added
|
|
29
|
+
- Allow child agents whose resolved builtin tools explicitly include `subagent` to run child-safe nested fanout, with parent-visible nested status trees and nested `status`/`interrupt`/`resume` by id.
|
|
6
30
|
|
|
7
31
|
### Fixed
|
|
32
|
+
- Preserve compact nested child summaries in grouped result/intercom payloads and async completion metadata before ordinary result files are processed and deleted.
|
|
33
|
+
- Keep async result files retryable when nested registry enrichment temporarily fails, instead of marking them seen before a successful delivery pass.
|
|
34
|
+
- Require an explicit id for child-safe nested `status` when no local foreground run is active, preventing fanout children from listing unrelated top-level async runs.
|
|
35
|
+
- Keep fanout child control inbox polling alive across transient filesystem errors, and retain control requests for retry when control-result writes fail.
|
|
36
|
+
- Share nested path/env sanitization between child launch arguments and nested event projection.
|
|
8
37
|
|
|
9
38
|
## [0.24.4] - 2026-05-20
|
|
10
39
|
|
package/README.md
CHANGED
|
@@ -149,7 +149,7 @@ Foreground runs stream progress in the conversation while they run.
|
|
|
149
149
|
|
|
150
150
|
Background runs keep working after control returns to you. Inspect active runs with `subagent({ action: "status" })`, or a specific run with `subagent({ action: "status", id: "..." })`.
|
|
151
151
|
|
|
152
|
-
They also show a compact async widget and send completion notifications. Parallel background runs show per-agent progress instead of fake chain steps. Chains with parallel groups keep their grouped shape in progress and results, so failed or paused agents stay visible next to completed ones.
|
|
152
|
+
They also show a compact async widget and send completion notifications. Parallel background runs show per-agent progress instead of fake chain steps. Chains with parallel groups keep their grouped shape in progress and results, so failed or paused agents stay visible next to completed ones. When a child is explicitly allowed to fan out with `tools: subagent`, its nested runs appear under that parent child in the main status tree instead of being hidden inside the child process.
|
|
153
153
|
|
|
154
154
|
You can also ask naturally:
|
|
155
155
|
|
|
@@ -181,7 +181,7 @@ Use the optional prompt shortcuts below when you want the pattern to be repeatab
|
|
|
181
181
|
|
|
182
182
|
Packaged `planner`, `worker`, and `oracle` default to forked context when a launch omits `context`; pass `context: "fresh"` when you intentionally want a fresh child run.
|
|
183
183
|
|
|
184
|
-
Child-safety boundaries are enforced at runtime. Spawned child sessions do not
|
|
184
|
+
Child-safety boundaries are enforced at runtime. Spawned child sessions do not receive the bundled `pi-subagents` skill, and forked child context filtering removes parent-only subagent artifacts (including old hidden orchestration-instruction messages, slash/status/control messages, and prior parent `subagent` tool-call/tool-result history) while preserving ordinary prose and unrelated tool calls/results. By default, children do not register the `subagent` tool and receive boundary instructions that they are not the parent orchestrator and must not propose or run subagents. The explicit exception is an agent whose resolved builtin `tools` includes `subagent`; that child gets a child-safe `subagent` tool for the fanout work the parent assigned, still bounded by `maxSubagentDepth`.
|
|
185
185
|
|
|
186
186
|
## Optional shortcuts
|
|
187
187
|
|
|
@@ -223,7 +223,7 @@ The child can use one dedicated coordination tool:
|
|
|
223
223
|
|
|
224
224
|
- `contact_supervisor`: the child contacts the parent/supervisor session that delegated the task. Use `reason: "need_decision"` for blocking decisions or clarification, and `reason: "progress_update"` for short non-blocking updates when a discovery changes the plan. Do not ask for clarification when the only conflict is review-only/no-edit versus progress-writing or artifact-writing instructions; no-edit wins.
|
|
225
225
|
|
|
226
|
-
Child-side routine completion handoffs are still not expected. With the intercom bridge active, parent-side `pi-subagents` sends grouped completion results through `pi-intercom`: one grouped message per foreground parent `subagent` run and one per completed async result file. Acknowledged foreground delivery returns a compact receipt with artifact/session paths; if unacknowledged, the normal full output is preserved. Grouped messages include child intercom targets and
|
|
226
|
+
Child-side routine completion handoffs are still not expected. With the intercom bridge active, parent-side `pi-subagents` sends grouped completion results through `pi-intercom`: one grouped message per foreground parent `subagent` run and one per completed async result file. Acknowledged foreground delivery returns a compact receipt with artifact/session paths; if unacknowledged, the normal full output is preserved. Grouped messages include child intercom targets, full child summaries, and compact nested child summaries under the parent child that launched them.
|
|
227
227
|
|
|
228
228
|
If a child appears stalled, needs-attention notices can show up in the parent session with useful next actions, such as checking `subagent({ action: "status" })`, interrupting the run, or nudging the child.
|
|
229
229
|
|
|
@@ -246,7 +246,7 @@ Skip this section until you want exact syntax.
|
|
|
246
246
|
| `/run <agent> [task]` | Run one agent; omit the task for self-contained agents |
|
|
247
247
|
| `/chain agent1 "task1" -> agent2 "task2"` | Run agents in sequence |
|
|
248
248
|
| `/parallel agent1 "task1" -> agent2 "task2"` | Run agents in parallel |
|
|
249
|
-
| `/run-chain <chainName> -- <task>` | Launch a saved `.chain.md` workflow |
|
|
249
|
+
| `/run-chain <chainName> -- <task>` | Launch a saved `.chain.md` or `.chain.json` workflow |
|
|
250
250
|
| `/subagents-doctor` | Show read-only setup diagnostics |
|
|
251
251
|
|
|
252
252
|
Commands validate agent names locally, support tab completion, and send results back into the conversation.
|
|
@@ -472,8 +472,9 @@ Examples:
|
|
|
472
472
|
- `tools` omitted and `extensions` omitted: normal builtins and normal extensions.
|
|
473
473
|
- `tools: mcp:chrome-devtools`: normal builtins plus direct Chrome DevTools MCP tools.
|
|
474
474
|
- `tools: read, bash, mcp:chrome-devtools`: only `read` and `bash` as builtins, plus direct Chrome DevTools MCP tools.
|
|
475
|
+
- `tools: subagent, read`: a child-safe `subagent` tool is available inside that child so it can run explicitly assigned nested fanout.
|
|
475
476
|
|
|
476
|
-
Direct MCP tools require [pi-mcp-adapter](https://github.com/nicobailon/pi-mcp-adapter). Subagents only receive direct MCP tools when `mcp:` entries are listed in their frontmatter; global `directTools: true` in `mcp.json` is not enough by itself. The generic `mcp` proxy tool can still be used for discovery when available. The adapter caches tool metadata at startup, so after connecting a new MCP server for the first time, restart Pi before relying on direct tools.
|
|
477
|
+
Direct MCP tools require [pi-mcp-adapter](https://github.com/nicobailon/pi-mcp-adapter). Subagents only receive direct MCP tools when `mcp:` entries are listed in their frontmatter; global `directTools: true` in `mcp.json` is not enough by itself. The generic `mcp` proxy tool can still be used for discovery when available. The adapter caches tool metadata at startup, so after connecting a new MCP server for the first time, restart Pi before relying on direct tools. An `mcp:` entry named `subagent` does not authorize nested fanout; only the builtin `subagent` tool name does.
|
|
477
478
|
|
|
478
479
|
`extensions` controls child extension loading:
|
|
479
480
|
|
|
@@ -491,14 +492,14 @@ When `extensions` is present, it takes precedence over extension paths implied b
|
|
|
491
492
|
|
|
492
493
|
## Chain files
|
|
493
494
|
|
|
494
|
-
Chains are reusable
|
|
495
|
+
Chains are reusable workflows stored separately from agent files. Use `.chain.md` for simple sequential saved chains. Use `.chain.json` when a chain needs dynamic fanout.
|
|
495
496
|
|
|
496
497
|
| Scope | Path |
|
|
497
498
|
|-------|------|
|
|
498
|
-
| User | `~/.pi/agent/chains/**/*.chain.md` |
|
|
499
|
-
| Project | `.pi/chains/**/*.chain.md` |
|
|
499
|
+
| User | `~/.pi/agent/chains/**/*.chain.md`, `~/.pi/agent/chains/**/*.chain.json` |
|
|
500
|
+
| Project | `.pi/chains/**/*.chain.md`, `.pi/chains/**/*.chain.json` |
|
|
500
501
|
|
|
501
|
-
Nested subdirectories are discovered recursively. If user and project scopes define the same parsed runtime chain name, the project chain wins. Chains support the same optional `package` frontmatter as agents; `name: review-flow` plus `package: code-analysis` runs as `code-analysis.review-flow`.
|
|
502
|
+
Nested subdirectories are discovered recursively. If both `.chain.md` and `.chain.json` define the same parsed runtime chain name in the same scope, `.chain.json` wins. If user and project scopes define the same parsed runtime chain name, the project chain wins. Chains support the same optional `package` frontmatter as agents; `name: review-flow` plus `package: code-analysis` runs as `code-analysis.review-flow`.
|
|
502
503
|
|
|
503
504
|
Example:
|
|
504
505
|
|
|
@@ -509,23 +510,67 @@ description: Gather context then plan implementation
|
|
|
509
510
|
---
|
|
510
511
|
|
|
511
512
|
## scout
|
|
513
|
+
phase: Context
|
|
514
|
+
label: Map auth flow
|
|
515
|
+
as: context
|
|
512
516
|
output: context.md
|
|
513
517
|
|
|
514
518
|
Analyze the codebase for {task}
|
|
515
519
|
|
|
516
520
|
## planner
|
|
521
|
+
phase: Planning
|
|
522
|
+
label: Implementation plan
|
|
517
523
|
reads: context.md
|
|
518
524
|
model: anthropic/claude-sonnet-4-5:high
|
|
519
525
|
progress: true
|
|
520
526
|
|
|
521
|
-
Create an implementation plan based on {
|
|
527
|
+
Create an implementation plan based on {outputs.context}
|
|
522
528
|
```
|
|
523
529
|
|
|
524
|
-
Each `## agent-name` section is a step. Config lines such as `output`, `outputMode`, `reads`, `model`, `skills`, and `progress` go immediately after the header. A blank line separates config from task text.
|
|
530
|
+
Each `.chain.md` `## agent-name` section is a step. Config lines such as `phase`, `label`, `as`, `outputSchema`, `output`, `outputMode`, `reads`, `model`, `skills`, and `progress` go immediately after the header. A blank line separates config from task text. In saved `.chain.md` files, `outputSchema` is a path to a JSON Schema file; direct tool calls and `.chain.json` files can pass the schema object inline.
|
|
525
531
|
|
|
526
532
|
For `output`, `reads`, `skills`, and `progress`, chain behavior is three-state: omitted inherits from the agent, a value overrides, and `false` disables.
|
|
527
533
|
|
|
528
|
-
|
|
534
|
+
Use `phase` to group related work in status output, `label` for a readable step name, and `as` to store a successful step or parallel task result for later `{outputs.name}` references. Duplicate `as` names, invalid identifiers, and unknown output references fail before child execution.
|
|
535
|
+
|
|
536
|
+
Dynamic fanout is available only through direct `subagent({ chain: [...] })` JSON or saved `.chain.json` files. It expands an array from a prior structured named output, runs one child template per item, and stores the ordered collection under `collect.as`. The source must be structured output; prose is never parsed. `expand.maxItems` is required, over-limit arrays fail, nested fanout and arbitrary expressions are not supported, and `.chain.md` has no dynamic syntax in this release.
|
|
537
|
+
|
|
538
|
+
```json
|
|
539
|
+
{
|
|
540
|
+
"name": "dynamic-review",
|
|
541
|
+
"description": "Find review targets, fan out reviewers, then synthesize.",
|
|
542
|
+
"chain": [
|
|
543
|
+
{
|
|
544
|
+
"agent": "scout",
|
|
545
|
+
"task": "Return {\"items\":[{\"path\":\"...\",\"reason\":\"...\"}]} via structured_output.",
|
|
546
|
+
"as": "targets",
|
|
547
|
+
"outputSchema": { "type": "object" }
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
"expand": {
|
|
551
|
+
"from": { "output": "targets", "path": "/items" },
|
|
552
|
+
"item": "target",
|
|
553
|
+
"key": "/path",
|
|
554
|
+
"maxItems": 12
|
|
555
|
+
},
|
|
556
|
+
"parallel": {
|
|
557
|
+
"agent": "reviewer",
|
|
558
|
+
"label": "Review {target.path}",
|
|
559
|
+
"task": "Review {target.path}. Reason: {target.reason}",
|
|
560
|
+
"outputSchema": { "type": "object" }
|
|
561
|
+
},
|
|
562
|
+
"collect": { "as": "reviews" },
|
|
563
|
+
"concurrency": 4
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
"agent": "worker",
|
|
567
|
+
"task": "Synthesize fixes from {outputs.reviews}"
|
|
568
|
+
}
|
|
569
|
+
]
|
|
570
|
+
}
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
Create simple `.chain.md` chains by writing files directly or with the `subagent({ action: "create", config: ... })` management action. Create dynamic `.chain.json` chains by writing the JSON file directly. Run saved chains with natural language or:
|
|
529
574
|
|
|
530
575
|
```text
|
|
531
576
|
/run-chain scout-planner -- refactor authentication
|
|
@@ -540,6 +585,7 @@ Task templates support:
|
|
|
540
585
|
| `{task}` | Original task from the first step. |
|
|
541
586
|
| `{previous}` | Output from the prior step, or aggregated output from a parallel step. |
|
|
542
587
|
| `{chain_dir}` | Path to the chain artifact directory. |
|
|
588
|
+
| `{outputs.name}` | Text value from a prior step or completed parallel task with `as: "name"`. |
|
|
543
589
|
|
|
544
590
|
Parallel outputs are aggregated with clear separators before being passed to the next step:
|
|
545
591
|
|
|
@@ -593,7 +639,7 @@ What the bundled skill covers:
|
|
|
593
639
|
- **Delegation patterns**: when to launch which agent, whether to use single, parallel, chain, or async mode, and whether to use fresh or forked context
|
|
594
640
|
- **Prompt workflow recipes**: how to apply the packaged techniques directly with `subagent(...)` when the user describes the workflow in natural language instead of invoking a slash command. This includes parallel review, review-loop, parallel research, parallel context-build, parallel handoff-plan, gather-context-and-clarify, and parallel cleanup
|
|
595
641
|
- **Role-agent prompting guidance**: compact contract prompts instead of long scripts, what to include in role-specific meta prompts, and retrieval budgets for researchers
|
|
596
|
-
- **Safety boundaries**: child agents must not run subagents
|
|
642
|
+
- **Safety boundaries**: child agents must not run subagents unless their resolved builtin tools explicitly include `subagent`, must not invent intercom targets, and must escalate unapproved decisions
|
|
597
643
|
- **Intercom conventions**: when to ask vs send, and how parent-side result delivery works with `pi-intercom`
|
|
598
644
|
- **Control and diagnostics**: attention signals, soft interrupts, status, and the `doctor` action
|
|
599
645
|
|
|
@@ -633,14 +679,49 @@ These are the parameters the LLM passes when it calls the `subagent` tool. Most
|
|
|
633
679
|
|
|
634
680
|
// Chain with fan-out/fan-in
|
|
635
681
|
{ chain: [
|
|
636
|
-
{ agent: "scout", task: "Gather context" },
|
|
682
|
+
{ agent: "scout", task: "Gather context", phase: "Context", label: "Map code", as: "context" },
|
|
637
683
|
{ parallel: [
|
|
638
|
-
{ agent: "worker", task: "Implement feature A from {
|
|
639
|
-
{ agent: "worker", task: "Implement feature B from {
|
|
684
|
+
{ agent: "worker", task: "Implement feature A from {outputs.context}", label: "Feature A", as: "featureA" },
|
|
685
|
+
{ agent: "worker", task: "Implement feature B from {outputs.context}", label: "Feature B", as: "featureB" }
|
|
640
686
|
], concurrency: 2, failFast: true },
|
|
641
|
-
{ agent: "reviewer", task: "Review
|
|
687
|
+
{ agent: "reviewer", task: "Review {outputs.featureA} and {outputs.featureB}" }
|
|
642
688
|
]}
|
|
643
689
|
|
|
690
|
+
// Dynamic fanout from structured output
|
|
691
|
+
{ chain: [
|
|
692
|
+
{
|
|
693
|
+
agent: "scout",
|
|
694
|
+
task: "Return review targets as structured_output: { items: [{ path, reason }] }",
|
|
695
|
+
as: "targets",
|
|
696
|
+
outputSchema: { type: "object" }
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
expand: { from: { output: "targets", path: "/items" }, item: "target", key: "/path", maxItems: 12 },
|
|
700
|
+
parallel: { agent: "reviewer", task: "Review {target.path}. Reason: {target.reason}", outputSchema: { type: "object" } },
|
|
701
|
+
collect: { as: "reviews" },
|
|
702
|
+
concurrency: 4
|
|
703
|
+
},
|
|
704
|
+
{ agent: "worker", task: "Synthesize fixes from {outputs.reviews}" }
|
|
705
|
+
] }
|
|
706
|
+
|
|
707
|
+
// Strict structured output for reliable handoff data
|
|
708
|
+
{ chain: [
|
|
709
|
+
{
|
|
710
|
+
agent: "scout",
|
|
711
|
+
task: "Return the key files and risks for {task}",
|
|
712
|
+
as: "scan",
|
|
713
|
+
outputSchema: {
|
|
714
|
+
type: "object",
|
|
715
|
+
required: ["files", "risks"],
|
|
716
|
+
properties: {
|
|
717
|
+
files: { type: "array", items: { type: "string" } },
|
|
718
|
+
risks: { type: "array", items: { type: "string" } }
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
},
|
|
722
|
+
{ agent: "planner", task: "Plan from this scan: {outputs.scan}" }
|
|
723
|
+
] }
|
|
724
|
+
|
|
644
725
|
// Worktree isolation
|
|
645
726
|
{ tasks: [
|
|
646
727
|
{ agent: "worker", task: "Implement auth" },
|
|
@@ -710,10 +791,10 @@ Agent definitions are not loaded into context by default. Management actions let
|
|
|
710
791
|
| `outputMode` | `"inline" \| "file-only"` | `inline` | Return saved output inline or as a concise saved-file reference. `file-only` requires an `output` path. |
|
|
711
792
|
| `skill` | `string \| string[] \| false` | agent default | Override skills or disable all. |
|
|
712
793
|
| `model` | string | agent default | Override model. |
|
|
713
|
-
| `tasks` | array | - | Top-level parallel tasks. Supports `agent`, `task`, `cwd`, `count`, `output`, `outputMode`, `reads`, `progress`, `skill`, and `
|
|
794
|
+
| `tasks` | array | - | Top-level parallel tasks. Supports `agent`, `task`, `cwd`, `count`, `output`, `outputMode`, `reads`, `progress`, `skill`, `model`, and `acceptance`. |
|
|
714
795
|
| `concurrency` | number | config or `4` | Top-level parallel concurrency. |
|
|
715
796
|
| `worktree` | boolean | false | Create isolated git worktrees for parallel tasks. |
|
|
716
|
-
| `chain` | array | - | Sequential
|
|
797
|
+
| `chain` | array | - | Sequential, static parallel, and dynamic fanout chain steps. Sequential steps and parallel child tasks support `phase`, `label`, `as`, `outputSchema`, and `acceptance` in addition to the usual execution fields. Dynamic fanout uses `expand`, one child `parallel` template, and `collect`; group-level acceptance is not supported because there is no child session to finalize. |
|
|
717
798
|
| `context` | `fresh \| fork` | agent default or `fresh` | `fork` creates real branched sessions from the parent leaf. Packaged `planner`, `worker`, and `oracle` default to `fork`. |
|
|
718
799
|
| `chainDir` | string | temp chain dir | Persistent directory for chain artifacts. |
|
|
719
800
|
| `clarify` | boolean | true for chains | Show TUI preview/edit flow. |
|
|
@@ -725,25 +806,31 @@ Agent definitions are not loaded into context by default. Management actions let
|
|
|
725
806
|
| `includeProgress` | boolean | false | Include full progress in result. |
|
|
726
807
|
| `share` | boolean | false | Upload session export to GitHub Gist. |
|
|
727
808
|
| `sessionDir` | string | derived | Override session log directory. |
|
|
809
|
+
| `acceptance` | object | omitted | Explicit acceptance contract. When present, the child gets a structured contract, then the runtime continues the same session for a bounded self-review/repair loop before evaluating acceptance. |
|
|
728
810
|
|
|
729
811
|
`context: "fork"` fails fast when the parent session is not persisted, the current leaf is missing, or the branched child session cannot be created. It never silently downgrades to `fresh`. In multi-agent runs, if any requested agent has `defaultContext: fork` and the launch omits `context`, the whole invocation uses forked context; pass `context: "fresh"` when you intentionally want a fresh run.
|
|
730
812
|
|
|
731
813
|
Use `outputMode: "file-only"` when a saved output may be large and the parent only needs a pointer. The returned text is a compact reference like `Output saved to: /abs/report.md (48.2 KB, 2847 lines). Read this file if needed.` Failed runs and save errors still return normal inline output for debugging. In chains, later `{previous}` steps receive the same compact reference when the prior step used file-only mode.
|
|
732
814
|
|
|
733
|
-
Sequential and parallel chain tasks accept `agent`, `task`, `cwd`, `output`, `outputMode`, `reads`, `progress`, `skill`, and `model`. Parallel tasks also accept `count`. Parallel step groups accept `parallel`, `concurrency`, `failFast`, and `worktree`.
|
|
815
|
+
Sequential and parallel chain tasks accept `agent`, `task`, `phase`, `label`, `as`, `outputSchema`, `cwd`, `output`, `outputMode`, `reads`, `progress`, `skill`, and `model`. Parallel tasks also accept `count`. Parallel step groups accept `parallel`, `concurrency`, `failFast`, and `worktree`. If `outputSchema` is present, the child must call `structured_output` with schema-valid JSON; prose-only completion or invalid JSON fails the step. Validated structured values are preserved on the step result, and `as` also exposes a compact text representation through `{outputs.name}`.
|
|
734
816
|
|
|
735
817
|
Status and control actions:
|
|
736
818
|
|
|
737
819
|
```ts
|
|
738
820
|
subagent({ action: "status" })
|
|
739
821
|
subagent({ action: "status", id: "<run-id>" })
|
|
822
|
+
subagent({ action: "status", id: "<nested-run-id>" })
|
|
740
823
|
subagent({ action: "interrupt", id: "<run-id>" })
|
|
824
|
+
subagent({ action: "interrupt", id: "<nested-run-id>" })
|
|
741
825
|
subagent({ action: "resume", id: "<run-id>", message: "follow-up question" })
|
|
742
826
|
subagent({ action: "resume", id: "<run-id>", index: 1, message: "follow-up for child 2" })
|
|
827
|
+
subagent({ action: "resume", id: "<nested-run-id>", message: "follow-up for a nested child" })
|
|
743
828
|
subagent({ action: "doctor" })
|
|
744
829
|
```
|
|
745
830
|
|
|
746
|
-
`
|
|
831
|
+
`status` resolves exact foreground ids, top-level async ids, and nested run ids before falling back to prefix matching. Nested status shows the root/parent path, nested children, session/artifact paths when known, and nested control commands. Inside child-safe fanout mode, bare `status` requires an id when no local foreground run is active, so children cannot enumerate unrelated top-level async runs. Bare `interrupt` still targets only the visible top-level run; interrupting a nested run requires its explicit nested id.
|
|
832
|
+
|
|
833
|
+
`resume` sends the follow-up directly when an async child is still reachable over intercom. After completion, it revives the child by starting a new async child from the stored child session file. Multi-child async runs and remembered foreground single, parallel, or chain runs can be revived by passing `index` to choose the child. Nested runs can be resumed by nested id when their live route or persisted session metadata is available. Revive starts a new child process from the old session context; it does not restart the same OS process, and it requires the chosen child to have a persisted `.jsonl` session file.
|
|
747
834
|
|
|
748
835
|
## Worktree isolation
|
|
749
836
|
|
|
@@ -822,7 +909,7 @@ Session directory precedence is: `params.sessionDir`, then `config.defaultSessio
|
|
|
822
909
|
{ "maxSubagentDepth": 1 }
|
|
823
910
|
```
|
|
824
911
|
|
|
825
|
-
Controls nested delegation when no inherited `PI_SUBAGENT_MAX_DEPTH` is already in effect. Per-agent `maxSubagentDepth` can tighten the limit for that agent’s child runs, but cannot relax an inherited stricter limit.
|
|
912
|
+
Controls nested delegation when no inherited `PI_SUBAGENT_MAX_DEPTH` is already in effect. Per-agent `maxSubagentDepth` can tighten the limit for that agent’s child runs, but cannot relax an inherited stricter limit. This applies even to children that explicitly declare `tools: subagent`; at the cap, execution fanout is blocked instead of silently hiding nested work.
|
|
826
913
|
|
|
827
914
|
### `intercomBridge`
|
|
828
915
|
|
|
@@ -898,15 +985,46 @@ Async runs write:
|
|
|
898
985
|
subagent-log-<id>.md
|
|
899
986
|
```
|
|
900
987
|
|
|
901
|
-
`status.json` powers the widget and `subagent({ action: "status" })` output. `events.jsonl` contains wrapper events plus child Pi JSON events annotated with run and step metadata. `output-<n>.log` is a live human-readable tail. Fallback information is persisted so background runs are debuggable after completion.
|
|
988
|
+
`status.json` powers the widget and `subagent({ action: "status" })` output. `events.jsonl` contains wrapper events plus child Pi JSON events annotated with run and step metadata. Nested fanout status is stored as compact sidecar event/registry metadata and merged into parent status views and result/intercom payloads; full recursive status snapshots are not embedded in parent result files. `output-<n>.log` is a live human-readable tail. Fallback information is persisted so background runs are debuggable after completion.
|
|
989
|
+
|
|
990
|
+
## Acceptance Gates
|
|
991
|
+
|
|
992
|
+
`acceptance` is an explicit contract. Omit it for lightweight runs. Set it on single runs, top-level parallel task items, sequential chain steps, static parallel task items, and dynamic fanout child templates when the child must prove the work meets concrete criteria. Do not set it on static parallel groups or dynamic fanout aggregate groups; those groups do not own a same-session child turn.
|
|
993
|
+
|
|
994
|
+
If you are coming from Codex Goals, `acceptance` is the subagent equivalent for one delegated run. When a user says `/goal`, “goal”, “active goal”, “continue until evidence says done”, or “verify against a goal”, translate that into an acceptance contract: `criteria` are the target, `evidence` and `verify` are proof, `stopRules` are constraints, and `maxFinalizationTurns` is the bounded loop budget.
|
|
995
|
+
|
|
996
|
+
```ts
|
|
997
|
+
{
|
|
998
|
+
agent: "worker",
|
|
999
|
+
task: "Implement the fix",
|
|
1000
|
+
acceptance: {
|
|
1001
|
+
criteria: ["Patch the bug without widening scope"],
|
|
1002
|
+
evidence: ["changed-files", "tests-added", "commands-run", "residual-risks", "no-staged-files"],
|
|
1003
|
+
verify: [{ id: "focused", command: "npm test", timeoutMs: 120000 }],
|
|
1004
|
+
maxFinalizationTurns: 3
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
```
|
|
1008
|
+
|
|
1009
|
+
When `acceptance` is present, the initial child prompt includes a standardized acceptance section and asks for a fenced `acceptance-report` JSON block. After the child’s initial completion, the runtime continues the same persisted child session with an acceptance finalization prompt. The child can repair omissions in that same session, then must return the final `acceptance-report`. Missing or malformed finalization reports reject the run when the loop limit is reached.
|
|
1010
|
+
|
|
1011
|
+
Public acceptance config is evidence-driven. There is no public `level` field and no `acceptance: "checked"` shorthand. Runtime provenance is derived from what actually happened:
|
|
1012
|
+
|
|
1013
|
+
- `attested`: the child returned a structured acceptance report.
|
|
1014
|
+
- `checked`: runtime structural checks passed, such as required criteria, required evidence, and no staged files.
|
|
1015
|
+
- `verified`: configured runtime verification commands passed. Child-reported command success does not count.
|
|
1016
|
+
- `reviewed`: an independent reviewer result is present.
|
|
1017
|
+
- `rejected`: attestation, structural checks, verification, review, or finalization failed.
|
|
1018
|
+
|
|
1019
|
+
Self-review finalization never counts as `reviewed`, and it never counts as `verified` unless configured runtime verification commands actually pass. The visible child output remains the initial answer; finalization reports and residual risks are stored in the acceptance ledger and async/status details.
|
|
902
1020
|
|
|
903
1021
|
## Live progress
|
|
904
1022
|
|
|
905
|
-
Foreground runs show compact live progress for single, chain, and parallel modes: current tool, recent output, token counts, duration, activity freshness,
|
|
1023
|
+
Foreground runs show compact live progress for single, chain, and parallel modes: current tool, recent output, token counts, duration, activity freshness, current-tool duration, and chain graph metadata when available.
|
|
906
1024
|
|
|
907
1025
|
Press `Ctrl+O` to expand the full streaming view with complete output per step.
|
|
908
1026
|
|
|
909
|
-
Sequential chains show a flow line like `done scout → running planner`. Chains with parallel steps show per-step cards instead.
|
|
1027
|
+
Sequential chains show a flow line like `done scout → running planner`. Chains with parallel steps show per-step cards instead. Chain status uses `label` and `phase` metadata when present, while falling back to agent names for older chains.
|
|
910
1028
|
|
|
911
1029
|
## Session sharing
|
|
912
1030
|
|
|
@@ -920,9 +1038,9 @@ This is disabled by default. Session data may contain source code, paths, enviro
|
|
|
920
1038
|
|
|
921
1039
|
## Recursion guard
|
|
922
1040
|
|
|
923
|
-
Subagents can call `subagent
|
|
1041
|
+
Subagents can call `subagent` only when their resolved builtin tools explicitly include `subagent`. That is meant for delegated fanout agents, not ordinary worker/reviewer children. A depth guard prevents unbounded nesting.
|
|
924
1042
|
|
|
925
|
-
By default, nesting is limited to two levels: main session → subagent → sub-subagent. Deeper calls are blocked with guidance to complete the current task directly.
|
|
1043
|
+
By default, nesting is limited to two levels: main session → subagent → sub-subagent. Deeper calls are blocked with guidance to complete the current task directly. Nested runs appear in the parent status widget and `status` output as a tree, and `status`, `interrupt`, and `resume` can target a nested run by its id.
|
|
926
1044
|
|
|
927
1045
|
Configure the limit with:
|
|
928
1046
|
|
package/package.json
CHANGED
|
@@ -4,12 +4,14 @@ description: Parallel context builders for planning handoff
|
|
|
4
4
|
|
|
5
5
|
Launch fresh-context `context-builder` subagents in parallel to build grounded handoff context for planning or implementation.
|
|
6
6
|
|
|
7
|
-
Use the `subagent` tool in chain mode with a single parallel step, not top-level parallel tasks, so relative output files live under the temporary chain directory. Use `context: "fresh"` unless I explicitly ask for forked context. Give every parallel task a distinct `output` path, for example:
|
|
7
|
+
Use the `subagent` tool in chain mode with a single parallel step, not top-level parallel tasks, so relative output files live under the temporary chain directory. Use `context: "fresh"` unless I explicitly ask for forked context. Give every parallel task a distinct `output` path, `label`, and `as` name, for example:
|
|
8
8
|
|
|
9
9
|
- `context-build/request-and-scope.md`
|
|
10
10
|
- `context-build/codebase-and-patterns.md`
|
|
11
11
|
- `context-build/validation-and-risks.md`
|
|
12
12
|
|
|
13
|
+
Use one phase such as `phase: "Context build"` for the parallel tasks so async status is readable. A later synthesis step can reference specific outputs with `{outputs.requestScope}`, `{outputs.codebasePatterns}`, and `{outputs.validationRisks}` instead of relying only on `{previous}`.
|
|
14
|
+
|
|
13
15
|
Do not write these context artifacts into the repository unless I explicitly ask for persistent files.
|
|
14
16
|
|
|
15
17
|
Treat the slash command arguments as the primary request, target, or focus:
|
|
@@ -19,12 +19,14 @@ Use the `subagent` tool in chain mode:
|
|
|
19
19
|
|
|
20
20
|
2. Second step: a synthesis `context-builder` that reads the parallel findings and writes the final handoff plan and meta-prompt.
|
|
21
21
|
|
|
22
|
-
Use distinct output paths under the chain directory. Example outputs:
|
|
22
|
+
Use distinct output paths, `label` values, and `as` names under the chain directory. Example outputs:
|
|
23
23
|
- `handoff/external-reference.md`
|
|
24
24
|
- `handoff/local-context.md`
|
|
25
25
|
- `handoff/implementation-strategy.md`
|
|
26
26
|
- `handoff/final-handoff-plan.md`
|
|
27
27
|
|
|
28
|
+
Use phases such as `Research`, `Local context`, and `Synthesis` so async status is readable. Prefer `{outputs.externalReference}`, `{outputs.localContext}`, and `{outputs.implementationStrategy}` in the synthesis task when those specific inputs are available; keep `{previous}` only when the whole parallel fan-in summary is the desired input.
|
|
29
|
+
|
|
28
30
|
Do not write these artifacts into the repository unless I explicitly ask for persistent files.
|
|
29
31
|
|
|
30
32
|
Role guidance:
|
package/prompts/review-loop.md
CHANGED
|
@@ -4,7 +4,7 @@ description: Review/fix loop until clean
|
|
|
4
4
|
|
|
5
5
|
Run a parent-orchestrated review loop for the requested work.
|
|
6
6
|
|
|
7
|
-
Use the `subagent` tool. Keep the parent session as the loop controller and final decision-maker. Child subagents must receive concrete role-specific tasks; they must not run subagents or manage the loop themselves.
|
|
7
|
+
Use the `subagent` tool. Keep the parent session as the loop controller and final decision-maker. Child subagents must receive concrete role-specific tasks; they must not run subagents or manage the loop themselves unless the parent intentionally selected an explicit fanout agent whose builtin `tools` includes `subagent` for that assigned fanout.
|
|
8
8
|
|
|
9
9
|
Default to a maximum of 3 review rounds unless I specify a different cap. Count a review round each time fresh-context reviewers inspect the current diff after a worker pass. Stop early when reviewers find no blockers or fixes worth doing now.
|
|
10
10
|
|