@narumitw/pi-subagents 2.0.1 → 2.0.2

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 (148) hide show
  1. package/README.md +21 -8
  2. package/dist/chunks/auto-transport-SY2VHUFH.ts +109 -0
  3. package/dist/chunks/auto-transport-SY2VHUFH.ts.map +7 -0
  4. package/dist/chunks/capability-grant-CGEWOEKE.ts +19 -0
  5. package/dist/chunks/capability-grant-CGEWOEKE.ts.map +7 -0
  6. package/dist/chunks/chunk-434NII74.ts +282 -0
  7. package/dist/chunks/chunk-434NII74.ts.map +7 -0
  8. package/dist/chunks/chunk-47SK2QYC.ts +56 -0
  9. package/dist/chunks/chunk-47SK2QYC.ts.map +7 -0
  10. package/dist/chunks/chunk-6KJ34M6S.ts +159 -0
  11. package/dist/chunks/chunk-6KJ34M6S.ts.map +7 -0
  12. package/dist/chunks/chunk-7OBINKFM.ts +80 -0
  13. package/dist/chunks/chunk-7OBINKFM.ts.map +7 -0
  14. package/dist/chunks/chunk-7QPPBBXZ.ts +335 -0
  15. package/dist/chunks/chunk-7QPPBBXZ.ts.map +7 -0
  16. package/dist/chunks/chunk-AEUYS7JC.ts +73 -0
  17. package/dist/chunks/chunk-AEUYS7JC.ts.map +7 -0
  18. package/dist/chunks/chunk-BFK2Z4ZF.ts +189 -0
  19. package/dist/chunks/chunk-BFK2Z4ZF.ts.map +7 -0
  20. package/dist/chunks/chunk-BOAXY55Y.ts +153 -0
  21. package/dist/chunks/chunk-BOAXY55Y.ts.map +7 -0
  22. package/dist/chunks/chunk-C4L6P266.ts +22 -0
  23. package/dist/chunks/chunk-C4L6P266.ts.map +7 -0
  24. package/dist/chunks/chunk-DPPVEQAM.ts +29 -0
  25. package/dist/chunks/chunk-DPPVEQAM.ts.map +7 -0
  26. package/dist/chunks/chunk-DQMN4OYM.ts +913 -0
  27. package/dist/chunks/chunk-DQMN4OYM.ts.map +7 -0
  28. package/dist/chunks/chunk-DSOOH73Y.ts +238 -0
  29. package/dist/chunks/chunk-DSOOH73Y.ts.map +7 -0
  30. package/dist/chunks/chunk-EFBPISNT.ts +421 -0
  31. package/dist/chunks/chunk-EFBPISNT.ts.map +7 -0
  32. package/dist/chunks/chunk-EWWXFU7N.ts +150 -0
  33. package/dist/chunks/chunk-EWWXFU7N.ts.map +7 -0
  34. package/dist/chunks/chunk-F4L2UVSK.ts +380 -0
  35. package/dist/chunks/chunk-F4L2UVSK.ts.map +7 -0
  36. package/dist/chunks/chunk-F5YWVHQX.ts +1543 -0
  37. package/dist/chunks/chunk-F5YWVHQX.ts.map +7 -0
  38. package/dist/chunks/chunk-G3RSMSXJ.ts +63 -0
  39. package/dist/chunks/chunk-G3RSMSXJ.ts.map +7 -0
  40. package/dist/chunks/chunk-G6VZTCFH.ts +70 -0
  41. package/dist/chunks/chunk-G6VZTCFH.ts.map +7 -0
  42. package/dist/chunks/chunk-H3FP6DLR.ts +160 -0
  43. package/dist/chunks/chunk-H3FP6DLR.ts.map +7 -0
  44. package/dist/chunks/chunk-HA36LPCO.ts +130 -0
  45. package/dist/chunks/chunk-HA36LPCO.ts.map +7 -0
  46. package/dist/chunks/chunk-HKC4ES4B.ts +65 -0
  47. package/dist/chunks/chunk-HKC4ES4B.ts.map +7 -0
  48. package/dist/chunks/chunk-HOP5FXDT.ts +27 -0
  49. package/dist/chunks/chunk-HOP5FXDT.ts.map +7 -0
  50. package/dist/chunks/chunk-I2FAK44T.ts +324 -0
  51. package/dist/chunks/chunk-I2FAK44T.ts.map +7 -0
  52. package/dist/chunks/chunk-IGAMVWFN.ts +139 -0
  53. package/dist/chunks/chunk-IGAMVWFN.ts.map +7 -0
  54. package/dist/chunks/chunk-KMGKCEO4.ts +38 -0
  55. package/dist/chunks/chunk-KMGKCEO4.ts.map +7 -0
  56. package/dist/chunks/chunk-N7BLVXKK.ts +73 -0
  57. package/dist/chunks/chunk-N7BLVXKK.ts.map +7 -0
  58. package/dist/chunks/chunk-NIF42QMF.ts +297 -0
  59. package/dist/chunks/chunk-NIF42QMF.ts.map +7 -0
  60. package/dist/chunks/chunk-O4VO6JUJ.ts +52 -0
  61. package/dist/chunks/chunk-O4VO6JUJ.ts.map +7 -0
  62. package/dist/chunks/chunk-ONDTY4EL.ts +91 -0
  63. package/dist/chunks/chunk-ONDTY4EL.ts.map +7 -0
  64. package/dist/chunks/chunk-OVPHFGKO.ts +1769 -0
  65. package/dist/chunks/chunk-OVPHFGKO.ts.map +7 -0
  66. package/dist/chunks/chunk-P7OH4XMF.ts +60 -0
  67. package/dist/chunks/chunk-P7OH4XMF.ts.map +7 -0
  68. package/dist/chunks/chunk-PSK43Y6A.ts +339 -0
  69. package/dist/chunks/chunk-PSK43Y6A.ts.map +7 -0
  70. package/dist/chunks/chunk-QBORTI4W.ts +468 -0
  71. package/dist/chunks/chunk-QBORTI4W.ts.map +7 -0
  72. package/dist/chunks/chunk-QDVGH2X7.ts +171 -0
  73. package/dist/chunks/chunk-QDVGH2X7.ts.map +7 -0
  74. package/dist/chunks/chunk-RHRQMT7Q.ts +490 -0
  75. package/dist/chunks/chunk-RHRQMT7Q.ts.map +7 -0
  76. package/dist/chunks/chunk-RRR66UWR.ts +28 -0
  77. package/dist/chunks/chunk-RRR66UWR.ts.map +7 -0
  78. package/dist/chunks/chunk-RSUXZD6S.ts +275 -0
  79. package/dist/chunks/chunk-RSUXZD6S.ts.map +7 -0
  80. package/dist/chunks/chunk-RTCVYIZA.ts +221 -0
  81. package/dist/chunks/chunk-RTCVYIZA.ts.map +7 -0
  82. package/dist/chunks/chunk-S2IWVK3J.ts +44 -0
  83. package/dist/chunks/chunk-S2IWVK3J.ts.map +7 -0
  84. package/dist/chunks/chunk-SCZ33MYW.ts +52 -0
  85. package/dist/chunks/chunk-SCZ33MYW.ts.map +7 -0
  86. package/dist/chunks/chunk-SWGQLFSD.ts +60 -0
  87. package/dist/chunks/chunk-SWGQLFSD.ts.map +7 -0
  88. package/dist/chunks/chunk-UMBPMVJW.ts +22 -0
  89. package/dist/chunks/chunk-UMBPMVJW.ts.map +7 -0
  90. package/dist/chunks/chunk-UVFVHIOP.ts +735 -0
  91. package/dist/chunks/chunk-UVFVHIOP.ts.map +7 -0
  92. package/dist/chunks/completion-delivery-YPOWSSV3.ts +16 -0
  93. package/dist/chunks/completion-delivery-YPOWSSV3.ts.map +7 -0
  94. package/dist/chunks/config-status-J4GPWP46.ts +34 -0
  95. package/dist/chunks/config-status-J4GPWP46.ts.map +7 -0
  96. package/dist/chunks/config-ui-3IBMHTQB.ts +1146 -0
  97. package/dist/chunks/config-ui-3IBMHTQB.ts.map +7 -0
  98. package/dist/chunks/consult-NYXVDN5G.ts +518 -0
  99. package/dist/chunks/consult-NYXVDN5G.ts.map +7 -0
  100. package/dist/chunks/context-QDKLVQXE.ts +11 -0
  101. package/dist/chunks/context-QDKLVQXE.ts.map +7 -0
  102. package/dist/chunks/create-stateful-transport-4WKZHRSI.ts +130 -0
  103. package/dist/chunks/create-stateful-transport-4WKZHRSI.ts.map +7 -0
  104. package/dist/chunks/cwd-policy-NB6XZ5GF.ts +17 -0
  105. package/dist/chunks/cwd-policy-NB6XZ5GF.ts.map +7 -0
  106. package/dist/chunks/delegation-contract-WJPT4FVS.ts +24 -0
  107. package/dist/chunks/delegation-contract-WJPT4FVS.ts.map +7 -0
  108. package/dist/chunks/discovery-K25T3SH4.ts +12 -0
  109. package/dist/chunks/discovery-K25T3SH4.ts.map +7 -0
  110. package/dist/chunks/execution-DS2DEIQZ.ts +4034 -0
  111. package/dist/chunks/execution-DS2DEIQZ.ts.map +7 -0
  112. package/dist/chunks/in-process-transport-TEYAWSEC.ts +38 -0
  113. package/dist/chunks/in-process-transport-TEYAWSEC.ts.map +7 -0
  114. package/dist/chunks/inspect-UOQQ3KNL.ts +619 -0
  115. package/dist/chunks/inspect-UOQQ3KNL.ts.map +7 -0
  116. package/dist/chunks/peer-communication-KL36Z6CO.ts +294 -0
  117. package/dist/chunks/peer-communication-KL36Z6CO.ts.map +7 -0
  118. package/dist/chunks/persistence-VSGXAW4P.ts +344 -0
  119. package/dist/chunks/persistence-VSGXAW4P.ts.map +7 -0
  120. package/dist/chunks/registry-E6XPJB7L.ts +1324 -0
  121. package/dist/chunks/registry-E6XPJB7L.ts.map +7 -0
  122. package/dist/chunks/retained-semantic-state-7WXSGRJU.ts +81 -0
  123. package/dist/chunks/retained-semantic-state-7WXSGRJU.ts.map +7 -0
  124. package/dist/chunks/rpc-transport-Y6LA5BOP.ts +1154 -0
  125. package/dist/chunks/rpc-transport-Y6LA5BOP.ts.map +7 -0
  126. package/dist/chunks/runtime-policy-5YELCOVC.ts +15 -0
  127. package/dist/chunks/runtime-policy-5YELCOVC.ts.map +7 -0
  128. package/dist/chunks/semantic-snapshot-WPJ3UAFW.ts +19 -0
  129. package/dist/chunks/semantic-snapshot-WPJ3UAFW.ts.map +7 -0
  130. package/dist/chunks/spawn-idempotency-QGHO2WKC.ts +13 -0
  131. package/dist/chunks/spawn-idempotency-QGHO2WKC.ts.map +7 -0
  132. package/dist/chunks/stateful-lifecycle-JAR6K55H.ts +15 -0
  133. package/dist/chunks/stateful-lifecycle-JAR6K55H.ts.map +7 -0
  134. package/dist/chunks/subprocess-transport-C2XVR25R.ts +158 -0
  135. package/dist/chunks/subprocess-transport-C2XVR25R.ts.map +7 -0
  136. package/dist/chunks/workspace-WDKLN72J.ts +11 -0
  137. package/dist/chunks/workspace-WDKLN72J.ts.map +7 -0
  138. package/dist/index.ts +1057 -0
  139. package/dist/index.ts.map +7 -0
  140. package/package.json +7 -3
  141. package/src/index.ts +1 -1
  142. package/src/settings-reader.ts +208 -0
  143. package/src/settings.ts +22 -187
  144. package/src/stateful-registration.ts +1230 -0
  145. package/src/stateful-safety.ts +1 -1
  146. package/src/stateful.ts +2 -1234
  147. package/src/subagents-extension.ts +307 -0
  148. package/src/subagents.ts +1 -308
