@narumitw/pi-subagents 2.0.5 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/README.md +152 -50
  2. package/dist/chunks/{auto-transport-SY2VHUFH.ts → auto-transport-FUUKFDIG.ts} +6 -6
  3. package/dist/chunks/{capability-grant-CGEWOEKE.ts → capability-grant-PR72SWWS.ts} +4 -4
  4. package/dist/chunks/{chunk-DPPVEQAM.ts → chunk-4AQSF7AS.ts} +1 -1
  5. package/dist/chunks/chunk-4AQSF7AS.ts.map +7 -0
  6. package/dist/chunks/chunk-6H6TBBED.ts +108 -0
  7. package/dist/chunks/chunk-6H6TBBED.ts.map +7 -0
  8. package/dist/chunks/{chunk-DSOOH73Y.ts → chunk-7AAJEUSL.ts} +3 -3
  9. package/dist/chunks/{chunk-DSOOH73Y.ts.map → chunk-7AAJEUSL.ts.map} +2 -2
  10. package/dist/chunks/{chunk-7QPPBBXZ.ts → chunk-D4CR7T73.ts} +21 -3
  11. package/dist/chunks/chunk-D4CR7T73.ts.map +7 -0
  12. package/dist/chunks/{chunk-434NII74.ts → chunk-DIHBUR2E.ts} +54 -8
  13. package/dist/chunks/chunk-DIHBUR2E.ts.map +7 -0
  14. package/dist/chunks/{chunk-NIF42QMF.ts → chunk-FEVPWRMU.ts} +7 -4
  15. package/dist/chunks/chunk-FEVPWRMU.ts.map +7 -0
  16. package/dist/chunks/{chunk-YBUWBRF7.ts → chunk-FXI45N3J.ts} +5 -5
  17. package/dist/chunks/{chunk-S2IWVK3J.ts → chunk-ILEQ27AL.ts} +3 -2
  18. package/dist/chunks/chunk-ILEQ27AL.ts.map +7 -0
  19. package/dist/chunks/{chunk-DQMN4OYM.ts → chunk-ITVWPNU4.ts} +12 -106
  20. package/dist/chunks/chunk-ITVWPNU4.ts.map +7 -0
  21. package/dist/chunks/{chunk-QDVGH2X7.ts → chunk-IWC32VPY.ts} +2 -1
  22. package/dist/chunks/{chunk-QDVGH2X7.ts.map → chunk-IWC32VPY.ts.map} +2 -2
  23. package/dist/chunks/{chunk-I2FAK44T.ts → chunk-JSZIP73U.ts} +48 -10
  24. package/dist/chunks/chunk-JSZIP73U.ts.map +7 -0
  25. package/dist/chunks/{chunk-ZHTNCZIA.ts → chunk-JU6LUNLP.ts} +2 -2
  26. package/dist/chunks/{chunk-PSK43Y6A.ts → chunk-LASD73CM.ts} +2 -2
  27. package/dist/chunks/{chunk-C4L6P266.ts → chunk-LEOYDZI3.ts} +1 -1
  28. package/dist/chunks/{chunk-C4L6P266.ts.map → chunk-LEOYDZI3.ts.map} +2 -2
  29. package/dist/chunks/{chunk-H3BFJ7HJ.ts → chunk-LL4LP2T7.ts} +5 -5
  30. package/dist/chunks/chunk-N2T5IN4X.ts +18 -0
  31. package/dist/chunks/chunk-N2T5IN4X.ts.map +7 -0
  32. package/dist/chunks/{chunk-G3RSMSXJ.ts → chunk-NTRPLF46.ts} +1 -1
  33. package/dist/chunks/chunk-NTRPLF46.ts.map +7 -0
  34. package/dist/chunks/{chunk-CBP76ARQ.ts → chunk-PABJJYP6.ts} +174 -47
  35. package/dist/chunks/chunk-PABJJYP6.ts.map +7 -0
  36. package/dist/chunks/{chunk-EFBPISNT.ts → chunk-PBZMBTNJ.ts} +104 -103
  37. package/dist/chunks/chunk-PBZMBTNJ.ts.map +7 -0
  38. package/dist/chunks/{chunk-SCZ33MYW.ts → chunk-PGLSFLYW.ts} +2 -2
  39. package/dist/chunks/{chunk-O4VO6JUJ.ts → chunk-TM2R67J3.ts} +3 -3
  40. package/dist/chunks/{chunk-QBORTI4W.ts → chunk-TMZRHIIK.ts} +32 -3
  41. package/dist/chunks/chunk-TMZRHIIK.ts.map +7 -0
  42. package/dist/chunks/chunk-TZ34IQ3M.ts +59 -0
  43. package/dist/chunks/chunk-TZ34IQ3M.ts.map +7 -0
  44. package/dist/chunks/chunk-VBDGNNLM.ts +214 -0
  45. package/dist/chunks/chunk-VBDGNNLM.ts.map +7 -0
  46. package/dist/chunks/{chunk-7OBINKFM.ts → chunk-VDG7LTYE.ts} +11 -11
  47. package/dist/chunks/chunk-VDG7LTYE.ts.map +7 -0
  48. package/dist/chunks/{chunk-AEUYS7JC.ts → chunk-X4NMONPE.ts} +1 -1
  49. package/dist/chunks/chunk-X4NMONPE.ts.map +7 -0
  50. package/dist/chunks/{chunk-HKC4ES4B.ts → chunk-YPJEN6NU.ts} +2 -2
  51. package/dist/chunks/{completion-delivery-YPOWSSV3.ts → completion-delivery-JVLNQRWX.ts} +5 -4
  52. package/dist/chunks/{config-status-J4GPWP46.ts → config-status-FKGDECZ3.ts} +7 -6
  53. package/dist/chunks/{config-ui-2YUCUEBM.ts → config-ui-DDKERQHI.ts} +297 -231
  54. package/dist/chunks/config-ui-DDKERQHI.ts.map +7 -0
  55. package/dist/chunks/{consult-IV7UBNQQ.ts → consult-PQ6PRAKC.ts} +14 -13
  56. package/dist/chunks/consult-PQ6PRAKC.ts.map +7 -0
  57. package/dist/chunks/{create-stateful-transport-ZP3IXNV3.ts → create-stateful-transport-JWC2EFYL.ts} +6 -6
  58. package/dist/chunks/{delegation-contract-WJPT4FVS.ts → delegation-contract-LA56I5DT.ts} +2 -2
  59. package/dist/chunks/{discovery-K25T3SH4.ts → discovery-MIFB2U4Y.ts} +3 -3
  60. package/dist/chunks/{execution-LA7HN5YF.ts → execution-Q2JZLKJA.ts} +19 -16
  61. package/dist/chunks/execution-Q2JZLKJA.ts.map +7 -0
  62. package/dist/chunks/{in-process-transport-4RF3J6XK.ts → in-process-transport-HJ6TZXC3.ts} +9 -9
  63. package/dist/chunks/{inspect-XV2QALMR.ts → inspect-UH2TKH6E.ts} +25 -10
  64. package/dist/chunks/inspect-UH2TKH6E.ts.map +7 -0
  65. package/dist/chunks/{persistence-VSGXAW4P.ts → persistence-XHPJBZL7.ts} +11 -7
  66. package/dist/chunks/persistence-XHPJBZL7.ts.map +7 -0
  67. package/dist/chunks/{registry-E6XPJB7L.ts → registry-XDXPECWF.ts} +136 -15
  68. package/dist/chunks/registry-XDXPECWF.ts.map +7 -0
  69. package/dist/chunks/{retained-semantic-state-7WXSGRJU.ts → retained-semantic-state-GM75FZGE.ts} +3 -3
  70. package/dist/chunks/{rpc-transport-NEHBHWX4.ts → rpc-transport-7R7DVCEB.ts} +12 -16
  71. package/dist/chunks/rpc-transport-7R7DVCEB.ts.map +7 -0
  72. package/dist/chunks/{spawn-idempotency-QGHO2WKC.ts → spawn-idempotency-BNHOSMZW.ts} +2 -2
  73. package/dist/chunks/{subprocess-transport-NSHOGDC4.ts → subprocess-transport-VHZJRBTW.ts} +15 -14
  74. package/dist/chunks/subprocess-transport-VHZJRBTW.ts.map +7 -0
  75. package/dist/chunks/usage-recording-store-CW3EH2SZ.ts +164 -0
  76. package/dist/chunks/usage-recording-store-CW3EH2SZ.ts.map +7 -0
  77. package/dist/index.ts +427 -30
  78. package/dist/index.ts.map +3 -3
  79. package/docs/async-runtime-protocol.md +69 -0
  80. package/docs/implementation-notes/pi-subagents-capability-matrix.md +62 -0
  81. package/docs/implementation-notes/pi-subagents-current-direction.md +99 -0
  82. package/docs/implementation-notes/pi-subagents-rpc-v1.md +153 -0
  83. package/docs/pi-subagents-diagrams.md +183 -0
  84. package/package.json +9 -8
  85. package/src/agents/types.ts +2 -0
  86. package/src/async-subagent-benchmark.ts +532 -0
  87. package/src/completion-delivery.ts +71 -4
  88. package/src/completion-render.ts +1 -0
  89. package/src/completion-requirement.ts +308 -0
  90. package/src/config-registration.ts +5 -5
  91. package/src/config-status.ts +66 -70
  92. package/src/config-ui.ts +244 -150
  93. package/src/consult-resources.ts +1 -1
  94. package/src/consult.ts +3 -8
  95. package/src/delegation-contract.ts +55 -9
  96. package/src/execution-plan.ts +1 -1
  97. package/src/execution-ui.ts +40 -29
  98. package/src/execution.ts +2 -3
  99. package/src/inspect.ts +24 -1
  100. package/src/orchestration-metrics.ts +1 -1
  101. package/src/panel-execution.ts +2 -3
  102. package/src/panel-failure.ts +1 -1
  103. package/src/panel-render.ts +1 -1
  104. package/src/parallel-limit-ui.ts +6 -5
  105. package/src/params.ts +2 -1
  106. package/src/persistence.ts +9 -0
  107. package/src/process-control.ts +43 -0
  108. package/src/registry-types.ts +5 -0
  109. package/src/registry.ts +162 -18
  110. package/src/render.ts +2 -1
  111. package/src/rpc-transport.ts +1 -1
  112. package/src/runner-outcome.ts +1 -1
  113. package/src/runner-result.ts +1 -1
  114. package/src/runner-types.ts +102 -0
  115. package/src/runner.ts +11 -192
  116. package/src/settings/inspection.ts +27 -0
  117. package/src/settings/schema.ts +9 -0
  118. package/src/settings-reader.ts +7 -0
  119. package/src/settings.ts +20 -0
  120. package/src/spawn-idempotency.ts +5 -0
  121. package/src/stateful-agent-view.ts +15 -19
  122. package/src/stateful-guidance.ts +14 -4
  123. package/src/stateful-limit-ui.ts +23 -20
  124. package/src/stateful-limits.ts +10 -10
  125. package/src/stateful-registration.ts +126 -9
  126. package/src/stateful-render.ts +27 -2
  127. package/src/subagent-details.ts +43 -0
  128. package/src/subagents-extension.ts +66 -8
  129. package/src/subagents.ts +2 -0
  130. package/src/subprocess-transport.ts +2 -1
  131. package/src/supervision.ts +2 -1
  132. package/src/timeout-finalization.ts +1 -1
  133. package/src/tool-schema-compatibility.ts +73 -0
  134. package/src/transport-types.ts +6 -0
  135. package/src/transport-ui.ts +18 -46
  136. package/src/usage-recording-config.ts +13 -0
  137. package/src/usage-recording-store.ts +183 -0
  138. package/src/usage-recording.ts +478 -0
  139. package/src/verification-harness.ts +1 -1
  140. package/src/workflow-ui.ts +17 -9
  141. package/dist/chunks/chunk-434NII74.ts.map +0 -7
  142. package/dist/chunks/chunk-7OBINKFM.ts.map +0 -7
  143. package/dist/chunks/chunk-7QPPBBXZ.ts.map +0 -7
  144. package/dist/chunks/chunk-AEUYS7JC.ts.map +0 -7
  145. package/dist/chunks/chunk-CBP76ARQ.ts.map +0 -7
  146. package/dist/chunks/chunk-DPPVEQAM.ts.map +0 -7
  147. package/dist/chunks/chunk-DQMN4OYM.ts.map +0 -7
  148. package/dist/chunks/chunk-EFBPISNT.ts.map +0 -7
  149. package/dist/chunks/chunk-G3RSMSXJ.ts.map +0 -7
  150. package/dist/chunks/chunk-I2FAK44T.ts.map +0 -7
  151. package/dist/chunks/chunk-NIF42QMF.ts.map +0 -7
  152. package/dist/chunks/chunk-QBORTI4W.ts.map +0 -7
  153. package/dist/chunks/chunk-S2IWVK3J.ts.map +0 -7
  154. package/dist/chunks/config-ui-2YUCUEBM.ts.map +0 -7
  155. package/dist/chunks/consult-IV7UBNQQ.ts.map +0 -7
  156. package/dist/chunks/execution-LA7HN5YF.ts.map +0 -7
  157. package/dist/chunks/inspect-XV2QALMR.ts.map +0 -7
  158. package/dist/chunks/persistence-VSGXAW4P.ts.map +0 -7
  159. package/dist/chunks/registry-E6XPJB7L.ts.map +0 -7
  160. package/dist/chunks/rpc-transport-NEHBHWX4.ts.map +0 -7
  161. package/dist/chunks/subprocess-transport-NSHOGDC4.ts.map +0 -7
  162. /package/dist/chunks/{auto-transport-SY2VHUFH.ts.map → auto-transport-FUUKFDIG.ts.map} +0 -0
  163. /package/dist/chunks/{capability-grant-CGEWOEKE.ts.map → capability-grant-PR72SWWS.ts.map} +0 -0
  164. /package/dist/chunks/{chunk-YBUWBRF7.ts.map → chunk-FXI45N3J.ts.map} +0 -0
  165. /package/dist/chunks/{chunk-ZHTNCZIA.ts.map → chunk-JU6LUNLP.ts.map} +0 -0
  166. /package/dist/chunks/{chunk-PSK43Y6A.ts.map → chunk-LASD73CM.ts.map} +0 -0
  167. /package/dist/chunks/{chunk-H3BFJ7HJ.ts.map → chunk-LL4LP2T7.ts.map} +0 -0
  168. /package/dist/chunks/{chunk-SCZ33MYW.ts.map → chunk-PGLSFLYW.ts.map} +0 -0
  169. /package/dist/chunks/{chunk-O4VO6JUJ.ts.map → chunk-TM2R67J3.ts.map} +0 -0
  170. /package/dist/chunks/{chunk-HKC4ES4B.ts.map → chunk-YPJEN6NU.ts.map} +0 -0
  171. /package/dist/chunks/{completion-delivery-YPOWSSV3.ts.map → completion-delivery-JVLNQRWX.ts.map} +0 -0
  172. /package/dist/chunks/{config-status-J4GPWP46.ts.map → config-status-FKGDECZ3.ts.map} +0 -0
  173. /package/dist/chunks/{create-stateful-transport-ZP3IXNV3.ts.map → create-stateful-transport-JWC2EFYL.ts.map} +0 -0
  174. /package/dist/chunks/{delegation-contract-WJPT4FVS.ts.map → delegation-contract-LA56I5DT.ts.map} +0 -0
  175. /package/dist/chunks/{discovery-K25T3SH4.ts.map → discovery-MIFB2U4Y.ts.map} +0 -0
  176. /package/dist/chunks/{in-process-transport-4RF3J6XK.ts.map → in-process-transport-HJ6TZXC3.ts.map} +0 -0
  177. /package/dist/chunks/{retained-semantic-state-7WXSGRJU.ts.map → retained-semantic-state-GM75FZGE.ts.map} +0 -0
  178. /package/dist/chunks/{spawn-idempotency-QGHO2WKC.ts.map → spawn-idempotency-BNHOSMZW.ts.map} +0 -0
@@ -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.0.5",
3
+ "version": "2.1.0",
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.9",
46
- "@earendil-works/pi-agent-core": "0.84.2",
47
- "@earendil-works/pi-ai": "0.84.2",
48
- "@earendil-works/pi-coding-agent": "0.84.2",
49
- "@earendil-works/pi-tui": "0.84.2",
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.16",
52
+ "typebox": "1.3.18",
52
53
  "typescript": "7.0.2"
53
54
  },
54
55
  "dependencies": {
55
- "@narumitw/pi-tui-kit": "^0.56.1",
56
+ "@narumitw/pi-tui-kit": "^0.58.0",
56
57
  "proper-lockfile": "^4.1.2"
57
58
  },
58
59
  "repository": {
@@ -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
  }