@narumitw/pi-subagents 2.0.6 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +171 -60
- package/dist/chunks/{auto-transport-SY2VHUFH.ts → auto-transport-FUUKFDIG.ts} +6 -6
- package/dist/chunks/{capability-grant-CGEWOEKE.ts → capability-grant-PR72SWWS.ts} +4 -4
- package/dist/chunks/{chunk-CBP76ARQ.ts → chunk-2LMJU25E.ts} +172 -74
- package/dist/chunks/chunk-2LMJU25E.ts.map +7 -0
- package/dist/chunks/{chunk-DPPVEQAM.ts → chunk-4AQSF7AS.ts} +1 -1
- package/dist/chunks/chunk-4AQSF7AS.ts.map +7 -0
- package/dist/chunks/chunk-6H6TBBED.ts +108 -0
- package/dist/chunks/chunk-6H6TBBED.ts.map +7 -0
- package/dist/chunks/{chunk-YBUWBRF7.ts → chunk-6NSJVPXX.ts} +6 -16
- package/dist/chunks/{chunk-YBUWBRF7.ts.map → chunk-6NSJVPXX.ts.map} +2 -2
- package/dist/chunks/{chunk-DSOOH73Y.ts → chunk-7AAJEUSL.ts} +3 -3
- package/dist/chunks/{chunk-DSOOH73Y.ts.map → chunk-7AAJEUSL.ts.map} +2 -2
- package/dist/chunks/{chunk-7QPPBBXZ.ts → chunk-D4CR7T73.ts} +21 -3
- package/dist/chunks/chunk-D4CR7T73.ts.map +7 -0
- package/dist/chunks/{chunk-NIF42QMF.ts → chunk-FEVPWRMU.ts} +7 -4
- package/dist/chunks/chunk-FEVPWRMU.ts.map +7 -0
- package/dist/chunks/{chunk-S2IWVK3J.ts → chunk-ILEQ27AL.ts} +3 -2
- package/dist/chunks/chunk-ILEQ27AL.ts.map +7 -0
- package/dist/chunks/{chunk-DQMN4OYM.ts → chunk-ITVWPNU4.ts} +12 -106
- package/dist/chunks/chunk-ITVWPNU4.ts.map +7 -0
- package/dist/chunks/{chunk-QDVGH2X7.ts → chunk-IWC32VPY.ts} +2 -1
- package/dist/chunks/{chunk-QDVGH2X7.ts.map → chunk-IWC32VPY.ts.map} +2 -2
- package/dist/chunks/{chunk-I2FAK44T.ts → chunk-JSZIP73U.ts} +48 -10
- package/dist/chunks/chunk-JSZIP73U.ts.map +7 -0
- package/dist/chunks/{chunk-ZHTNCZIA.ts → chunk-JU6LUNLP.ts} +2 -2
- package/dist/chunks/{chunk-PSK43Y6A.ts → chunk-LASD73CM.ts} +2 -2
- package/dist/chunks/{chunk-C4L6P266.ts → chunk-LEOYDZI3.ts} +1 -1
- package/dist/chunks/{chunk-C4L6P266.ts.map → chunk-LEOYDZI3.ts.map} +2 -2
- package/dist/chunks/{chunk-H3BFJ7HJ.ts → chunk-LL4LP2T7.ts} +5 -5
- package/dist/chunks/chunk-N2T5IN4X.ts +18 -0
- package/dist/chunks/chunk-N2T5IN4X.ts.map +7 -0
- package/dist/chunks/chunk-NLT67IZS.ts +322 -0
- package/dist/chunks/chunk-NLT67IZS.ts.map +7 -0
- package/dist/chunks/{chunk-G3RSMSXJ.ts → chunk-NTRPLF46.ts} +1 -1
- package/dist/chunks/chunk-NTRPLF46.ts.map +7 -0
- package/dist/chunks/{chunk-EFBPISNT.ts → chunk-PBZMBTNJ.ts} +104 -103
- package/dist/chunks/chunk-PBZMBTNJ.ts.map +7 -0
- package/dist/chunks/{chunk-SCZ33MYW.ts → chunk-PGLSFLYW.ts} +2 -2
- package/dist/chunks/{chunk-O4VO6JUJ.ts → chunk-TM2R67J3.ts} +3 -3
- package/dist/chunks/{chunk-QBORTI4W.ts → chunk-TMZRHIIK.ts} +32 -3
- package/dist/chunks/chunk-TMZRHIIK.ts.map +7 -0
- package/dist/chunks/chunk-TZ34IQ3M.ts +59 -0
- package/dist/chunks/chunk-TZ34IQ3M.ts.map +7 -0
- package/dist/chunks/{chunk-7OBINKFM.ts → chunk-VDG7LTYE.ts} +11 -11
- package/dist/chunks/chunk-VDG7LTYE.ts.map +7 -0
- package/dist/chunks/{chunk-AEUYS7JC.ts → chunk-X4NMONPE.ts} +1 -1
- package/dist/chunks/chunk-X4NMONPE.ts.map +7 -0
- package/dist/chunks/{chunk-HKC4ES4B.ts → chunk-YPJEN6NU.ts} +2 -2
- package/dist/chunks/{chunk-434NII74.ts → chunk-YU53SHA7.ts} +54 -8
- package/dist/chunks/chunk-YU53SHA7.ts.map +7 -0
- package/dist/chunks/{completion-delivery-YPOWSSV3.ts → completion-delivery-RSJU6BXL.ts} +5 -4
- package/dist/chunks/{config-status-J4GPWP46.ts → config-status-FKGDECZ3.ts} +7 -6
- package/dist/chunks/{config-ui-2YUCUEBM.ts → config-ui-ABHYNGQ7.ts} +297 -231
- package/dist/chunks/config-ui-ABHYNGQ7.ts.map +7 -0
- package/dist/chunks/{consult-IV7UBNQQ.ts → consult-LJU3IQY5.ts} +14 -13
- package/dist/chunks/consult-LJU3IQY5.ts.map +7 -0
- package/dist/chunks/{create-stateful-transport-ZP3IXNV3.ts → create-stateful-transport-JWC2EFYL.ts} +6 -6
- package/dist/chunks/{delegation-contract-WJPT4FVS.ts → delegation-contract-LA56I5DT.ts} +2 -2
- package/dist/chunks/{discovery-K25T3SH4.ts → discovery-MIFB2U4Y.ts} +3 -3
- package/dist/chunks/{execution-LA7HN5YF.ts → execution-Q2JZLKJA.ts} +19 -16
- package/dist/chunks/execution-Q2JZLKJA.ts.map +7 -0
- package/dist/chunks/{in-process-transport-4RF3J6XK.ts → in-process-transport-HJ6TZXC3.ts} +9 -9
- package/dist/chunks/{inspect-XV2QALMR.ts → inspect-UH2TKH6E.ts} +25 -10
- package/dist/chunks/inspect-UH2TKH6E.ts.map +7 -0
- package/dist/chunks/{persistence-VSGXAW4P.ts → persistence-UY3PY6E5.ts} +11 -7
- package/dist/chunks/persistence-UY3PY6E5.ts.map +7 -0
- package/dist/chunks/{registry-E6XPJB7L.ts → registry-BT54L6CY.ts} +136 -15
- package/dist/chunks/registry-BT54L6CY.ts.map +7 -0
- package/dist/chunks/{retained-semantic-state-7WXSGRJU.ts → retained-semantic-state-GM75FZGE.ts} +3 -3
- package/dist/chunks/{rpc-transport-NEHBHWX4.ts → rpc-transport-7R7DVCEB.ts} +12 -16
- package/dist/chunks/rpc-transport-7R7DVCEB.ts.map +7 -0
- package/dist/chunks/{spawn-idempotency-QGHO2WKC.ts → spawn-idempotency-BNHOSMZW.ts} +2 -2
- package/dist/chunks/{subprocess-transport-NSHOGDC4.ts → subprocess-transport-VHZJRBTW.ts} +15 -14
- package/dist/chunks/subprocess-transport-VHZJRBTW.ts.map +7 -0
- package/dist/chunks/usage-recording-store-CW3EH2SZ.ts +164 -0
- package/dist/chunks/usage-recording-store-CW3EH2SZ.ts.map +7 -0
- package/dist/index.ts +682 -82
- package/dist/index.ts.map +3 -3
- package/docs/async-runtime-protocol.md +83 -0
- package/docs/implementation-notes/pi-subagents-capability-matrix.md +62 -0
- package/docs/implementation-notes/pi-subagents-current-direction.md +99 -0
- package/docs/implementation-notes/pi-subagents-rpc-v1.md +153 -0
- package/docs/pi-subagents-diagrams.md +183 -0
- package/package.json +9 -8
- package/src/agents/types.ts +2 -0
- package/src/async-subagent-benchmark.ts +532 -0
- package/src/completion-delivery.ts +71 -4
- package/src/completion-render.ts +1 -0
- package/src/completion-requirement.ts +479 -0
- package/src/config-registration.ts +5 -5
- package/src/config-status.ts +66 -70
- package/src/config-ui.ts +244 -150
- package/src/consult-registration.ts +4 -12
- package/src/consult-resources.ts +1 -1
- package/src/consult.ts +3 -8
- package/src/delegation-contract.ts +55 -9
- package/src/execution-plan.ts +1 -1
- package/src/execution-ui.ts +40 -29
- package/src/execution.ts +2 -3
- package/src/inspect.ts +24 -1
- package/src/orchestration-metrics.ts +1 -1
- package/src/panel-execution.ts +2 -3
- package/src/panel-failure.ts +1 -1
- package/src/panel-render.ts +1 -1
- package/src/parallel-limit-ui.ts +6 -5
- package/src/params.ts +2 -1
- package/src/persistence.ts +9 -0
- package/src/process-control.ts +43 -0
- package/src/registry-types.ts +5 -0
- package/src/registry.ts +162 -18
- package/src/render.ts +2 -1
- package/src/rpc-transport.ts +1 -1
- package/src/runner-outcome.ts +1 -1
- package/src/runner-result.ts +1 -1
- package/src/runner-types.ts +102 -0
- package/src/runner.ts +11 -192
- package/src/session-guidance-contract.ts +309 -0
- package/src/settings/inspection.ts +27 -0
- package/src/settings/schema.ts +9 -0
- package/src/settings-reader.ts +7 -0
- package/src/settings.ts +20 -0
- package/src/spawn-idempotency.ts +5 -0
- package/src/stateful-agent-view.ts +15 -19
- package/src/stateful-guidance.ts +11 -18
- package/src/stateful-limit-ui.ts +23 -20
- package/src/stateful-limits.ts +10 -10
- package/src/stateful-registration.ts +126 -36
- package/src/stateful-render.ts +27 -2
- package/src/subagent-details.ts +43 -0
- package/src/subagents-extension.ts +116 -68
- package/src/subagents.ts +2 -0
- package/src/subprocess-transport.ts +2 -1
- package/src/supervision.ts +2 -1
- package/src/timeout-finalization.ts +1 -1
- package/src/tool-schema-compatibility.ts +73 -0
- package/src/transport-types.ts +6 -0
- package/src/transport-ui.ts +18 -46
- package/src/usage-recording-config.ts +13 -0
- package/src/usage-recording-store.ts +183 -0
- package/src/usage-recording.ts +478 -0
- package/src/verification-harness.ts +1 -1
- package/src/workflow-ui.ts +17 -9
- package/dist/chunks/chunk-434NII74.ts.map +0 -7
- package/dist/chunks/chunk-7OBINKFM.ts.map +0 -7
- package/dist/chunks/chunk-7QPPBBXZ.ts.map +0 -7
- package/dist/chunks/chunk-AEUYS7JC.ts.map +0 -7
- package/dist/chunks/chunk-CBP76ARQ.ts.map +0 -7
- package/dist/chunks/chunk-DPPVEQAM.ts.map +0 -7
- package/dist/chunks/chunk-DQMN4OYM.ts.map +0 -7
- package/dist/chunks/chunk-EFBPISNT.ts.map +0 -7
- package/dist/chunks/chunk-G3RSMSXJ.ts.map +0 -7
- package/dist/chunks/chunk-I2FAK44T.ts.map +0 -7
- package/dist/chunks/chunk-NIF42QMF.ts.map +0 -7
- package/dist/chunks/chunk-QBORTI4W.ts.map +0 -7
- package/dist/chunks/chunk-S2IWVK3J.ts.map +0 -7
- package/dist/chunks/config-ui-2YUCUEBM.ts.map +0 -7
- package/dist/chunks/consult-IV7UBNQQ.ts.map +0 -7
- package/dist/chunks/execution-LA7HN5YF.ts.map +0 -7
- package/dist/chunks/inspect-XV2QALMR.ts.map +0 -7
- package/dist/chunks/persistence-VSGXAW4P.ts.map +0 -7
- package/dist/chunks/registry-E6XPJB7L.ts.map +0 -7
- package/dist/chunks/rpc-transport-NEHBHWX4.ts.map +0 -7
- package/dist/chunks/subprocess-transport-NSHOGDC4.ts.map +0 -7
- /package/dist/chunks/{auto-transport-SY2VHUFH.ts.map → auto-transport-FUUKFDIG.ts.map} +0 -0
- /package/dist/chunks/{capability-grant-CGEWOEKE.ts.map → capability-grant-PR72SWWS.ts.map} +0 -0
- /package/dist/chunks/{chunk-ZHTNCZIA.ts.map → chunk-JU6LUNLP.ts.map} +0 -0
- /package/dist/chunks/{chunk-PSK43Y6A.ts.map → chunk-LASD73CM.ts.map} +0 -0
- /package/dist/chunks/{chunk-H3BFJ7HJ.ts.map → chunk-LL4LP2T7.ts.map} +0 -0
- /package/dist/chunks/{chunk-SCZ33MYW.ts.map → chunk-PGLSFLYW.ts.map} +0 -0
- /package/dist/chunks/{chunk-O4VO6JUJ.ts.map → chunk-TM2R67J3.ts.map} +0 -0
- /package/dist/chunks/{chunk-HKC4ES4B.ts.map → chunk-YPJEN6NU.ts.map} +0 -0
- /package/dist/chunks/{completion-delivery-YPOWSSV3.ts.map → completion-delivery-RSJU6BXL.ts.map} +0 -0
- /package/dist/chunks/{config-status-J4GPWP46.ts.map → config-status-FKGDECZ3.ts.map} +0 -0
- /package/dist/chunks/{create-stateful-transport-ZP3IXNV3.ts.map → create-stateful-transport-JWC2EFYL.ts.map} +0 -0
- /package/dist/chunks/{delegation-contract-WJPT4FVS.ts.map → delegation-contract-LA56I5DT.ts.map} +0 -0
- /package/dist/chunks/{discovery-K25T3SH4.ts.map → discovery-MIFB2U4Y.ts.map} +0 -0
- /package/dist/chunks/{in-process-transport-4RF3J6XK.ts.map → in-process-transport-HJ6TZXC3.ts.map} +0 -0
- /package/dist/chunks/{retained-semantic-state-7WXSGRJU.ts.map → retained-semantic-state-GM75FZGE.ts.map} +0 -0
- /package/dist/chunks/{spawn-idempotency-QGHO2WKC.ts.map → spawn-idempotency-BNHOSMZW.ts.map} +0 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Async runtime protocol
|
|
2
|
+
|
|
3
|
+
This document defines `pi-subagents:completion-requirement:v1` and the current runtime boundary for final-answer-dependent detached work.
|
|
4
|
+
|
|
5
|
+
## Requirement identity
|
|
6
|
+
|
|
7
|
+
A caller marks one `subagent_spawn` or `subagent_send` turn with `completionRequirement: "required"`.
|
|
8
|
+
The runtime binds that requirement to the accepted `agentId`, executor-owned `runId`, and monotonically increasing turn generation.
|
|
9
|
+
Agent names and task paths are display and addressing aids and never replace exact run identity.
|
|
10
|
+
Omitting the field or using `background` preserves prior behavior and does not create a final-answer dependency.
|
|
11
|
+
|
|
12
|
+
## State ownership
|
|
13
|
+
|
|
14
|
+
`AgentRegistry` owns requirement transitions with the child turn and persisted completion outbox.
|
|
15
|
+
Tool-result `details.agent.completionRequirements` provides fork-sensitive branch evidence.
|
|
16
|
+
Session restoration retains exact requirements found on the active branch and treats sessions without visible subagent state as a possible compacted continuation.
|
|
17
|
+
The successful lifecycle tool result and delivered completion message are the ordinary model-visible requirement handoff.
|
|
18
|
+
When a resume changes a pending run to cancelled and interrupted while its stale handoff remains in model context, `before_agent_start` appends one hidden versioned transition after that handoff.
|
|
19
|
+
This append-only transition also applies when leading summaries retain the stale handoff, prevents duplicate publication on later turns, and participates in fork-sensitive branch reconstruction.
|
|
20
|
+
If leading compaction or branch summaries remove the handoff, the `context` hook restores one canonical hidden `pi-subagent-required-completions` fallback immediately after the summaries.
|
|
21
|
+
The fallback remains at that fixed boundary for the leading-summary epoch, while a later completion or cancellation transition supersedes it at the conversation tail.
|
|
22
|
+
`CompletionDeliveryBroker` owns exact completion visibility acknowledgement and asks the registry to mark the corresponding requirement visible.
|
|
23
|
+
No timer, waiter, or UI object owns requirement truth.
|
|
24
|
+
|
|
25
|
+
## States
|
|
26
|
+
|
|
27
|
+
A newly accepted exact run enters `pending`.
|
|
28
|
+
A durably persisted terminal completion moves the exact run to `available` and records its completion ID and terminal child state.
|
|
29
|
+
Observation of that exact completion ID in the intended parent context moves the run to `visible`.
|
|
30
|
+
Interruption, close, restore of a non-running owner, or shutdown moves an unfinished requirement to `cancelled` with an explicit terminal state.
|
|
31
|
+
Duplicate completion delivery and acknowledgement are idempotent.
|
|
32
|
+
A follow-up receives a new run ID and generation and creates a requirement only when that follow-up explicitly requests one.
|
|
33
|
+
The runtime bounds retained requirement records per agent and rejects a sixty-fifth unresolved required run before acceptance so every unresolved exact identity fits in the canonical parent context.
|
|
34
|
+
|
|
35
|
+
## Parent behavior
|
|
36
|
+
|
|
37
|
+
Pending and available requirements remain final-answer dependencies.
|
|
38
|
+
A newly established canonical fallback omits requirements already visible at that boundary.
|
|
39
|
+
A fallback retained from an earlier request remains historical prefix context after visibility changes, and the later completion message supplies the superseding state.
|
|
40
|
+
Cancelled requirements are terminal and must be reported rather than silently treated as successful evidence.
|
|
41
|
+
A failed, partial, interrupted, stale, or cancelled child never satisfies mutating acceptance or independent-verification requirements merely because its turn settled.
|
|
42
|
+
|
|
43
|
+
## Prompt-cache boundary
|
|
44
|
+
|
|
45
|
+
Provider-visible subagent tool definitions and prompt metadata remain stable within one configured tool-surface epoch.
|
|
46
|
+
A versioned hidden session-guidance message carries the bounded agent catalog, completion delivery, capacity, cwd policy, and consultation resource policy without placing mutable values in leading tool metadata.
|
|
47
|
+
The initial guidance contract is persisted once before the first agent turn when no equivalent retained contract exists.
|
|
48
|
+
A successfully applied live policy change appends a superseding guidance contract without triggering a model turn.
|
|
49
|
+
Compaction restores missing guidance and required-completion fallbacks in deterministic order after leading summaries.
|
|
50
|
+
These rules preserve normalized cache-eligible prefixes across ordinary turns but do not guarantee a provider-reported cache hit.
|
|
51
|
+
|
|
52
|
+
## Budget termination
|
|
53
|
+
|
|
54
|
+
Omitted limits use runtime or agent policy and are recorded as runtime-sourced telemetry.
|
|
55
|
+
Explicit timeout, idle, turn, and tool-call limits remain compatible and are recorded as explicit sources.
|
|
56
|
+
A limit stop with non-empty successful bounded finalization becomes a typed `partial` outcome with the exact termination reason.
|
|
57
|
+
Empty finalization, failed finalization, malformed required structured output, and transport failures remain failed or contract-invalid.
|
|
58
|
+
Partial evidence is available to the parent but is not successful verification or mutating acceptance.
|
|
59
|
+
|
|
60
|
+
## Pi core boundary
|
|
61
|
+
|
|
62
|
+
The inspected supported Pi runtime emits provider `message_update` events before the TUI, RPC, JSON, and SDK surfaces display them.
|
|
63
|
+
An extension `message_end` handler can replace the finalized same-role message but cannot retract previously displayed deltas.
|
|
64
|
+
Steering is queued after the extension `input` event, direct RPC steering bypasses that event, and tool abort signals do not observe every accepted steer.
|
|
65
|
+
Therefore an extension cannot provide a hard pre-display final-answer barrier or a reliably steer-interruptible join across all supported modes.
|
|
66
|
+
`subagent_await` remains the bounded non-polling compatibility join and accurately states that queued steering is blocked until the tool settles.
|
|
67
|
+
|
|
68
|
+
A future core implementation would need replay-safe post-enqueue input activity, exact session-owned blocker handles, pre-display buffering or suppression, bounded timeout, and abort, replacement, reload, shutdown, and headless-mode semantics.
|
|
69
|
+
This repository does not modify or publish Pi core packages for this work.
|
|
70
|
+
|
|
71
|
+
## Codex reference
|
|
72
|
+
|
|
73
|
+
Codex `wait_agent` uses replay-safe pending activity plus an event-driven watch receiver for mailbox and steering activity.
|
|
74
|
+
Codex completion context uses a typed `FINAL_ANSWER` envelope with explicit task, sender, and payload fields.
|
|
75
|
+
Codex rollout budgets use shared runtime-owned accounting and acknowledge reminders only after context insertion.
|
|
76
|
+
These patterns inform waiting, completion identity, and budget ownership, but Codex also does not provide an absolute pre-display final-answer barrier.
|
|
77
|
+
|
|
78
|
+
## Compatibility fallback
|
|
79
|
+
|
|
80
|
+
Older persisted agents without requirement metadata behave as background work.
|
|
81
|
+
Current Pi versions continue using bounded persisted at-least-once completion delivery and optional idle-root auto-resume.
|
|
82
|
+
The package must not claim that prompt guidance, context injection, automatic delivery, or finalized-message replacement is a hard barrier.
|
|
83
|
+
The deprecated synchronous `subagent` tool remains available for unmatched chain, fan-in, panel, workflow, and compatibility callers.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# pi-subagents capability matrix
|
|
2
|
+
|
|
3
|
+
This matrix records the maintained capability boundaries of `@narumitw/pi-subagents`.
|
|
4
|
+
The package README owns public schemas and usage.
|
|
5
|
+
Source and focused tests are the executable authority.
|
|
6
|
+
|
|
7
|
+
| Capability | Status and boundary | Evidence |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| Blocking orchestration | Deprecated `subagent` remains a compatibility tool for single, parallel, chain, fan-in, panel, and explicit dependency workflows; the complete request is preflighted before launch and its schema and execution contract remain supported | `src/execution.ts`, `src/panel-execution.ts`, blocking execution and workflow tests |
|
|
10
|
+
| Detached addressable agents | `subagent_spawn` returns an opaque id and canonical task path without waiting for completion | `src/stateful-registration.ts`, registry and stateful registration tests |
|
|
11
|
+
| Follow-up and retained lifecycle | `subagent_send` starts follow-up work; `subagent_await` blocks for one current turn without interrupting on wait timeout or cancellation; `subagent_manage` supports only interrupt and close; `subagent_mailbox` owns queue-only send and acknowledged read | `src/stateful-tool-params.ts`, registry and lifecycle tests |
|
|
12
|
+
| Metadata-only inspection | `subagent_inspect` is registered in every workflow and never launches children, changes lifecycle state, or reads or acknowledges mailbox content | `src/inspect.ts`, `test/inspect.test.ts` |
|
|
13
|
+
| Synchronous read-only consultation | `subagent_consult` runs one ephemeral child with extensions disabled and only the effective subset of `read`, `grep`, `find`, and `ls` | `src/consult.ts`, `src/consult-policy.ts`, `test/consult.test.ts` |
|
|
14
|
+
| Workflow-dependent tool surface | `all` registers eight tools including supported `subagent_await` and `subagent_consult` plus deprecated `subagent`; `async-only` registers detached lifecycle plus inspection; `blocking-only` registers deprecated `subagent` plus supported consultation and inspection; `disabled` registers inspection only | `src/subagents-extension.ts`, settings UI and registration tests |
|
|
15
|
+
| Transport selection | Stateful execution supports `subprocess`, `in-process`, `rpc`, and `auto`; subprocess remains the compatibility default and selection never falls back after acceptance | `src/create-stateful-transport.ts`, transport tests |
|
|
16
|
+
| Automatic transport | Read-only built-in tools select in-process, write-capable built-ins select RPC, and extension or custom tools select fresh subprocess execution | `src/auto-transport.ts`, automatic transport tests |
|
|
17
|
+
| In-process SDK boundary | In-process children use public session-service and model-resolution APIs, disable child extensions, and reject unsupported tools without widening or fallback | `src/in-process-transport.ts`, in-process transport tests |
|
|
18
|
+
| Persistent RPC transport | One retained agent lazily owns at most one exact-loaded Pi RPC child; `agent_settled` is the completion boundary and accepted work is never replayed automatically | `src/rpc-transport.ts`, [`pi-subagents-rpc-v1.md`](pi-subagents-rpc-v1.md) |
|
|
19
|
+
| Detached completion delivery | `next-turn` is the default non-waking delivery; opt-in `auto-resume` steers completion into active root context without a wake, or requests at most one in-flight synthesis turn when the root is idle and has no pending input; exact completion IDs remain pending until context acknowledgement | `src/completion-delivery.ts`, completion-delivery tests |
|
|
20
|
+
| Deterministic timeout and cleanup | Work, idle, turn, and tool budgets use bounded abort and process or session cleanup; explicit parent interruption never starts timeout finalization | runner, transport, timeout, and cleanup tests |
|
|
21
|
+
| Bounded protocol and output | Model-facing content and safe projections are bounded to 50 KiB or 2,000 lines | `src/protocol.ts`, `src/limits.ts`, rendering and inspection tests |
|
|
22
|
+
| Partial structured outcomes | Blocking, detached, and consultation paths preserve bounded post-launch evidence and usage; structured-v2 keeps claims, artifacts, verification, limitations, and unresolved dependencies | result-contract, runner, consultation, and orchestration tests |
|
|
23
|
+
| Enforced delegation contracts | Optional `pi-subagents:delegation:v2` contracts validate declared capabilities, dependencies, evidence, side-effect policy, and supported enforcement without claiming unsupported path, network, or secret guarantees | `src/delegation-contract.ts`, contract and workflow tests |
|
|
24
|
+
| Recursion guard | `PI_SUBAGENT_DEPTH` and `PI_SUBAGENT_MAX_DEPTH` bound nested delegation | `src/execution.ts`, runtime policy and runner tests |
|
|
25
|
+
| Hierarchical ownership | Parent, root, depth, children, and authenticated task paths are persisted; subtree interrupt and close run child-first | `src/registry.ts`, registry and orchestration tests |
|
|
26
|
+
| Bounded mailbox and peer delivery | Mailboxes support acknowledgement and deduplication; inspection exposes only counts; nested peer delivery uses session-scoped authenticated channels | registry, peer transport, mailbox, and inspection tests |
|
|
27
|
+
| Shared and isolated workspaces | Shared-workspace agents may write concurrently by default; deprecated `allowConcurrentWrites` is a no-op; opt-in clean-Git worktrees provide disposable repository isolation | `src/stateful-registration.ts`, `src/workspace.ts`, workspace tests |
|
|
28
|
+
| Separate active and retained capacity | FIFO active-turn scheduling and retained-agent limits are independent and hierarchy depth and child counts are bounded separately | `src/registry.ts`, capacity and fairness tests |
|
|
29
|
+
| Parent context selection | Context supports none, all, summary, recent N user turns, and selected entry ids; projection is text-only, sanitized, and bounded | `src/context.ts`, context protocol tests |
|
|
30
|
+
| Target trust resolution | Current workspace uses session trust; external targets use the nearest saved `ProjectTrustStore` decision, with a nearer denial winning | `src/cwd-policy.ts`, `test/cwd-policy.test.ts` |
|
|
31
|
+
| Consultation target policy | Consultation defaults to any existing target and removes inherited target and project resources when effective trust is absent | `src/consult.ts`, consultation cwd and trust tests |
|
|
32
|
+
| General delegation target policy | Delegation defaults to trusted targets; blocking and detached requests are preflighted and every transport receives the same resolved trust decision | execution, stateful, cwd-policy, and transport tests |
|
|
33
|
+
| Durable logical history | Versioned private state restores inert; retained transports seed bounded sanitized context and logical history once after explicit follow-up | `src/persistence.ts`, persistence and orchestration tests |
|
|
34
|
+
| Automatic side-effect resume | Restored records never restart work; semantic resource skew requires explicit revalidation before a follow-up | persistence, semantic snapshot, and lifecycle tests |
|
|
35
|
+
| Stable tool schema | Registered tool membership does not change across retained-agent state transitions; workflow changes require reload | registration and settings UI tests |
|
|
36
|
+
| Native transcript switching | Unsupported because Pi exposes no supported child transcript or session switch handle | public SDK boundary review |
|
|
37
|
+
| Approval, sandbox, and header inheritance | Unsupported as a general guarantee and reported explicitly in result policy metadata | result policy and transport tests |
|
|
38
|
+
| Filesystem isolation | Optional disposable worktree only; cwd and trust policies are not OS sandboxes and do not restrict absolute paths, processes, network, or credentials | `src/workspace.ts`, README security boundary |
|
|
39
|
+
| Extension-owned autonomous planning | Removed; topology belongs to the main agent or a caller-authored workflow request | built-in catalog, execution, and registration tests |
|
|
40
|
+
|
|
41
|
+
## Read-only boundary
|
|
42
|
+
|
|
43
|
+
`subagent_inspect` is side-effect-free at the extension capability boundary.
|
|
44
|
+
It uses pure settings and metadata snapshots, applies project-trust gates before project discovery, and omits prompts, history, context content, mailbox content, credential-bearing model fields, and unsafe paths.
|
|
45
|
+
|
|
46
|
+
`subagent_consult` is synchronous and non-retained.
|
|
47
|
+
Missing agent tool configuration selects the read-only default set, an explicit empty list selects no tools, and any explicit list is intersected with the supported read-only built-ins.
|
|
48
|
+
Extensions, sessions, lifecycle tools, shell execution, and file mutation tools are disabled.
|
|
49
|
+
Pre-launch failures throw.
|
|
50
|
+
Once a child starts, bounded partial evidence and nested usage are retained and the finalized Pi tool result is marked as an error when consultation fails.
|
|
51
|
+
|
|
52
|
+
These are executor and resource-loading guarantees, not filesystem, network, process, or confidentiality sandboxes.
|
|
53
|
+
A consultation can read an accessible absolute path when explicitly asked and calls the configured model over the network.
|
|
54
|
+
|
|
55
|
+
## Runtime ownership boundary
|
|
56
|
+
|
|
57
|
+
The logical registry owns ids, hierarchy, capacity, mailboxes, completion delivery, persistence, semantic revalidation, and workspace cleanup.
|
|
58
|
+
Each retained turn owns one transport session or process according to its fixed effective transport.
|
|
59
|
+
Close, expiry, replacement, reload, and shutdown abort work and release transport and disposable-workspace ownership.
|
|
60
|
+
|
|
61
|
+
Pi core still owns provider execution, active-turn admission, message ordering, retries, compaction, interactive transcript selection, and global scheduling.
|
|
62
|
+
The extension does not claim inherited approval or sandbox policy, provider-header hooks, extension state, or a core-owned child-session tree.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# pi-subagents current direction
|
|
2
|
+
|
|
3
|
+
This note is the entry point for current `@narumitw/pi-subagents` planning.
|
|
4
|
+
|
|
5
|
+
## Current product shape
|
|
6
|
+
|
|
7
|
+
`pi-subagents` is a delegation runtime, not an automatic planner.
|
|
8
|
+
|
|
9
|
+
The main agent decides whether to delegate and how to split work.
|
|
10
|
+
|
|
11
|
+
The built-in catalog is intentionally small:
|
|
12
|
+
|
|
13
|
+
| Built-in | Purpose | Default tools |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| `explorer` | Bounded read-only repository exploration with cited paths and evidence. | `read`, `grep`, `find`, `ls` |
|
|
16
|
+
| `worker` | Write-capable parallel implementation, command execution, and fixes. | Pi default tools |
|
|
17
|
+
|
|
18
|
+
Removed built-ins and tools are not part of the active surface:
|
|
19
|
+
|
|
20
|
+
- `planner`;
|
|
21
|
+
- `reviewer`;
|
|
22
|
+
- `general`;
|
|
23
|
+
- `general-purpose`; and
|
|
24
|
+
- `subagent_auto`.
|
|
25
|
+
|
|
26
|
+
## Delegation rules
|
|
27
|
+
|
|
28
|
+
Use no subagent for simple, latency-sensitive, conversational, tightly coupled, or single-lane implementation work that the main agent can do directly.
|
|
29
|
+
|
|
30
|
+
Use `explorer` when a bounded read-only search can save main-context space or run independently.
|
|
31
|
+
|
|
32
|
+
Keep overall planning, immediate critical-path work, integration, final verification, and the final answer in the main agent.
|
|
33
|
+
|
|
34
|
+
A worker may directly implement a bounded slice with clear ownership when it can run independently beside useful non-overlapping main-agent work.
|
|
35
|
+
|
|
36
|
+
Use one async `worker` only when the main agent has named that local work to continue immediately and the worker result has a supported delivery and integration path.
|
|
37
|
+
|
|
38
|
+
If the main agent has no such local work, it should implement directly instead of spawning one worker.
|
|
39
|
+
|
|
40
|
+
Use two or more workers only for disjoint implementation slices whose parallel progress justifies coordination, and keep integration ownership in the main agent.
|
|
41
|
+
|
|
42
|
+
A single worker without concurrent main-agent work remains an explicit escape hatch for a user-requested specialist model, tool profile, or isolation boundary rather than the ordinary implementation path.
|
|
43
|
+
|
|
44
|
+
Use custom user or project agents for specialist review, verification, or shell-capable read-mostly work.
|
|
45
|
+
|
|
46
|
+
Custom project agents remain subject to existing trust and confirmation behavior.
|
|
47
|
+
|
|
48
|
+
Review should usually be handled by the main agent plus review skills and deterministic checks.
|
|
49
|
+
|
|
50
|
+
Use custom verifier agents only when independent child verification is explicitly worth the added cost and coordination.
|
|
51
|
+
|
|
52
|
+
## Tool-surface direction
|
|
53
|
+
|
|
54
|
+
`all` remains the compatibility default, while `async-only` remains an optional smaller tool surface.
|
|
55
|
+
|
|
56
|
+
`async-only` exposes `subagent_spawn`, `subagent_send`, `subagent_manage`, `subagent_mailbox`, and `subagent_inspect`.
|
|
57
|
+
`all` additionally exposes supported `subagent_await` and `subagent_consult` plus deprecated blocking `subagent` for compatibility.
|
|
58
|
+
|
|
59
|
+
`subagent_spawn` is preferred only when detached execution creates real parallelism rather than moving the main agent's only useful task into a child.
|
|
60
|
+
|
|
61
|
+
After spawning one worker, the main agent should immediately continue the named non-overlapping work instead of only announcing the spawn, waiting, polling, or ending the turn.
|
|
62
|
+
|
|
63
|
+
Final-answer-dependent detached work needs a supported synthesis path such as opt-in `auto-resume`; default `next-turn` delivery remains appropriate only when the current response does not depend on the result.
|
|
64
|
+
|
|
65
|
+
Blocking `subagent` is deprecated for new work but remains available with its existing schema and execution behavior for established callers and explicit requests whose chain, fan-in, panel, or workflow semantics lack a detached replacement.
|
|
66
|
+
|
|
67
|
+
No removal release or date is set until those compatibility modes have a separately approved replacement or migration.
|
|
68
|
+
|
|
69
|
+
`subagent_consult` remains a supported synchronous read-only exception.
|
|
70
|
+
|
|
71
|
+
`subagent_await` remains a supported intentional join after useful overlapping parent work is complete.
|
|
72
|
+
|
|
73
|
+
The four async lifecycle tools remain split because start, follow-up, lifecycle, and queue operations have distinct contracts.
|
|
74
|
+
`subagent_await` remains separate because waiting blocks the parent, its timeout never interrupts the child, and the async-only workflow must omit it.
|
|
75
|
+
|
|
76
|
+
Changing the default, removing deprecated `subagent`, or consolidating lifecycle tools needs a separate approved migration decision.
|
|
77
|
+
|
|
78
|
+
## Active follow-ups
|
|
79
|
+
|
|
80
|
+
None.
|
|
81
|
+
|
|
82
|
+
New implementation work should respond to demonstrated user needs rather than extending automatic or adaptive routing speculatively.
|
|
83
|
+
|
|
84
|
+
## Current reference notes
|
|
85
|
+
|
|
86
|
+
- Git history for the completed main-agent-led delegation guidance records the accepted delegation rubric and verification evidence.
|
|
87
|
+
- Git history for the completed async-first tool-surface work records the earlier tool-surface decision and implementation evidence.
|
|
88
|
+
- [`pi-subagents-capability-matrix.md`](pi-subagents-capability-matrix.md) records maintained capability, detached lifecycle, transport, trust, and runtime-ownership boundaries.
|
|
89
|
+
- [`pi-subagents-rpc-v1.md`](pi-subagents-rpc-v1.md) records the persistent RPC transport contract.
|
|
90
|
+
|
|
91
|
+
## Historical evidence
|
|
92
|
+
|
|
93
|
+
The consolidated [research synthesis](../../../../docs/research/coding-agent-subagents-research.md) records the architecture conclusions available at the research cutoff.
|
|
94
|
+
|
|
95
|
+
The companion [evidence catalog](../../../../docs/research/coding-agent-subagents-evidence-catalog.md) preserves paper-level results, caveats, and primary sources.
|
|
96
|
+
|
|
97
|
+
Superseded automation, proactivity, and old runtime notes were removed to keep the active docs small.
|
|
98
|
+
|
|
99
|
+
Git history remains the record of earlier research drafts and raw search transcripts.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# pi-subagents RPC v1
|
|
2
|
+
|
|
3
|
+
`pi-subagents:v1` is the extension-owned transport and metadata contract layered over Pi's built-in RPC JSONL protocol.
|
|
4
|
+
|
|
5
|
+
It does not add commands to Pi RPC or alter Pi command and event payloads.
|
|
6
|
+
|
|
7
|
+
## Envelope
|
|
8
|
+
|
|
9
|
+
Extension-owned progress, run inspection, and completion metadata may include these bounded fields:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"protocol": "pi-subagents:v1",
|
|
14
|
+
"agentId": "sa_…",
|
|
15
|
+
"transport": "rpc",
|
|
16
|
+
"phase": "starting | ready | accepted | running | finalizing | retrying | compacting | settled | failed | interrupted",
|
|
17
|
+
"timing": {},
|
|
18
|
+
"provider": "…",
|
|
19
|
+
"model": "…",
|
|
20
|
+
"thinkingLevel": "medium",
|
|
21
|
+
"usage": {}
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Fields are additive and optional within v1.
|
|
26
|
+
|
|
27
|
+
A breaking lifecycle or envelope change requires another protocol identifier.
|
|
28
|
+
|
|
29
|
+
Raw prompts, chain-of-thought, credentials, headers, environment values, full stderr, and raw tool arguments never enter the envelope.
|
|
30
|
+
|
|
31
|
+
## Usage accounting
|
|
32
|
+
|
|
33
|
+
Pi 0.84.2 RPC `message_update.usage` values are cumulative for the current assistant message.
|
|
34
|
+
|
|
35
|
+
RPC v1 keeps the latest validated update as one replaceable in-flight snapshot instead of adding successive updates together.
|
|
36
|
+
|
|
37
|
+
A valid `message_end.message.usage` is authoritative for the finalized assistant message.
|
|
38
|
+
|
|
39
|
+
When final usage has no valid token or total-cost field, RPC v1 commits the latest valid in-flight snapshot instead.
|
|
40
|
+
|
|
41
|
+
A new assistant `message_start` commits usage from an interrupted prior attempt before tracking the new cumulative stream.
|
|
42
|
+
|
|
43
|
+
Timeout finalization commits the interrupted work snapshot before clearing captured output and starting the bounded summary attempt.
|
|
44
|
+
|
|
45
|
+
Progress and terminal outcomes expose the safe sum of committed usage plus the current in-flight snapshot.
|
|
46
|
+
|
|
47
|
+
Only non-negative finite values no larger than `Number.MAX_SAFE_INTEGER` enter telemetry, and `totalTokens` is derived from valid components only when no valid reported total exists.
|
|
48
|
+
|
|
49
|
+
The `turns` field continues to count finalized assistant messages only, so interrupted attempts and tool-result messages do not increment it.
|
|
50
|
+
|
|
51
|
+
Usage progress contains only normalized token counts, total cost, and finalized-turn count, and never adds raw RPC events, prompts, content, reasoning, credentials, headers, or environment values to the envelope.
|
|
52
|
+
|
|
53
|
+
## Lifecycle
|
|
54
|
+
|
|
55
|
+
One retained `agentId` lazily owns at most one RPC child.
|
|
56
|
+
|
|
57
|
+
The child starts through the exact loaded Pi package with `--mode rpc --no-session --no-extensions`.
|
|
58
|
+
|
|
59
|
+
A correlated `get_state` response is the readiness handshake.
|
|
60
|
+
|
|
61
|
+
The task timeout begins only after readiness.
|
|
62
|
+
|
|
63
|
+
Optional idle, assistant-turn, and tool-call budgets begin with prompt execution and observe only completed assistant messages or tool results as meaningful progress.
|
|
64
|
+
|
|
65
|
+
The transport subscribes before sending `prompt`.
|
|
66
|
+
|
|
67
|
+
A successful prompt response means accepted, not completed.
|
|
68
|
+
|
|
69
|
+
`agent_end` is a low-level run boundary and cannot complete a retained turn.
|
|
70
|
+
|
|
71
|
+
`agent_settled` is the authoritative completion boundary after retries, compaction, and queued continuations settle.
|
|
72
|
+
|
|
73
|
+
Abort and timeout send the Pi RPC `abort` command and wait for settlement within a bounded grace period.
|
|
74
|
+
|
|
75
|
+
After a work, idle, assistant-turn, or tool-call budget stop settles, the transport creates a bounded redacted checkpoint and sends one bounded finalization prompt that requests only a summary of already gathered evidence and explicitly forbids further tool use.
|
|
76
|
+
|
|
77
|
+
Pi RPC does not currently replace an existing child session's active tool set for one turn, so the finalization deadline and abort path remain authoritative if the model disregards that instruction.
|
|
78
|
+
|
|
79
|
+
The finalization turn has a separate model-work deadline of at most 45 seconds, followed only by bounded abort and process-cleanup grace, and never replays the timed-out task.
|
|
80
|
+
|
|
81
|
+
Explicit parent interruption does not start finalization.
|
|
82
|
+
|
|
83
|
+
A child that does not settle after work or finalization abort is terminated and cannot be reused.
|
|
84
|
+
|
|
85
|
+
An accepted or ambiguously accepted task is never replayed automatically.
|
|
86
|
+
|
|
87
|
+
Process exit marks the turn failed or interrupted with bounded partial evidence.
|
|
88
|
+
|
|
89
|
+
Budget-stopped outcomes keep exit `124` and add a `pi-subagents:termination:v1` report with the stop reason, selected limit, deterministic `pi-subagents:checkpoint:v1`, side-effect warning, and finalization status.
|
|
90
|
+
|
|
91
|
+
Release, expiry, close, session replacement, reload, and shutdown abort owned work and terminate the process group until captured streams close.
|
|
92
|
+
|
|
93
|
+
Extension UI requests fail closed in v1.
|
|
94
|
+
|
|
95
|
+
## Resources and tools
|
|
96
|
+
|
|
97
|
+
RPC v1 supports Pi built-in tools only.
|
|
98
|
+
|
|
99
|
+
Child extensions stay disabled to prevent recursive `pi-subagents` loading and duplicate extension side effects.
|
|
100
|
+
|
|
101
|
+
Custom or extension tools fail before RPC child creation with a subprocess recommendation.
|
|
102
|
+
|
|
103
|
+
The selected cwd, project-trust decision, role prompt, model, thinking level, context, mailbox input, execution budgets, recursion depth, and output bounds retain their existing owners.
|
|
104
|
+
|
|
105
|
+
`subagent_spawn.timeoutMs`, `idleTimeoutMs`, `maxTurns`, and `maxToolCalls` are retained as agent defaults, while the same fields on `subagent_send` override only one follow-up turn.
|
|
106
|
+
|
|
107
|
+
RPC session-file persistence stays disabled because `AgentPersistence` owns sanitized logical recovery records.
|
|
108
|
+
|
|
109
|
+
A restored record starts no process until an explicit follow-up arrives.
|
|
110
|
+
|
|
111
|
+
Its first new RPC turn seeds bounded sanitized parent context and logical history exactly once.
|
|
112
|
+
|
|
113
|
+
## Automatic selection
|
|
114
|
+
|
|
115
|
+
`stateful.transport: "auto"` selects exactly one transport before child creation.
|
|
116
|
+
|
|
117
|
+
Read-only built-in tool sets select `in-process` for the lowest startup overhead.
|
|
118
|
+
|
|
119
|
+
The current built-in `explorer` default uses only `read`, `grep`, `find`, and `ls`, so it remains eligible for this route.
|
|
120
|
+
|
|
121
|
+
Write-capable built-in tool sets select `rpc` for a persistent separate process.
|
|
122
|
+
|
|
123
|
+
Extension or custom tools select the existing fresh `subprocess` path.
|
|
124
|
+
|
|
125
|
+
The selection remains fixed for the retained agent's current runtime lifetime.
|
|
126
|
+
|
|
127
|
+
A restored inert record is preflighted again on its first explicit follow-up.
|
|
128
|
+
|
|
129
|
+
No startup or post-acceptance failure triggers automatic fallback.
|
|
130
|
+
|
|
131
|
+
## Execution defaults
|
|
132
|
+
|
|
133
|
+
Fast, Balanced, and Deep execution profiles were removed.
|
|
134
|
+
|
|
135
|
+
The built-in `explorer` defaults to `low` thinking for bounded read-only exploration.
|
|
136
|
+
|
|
137
|
+
The built-in `worker` inherits model and thinking unless a caller, frontmatter, or per-agent setting selects a value.
|
|
138
|
+
|
|
139
|
+
Execution defaults do not change tools, transport, completion delivery, parent context, or explicit tool-call limits.
|
|
140
|
+
|
|
141
|
+
## Measurement
|
|
142
|
+
|
|
143
|
+
Run `just benchmark-subagents` for serial offline startup and retained state-command measurements.
|
|
144
|
+
|
|
145
|
+
The benchmark makes no provider request and therefore measures transport overhead rather than model quality or latency.
|
|
146
|
+
|
|
147
|
+
A provider-backed smoke is optional and must stop after one clear external quota, credential, or entitlement failure.
|
|
148
|
+
|
|
149
|
+
A seven-sample isolated-agent run on 2026-08-09 recorded 27.728 ms median deterministic fresh subprocess turn overhead with 0.782 ms MAD, 0.073 ms first retained RPC turn with 0.006 ms MAD, 0.037 ms retained RPC follow-up with 0.004 ms MAD, 445.631 ms real Pi RPC readiness with 9.765 ms MAD, 0.893 ms retained real Pi RPC `get_state` with 0.036 ms MAD, 3.759 ms in-process session creation with 0.198 ms MAD, and 0.001 ms retained in-process state access with 0.000 ms MAD.
|
|
150
|
+
|
|
151
|
+
The deterministic turn measurements use a fake Pi while the readiness and SDK measurements use an isolated real Pi installation without credentials.
|
|
152
|
+
|
|
153
|
+
The measurement supports retained transports as startup-overhead improvements without claiming provider-turn latency or quality.
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# pi-subagents Architecture Diagrams
|
|
2
|
+
|
|
3
|
+
These diagrams describe the main `pi-subagents` components, detached-agent lifecycle, transport selection, and verified workflow.
|
|
4
|
+
|
|
5
|
+
## Overall architecture
|
|
6
|
+
|
|
7
|
+
```mermaid
|
|
8
|
+
flowchart TB
|
|
9
|
+
Root["Main Pi Agent<br/>Planning, integration, verification, and final answer"]
|
|
10
|
+
Extension["pi-subagents Extension"]
|
|
11
|
+
Settings["User Settings<br/>pi-subagents.json"]
|
|
12
|
+
Catalog["Agent Catalog<br/>built-in / user / project"]
|
|
13
|
+
UI["/subagents Manager<br/>pi-tui-kit"]
|
|
14
|
+
|
|
15
|
+
Root --> Extension
|
|
16
|
+
Settings --> Extension
|
|
17
|
+
Catalog --> Extension
|
|
18
|
+
UI <--> Extension
|
|
19
|
+
|
|
20
|
+
subgraph Surfaces["Tool Surfaces"]
|
|
21
|
+
Blocking["subagent<br/>Blocking workflows"]
|
|
22
|
+
Consult["subagent_consult<br/>Synchronous read-only consultation"]
|
|
23
|
+
Stateful["Detached lifecycle<br/>spawn / send / manage / mailbox"]
|
|
24
|
+
Inspect["subagent_inspect<br/>Read-only diagnostics"]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Extension --> Blocking
|
|
28
|
+
Extension --> Consult
|
|
29
|
+
Extension --> Stateful
|
|
30
|
+
Extension --> Inspect
|
|
31
|
+
|
|
32
|
+
Blocking --> BlockingExecution["Blocking Execution<br/>single / parallel / chain / workflow / panel"]
|
|
33
|
+
Consult --> ConsultPolicy["Read-only tool intersection<br/>read / grep / find / ls"]
|
|
34
|
+
Stateful --> Registry["Agent Registry<br/>queue / generations / hierarchy"]
|
|
35
|
+
Inspect --> Snapshots["Safe projections<br/>runs / workflows / models / status"]
|
|
36
|
+
|
|
37
|
+
Registry --> Persistence["Persistent State and Completion Outbox"]
|
|
38
|
+
Registry --> TransportSelector["Transport Selector"]
|
|
39
|
+
BlockingExecution --> Runner["Subprocess Runner"]
|
|
40
|
+
ConsultPolicy --> Runner
|
|
41
|
+
|
|
42
|
+
TransportSelector --> InProcess["In-process<br/>Low startup overhead"]
|
|
43
|
+
TransportSelector --> RPC["Retained RPC process<br/>Process isolation and retained history"]
|
|
44
|
+
TransportSelector --> Subprocess["Fresh subprocess<br/>Custom-tool compatibility"]
|
|
45
|
+
|
|
46
|
+
Registry --> Delivery["Completion Routing"]
|
|
47
|
+
Delivery --> Root
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Detached-agent execution and completion delivery
|
|
51
|
+
|
|
52
|
+
```mermaid
|
|
53
|
+
sequenceDiagram
|
|
54
|
+
participant R as Root Agent
|
|
55
|
+
participant E as Extension
|
|
56
|
+
participant P as Policy / Preflight
|
|
57
|
+
participant G as Agent Registry
|
|
58
|
+
participant T as Transport
|
|
59
|
+
participant S as Persistent State
|
|
60
|
+
participant D as Completion Broker
|
|
61
|
+
|
|
62
|
+
R->>E: subagent_spawn(task, contract, budgets)
|
|
63
|
+
E->>P: Check cwd, trust, agent scope, and capacity
|
|
64
|
+
P-->>E: Approved execution plan
|
|
65
|
+
E->>G: Create agent, generation, and runId
|
|
66
|
+
G->>S: Persist starting / queued state
|
|
67
|
+
E-->>R: Immediately return agentId and taskPath
|
|
68
|
+
|
|
69
|
+
Note over R: Root continues non-overlapping local work
|
|
70
|
+
|
|
71
|
+
G->>T: runTurn() when capacity is available
|
|
72
|
+
T-->>G: Bounded progress / telemetry
|
|
73
|
+
T-->>G: Terminal outcome
|
|
74
|
+
|
|
75
|
+
G->>G: Classify completed / failed / blocked / interrupted
|
|
76
|
+
G->>G: Create completionId and outbox record
|
|
77
|
+
G->>S: Persist terminal state and completion first
|
|
78
|
+
S-->>G: Durable
|
|
79
|
+
|
|
80
|
+
G->>D: Route to the direct parent or nearest live ancestor
|
|
81
|
+
|
|
82
|
+
alt next-turn
|
|
83
|
+
D-->>R: Steer without waking an idle root
|
|
84
|
+
else auto-resume
|
|
85
|
+
D-->>R: Trigger a synthesis turn after the root settles
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
R->>E: subagent_send(agentId, follow-up)
|
|
89
|
+
E->>G: Start a new generation while retaining agent history
|
|
90
|
+
G->>T: Execute the follow-up
|
|
91
|
+
|
|
92
|
+
R->>E: subagent_manage(close)
|
|
93
|
+
E->>G: Release descendants child-first
|
|
94
|
+
G->>T: Shutdown / release
|
|
95
|
+
G->>S: Update or remove retained state
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The system persists each completion before notifying its parent so that a process interruption does not permanently lose the result.
|
|
99
|
+
|
|
100
|
+
## Automatic transport selection
|
|
101
|
+
|
|
102
|
+
```mermaid
|
|
103
|
+
flowchart TD
|
|
104
|
+
Start["Create a detached agent"]
|
|
105
|
+
Explicit{"Was transport explicitly selected?"}
|
|
106
|
+
UseExplicit["Use the selected transport"]
|
|
107
|
+
BuiltIn{"Are all effective tools<br/>Pi built-in tools?"}
|
|
108
|
+
ReadOnly{"Is the tool set read-only?"}
|
|
109
|
+
InProcess["in-process<br/>Retained SDK session"]
|
|
110
|
+
RPC["rpc<br/>Retained independent Pi process"]
|
|
111
|
+
Subprocess["subprocess<br/>Fresh process for each turn"]
|
|
112
|
+
Run["Create the child and accept the prompt"]
|
|
113
|
+
Failure["Startup or execution failure<br/>Report failure without switching transport"]
|
|
114
|
+
Note["After a child is created or may have accepted work,<br/>automatic fallback is forbidden to prevent duplicate side effects"]
|
|
115
|
+
|
|
116
|
+
Start --> Explicit
|
|
117
|
+
Explicit -- "Yes" --> UseExplicit
|
|
118
|
+
Explicit -- "No, use auto" --> BuiltIn
|
|
119
|
+
|
|
120
|
+
BuiltIn -- "No, includes extension/custom tools" --> Subprocess
|
|
121
|
+
BuiltIn -- "Yes" --> ReadOnly
|
|
122
|
+
|
|
123
|
+
ReadOnly -- "Yes" --> InProcess
|
|
124
|
+
ReadOnly -- "No, includes bash/edit/write" --> RPC
|
|
125
|
+
|
|
126
|
+
UseExplicit --> Run
|
|
127
|
+
InProcess --> Run
|
|
128
|
+
RPC --> Run
|
|
129
|
+
Subprocess --> Run
|
|
130
|
+
Run --> Failure
|
|
131
|
+
Failure -.-> Note
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Read-only classification is based on effective tool permissions rather than promises written in the task prompt.
|
|
135
|
+
|
|
136
|
+
## Verified workflow and acceptance barrier
|
|
137
|
+
|
|
138
|
+
```mermaid
|
|
139
|
+
flowchart TD
|
|
140
|
+
Request["Caller-authored workflow"]
|
|
141
|
+
Validate["Validate DAG, contracts, dependencies, and budgets"]
|
|
142
|
+
Preflight["Preflight every cwd, agent, scope, and authority"]
|
|
143
|
+
Ledger["Create the WorkItem Ledger"]
|
|
144
|
+
Scheduler["Adaptive Scheduler<br/>dependency / capacity / budget / conflict"]
|
|
145
|
+
Worker["Execute Worker"]
|
|
146
|
+
Result["Parse structured-v2<br/>Record artifacts and tree identity"]
|
|
147
|
+
NeedsVerify{"Is independent verification required?"}
|
|
148
|
+
OrdinaryDone["Complete the ordinary workflow item"]
|
|
149
|
+
|
|
150
|
+
Checks["Run executor-owned checks<br/>in a disposable worktree"]
|
|
151
|
+
ChecksPass{"Did every check pass?"}
|
|
152
|
+
Verifier["Independent read-only Verifier<br/>Different agent and generation"]
|
|
153
|
+
Receipt["Create verification receipt<br/>Bind patch, tree, plan, and evidence"]
|
|
154
|
+
Decision{"Verifier decision"}
|
|
155
|
+
|
|
156
|
+
Accept["Acceptance Controller<br/>Mark accepted"]
|
|
157
|
+
Rework{"Is rework capacity available?"}
|
|
158
|
+
Rotate["Revoke old grants<br/>Rotate worker/verifier generations"]
|
|
159
|
+
Reject["rejected / non-success"]
|
|
160
|
+
Finish["Workflow terminal result"]
|
|
161
|
+
|
|
162
|
+
Request --> Validate --> Preflight --> Ledger --> Scheduler
|
|
163
|
+
Scheduler --> Worker --> Result --> NeedsVerify
|
|
164
|
+
|
|
165
|
+
NeedsVerify -- "No" --> OrdinaryDone --> Finish
|
|
166
|
+
NeedsVerify -- "Yes" --> Checks
|
|
167
|
+
Checks --> ChecksPass
|
|
168
|
+
ChecksPass -- "No" --> Reject
|
|
169
|
+
ChecksPass -- "Yes" --> Verifier
|
|
170
|
+
Verifier --> Receipt --> Decision
|
|
171
|
+
|
|
172
|
+
Decision -- "accepted" --> Accept --> Finish
|
|
173
|
+
Decision -- "rework" --> Rework
|
|
174
|
+
Decision -- "rejected" --> Reject
|
|
175
|
+
|
|
176
|
+
Rework -- "Yes, at most once" --> Rotate --> Scheduler
|
|
177
|
+
Rework -- "No" --> Reject
|
|
178
|
+
Reject --> Finish
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
A worker's own claim that verification passed cannot move acceptance from `pending` to `accepted`.
|
|
182
|
+
|
|
183
|
+
Only executor-owned checks, an independent verifier, and the acceptance controller can complete acceptance.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@narumitw/pi-subagents",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "Pi extension for delegating work to specialized isolated subagents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"files": [
|
|
17
17
|
"src",
|
|
18
18
|
"dist",
|
|
19
|
+
"docs",
|
|
19
20
|
"README.md",
|
|
20
21
|
"LICENSE"
|
|
21
22
|
],
|
|
@@ -42,17 +43,17 @@
|
|
|
42
43
|
"typebox": "*"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
|
-
"@biomejs/biome": "2.5.
|
|
46
|
-
"@earendil-works/pi-agent-core": "0.84.
|
|
47
|
-
"@earendil-works/pi-ai": "0.84.
|
|
48
|
-
"@earendil-works/pi-coding-agent": "0.84.
|
|
49
|
-
"@earendil-works/pi-tui": "0.84.
|
|
46
|
+
"@biomejs/biome": "2.5.10",
|
|
47
|
+
"@earendil-works/pi-agent-core": "0.84.3",
|
|
48
|
+
"@earendil-works/pi-ai": "0.84.3",
|
|
49
|
+
"@earendil-works/pi-coding-agent": "0.84.3",
|
|
50
|
+
"@earendil-works/pi-tui": "0.84.3",
|
|
50
51
|
"esbuild": "0.28.2",
|
|
51
|
-
"typebox": "1.3.
|
|
52
|
+
"typebox": "1.3.18",
|
|
52
53
|
"typescript": "7.0.2"
|
|
53
54
|
},
|
|
54
55
|
"dependencies": {
|
|
55
|
-
"@narumitw/pi-tui-kit": "^0.
|
|
56
|
+
"@narumitw/pi-tui-kit": "^0.58.0",
|
|
56
57
|
"proper-lockfile": "^4.1.2"
|
|
57
58
|
},
|
|
58
59
|
"repository": {
|
package/src/agents/types.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { AgentCapabilityManifest } from "../capabilities.js";
|
|
6
|
+
import type { SubagentUsageRecordingSettings } from "../usage-recording-config.js";
|
|
6
7
|
|
|
7
8
|
export const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"] as const;
|
|
8
9
|
|
|
@@ -95,4 +96,5 @@ export interface SubagentSettings {
|
|
|
95
96
|
stateful?: SubagentRuntimeSettings;
|
|
96
97
|
consult?: SubagentConsultSettings;
|
|
97
98
|
cwdPolicy?: SubagentCwdPolicySettings;
|
|
99
|
+
usageRecording?: SubagentUsageRecordingSettings;
|
|
98
100
|
}
|