package/README.md CHANGED
@@ -12,6 +12,7 @@ One ordinary async worker requires named non-overlapping main-agent work that st
12
12
 
13
13
  ## ✨ Features
14
14
 
15
+ - Loads a generated split TypeScript runtime through Pi's Jiti loader while preserving first-use execution, UI, inspection, and transport chunks.
15
16
  - Keeps all delegation methods as the compatibility default while recommending async-only for a smaller responsive surface.
16
17
  - Adds `subagent_inspect` for bounded metadata without child launch, mailbox-content access, acknowledgement, or mutation.
17
18
  - Adds `subagent_consult` for one synchronous ephemeral child constrained to built-in `read`, `grep`, `find`, and `ls` tools (or a narrower agent allow-list).
@@ -53,12 +54,16 @@ Try without installing permanently:
53
54
  pi -e npm:@narumitw/pi-subagents
54
55
  ```
55
56
 
56
- Try this package locally from the repository root:
57
+ Build and try this package locally from the repository root:
57
58
 
58
59
  ```bash
59
- pi -e ./packages/pi-subagents
60
+ just try subagents
60
61
  ```
61
62
 
63
+ The published package declares `dist/index.ts`, and `just try` runs its build before loading the package directory.
64
+ For an explicit local flow, run `npm --workspace @narumitw/pi-subagents run build` before `pi -e ./packages/pi-subagents`.
65
+ An unbuilt checkout intentionally has no declared generated entrypoint.
66
+
62
67
  ## 🚀 Quick start
63
68
 
64
69
  For normal async-first use, run `/subagents`, choose **Change delegation**, select **Async only · Recommended**, confirm the exact tool changes, and reload.
@@ -592,7 +597,7 @@ Simple and immediate critical-path work should stay in the main agent.
592
597
  The bounded persisted completion outbox provides ordered at-least-once delivery across process restart without replaying the child turn. A top-level completion targets `/root`; a nested completion enters the direct retained parent's mailbox and is not duplicated into the root transcript. If the direct parent cannot own delivery, routing walks toward the nearest live retained ancestor and uses `/root` only as the final fallback. An idle parent remains asleep, and inspection exposes its unread and pending-completion counts until a later turn consumes the envelope. When state must be reduced to its storage bound, persistence drops roots without pending completions first and trims old history rather than discarding an outbox-owned root. A completion is acknowledged only after the intended recipient context observes its exact `completionId`; an injection that returns synchronously but never reaches context remains pending for retry. If the process exits after context assembly but before acknowledgement is persisted, the same ID can be delivered again and consumers must deduplicate it. Auto-resume applies only to `/root`; nested delivery never silently starts the parent. Transient terminal-persistence failures retry with bounded exponential backoff and keep the run pending; shutdown cancels retry waits and reports a final persistence failure instead of silently resolving unsaved work.
593
598
 
594
599
  The default `subprocess` transport preserves compatibility: each turn starts a fresh isolated `pi --mode json -p --no-session` child and receives sanitized, bounded history.
595
- Pi registers every Subagents tool and command during startup, but loads blocking execution, manager UI, inspection work, and the selected detached transport implementation only on first use.
600
+ Pi loads one generated split TypeScript runtime and registers every Subagents tool and command during startup, but loads blocking execution, manager UI, inspection work, and the selected detached transport implementation only on first use.
596
601
  Session restoration, pending completion delivery, settings validation, and cleanup ownership remain eager.
597
602
  A failed first-use code load is reported normally and can be retried.
598
603
  Set `transport` to `in-process` to retain one public Pi SDK `AgentSession` per stateful `agentId`, avoiding repeated process startup while preserving native child history in memory.
@@ -1062,9 +1067,13 @@ Downgrading is safe: older extension versions ignore this separate state directo
1062
1067
 
1063
1068
  ```txt
1064
1069
  packages/pi-subagents/
1070
+ ├── dist/ # Generated split TypeScript runtime loaded through Pi's Jiti loader
1071
+ ├── scripts/
1072
+ │ └── build-runtime.mjs # Deterministic bundler and eager-boundary validator
1065
1073
  ├── src/
1066
- │ ├── index.ts # Pi package entrypoint
1067
- │ ├── subagents.ts # Lightweight extension composition and blocking registration
1074
+ │ ├── index.ts # Thin authoritative source entrypoint
1075
+ │ ├── subagents-extension.ts # Lightweight extension composition and blocking registration
1076
+ │ ├── subagents.ts # Backward-compatible public utility exports
1068
1077
  │ ├── cached-module-loader.ts # Retryable first-use code-module cache
1069
1078
  │ ├── inspect-registration.ts # Lightweight inspection tool registration
1070
1079
  │ ├── inspect.ts # First-use side-effect-free metadata inspection
@@ -1074,7 +1083,9 @@ packages/pi-subagents/
1074
1083
  │ ├── cwd-policy.ts # Canonical target and saved-trust resolution
1075
1084
  │ ├── prompt-resources.ts # Core-selected SYSTEM and APPEND_SYSTEM resources
1076
1085
  │ ├── safe-text.ts # Shared byte/line/path sanitization
1077
- │ ├── stateful.ts # Detached lifecycle registration and dispatch
1086
+ │ ├── stateful-registration.ts # Detached lifecycle registration and dispatch
1087
+ │ ├── stateful.ts # Backward-compatible detached utility exports
1088
+ │ ├── settings-reader.ts # Side-effect-free startup settings reads and inspection
1078
1089
  │ ├── create-stateful-transport.ts # First-turn selected transport loader
1079
1090
  │ ├── rpc-transport.ts # Persistent strict-JSONL Pi RPC child transport
1080
1091
  │ ├── rpc-timeout-finalization.ts # RPC abort-settle-summary recovery
@@ -1132,7 +1143,9 @@ packages/pi-subagents/
1132
1143
  └── package.json
1133
1144
  ```
1134
1145
 
1135
- `index.ts` is the Pi entrypoint and forwards to `subagents.ts`; the other source modules are internal.
1146
+ `src/index.ts` is the authoritative thin entrypoint and forwards to `subagents-extension.ts`.
1147
+ The package build bundles that source graph into split `.ts` files under `dist` for Pi's Jiti loader.
1148
+ `subagents.ts` and `stateful.ts` preserve existing source-level utility imports without making those utility graphs part of Pi startup.
1136
1149
  Workflow settings remain backward compatible: older files without `blocking.enabled` receive the eight-tool default, and an absent `blocking.maxParallelTasks` keeps the previous eight-worker limit.
1137
1150
  Existing `stateful.enabled: false` files expose blocking delegation plus inspection/consultation.
1138
1151
  Older package releases ignore and preserve the optional `blocking.maxParallelTasks`, `consult`, and `cwdPolicy` fields.
@@ -1141,7 +1154,7 @@ The package exposes its Pi extension through `package.json`:
1141
1154
  ```json
1142
1155
  {
1143
1156
  "pi": {
1144
- "extensions": ["./src/index.ts"]
1157
+ "extensions": ["./dist/index.ts"]
1145
1158
  }
1146
1159
  }
1147
1160
  ```
@@ -0,0 +1,109 @@
1
+ // @generated by scripts/build-runtime.mjs; do not edit.
2
+ // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
+ import {
4
+ isWriteCapable
5
+ } from "./chunk-O4VO6JUJ.js";
6
+ import {
7
+ discoverAgents
8
+ } from "./chunk-PSK43Y6A.js";
9
+ import "./chunk-RSUXZD6S.js";
10
+ import "./chunk-QBORTI4W.js";
11
+ import "./chunk-7OBINKFM.js";
12
+ import "./chunk-DPPVEQAM.js";
13
+ import "./chunk-SWGQLFSD.js";
14
+ import "./chunk-H3FP6DLR.js";
15
+
16
+ // src/auto-transport.ts
17
+ var BUILT_IN_TOOL_NAMES = /* @__PURE__ */ new Set(["read", "bash", "edit", "write", "grep", "find", "ls"]);
18
+ var AutoTransport = class {
19
+ constructor(options) {
20
+ this.options = options;
21
+ }
22
+ options;
23
+ kind = "auto";
24
+ selections = /* @__PURE__ */ new Map();
25
+ async runTurn(agent, task, signal, onProgress) {
26
+ const selection = this.selections.get(agent.id) ?? this.select(agent);
27
+ this.selections.set(agent.id, selection);
28
+ const transport = this.transport(selection.kind);
29
+ const outcome = await transport.runTurn(
30
+ agent,
31
+ task,
32
+ signal,
33
+ (progress) => onProgress?.({ ...progress, selectionReason: selection.reason })
34
+ );
35
+ return {
36
+ ...outcome,
37
+ telemetry: outcome.telemetry ? { ...outcome.telemetry, selectionReason: selection.reason } : outcome.telemetry
38
+ };
39
+ }
40
+ async deliverMessage(agent, message) {
41
+ const selection = this.selections.get(agent.id);
42
+ if (!selection) return false;
43
+ return this.transport(selection.kind).deliverMessage?.(agent, message) ?? false;
44
+ }
45
+ async release(agent) {
46
+ const selection = this.selections.get(agent.id);
47
+ this.selections.delete(agent.id);
48
+ if (selection) await this.transport(selection.kind).release?.(agent);
49
+ }
50
+ async shutdown() {
51
+ this.selections.clear();
52
+ const transports = [this.options.subprocess, this.options.inProcess, this.options.rpc];
53
+ const results = await Promise.allSettled(transports.map((transport) => transport.shutdown?.()));
54
+ const failures = results.flatMap(
55
+ (result) => result.status === "rejected" ? [result.reason] : []
56
+ );
57
+ if (failures.length > 0) {
58
+ throw new AggregateError(
59
+ failures,
60
+ `Failed to shut down ${failures.length} auto transport(s)`
61
+ );
62
+ }
63
+ }
64
+ selectionFor(agentId) {
65
+ const selection = this.selections.get(agentId);
66
+ return selection ? { ...selection } : void 0;
67
+ }
68
+ select(agent) {
69
+ const settings = this.options.getSettings?.();
70
+ const config = discoverAgents(agent.cwd, agent.agentScope ?? "user", settings).agents.find(
71
+ (candidate) => candidate.name === agent.agent
72
+ );
73
+ if (!config) {
74
+ throw new Error(`Automatic transport cannot resolve subagent ${agent.agent}`);
75
+ }
76
+ const effectiveTools = agent.executionPlan?.effectiveTools ?? config.tools;
77
+ const unsupported = (effectiveTools ?? []).filter((tool) => !BUILT_IN_TOOL_NAMES.has(tool));
78
+ if (unsupported.length > 0) {
79
+ return {
80
+ kind: "subprocess",
81
+ reason: `extension/custom tools require subprocess: ${unsupported.join(", ")}`
82
+ };
83
+ }
84
+ if (isWriteCapable(effectiveTools)) {
85
+ return {
86
+ kind: "rpc",
87
+ reason: "write-capable built-in tools use a persistent isolated process"
88
+ };
89
+ }
90
+ return {
91
+ kind: "in-process",
92
+ reason: "read-only built-in tools use the lowest-overhead public SDK session"
93
+ };
94
+ }
95
+ transport(kind) {
96
+ switch (kind) {
97
+ case "subprocess":
98
+ return this.options.subprocess;
99
+ case "in-process":
100
+ return this.options.inProcess;
101
+ case "rpc":
102
+ return this.options.rpc;
103
+ }
104
+ }
105
+ };
106
+ export {
107
+ AutoTransport
108
+ };
109
+ //# sourceMappingURL=auto-transport-SY2VHUFH.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/auto-transport.ts"],
4
+ "sourcesContent": ["import { discoverAgents } from \"./agents/discovery.js\";\nimport type { SubagentSettings } from \"./agents/types.js\";\nimport type { AgentMailboxMessage, ManagedAgent, TurnOutcome } from \"./registry.js\";\nimport { isWriteCapable } from \"./stateful-safety.js\";\nimport type { SubagentTransport } from \"./transport.js\";\nimport type {\n\tEffectiveSubagentTransportKind,\n\tTransportProgressCallback,\n} from \"./transport-types.js\";\n\nconst BUILT_IN_TOOL_NAMES = new Set([\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"]);\n\nexport interface AutoTransportOptions {\n\tsubprocess: SubagentTransport;\n\tinProcess: SubagentTransport;\n\trpc: SubagentTransport;\n\tgetSettings?: () => SubagentSettings | undefined;\n}\n\nexport interface AutoTransportSelection {\n\tkind: EffectiveSubagentTransportKind;\n\treason: string;\n}\n\nexport class AutoTransport implements SubagentTransport {\n\treadonly kind = \"auto\" as const;\n\tprivate readonly selections = new Map<string, AutoTransportSelection>();\n\n\tconstructor(private readonly options: AutoTransportOptions) {}\n\n\tasync runTurn(\n\t\tagent: ManagedAgent,\n\t\ttask: string,\n\t\tsignal: AbortSignal,\n\t\tonProgress?: TransportProgressCallback,\n\t): Promise<TurnOutcome> {\n\t\tconst selection = this.selections.get(agent.id) ?? this.select(agent);\n\t\tthis.selections.set(agent.id, selection);\n\t\tconst transport = this.transport(selection.kind);\n\t\tconst outcome = await transport.runTurn(agent, task, signal, (progress) =>\n\t\t\tonProgress?.({ ...progress, selectionReason: selection.reason }),\n\t\t);\n\t\treturn {\n\t\t\t...outcome,\n\t\t\ttelemetry: outcome.telemetry\n\t\t\t\t? { ...outcome.telemetry, selectionReason: selection.reason }\n\t\t\t\t: outcome.telemetry,\n\t\t};\n\t}\n\n\tasync deliverMessage(agent: ManagedAgent, message: AgentMailboxMessage): Promise<boolean> {\n\t\tconst selection = this.selections.get(agent.id);\n\t\tif (!selection) return false;\n\t\treturn this.transport(selection.kind).deliverMessage?.(agent, message) ?? false;\n\t}\n\n\tasync release(agent: ManagedAgent): Promise<void> {\n\t\tconst selection = this.selections.get(agent.id);\n\t\tthis.selections.delete(agent.id);\n\t\tif (selection) await this.transport(selection.kind).release?.(agent);\n\t}\n\n\tasync shutdown(): Promise<void> {\n\t\tthis.selections.clear();\n\t\tconst transports = [this.options.subprocess, this.options.inProcess, this.options.rpc];\n\t\tconst results = await Promise.allSettled(transports.map((transport) => transport.shutdown?.()));\n\t\tconst failures = results.flatMap((result) =>\n\t\t\tresult.status === \"rejected\" ? [result.reason] : [],\n\t\t);\n\t\tif (failures.length > 0) {\n\t\t\tthrow new AggregateError(\n\t\t\t\tfailures,\n\t\t\t\t`Failed to shut down ${failures.length} auto transport(s)`,\n\t\t\t);\n\t\t}\n\t}\n\n\tselectionFor(agentId: string): AutoTransportSelection | undefined {\n\t\tconst selection = this.selections.get(agentId);\n\t\treturn selection ? { ...selection } : undefined;\n\t}\n\n\tprivate select(agent: ManagedAgent): AutoTransportSelection {\n\t\tconst settings = this.options.getSettings?.();\n\t\tconst config = discoverAgents(agent.cwd, agent.agentScope ?? \"user\", settings).agents.find(\n\t\t\t(candidate) => candidate.name === agent.agent,\n\t\t);\n\t\tif (!config) {\n\t\t\tthrow new Error(`Automatic transport cannot resolve subagent ${agent.agent}`);\n\t\t}\n\t\tconst effectiveTools = agent.executionPlan?.effectiveTools ?? config.tools;\n\t\tconst unsupported = (effectiveTools ?? []).filter((tool) => !BUILT_IN_TOOL_NAMES.has(tool));\n\t\tif (unsupported.length > 0) {\n\t\t\treturn {\n\t\t\t\tkind: \"subprocess\",\n\t\t\t\treason: `extension/custom tools require subprocess: ${unsupported.join(\", \")}`,\n\t\t\t};\n\t\t}\n\t\tif (isWriteCapable(effectiveTools)) {\n\t\t\treturn {\n\t\t\t\tkind: \"rpc\",\n\t\t\t\treason: \"write-capable built-in tools use a persistent isolated process\",\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tkind: \"in-process\",\n\t\t\treason: \"read-only built-in tools use the lowest-overhead public SDK session\",\n\t\t};\n\t}\n\n\tprivate transport(kind: EffectiveSubagentTransportKind): SubagentTransport {\n\t\tswitch (kind) {\n\t\t\tcase \"subprocess\":\n\t\t\t\treturn this.options.subprocess;\n\t\t\tcase \"in-process\":\n\t\t\t\treturn this.options.inProcess;\n\t\t\tcase \"rpc\":\n\t\t\t\treturn this.options.rpc;\n\t\t}\n\t}\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,19 @@
1
+ // @generated by scripts/build-runtime.mjs; do not edit.
2
+ // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
+ import {
4
+ CAPABILITY_GRANT_VERSION,
5
+ isCapabilityGrant,
6
+ isCapabilityGrantActive,
7
+ issueCapabilityGrant,
8
+ revokeCapabilityGrant
9
+ } from "./chunk-HKC4ES4B.js";
10
+ import "./chunk-DSOOH73Y.js";
11
+ import "./chunk-DPPVEQAM.js";
12
+ export {
13
+ CAPABILITY_GRANT_VERSION,
14
+ isCapabilityGrant,
15
+ isCapabilityGrantActive,
16
+ issueCapabilityGrant,
17
+ revokeCapabilityGrant
18
+ };
19
+ //# sourceMappingURL=capability-grant-CGEWOEKE.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,282 @@
1
+ // @generated by scripts/build-runtime.mjs; do not edit.
2
+ // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
+ import {
4
+ PI_SUBAGENTS_RPC_PROTOCOL
5
+ } from "./chunk-C4L6P266.js";
6
+ import {
7
+ SUBAGENT_COMPLETION_MESSAGE_TYPE
8
+ } from "./chunk-QDVGH2X7.js";
9
+ import {
10
+ safeTerminalText
11
+ } from "./chunk-SWGQLFSD.js";
12
+ import {
13
+ DEFAULT_MAX_CONTEXT_BYTES,
14
+ MAX_TOOL_MESSAGE_BYTES,
15
+ redactPrivateText,
16
+ truncateUtf8
17
+ } from "./chunk-H3FP6DLR.js";
18
+
19
+ // src/completion-delivery.ts
20
+ var MAX_COMPLETION_ERROR_BYTES = 512;
21
+ var MAX_COMPLETIONS_PER_MESSAGE = 16;
22
+ var COMPLETION_BATCH_DELAY_MS = 10;
23
+ var CompletionDeliveryBroker = class {
24
+ constructor(pi, ctx, delivery, options = {}) {
25
+ this.pi = pi;
26
+ this.ctx = ctx;
27
+ this.delivery = delivery;
28
+ this.options = options;
29
+ }
30
+ pi;
31
+ ctx;
32
+ delivery;
33
+ options;
34
+ pending = [];
35
+ knownCompletionIds = /* @__PURE__ */ new Set();
36
+ awaitingParentAck = [];
37
+ flushTimer;
38
+ wakeInFlight = false;
39
+ closed = false;
40
+ enqueue(completion) {
41
+ if (this.closed || this.knownCompletionIds.has(completion.completionId)) return;
42
+ this.knownCompletionIds.add(completion.completionId);
43
+ this.pending.push(completion);
44
+ this.scheduleFlush();
45
+ }
46
+ setDelivery(value) {
47
+ this.delivery = value;
48
+ this.scheduleFlush();
49
+ }
50
+ onParentTurnStart() {
51
+ this.wakeInFlight = false;
52
+ this.scheduleFlush();
53
+ }
54
+ onParentContext(messages) {
55
+ this.acknowledgeVisible(completionIdsFromContext(messages));
56
+ if (this.awaitingParentAck.length > 0) {
57
+ this.pending = [...this.awaitingParentAck.splice(0), ...this.pending];
58
+ }
59
+ this.scheduleFlush();
60
+ }
61
+ onParentSettled() {
62
+ this.wakeInFlight = false;
63
+ this.scheduleFlush();
64
+ }
65
+ flush() {
66
+ if (this.closed || this.pending.length === 0) return;
67
+ if (this.flushTimer) clearTimeout(this.flushTimer);
68
+ this.flushTimer = void 0;
69
+ if (this.delivery === "auto-resume" && !this.isRootIdle()) return;
70
+ const completions = this.pending.splice(0);
71
+ const batches = chunkCompletions(completions);
72
+ let canWake = this.shouldWakeRoot();
73
+ for (let index = 0; index < batches.length; index++) {
74
+ const triggerTurn = canWake && index === batches.length - 1;
75
+ const batch = batches[index];
76
+ const message = buildCompletionMessage(batch);
77
+ if (triggerTurn) this.wakeInFlight = true;
78
+ this.awaitingParentAck.push(...batch);
79
+ try {
80
+ this.pi.sendMessage(message, {
81
+ deliverAs: "steer",
82
+ ...triggerTurn ? { triggerTurn: true } : {}
83
+ });
84
+ } catch (primaryError) {
85
+ this.removeAwaiting(batch);
86
+ if (triggerTurn) this.wakeInFlight = false;
87
+ canWake = false;
88
+ this.awaitingParentAck.push(...batch);
89
+ try {
90
+ this.pi.sendMessage(message, { deliverAs: "nextTurn", triggerTurn: false });
91
+ } catch (fallbackError) {
92
+ this.removeAwaiting(batch);
93
+ this.pending = [...batches.slice(index).flat(), ...this.pending];
94
+ try {
95
+ this.options.onDeliveryError?.(
96
+ new AggregateError(
97
+ [primaryError, fallbackError],
98
+ "Detached subagent completion delivery failed"
99
+ )
100
+ );
101
+ } catch {
102
+ }
103
+ return;
104
+ }
105
+ }
106
+ }
107
+ }
108
+ close() {
109
+ this.closed = true;
110
+ if (this.flushTimer) clearTimeout(this.flushTimer);
111
+ this.flushTimer = void 0;
112
+ this.pending = [];
113
+ this.awaitingParentAck = [];
114
+ this.knownCompletionIds.clear();
115
+ }
116
+ scheduleFlush() {
117
+ if (this.closed || this.pending.length === 0 || this.flushTimer) return;
118
+ this.flushTimer = setTimeout(() => {
119
+ this.flushTimer = void 0;
120
+ this.flush();
121
+ }, COMPLETION_BATCH_DELAY_MS);
122
+ }
123
+ acknowledgeVisible(visibleIds) {
124
+ if (visibleIds.size === 0) return;
125
+ const completions = [...this.awaitingParentAck, ...this.pending].filter(
126
+ (completion) => visibleIds.has(completion.completionId)
127
+ );
128
+ if (completions.length === 0) return;
129
+ const acknowledgedIds = new Set(completions.map((completion) => completion.completionId));
130
+ this.awaitingParentAck = this.awaitingParentAck.filter(
131
+ (completion) => !acknowledgedIds.has(completion.completionId)
132
+ );
133
+ this.pending = this.pending.filter(
134
+ (completion) => !acknowledgedIds.has(completion.completionId)
135
+ );
136
+ for (const completion of completions) this.knownCompletionIds.delete(completion.completionId);
137
+ try {
138
+ this.options.onAcknowledged?.(completions, (this.options.now ?? Date.now)());
139
+ } catch {
140
+ }
141
+ }
142
+ removeAwaiting(completions) {
143
+ const removed = new Set(completions.map((completion) => completion.completionId));
144
+ this.awaitingParentAck = this.awaitingParentAck.filter(
145
+ (completion) => !removed.has(completion.completionId)
146
+ );
147
+ }
148
+ isRootIdle() {
149
+ try {
150
+ return this.ctx.isIdle();
151
+ } catch {
152
+ return false;
153
+ }
154
+ }
155
+ shouldWakeRoot() {
156
+ if (this.delivery !== "auto-resume" || this.wakeInFlight) return false;
157
+ try {
158
+ return !this.ctx.hasPendingMessages();
159
+ } catch {
160
+ return false;
161
+ }
162
+ }
163
+ };
164
+ function completionIdsFromContext(messages) {
165
+ const ids = /* @__PURE__ */ new Set();
166
+ for (const message of messages) {
167
+ if (!message || typeof message !== "object" || Array.isArray(message)) continue;
168
+ const record = message;
169
+ if (record.role !== "custom" || record.customType !== SUBAGENT_COMPLETION_MESSAGE_TYPE)
170
+ continue;
171
+ const details = record.details;
172
+ if (!details || typeof details !== "object" || Array.isArray(details)) continue;
173
+ const metadata = details;
174
+ if (metadata.protocol === PI_SUBAGENTS_RPC_PROTOCOL && typeof metadata.completionId === "string") {
175
+ ids.add(metadata.completionId);
176
+ }
177
+ if (!Array.isArray(metadata.completions)) continue;
178
+ for (const completion of metadata.completions) {
179
+ if (!completion || typeof completion !== "object" || Array.isArray(completion)) continue;
180
+ const item = completion;
181
+ if (item.protocol === PI_SUBAGENTS_RPC_PROTOCOL && typeof item.completionId === "string") {
182
+ ids.add(item.completionId);
183
+ }
184
+ }
185
+ }
186
+ return ids;
187
+ }
188
+ function chunkCompletions(completions) {
189
+ const batches = [];
190
+ for (let index = 0; index < completions.length; index += MAX_COMPLETIONS_PER_MESSAGE) {
191
+ batches.push(completions.slice(index, index + MAX_COMPLETIONS_PER_MESSAGE));
192
+ }
193
+ return batches;
194
+ }
195
+ function buildCompletionMessage(completions) {
196
+ if (completions.length === 1) {
197
+ const completion = completions[0];
198
+ return {
199
+ customType: SUBAGENT_COMPLETION_MESSAGE_TYPE,
200
+ content: buildDetachedCompletionMessage(completion),
201
+ display: true,
202
+ details: completionMetadata(completion)
203
+ };
204
+ }
205
+ const content = truncateUtf8(
206
+ [
207
+ "Message Type: SUBAGENT_COMPLETION_BATCH",
208
+ `Protocol: ${PI_SUBAGENTS_RPC_PROTOCOL}`,
209
+ `Completion Count: ${completions.length}`,
210
+ ...completions.flatMap((completion, index) => [
211
+ "",
212
+ `--- Completion ${index + 1} of ${completions.length} ---`,
213
+ buildDetachedCompletionMessage(completion)
214
+ ])
215
+ ].join("\n"),
216
+ DEFAULT_MAX_CONTEXT_BYTES
217
+ ).text;
218
+ return {
219
+ customType: SUBAGENT_COMPLETION_MESSAGE_TYPE,
220
+ content,
221
+ display: true,
222
+ details: {
223
+ completionCount: completions.length,
224
+ completions: completions.map(completionMetadata)
225
+ }
226
+ };
227
+ }
228
+ function completionMetadata(completion) {
229
+ return {
230
+ protocol: PI_SUBAGENTS_RPC_PROTOCOL,
231
+ completionId: completion.completionId,
232
+ runId: completion.runId,
233
+ generation: completion.generation,
234
+ agentId: completion.agent.id,
235
+ ...completion.agent.taskPath ? { taskPath: completion.agent.taskPath } : {},
236
+ ...completion.recipientPath ? { recipientPath: completion.recipientPath } : {},
237
+ agent: completion.agent.agent,
238
+ task: sanitizeCompletionLine(completion.task, 256) || "(unknown task)",
239
+ state: completion.agent.state,
240
+ ...completion.agent.telemetry?.transport ? { transport: completion.agent.telemetry.transport } : {},
241
+ ...completion.agent.structuredResult ? { structuredResult: completion.agent.structuredResult } : {},
242
+ ...completion.agent.outcome ? { outcome: completion.agent.outcome } : {},
243
+ ...completion.agent.capabilityGrant ? { capabilityGrant: completion.agent.capabilityGrant } : {}
244
+ };
245
+ }
246
+ function buildDetachedCompletionMessage(completion) {
247
+ const task = sanitizeCompletionLine(completion.task, 256) || "(unknown task)";
248
+ const agentName = sanitizeCompletionLine(completion.agent.agent, 128) || "(unknown agent)";
249
+ const output = safeTerminalText(redactPrivateText(completion.output));
250
+ const error = completion.error ? truncateUtf8(
251
+ safeTerminalText(redactPrivateText(completion.error)),
252
+ MAX_COMPLETION_ERROR_BYTES
253
+ ).text : "";
254
+ return truncateUtf8(
255
+ [
256
+ "Message Type: SUBAGENT_COMPLETION",
257
+ `Protocol: ${PI_SUBAGENTS_RPC_PROTOCOL}`,
258
+ `Completion ID: ${completion.completionId}`,
259
+ `Run ID: ${completion.runId}`,
260
+ `Generation: ${completion.generation}`,
261
+ `Agent ID: ${completion.agent.id}`,
262
+ ...completion.agent.taskPath ? [`Agent Path: ${completion.agent.taskPath}`] : [],
263
+ ...completion.recipientPath ? [`Recipient Path: ${completion.recipientPath}`] : [],
264
+ `Agent: ${agentName}`,
265
+ `Task: ${task}`,
266
+ `State: ${completion.agent.state}`,
267
+ ...error.trim() ? ["Error:", error] : [],
268
+ "Payload:",
269
+ output.trim() ? output : "(no output)"
270
+ ].join("\n"),
271
+ MAX_TOOL_MESSAGE_BYTES
272
+ ).text;
273
+ }
274
+ function sanitizeCompletionLine(value, maxBytes) {
275
+ return truncateUtf8(redactPrivateText(value), maxBytes).text.replace(/[\u0000-\u001f\u007f]+/g, " ").replace(/\s+/g, " ").trim();
276
+ }
277
+
278
+ export {
279
+ CompletionDeliveryBroker,
280
+ buildDetachedCompletionMessage
281
+ };
282
+ //# sourceMappingURL=chunk-434NII74.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/completion-delivery.ts"],
4
+ "sourcesContent": ["import type { ExtensionAPI, ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport type { CompletionDelivery } from \"./agents/types.js\";\nimport { SUBAGENT_COMPLETION_MESSAGE_TYPE } from \"./completion-render.js\";\nimport { redactPrivateText } from \"./context.js\";\nimport { DEFAULT_MAX_CONTEXT_BYTES, MAX_TOOL_MESSAGE_BYTES, truncateUtf8 } from \"./limits.js\";\nimport type { AgentTurnCompletion, ManagedAgent } from \"./registry.js\";\nimport { safeTerminalText } from \"./safe-text.js\";\nimport { PI_SUBAGENTS_RPC_PROTOCOL } from \"./transport-types.js\";\n\nconst MAX_COMPLETION_ERROR_BYTES = 512;\nconst MAX_COMPLETIONS_PER_MESSAGE = 16;\nconst COMPLETION_BATCH_DELAY_MS = 10;\n\ninterface CompletionMetadata {\n\tprotocol: typeof PI_SUBAGENTS_RPC_PROTOCOL;\n\tcompletionId: string;\n\trunId: string;\n\tgeneration: number;\n\tagentId: string;\n\ttaskPath?: string;\n\trecipientPath?: string;\n\tagent: string;\n\ttask: string;\n\tstate: string;\n\ttransport?: string;\n\tstructuredResult?: ManagedAgent[\"structuredResult\"];\n\toutcome?: ManagedAgent[\"outcome\"];\n\tcapabilityGrant?: ManagedAgent[\"capabilityGrant\"];\n}\n\ninterface CompletionMessage {\n\tcustomType: typeof SUBAGENT_COMPLETION_MESSAGE_TYPE;\n\tcontent: string;\n\tdisplay: true;\n\tdetails:\n\t\t| CompletionMetadata\n\t\t| {\n\t\t\t\tcompletionCount: number;\n\t\t\t\tcompletions: CompletionMetadata[];\n\t\t };\n}\n\ntype CompletionContext = Pick<ExtensionContext, \"hasPendingMessages\" | \"isIdle\">;\ntype CompletionPi = Pick<ExtensionAPI, \"sendMessage\">;\n\nexport interface CompletionDeliveryBrokerOptions {\n\tonDeliveryError?: (error: unknown) => void;\n\tonAcknowledged?: (completions: readonly AgentTurnCompletion[], acknowledgedAt: number) => void;\n\tnow?: () => number;\n}\n\n/** Owns bounded completion batching and at most one idle-root wake for one parent session. */\nexport class CompletionDeliveryBroker {\n\tprivate pending: AgentTurnCompletion[] = [];\n\tprivate readonly knownCompletionIds = new Set<string>();\n\tprivate awaitingParentAck: AgentTurnCompletion[] = [];\n\tprivate flushTimer?: NodeJS.Timeout;\n\tprivate wakeInFlight = false;\n\tprivate closed = false;\n\n\tconstructor(\n\t\tprivate readonly pi: CompletionPi,\n\t\tprivate readonly ctx: CompletionContext,\n\t\tprivate delivery: CompletionDelivery,\n\t\tprivate readonly options: CompletionDeliveryBrokerOptions = {},\n\t) {}\n\n\tenqueue(completion: AgentTurnCompletion): void {\n\t\tif (this.closed || this.knownCompletionIds.has(completion.completionId)) return;\n\t\tthis.knownCompletionIds.add(completion.completionId);\n\t\tthis.pending.push(completion);\n\t\tthis.scheduleFlush();\n\t}\n\n\tsetDelivery(value: CompletionDelivery): void {\n\t\tthis.delivery = value;\n\t\tthis.scheduleFlush();\n\t}\n\n\tonParentTurnStart(): void {\n\t\tthis.wakeInFlight = false;\n\t\tthis.scheduleFlush();\n\t}\n\n\tonParentContext(messages: readonly unknown[]): void {\n\t\tthis.acknowledgeVisible(completionIdsFromContext(messages));\n\t\tif (this.awaitingParentAck.length > 0) {\n\t\t\tthis.pending = [...this.awaitingParentAck.splice(0), ...this.pending];\n\t\t}\n\t\tthis.scheduleFlush();\n\t}\n\n\tonParentSettled(): void {\n\t\tthis.wakeInFlight = false;\n\t\tthis.scheduleFlush();\n\t}\n\n\tflush(): void {\n\t\tif (this.closed || this.pending.length === 0) return;\n\t\tif (this.flushTimer) clearTimeout(this.flushTimer);\n\t\tthis.flushTimer = undefined;\n\t\tif (this.delivery === \"auto-resume\" && !this.isRootIdle()) return;\n\n\t\tconst completions = this.pending.splice(0);\n\t\tconst batches = chunkCompletions(completions);\n\t\tlet canWake = this.shouldWakeRoot();\n\t\tfor (let index = 0; index < batches.length; index++) {\n\t\t\tconst triggerTurn = canWake && index === batches.length - 1;\n\t\t\tconst batch = batches[index];\n\t\t\tconst message = buildCompletionMessage(batch);\n\t\t\tif (triggerTurn) this.wakeInFlight = true;\n\t\t\tthis.awaitingParentAck.push(...batch);\n\t\t\ttry {\n\t\t\t\t// Pi treats explicit false as immediate insertion instead of queued steering while streaming.\n\t\t\t\tthis.pi.sendMessage(message, {\n\t\t\t\t\tdeliverAs: \"steer\",\n\t\t\t\t\t...(triggerTurn ? { triggerTurn: true } : {}),\n\t\t\t\t});\n\t\t\t} catch (primaryError) {\n\t\t\t\tthis.removeAwaiting(batch);\n\t\t\t\tif (triggerTurn) this.wakeInFlight = false;\n\t\t\t\tcanWake = false;\n\t\t\t\tthis.awaitingParentAck.push(...batch);\n\t\t\t\ttry {\n\t\t\t\t\tthis.pi.sendMessage(message, { deliverAs: \"nextTurn\", triggerTurn: false });\n\t\t\t\t} catch (fallbackError) {\n\t\t\t\t\tthis.removeAwaiting(batch);\n\t\t\t\t\tthis.pending = [...batches.slice(index).flat(), ...this.pending];\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.options.onDeliveryError?.(\n\t\t\t\t\t\t\tnew AggregateError(\n\t\t\t\t\t\t\t\t[primaryError, fallbackError],\n\t\t\t\t\t\t\t\t\"Detached subagent completion delivery failed\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Delivery retention must survive a failing observer.\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tclose(): void {\n\t\tthis.closed = true;\n\t\tif (this.flushTimer) clearTimeout(this.flushTimer);\n\t\tthis.flushTimer = undefined;\n\t\tthis.pending = [];\n\t\tthis.awaitingParentAck = [];\n\t\tthis.knownCompletionIds.clear();\n\t}\n\n\tprivate scheduleFlush(): void {\n\t\tif (this.closed || this.pending.length === 0 || this.flushTimer) return;\n\t\tthis.flushTimer = setTimeout(() => {\n\t\t\tthis.flushTimer = undefined;\n\t\t\tthis.flush();\n\t\t}, COMPLETION_BATCH_DELAY_MS);\n\t}\n\n\tprivate acknowledgeVisible(visibleIds: ReadonlySet<string>): void {\n\t\tif (visibleIds.size === 0) return;\n\t\tconst completions = [...this.awaitingParentAck, ...this.pending].filter((completion) =>\n\t\t\tvisibleIds.has(completion.completionId),\n\t\t);\n\t\tif (completions.length === 0) return;\n\t\tconst acknowledgedIds = new Set(completions.map((completion) => completion.completionId));\n\t\tthis.awaitingParentAck = this.awaitingParentAck.filter(\n\t\t\t(completion) => !acknowledgedIds.has(completion.completionId),\n\t\t);\n\t\tthis.pending = this.pending.filter(\n\t\t\t(completion) => !acknowledgedIds.has(completion.completionId),\n\t\t);\n\t\tfor (const completion of completions) this.knownCompletionIds.delete(completion.completionId);\n\t\ttry {\n\t\t\tthis.options.onAcknowledged?.(completions, (this.options.now ?? Date.now)());\n\t\t} catch {\n\t\t\t// Context assembly already observed the message, so observer failures cannot retract it.\n\t\t}\n\t}\n\n\tprivate removeAwaiting(completions: readonly AgentTurnCompletion[]): void {\n\t\tconst removed = new Set(completions.map((completion) => completion.completionId));\n\t\tthis.awaitingParentAck = this.awaitingParentAck.filter(\n\t\t\t(completion) => !removed.has(completion.completionId),\n\t\t);\n\t}\n\n\tprivate isRootIdle(): boolean {\n\t\ttry {\n\t\t\treturn this.ctx.isIdle();\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate shouldWakeRoot(): boolean {\n\t\tif (this.delivery !== \"auto-resume\" || this.wakeInFlight) return false;\n\t\ttry {\n\t\t\treturn !this.ctx.hasPendingMessages();\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n\nfunction completionIdsFromContext(messages: readonly unknown[]): Set<string> {\n\tconst ids = new Set<string>();\n\tfor (const message of messages) {\n\t\tif (!message || typeof message !== \"object\" || Array.isArray(message)) continue;\n\t\tconst record = message as Record<string, unknown>;\n\t\tif (record.role !== \"custom\" || record.customType !== SUBAGENT_COMPLETION_MESSAGE_TYPE)\n\t\t\tcontinue;\n\t\tconst details = record.details;\n\t\tif (!details || typeof details !== \"object\" || Array.isArray(details)) continue;\n\t\tconst metadata = details as Record<string, unknown>;\n\t\tif (\n\t\t\tmetadata.protocol === PI_SUBAGENTS_RPC_PROTOCOL &&\n\t\t\ttypeof metadata.completionId === \"string\"\n\t\t) {\n\t\t\tids.add(metadata.completionId);\n\t\t}\n\t\tif (!Array.isArray(metadata.completions)) continue;\n\t\tfor (const completion of metadata.completions) {\n\t\t\tif (!completion || typeof completion !== \"object\" || Array.isArray(completion)) continue;\n\t\t\tconst item = completion as Record<string, unknown>;\n\t\t\tif (item.protocol === PI_SUBAGENTS_RPC_PROTOCOL && typeof item.completionId === \"string\") {\n\t\t\t\tids.add(item.completionId);\n\t\t\t}\n\t\t}\n\t}\n\treturn ids;\n}\n\nfunction chunkCompletions(completions: AgentTurnCompletion[]): AgentTurnCompletion[][] {\n\tconst batches: AgentTurnCompletion[][] = [];\n\tfor (let index = 0; index < completions.length; index += MAX_COMPLETIONS_PER_MESSAGE) {\n\t\tbatches.push(completions.slice(index, index + MAX_COMPLETIONS_PER_MESSAGE));\n\t}\n\treturn batches;\n}\n\nfunction buildCompletionMessage(completions: AgentTurnCompletion[]): CompletionMessage {\n\tif (completions.length === 1) {\n\t\tconst completion = completions[0];\n\t\treturn {\n\t\t\tcustomType: SUBAGENT_COMPLETION_MESSAGE_TYPE,\n\t\t\tcontent: buildDetachedCompletionMessage(completion),\n\t\t\tdisplay: true,\n\t\t\tdetails: completionMetadata(completion),\n\t\t};\n\t}\n\tconst content = truncateUtf8(\n\t\t[\n\t\t\t\"Message Type: SUBAGENT_COMPLETION_BATCH\",\n\t\t\t`Protocol: ${PI_SUBAGENTS_RPC_PROTOCOL}`,\n\t\t\t`Completion Count: ${completions.length}`,\n\t\t\t...completions.flatMap((completion, index) => [\n\t\t\t\t\"\",\n\t\t\t\t`--- Completion ${index + 1} of ${completions.length} ---`,\n\t\t\t\tbuildDetachedCompletionMessage(completion),\n\t\t\t]),\n\t\t].join(\"\\n\"),\n\t\tDEFAULT_MAX_CONTEXT_BYTES,\n\t).text;\n\treturn {\n\t\tcustomType: SUBAGENT_COMPLETION_MESSAGE_TYPE,\n\t\tcontent,\n\t\tdisplay: true,\n\t\tdetails: {\n\t\t\tcompletionCount: completions.length,\n\t\t\tcompletions: completions.map(completionMetadata),\n\t\t},\n\t};\n}\n\nfunction completionMetadata(completion: AgentTurnCompletion): CompletionMetadata {\n\treturn {\n\t\tprotocol: PI_SUBAGENTS_RPC_PROTOCOL,\n\t\tcompletionId: completion.completionId,\n\t\trunId: completion.runId,\n\t\tgeneration: completion.generation,\n\t\tagentId: completion.agent.id,\n\t\t...(completion.agent.taskPath ? { taskPath: completion.agent.taskPath } : {}),\n\t\t...(completion.recipientPath ? { recipientPath: completion.recipientPath } : {}),\n\t\tagent: completion.agent.agent,\n\t\ttask: sanitizeCompletionLine(completion.task, 256) || \"(unknown task)\",\n\t\tstate: completion.agent.state,\n\t\t...(completion.agent.telemetry?.transport\n\t\t\t? { transport: completion.agent.telemetry.transport }\n\t\t\t: {}),\n\t\t...(completion.agent.structuredResult\n\t\t\t? { structuredResult: completion.agent.structuredResult }\n\t\t\t: {}),\n\t\t...(completion.agent.outcome ? { outcome: completion.agent.outcome } : {}),\n\t\t...(completion.agent.capabilityGrant\n\t\t\t? { capabilityGrant: completion.agent.capabilityGrant }\n\t\t\t: {}),\n\t};\n}\n\nexport function buildDetachedCompletionMessage(completion: AgentTurnCompletion): string {\n\tconst task = sanitizeCompletionLine(completion.task, 256) || \"(unknown task)\";\n\tconst agentName = sanitizeCompletionLine(completion.agent.agent, 128) || \"(unknown agent)\";\n\tconst output = safeTerminalText(redactPrivateText(completion.output));\n\tconst error = completion.error\n\t\t? truncateUtf8(\n\t\t\t\tsafeTerminalText(redactPrivateText(completion.error)),\n\t\t\t\tMAX_COMPLETION_ERROR_BYTES,\n\t\t\t).text\n\t\t: \"\";\n\treturn truncateUtf8(\n\t\t[\n\t\t\t\"Message Type: SUBAGENT_COMPLETION\",\n\t\t\t`Protocol: ${PI_SUBAGENTS_RPC_PROTOCOL}`,\n\t\t\t`Completion ID: ${completion.completionId}`,\n\t\t\t`Run ID: ${completion.runId}`,\n\t\t\t`Generation: ${completion.generation}`,\n\t\t\t`Agent ID: ${completion.agent.id}`,\n\t\t\t...(completion.agent.taskPath ? [`Agent Path: ${completion.agent.taskPath}`] : []),\n\t\t\t...(completion.recipientPath ? [`Recipient Path: ${completion.recipientPath}`] : []),\n\t\t\t`Agent: ${agentName}`,\n\t\t\t`Task: ${task}`,\n\t\t\t`State: ${completion.agent.state}`,\n\t\t\t...(error.trim() ? [\"Error:\", error] : []),\n\t\t\t\"Payload:\",\n\t\t\toutput.trim() ? output : \"(no output)\",\n\t\t].join(\"\\n\"),\n\t\tMAX_TOOL_MESSAGE_BYTES,\n\t).text;\n}\n\nfunction sanitizeCompletionLine(value: string, maxBytes: number): string {\n\treturn (\n\t\ttruncateUtf8(redactPrivateText(value), maxBytes)\n\t\t\t// biome-ignore lint/suspicious/noControlCharactersInRegex: Strip untrusted terminal controls.\n\t\t\t.text.replace(/[\\u0000-\\u001f\\u007f]+/g, \" \")\n\t\t\t.replace(/\\s+/g, \" \")\n\t\t\t.trim()\n\t);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,56 @@
1
+ // @generated by scripts/build-runtime.mjs; do not edit.
2
+ // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
+
4
+ // src/outcome.ts
5
+ var TRANSIENT_REASONS = /* @__PURE__ */ new Set(["transient-transport", "transient-tool"]);
6
+ function classifyStructuredOutcome(status, reasonCode) {
7
+ if (TRANSIENT_REASONS.has(reasonCode ?? "") && status === "failed") {
8
+ return {
9
+ status,
10
+ ...reasonCode ? { reasonCode } : {},
11
+ recoveryActions: ["retry"],
12
+ retryable: true
13
+ };
14
+ }
15
+ const recoveryActions = recoveryFor(status, reasonCode);
16
+ return {
17
+ status,
18
+ ...reasonCode ? { reasonCode } : {},
19
+ recoveryActions,
20
+ retryable: false
21
+ };
22
+ }
23
+ function recoveryFor(status, reasonCode) {
24
+ if (reasonCode === "missing-dependency" || reasonCode === "missing-context") {
25
+ return ["supply-input"];
26
+ }
27
+ if (reasonCode === "ambiguous-task") return ["clarify"];
28
+ if (reasonCode === "capability-mismatch" || reasonCode === "authority-missing") {
29
+ return ["reroute"];
30
+ }
31
+ if (reasonCode === "dependency-superseded" || status === "stale") return ["revalidate"];
32
+ if (reasonCode === "verification-failed") return ["replan", "verify"];
33
+ if (reasonCode === "unsupported-guarantee") return ["stop"];
34
+ switch (status) {
35
+ case "completed":
36
+ case "partial":
37
+ return [];
38
+ case "needs-input":
39
+ return ["supply-input"];
40
+ case "blocked":
41
+ return ["clarify"];
42
+ case "abstained":
43
+ return ["reroute"];
44
+ case "contract-invalid":
45
+ return ["repair-contract"];
46
+ case "interrupted":
47
+ return ["stop"];
48
+ case "failed":
49
+ return ["stop"];
50
+ }
51
+ }
52
+
53
+ export {
54
+ classifyStructuredOutcome
55
+ };
56
+ //# sourceMappingURL=chunk-47SK2QYC.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/outcome.ts"],
4
+ "sourcesContent": ["import type { SubagentOutcomeStatus } from \"./result-contract.js\";\n\nexport interface ClassifiedSubagentOutcome {\n\tstatus: SubagentOutcomeStatus;\n\treasonCode?: string;\n\trecoveryActions: string[];\n\tretryable: boolean;\n}\n\nconst TRANSIENT_REASONS = new Set([\"transient-transport\", \"transient-tool\"]);\n\nexport function classifyStructuredOutcome(\n\tstatus: SubagentOutcomeStatus,\n\treasonCode?: string,\n): ClassifiedSubagentOutcome {\n\tif (TRANSIENT_REASONS.has(reasonCode ?? \"\") && status === \"failed\") {\n\t\treturn {\n\t\t\tstatus,\n\t\t\t...(reasonCode ? { reasonCode } : {}),\n\t\t\trecoveryActions: [\"retry\"],\n\t\t\tretryable: true,\n\t\t};\n\t}\n\tconst recoveryActions = recoveryFor(status, reasonCode);\n\treturn {\n\t\tstatus,\n\t\t...(reasonCode ? { reasonCode } : {}),\n\t\trecoveryActions,\n\t\tretryable: false,\n\t};\n}\n\nfunction recoveryFor(status: SubagentOutcomeStatus, reasonCode?: string): string[] {\n\tif (reasonCode === \"missing-dependency\" || reasonCode === \"missing-context\") {\n\t\treturn [\"supply-input\"];\n\t}\n\tif (reasonCode === \"ambiguous-task\") return [\"clarify\"];\n\tif (reasonCode === \"capability-mismatch\" || reasonCode === \"authority-missing\") {\n\t\treturn [\"reroute\"];\n\t}\n\tif (reasonCode === \"dependency-superseded\" || status === \"stale\") return [\"revalidate\"];\n\tif (reasonCode === \"verification-failed\") return [\"replan\", \"verify\"];\n\tif (reasonCode === \"unsupported-guarantee\") return [\"stop\"];\n\tswitch (status) {\n\t\tcase \"completed\":\n\t\tcase \"partial\":\n\t\t\treturn [];\n\t\tcase \"needs-input\":\n\t\t\treturn [\"supply-input\"];\n\t\tcase \"blocked\":\n\t\t\treturn [\"clarify\"];\n\t\tcase \"abstained\":\n\t\t\treturn [\"reroute\"];\n\t\tcase \"contract-invalid\":\n\t\t\treturn [\"repair-contract\"];\n\t\tcase \"interrupted\":\n\t\t\treturn [\"stop\"];\n\t\tcase \"failed\":\n\t\t\treturn [\"stop\"];\n\t}\n}\n"],
5
+ "mappings": ";;;;AASA,IAAM,oBAAoB,oBAAI,IAAI,CAAC,uBAAuB,gBAAgB,CAAC;AAEpE,SAAS,0BACf,QACA,YAC4B;AAC5B,MAAI,kBAAkB,IAAI,cAAc,EAAE,KAAK,WAAW,UAAU;AACnE,WAAO;AAAA,MACN;AAAA,MACA,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,MACnC,iBAAiB,CAAC,OAAO;AAAA,MACzB,WAAW;AAAA,IACZ;AAAA,EACD;AACA,QAAM,kBAAkB,YAAY,QAAQ,UAAU;AACtD,SAAO;AAAA,IACN;AAAA,IACA,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,IACnC;AAAA,IACA,WAAW;AAAA,EACZ;AACD;AAEA,SAAS,YAAY,QAA+B,YAA+B;AAClF,MAAI,eAAe,wBAAwB,eAAe,mBAAmB;AAC5E,WAAO,CAAC,cAAc;AAAA,EACvB;AACA,MAAI,eAAe,iBAAkB,QAAO,CAAC,SAAS;AACtD,MAAI,eAAe,yBAAyB,eAAe,qBAAqB;AAC/E,WAAO,CAAC,SAAS;AAAA,EAClB;AACA,MAAI,eAAe,2BAA2B,WAAW,QAAS,QAAO,CAAC,YAAY;AACtF,MAAI,eAAe,sBAAuB,QAAO,CAAC,UAAU,QAAQ;AACpE,MAAI,eAAe,wBAAyB,QAAO,CAAC,MAAM;AAC1D,UAAQ,QAAQ;AAAA,IACf,KAAK;AAAA,IACL,KAAK;AACJ,aAAO,CAAC;AAAA,IACT,KAAK;AACJ,aAAO,CAAC,cAAc;AAAA,IACvB,KAAK;AACJ,aAAO,CAAC,SAAS;AAAA,IAClB,KAAK;AACJ,aAAO,CAAC,SAAS;AAAA,IAClB,KAAK;AACJ,aAAO,CAAC,iBAAiB;AAAA,IAC1B,KAAK;AACJ,aAAO,CAAC,MAAM;AAAA,IACf,KAAK;AACJ,aAAO,CAAC,MAAM;AAAA,EAChB;AACD;",
6
+ "names": []
7
+ }