@narumitw/pi-subagents 2.1.3 → 3.0.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 (314) hide show
  1. package/README.md +181 -1250
  2. package/dist/child-communication-bridge.ts +136 -0
  3. package/dist/child-communication-bridge.ts.map +7 -0
  4. package/dist/chunks/chunk-UKTWUQRM.js +667 -0
  5. package/dist/chunks/chunk-UKTWUQRM.js.map +7 -0
  6. package/dist/index.ts +1448 -1598
  7. package/dist/index.ts.map +4 -4
  8. package/docs/design-principles.md +31 -0
  9. package/docs/ipc-transport-idea.md +103 -0
  10. package/docs/tools.md +109 -0
  11. package/package.json +11 -19
  12. package/src/broker-credentials.ts +71 -0
  13. package/src/child-communication-bridge.ts +153 -0
  14. package/src/child-communication-tools.ts +147 -0
  15. package/src/completion-renderer.ts +60 -0
  16. package/src/index.ts +1 -1
  17. package/src/message-broker.ts +628 -0
  18. package/src/model-output.ts +42 -0
  19. package/src/process.ts +688 -0
  20. package/src/runtime.ts +538 -0
  21. package/src/subagents.ts +33 -34
  22. package/src/tools.ts +416 -0
  23. package/src/types.ts +85 -0
  24. package/src/widget.ts +130 -0
  25. package/dist/chunks/auto-transport-FUUKFDIG.ts +0 -109
  26. package/dist/chunks/auto-transport-FUUKFDIG.ts.map +0 -7
  27. package/dist/chunks/capability-grant-PR72SWWS.ts +0 -19
  28. package/dist/chunks/capability-grant-PR72SWWS.ts.map +0 -7
  29. package/dist/chunks/child-peer-bridge.ts +0 -108
  30. package/dist/chunks/child-peer-bridge.ts.map +0 -7
  31. package/dist/chunks/chunk-2LMJU25E.ts +0 -1641
  32. package/dist/chunks/chunk-2LMJU25E.ts.map +0 -7
  33. package/dist/chunks/chunk-47SK2QYC.ts +0 -56
  34. package/dist/chunks/chunk-47SK2QYC.ts.map +0 -7
  35. package/dist/chunks/chunk-4AQSF7AS.ts +0 -29
  36. package/dist/chunks/chunk-4AQSF7AS.ts.map +0 -7
  37. package/dist/chunks/chunk-5DGRMKNV.ts +0 -126
  38. package/dist/chunks/chunk-5DGRMKNV.ts.map +0 -7
  39. package/dist/chunks/chunk-6H6TBBED.ts +0 -108
  40. package/dist/chunks/chunk-6H6TBBED.ts.map +0 -7
  41. package/dist/chunks/chunk-6KJ34M6S.ts +0 -159
  42. package/dist/chunks/chunk-6KJ34M6S.ts.map +0 -7
  43. package/dist/chunks/chunk-6NSJVPXX.ts +0 -480
  44. package/dist/chunks/chunk-6NSJVPXX.ts.map +0 -7
  45. package/dist/chunks/chunk-7AAJEUSL.ts +0 -238
  46. package/dist/chunks/chunk-7AAJEUSL.ts.map +0 -7
  47. package/dist/chunks/chunk-BFK2Z4ZF.ts +0 -189
  48. package/dist/chunks/chunk-BFK2Z4ZF.ts.map +0 -7
  49. package/dist/chunks/chunk-BOAXY55Y.ts +0 -153
  50. package/dist/chunks/chunk-BOAXY55Y.ts.map +0 -7
  51. package/dist/chunks/chunk-D4CR7T73.ts +0 -353
  52. package/dist/chunks/chunk-D4CR7T73.ts.map +0 -7
  53. package/dist/chunks/chunk-FEVPWRMU.ts +0 -300
  54. package/dist/chunks/chunk-FEVPWRMU.ts.map +0 -7
  55. package/dist/chunks/chunk-G6VZTCFH.ts +0 -70
  56. package/dist/chunks/chunk-G6VZTCFH.ts.map +0 -7
  57. package/dist/chunks/chunk-H3FP6DLR.ts +0 -160
  58. package/dist/chunks/chunk-H3FP6DLR.ts.map +0 -7
  59. package/dist/chunks/chunk-HA36LPCO.ts +0 -130
  60. package/dist/chunks/chunk-HA36LPCO.ts.map +0 -7
  61. package/dist/chunks/chunk-HOP5FXDT.ts +0 -27
  62. package/dist/chunks/chunk-HOP5FXDT.ts.map +0 -7
  63. package/dist/chunks/chunk-IGAMVWFN.ts +0 -139
  64. package/dist/chunks/chunk-IGAMVWFN.ts.map +0 -7
  65. package/dist/chunks/chunk-ILEQ27AL.ts +0 -45
  66. package/dist/chunks/chunk-ILEQ27AL.ts.map +0 -7
  67. package/dist/chunks/chunk-ITVWPNU4.ts +0 -819
  68. package/dist/chunks/chunk-ITVWPNU4.ts.map +0 -7
  69. package/dist/chunks/chunk-IWC32VPY.ts +0 -172
  70. package/dist/chunks/chunk-IWC32VPY.ts.map +0 -7
  71. package/dist/chunks/chunk-JSZIP73U.ts +0 -362
  72. package/dist/chunks/chunk-JSZIP73U.ts.map +0 -7
  73. package/dist/chunks/chunk-JU6LUNLP.ts +0 -380
  74. package/dist/chunks/chunk-JU6LUNLP.ts.map +0 -7
  75. package/dist/chunks/chunk-KMGKCEO4.ts +0 -38
  76. package/dist/chunks/chunk-KMGKCEO4.ts.map +0 -7
  77. package/dist/chunks/chunk-LASD73CM.ts +0 -339
  78. package/dist/chunks/chunk-LASD73CM.ts.map +0 -7
  79. package/dist/chunks/chunk-LEOYDZI3.ts +0 -22
  80. package/dist/chunks/chunk-LEOYDZI3.ts.map +0 -7
  81. package/dist/chunks/chunk-LL4LP2T7.ts +0 -737
  82. package/dist/chunks/chunk-LL4LP2T7.ts.map +0 -7
  83. package/dist/chunks/chunk-N2T5IN4X.ts +0 -18
  84. package/dist/chunks/chunk-N2T5IN4X.ts.map +0 -7
  85. package/dist/chunks/chunk-N7BLVXKK.ts +0 -73
  86. package/dist/chunks/chunk-N7BLVXKK.ts.map +0 -7
  87. package/dist/chunks/chunk-NLT67IZS.ts +0 -322
  88. package/dist/chunks/chunk-NLT67IZS.ts.map +0 -7
  89. package/dist/chunks/chunk-NTRPLF46.ts +0 -63
  90. package/dist/chunks/chunk-NTRPLF46.ts.map +0 -7
  91. package/dist/chunks/chunk-ONDTY4EL.ts +0 -91
  92. package/dist/chunks/chunk-ONDTY4EL.ts.map +0 -7
  93. package/dist/chunks/chunk-OVPHFGKO.ts +0 -1769
  94. package/dist/chunks/chunk-OVPHFGKO.ts.map +0 -7
  95. package/dist/chunks/chunk-P7OH4XMF.ts +0 -60
  96. package/dist/chunks/chunk-P7OH4XMF.ts.map +0 -7
  97. package/dist/chunks/chunk-PBZMBTNJ.ts +0 -422
  98. package/dist/chunks/chunk-PBZMBTNJ.ts.map +0 -7
  99. package/dist/chunks/chunk-PGLSFLYW.ts +0 -52
  100. package/dist/chunks/chunk-PGLSFLYW.ts.map +0 -7
  101. package/dist/chunks/chunk-RRR66UWR.ts +0 -28
  102. package/dist/chunks/chunk-RRR66UWR.ts.map +0 -7
  103. package/dist/chunks/chunk-RSUXZD6S.ts +0 -275
  104. package/dist/chunks/chunk-RSUXZD6S.ts.map +0 -7
  105. package/dist/chunks/chunk-RTCVYIZA.ts +0 -221
  106. package/dist/chunks/chunk-RTCVYIZA.ts.map +0 -7
  107. package/dist/chunks/chunk-RY2AEGMZ.ts +0 -34
  108. package/dist/chunks/chunk-RY2AEGMZ.ts.map +0 -7
  109. package/dist/chunks/chunk-SWGQLFSD.ts +0 -60
  110. package/dist/chunks/chunk-SWGQLFSD.ts.map +0 -7
  111. package/dist/chunks/chunk-TM2R67J3.ts +0 -52
  112. package/dist/chunks/chunk-TM2R67J3.ts.map +0 -7
  113. package/dist/chunks/chunk-TMZRHIIK.ts +0 -497
  114. package/dist/chunks/chunk-TMZRHIIK.ts.map +0 -7
  115. package/dist/chunks/chunk-TZ34IQ3M.ts +0 -59
  116. package/dist/chunks/chunk-TZ34IQ3M.ts.map +0 -7
  117. package/dist/chunks/chunk-UMBPMVJW.ts +0 -22
  118. package/dist/chunks/chunk-UMBPMVJW.ts.map +0 -7
  119. package/dist/chunks/chunk-VDG7LTYE.ts +0 -80
  120. package/dist/chunks/chunk-VDG7LTYE.ts.map +0 -7
  121. package/dist/chunks/chunk-X4NMONPE.ts +0 -73
  122. package/dist/chunks/chunk-X4NMONPE.ts.map +0 -7
  123. package/dist/chunks/chunk-YPJEN6NU.ts +0 -65
  124. package/dist/chunks/chunk-YPJEN6NU.ts.map +0 -7
  125. package/dist/chunks/chunk-YU53SHA7.ts +0 -328
  126. package/dist/chunks/chunk-YU53SHA7.ts.map +0 -7
  127. package/dist/chunks/completion-delivery-RSJU6BXL.ts +0 -17
  128. package/dist/chunks/completion-delivery-RSJU6BXL.ts.map +0 -7
  129. package/dist/chunks/config-status-FKGDECZ3.ts +0 -35
  130. package/dist/chunks/config-status-FKGDECZ3.ts.map +0 -7
  131. package/dist/chunks/config-ui-ABHYNGQ7.ts +0 -1212
  132. package/dist/chunks/config-ui-ABHYNGQ7.ts.map +0 -7
  133. package/dist/chunks/consult-LJU3IQY5.ts +0 -519
  134. package/dist/chunks/consult-LJU3IQY5.ts.map +0 -7
  135. package/dist/chunks/context-QDKLVQXE.ts +0 -11
  136. package/dist/chunks/context-QDKLVQXE.ts.map +0 -7
  137. package/dist/chunks/create-stateful-transport-JWC2EFYL.ts +0 -130
  138. package/dist/chunks/create-stateful-transport-JWC2EFYL.ts.map +0 -7
  139. package/dist/chunks/cwd-policy-NB6XZ5GF.ts +0 -17
  140. package/dist/chunks/cwd-policy-NB6XZ5GF.ts.map +0 -7
  141. package/dist/chunks/delegation-contract-LA56I5DT.ts +0 -24
  142. package/dist/chunks/delegation-contract-LA56I5DT.ts.map +0 -7
  143. package/dist/chunks/discovery-MIFB2U4Y.ts +0 -12
  144. package/dist/chunks/discovery-MIFB2U4Y.ts.map +0 -7
  145. package/dist/chunks/execution-Q2JZLKJA.ts +0 -4037
  146. package/dist/chunks/execution-Q2JZLKJA.ts.map +0 -7
  147. package/dist/chunks/in-process-transport-HJ6TZXC3.ts +0 -39
  148. package/dist/chunks/in-process-transport-HJ6TZXC3.ts.map +0 -7
  149. package/dist/chunks/inspect-UH2TKH6E.ts +0 -634
  150. package/dist/chunks/inspect-UH2TKH6E.ts.map +0 -7
  151. package/dist/chunks/peer-communication-KL36Z6CO.ts +0 -294
  152. package/dist/chunks/peer-communication-KL36Z6CO.ts.map +0 -7
  153. package/dist/chunks/persistence-UY3PY6E5.ts +0 -348
  154. package/dist/chunks/persistence-UY3PY6E5.ts.map +0 -7
  155. package/dist/chunks/registry-BT54L6CY.ts +0 -1445
  156. package/dist/chunks/registry-BT54L6CY.ts.map +0 -7
  157. package/dist/chunks/retained-semantic-state-GM75FZGE.ts +0 -81
  158. package/dist/chunks/retained-semantic-state-GM75FZGE.ts.map +0 -7
  159. package/dist/chunks/rpc-transport-7R7DVCEB.ts +0 -1222
  160. package/dist/chunks/rpc-transport-7R7DVCEB.ts.map +0 -7
  161. package/dist/chunks/runtime-policy-5YELCOVC.ts +0 -15
  162. package/dist/chunks/runtime-policy-5YELCOVC.ts.map +0 -7
  163. package/dist/chunks/semantic-snapshot-WPJ3UAFW.ts +0 -19
  164. package/dist/chunks/semantic-snapshot-WPJ3UAFW.ts.map +0 -7
  165. package/dist/chunks/spawn-idempotency-BNHOSMZW.ts +0 -13
  166. package/dist/chunks/spawn-idempotency-BNHOSMZW.ts.map +0 -7
  167. package/dist/chunks/stateful-lifecycle-JAR6K55H.ts +0 -15
  168. package/dist/chunks/stateful-lifecycle-JAR6K55H.ts.map +0 -7
  169. package/dist/chunks/subprocess-transport-VHZJRBTW.ts +0 -160
  170. package/dist/chunks/subprocess-transport-VHZJRBTW.ts.map +0 -7
  171. package/dist/chunks/usage-recording-store-CW3EH2SZ.ts +0 -164
  172. package/dist/chunks/usage-recording-store-CW3EH2SZ.ts.map +0 -7
  173. package/dist/chunks/workspace-WDKLN72J.ts +0 -11
  174. package/dist/chunks/workspace-WDKLN72J.ts.map +0 -7
  175. package/docs/async-runtime-protocol.md +0 -84
  176. package/docs/implementation-notes/pi-subagents-capability-matrix.md +0 -62
  177. package/docs/implementation-notes/pi-subagents-current-direction.md +0 -99
  178. package/docs/implementation-notes/pi-subagents-rpc-v1.md +0 -153
  179. package/docs/pi-subagents-diagrams.md +0 -183
  180. package/src/adaptive-scheduler.ts +0 -224
  181. package/src/admission-benchmark.ts +0 -95
  182. package/src/admission-policy.ts +0 -78
  183. package/src/agent-projection.ts +0 -53
  184. package/src/agents/built-ins.ts +0 -71
  185. package/src/agents/catalog.ts +0 -241
  186. package/src/agents/discovery.ts +0 -265
  187. package/src/agents/types.ts +0 -100
  188. package/src/agents.ts +0 -51
  189. package/src/async-subagent-benchmark.ts +0 -532
  190. package/src/auto-transport.ts +0 -121
  191. package/src/blocking-status.ts +0 -63
  192. package/src/cached-module-loader.ts +0 -18
  193. package/src/capabilities.ts +0 -145
  194. package/src/capability-grant.ts +0 -115
  195. package/src/capability-router.ts +0 -107
  196. package/src/child-peer-bridge.ts +0 -124
  197. package/src/child-peer-tools.ts +0 -132
  198. package/src/completion-delivery.ts +0 -409
  199. package/src/completion-render.ts +0 -190
  200. package/src/completion-requirement.ts +0 -479
  201. package/src/completion-routing.ts +0 -24
  202. package/src/config-registration.ts +0 -114
  203. package/src/config-status.ts +0 -217
  204. package/src/config-ui.ts +0 -983
  205. package/src/consult-policy.ts +0 -15
  206. package/src/consult-registration.ts +0 -125
  207. package/src/consult-render.ts +0 -194
  208. package/src/consult-resources.ts +0 -51
  209. package/src/consult-tool.ts +0 -95
  210. package/src/consult.ts +0 -566
  211. package/src/context.ts +0 -126
  212. package/src/create-stateful-transport.ts +0 -157
  213. package/src/cwd-policy.ts +0 -183
  214. package/src/delegation-contract.ts +0 -463
  215. package/src/execution/budget.ts +0 -56
  216. package/src/execution/runtime-policy.ts +0 -19
  217. package/src/execution-plan.ts +0 -322
  218. package/src/execution-ui.ts +0 -259
  219. package/src/execution.ts +0 -1679
  220. package/src/in-process-transport.ts +0 -941
  221. package/src/inspect-registration.ts +0 -64
  222. package/src/inspect-render.ts +0 -334
  223. package/src/inspect-tool.ts +0 -45
  224. package/src/inspect.ts +0 -769
  225. package/src/integration-controller.ts +0 -98
  226. package/src/limits.ts +0 -75
  227. package/src/orchestration-metrics.ts +0 -116
  228. package/src/outcome.ts +0 -61
  229. package/src/panel-child-group.ts +0 -35
  230. package/src/panel-contract.ts +0 -343
  231. package/src/panel-evidence.ts +0 -59
  232. package/src/panel-execution.ts +0 -769
  233. package/src/panel-failure.ts +0 -56
  234. package/src/panel-planning.ts +0 -175
  235. package/src/panel-presets.ts +0 -3
  236. package/src/panel-prompts.ts +0 -132
  237. package/src/panel-reconciliation.ts +0 -57
  238. package/src/panel-render.ts +0 -103
  239. package/src/parallel-limit-ui.ts +0 -113
  240. package/src/params.ts +0 -278
  241. package/src/peer-communication.ts +0 -352
  242. package/src/peer-transport.ts +0 -49
  243. package/src/persistence.ts +0 -522
  244. package/src/pi-args.ts +0 -43
  245. package/src/pi-invocation.ts +0 -168
  246. package/src/process-control.ts +0 -43
  247. package/src/prompt-resources.ts +0 -38
  248. package/src/prompt-source-safety.ts +0 -48
  249. package/src/protocol.ts +0 -76
  250. package/src/registry-types.ts +0 -204
  251. package/src/registry.ts +0 -1698
  252. package/src/render-common.ts +0 -252
  253. package/src/render.ts +0 -704
  254. package/src/result-contract.ts +0 -431
  255. package/src/retained-semantic-state.ts +0 -100
  256. package/src/rpc-timeout-finalization.ts +0 -207
  257. package/src/rpc-transport-metadata.ts +0 -65
  258. package/src/rpc-transport.ts +0 -1035
  259. package/src/rpc-turn-capture.ts +0 -217
  260. package/src/runner-outcome.ts +0 -31
  261. package/src/runner-result.ts +0 -55
  262. package/src/runner-types.ts +0 -102
  263. package/src/runner-usage.ts +0 -48
  264. package/src/runner.ts +0 -866
  265. package/src/safe-text.ts +0 -67
  266. package/src/semantic-snapshot.ts +0 -214
  267. package/src/session-guidance-contract.ts +0 -399
  268. package/src/settings/inspection.ts +0 -302
  269. package/src/settings/schema.ts +0 -195
  270. package/src/settings-reader.ts +0 -215
  271. package/src/settings.ts +0 -452
  272. package/src/spawn-idempotency.ts +0 -68
  273. package/src/stateful-agent-view.ts +0 -85
  274. package/src/stateful-config.ts +0 -13
  275. package/src/stateful-guidance.ts +0 -29
  276. package/src/stateful-lifecycle.ts +0 -74
  277. package/src/stateful-limit-ui.ts +0 -249
  278. package/src/stateful-limits.ts +0 -96
  279. package/src/stateful-prompt.ts +0 -49
  280. package/src/stateful-registration.ts +0 -1320
  281. package/src/stateful-render.ts +0 -318
  282. package/src/stateful-safety.ts +0 -47
  283. package/src/stateful-tool-params.ts +0 -215
  284. package/src/stateful.ts +0 -12
  285. package/src/subagent-details.ts +0 -43
  286. package/src/subagents-extension.ts +0 -355
  287. package/src/subprocess-transport.ts +0 -145
  288. package/src/supervision.ts +0 -104
  289. package/src/task-path.ts +0 -65
  290. package/src/timeout-checkpoint.ts +0 -305
  291. package/src/timeout-finalization.ts +0 -75
  292. package/src/tool-schema-compatibility.ts +0 -73
  293. package/src/transport-types.ts +0 -74
  294. package/src/transport-ui.ts +0 -135
  295. package/src/transport.ts +0 -43
  296. package/src/turn-budget.ts +0 -109
  297. package/src/usage-format.ts +0 -42
  298. package/src/usage-recording-config.ts +0 -13
  299. package/src/usage-recording-store.ts +0 -183
  300. package/src/usage-recording.ts +0 -478
  301. package/src/verification-harness.ts +0 -516
  302. package/src/verification-policy.ts +0 -67
  303. package/src/verification-receipt.ts +0 -275
  304. package/src/verified-execution-benchmark.ts +0 -86
  305. package/src/verified-execution-contract.ts +0 -191
  306. package/src/verified-execution-schema.ts +0 -32
  307. package/src/work-item-ledger.ts +0 -1404
  308. package/src/work-item-persistence.ts +0 -254
  309. package/src/workflow-completion-controller.ts +0 -397
  310. package/src/workflow-planning.ts +0 -172
  311. package/src/workflow-tree-identity.ts +0 -289
  312. package/src/workflow-ui.ts +0 -69
  313. package/src/workflow-verification.ts +0 -296
  314. package/src/workspace.ts +0 -174
@@ -0,0 +1,667 @@
1
+ // @generated by scripts/build-runtime.mjs; do not edit.
2
+ // @ts-nocheck -- generated entries use .ts extensions for Pi's Jiti loader.
3
+
4
+ // src/message-broker.ts
5
+ import { randomBytes, randomUUID } from "node:crypto";
6
+ import net from "node:net";
7
+ var BROKER_HOST = "127.0.0.1";
8
+ var MAX_MESSAGE_BYTES = 48 * 1024;
9
+ var MAX_MESSAGE_LINES = 1992;
10
+ var MAX_FRAME_BYTES = 384 * 1024;
11
+ var MAX_ERROR_BYTES = 8 * 1024;
12
+ var MAX_OUTSTANDING_REQUESTS = 4;
13
+ var MAX_IDENTIFIER_LENGTH = 128;
14
+ var MAX_CONNECTIONS = 32;
15
+ var REQUEST_FRAME_TIMEOUT_MS = 2e3;
16
+ var MAX_TIMEOUT_MS = 2147483647;
17
+ var MAX_RETAINED_CONSUMED_REQUESTS = 4;
18
+ var CHILD_WAIT_INTERRUPTED_ERROR = "Subagent wait was interrupted by an incoming main-agent request. The original request remains active.";
19
+ var MessageBroker = class {
20
+ constructor(options) {
21
+ this.options = options;
22
+ this.createServer = options.createServer ?? ((listener) => net.createServer(listener));
23
+ this.now = options.now ?? Date.now;
24
+ this.requestFrameTimeoutMs = options.requestFrameTimeoutMs ?? REQUEST_FRAME_TIMEOUT_MS;
25
+ if (!Number.isFinite(this.requestFrameTimeoutMs) || this.requestFrameTimeoutMs <= 0) {
26
+ throw new Error("Subagent broker frame timeout must be positive.");
27
+ }
28
+ }
29
+ options;
30
+ server;
31
+ starting;
32
+ address;
33
+ failure;
34
+ generation = 0;
35
+ sockets = /* @__PURE__ */ new Set();
36
+ jobsByToken = /* @__PURE__ */ new Map();
37
+ tokenByJob = /* @__PURE__ */ new Map();
38
+ requests = /* @__PURE__ */ new Map();
39
+ inboundMessageListeners = /* @__PURE__ */ new Set();
40
+ pendingInboundResponse = false;
41
+ createServer;
42
+ now;
43
+ requestFrameTimeoutMs;
44
+ async start() {
45
+ if (this.server && this.address && !this.failure) return;
46
+ if (this.starting) return this.starting;
47
+ const ownerGeneration = ++this.generation;
48
+ this.failure = void 0;
49
+ this.starting = new Promise((resolve, reject) => {
50
+ const server = this.createServer((socket) => this.accept(socket));
51
+ server.maxConnections = MAX_CONNECTIONS;
52
+ const onStartError = (error) => {
53
+ server.close(() => void 0);
54
+ reject(error);
55
+ };
56
+ server.once("error", onStartError);
57
+ server.listen({ host: BROKER_HOST, port: 0 }, () => {
58
+ server.off("error", onStartError);
59
+ if (ownerGeneration !== this.generation) {
60
+ server.close(() => void 0);
61
+ reject(new Error("Subagent message broker start was superseded."));
62
+ return;
63
+ }
64
+ const address = server.address();
65
+ if (!isLoopbackAddress(address)) {
66
+ server.close(() => void 0);
67
+ reject(new Error("Subagent message broker did not bind to loopback."));
68
+ return;
69
+ }
70
+ this.server = server;
71
+ this.address = { host: BROKER_HOST, port: address.port };
72
+ server.on("error", (error) => this.fail(error));
73
+ server.unref();
74
+ resolve();
75
+ });
76
+ }).catch((error) => {
77
+ const message = truncateError(error instanceof Error ? error.message : String(error));
78
+ this.failure = message;
79
+ throw new Error(`Subagent message broker failed to start: ${message}`);
80
+ }).finally(() => {
81
+ this.starting = void 0;
82
+ });
83
+ return this.starting;
84
+ }
85
+ assertReady() {
86
+ if (this.server && this.address && !this.failure) return;
87
+ throw new Error(
88
+ this.failure ? `Subagent messaging is unavailable: ${this.failure}` : "Subagent messaging is unavailable because the session broker is not ready."
89
+ );
90
+ }
91
+ issueCredentials(input) {
92
+ this.assertReady();
93
+ if (this.tokenByJob.has(input.jobId)) {
94
+ throw new Error(`Subagent messaging credentials already exist for ${input.jobId}.`);
95
+ }
96
+ const token = randomBytes(32).toString("hex");
97
+ const record = { ...input, token };
98
+ this.jobsByToken.set(token, record);
99
+ this.tokenByJob.set(input.jobId, token);
100
+ return { host: BROKER_HOST, port: this.address?.port ?? 0, token };
101
+ }
102
+ createMainRequest(jobId, message) {
103
+ this.assertReady();
104
+ const job = this.requireJob(jobId);
105
+ return this.createRequest(job, "main", message);
106
+ }
107
+ replyFromMain(requestId, message) {
108
+ this.assertReady();
109
+ return this.acceptResponse("main", void 0, requestId, message);
110
+ }
111
+ rollbackMainRequest(requestId) {
112
+ const request = this.requests.get(requestId);
113
+ if (request?.origin === "main" && request.response === void 0) {
114
+ this.clearWaiter(request);
115
+ this.requests.delete(requestId);
116
+ }
117
+ }
118
+ revokeJob(jobId, reason = "Subagent job is no longer active.") {
119
+ const token = this.tokenByJob.get(jobId);
120
+ if (token) {
121
+ this.tokenByJob.delete(jobId);
122
+ this.jobsByToken.delete(token);
123
+ }
124
+ for (const request of [...this.requests.values()]) {
125
+ if (request.jobId !== jobId) continue;
126
+ if (request.waiter) this.respondError(request.waiter.socket, reason);
127
+ this.clearWaiter(request);
128
+ this.requests.delete(request.requestId);
129
+ }
130
+ }
131
+ hasPendingMainRequest() {
132
+ return [...this.requests.values()].some(
133
+ (request) => request.origin === "child" && request.response === void 0
134
+ );
135
+ }
136
+ takePendingInboundResponse() {
137
+ const pending = this.pendingInboundResponse;
138
+ this.pendingInboundResponse = false;
139
+ return pending;
140
+ }
141
+ markMainRequestQueued(requestId) {
142
+ const request = this.requests.get(requestId);
143
+ if (request?.origin !== "main") {
144
+ throw new Error("Unknown or expired main-agent subagent request.");
145
+ }
146
+ request.deliveryQueued = true;
147
+ return request.response === void 0;
148
+ }
149
+ interruptChildWaits(jobId) {
150
+ let interrupted = 0;
151
+ for (const request of this.requests.values()) {
152
+ if (request.jobId !== jobId || request.origin !== "child" || !request.waiter) continue;
153
+ const socket = request.waiter.socket;
154
+ this.clearWaiter(request);
155
+ this.respondError(socket, CHILD_WAIT_INTERRUPTED_ERROR);
156
+ interrupted++;
157
+ }
158
+ return interrupted;
159
+ }
160
+ subscribeInboundMessage(listener) {
161
+ this.inboundMessageListeners.add(listener);
162
+ if (this.hasPendingMainRequest()) listener();
163
+ return () => this.inboundMessageListeners.delete(listener);
164
+ }
165
+ async shutdown() {
166
+ ++this.generation;
167
+ const starting = this.starting;
168
+ if (starting) await starting.catch(() => void 0);
169
+ for (const jobId of [...this.tokenByJob.keys()]) {
170
+ this.revokeJob(jobId, "Subagent session shut down.");
171
+ }
172
+ this.requests.clear();
173
+ this.inboundMessageListeners.clear();
174
+ this.pendingInboundResponse = false;
175
+ for (const socket of this.sockets) socket.destroy();
176
+ this.sockets.clear();
177
+ const server = this.server;
178
+ this.server = void 0;
179
+ this.address = void 0;
180
+ this.failure = void 0;
181
+ if (!server?.listening) return;
182
+ await new Promise((resolve) => server.close(() => resolve()));
183
+ }
184
+ requireJob(jobId) {
185
+ const token = this.tokenByJob.get(jobId);
186
+ const job = token ? this.jobsByToken.get(token) : void 0;
187
+ if (!job) throw new Error("Unknown or inactive subagent job.");
188
+ return job;
189
+ }
190
+ hasQueuedRequestForChild(jobId) {
191
+ return [...this.requests.values()].some(
192
+ (request) => request.jobId === jobId && request.origin === "main" && request.deliveryQueued === true && request.response === void 0
193
+ );
194
+ }
195
+ createRequest(job, origin, message) {
196
+ validateMessage(message, "Subagent request");
197
+ const outstanding = [...this.requests.values()].filter(
198
+ (request2) => request2.jobId === job.jobId && request2.consumedAt === void 0
199
+ ).length;
200
+ if (outstanding >= MAX_OUTSTANDING_REQUESTS) {
201
+ throw new Error(
202
+ `Subagent job may have at most ${MAX_OUTSTANDING_REQUESTS} outstanding requests.`
203
+ );
204
+ }
205
+ const request = {
206
+ requestId: `req_${randomUUID()}`,
207
+ jobId: job.jobId,
208
+ generation: job.generation,
209
+ origin,
210
+ expectedResponder: origin === "main" ? "child" : "main",
211
+ message,
212
+ createdAt: this.now()
213
+ };
214
+ this.requests.set(request.requestId, request);
215
+ if (origin === "child") {
216
+ try {
217
+ this.deliverInbound({
218
+ kind: "request",
219
+ requestId: request.requestId,
220
+ jobId: request.jobId,
221
+ message: request.message
222
+ });
223
+ } catch (error) {
224
+ this.requests.delete(request.requestId);
225
+ throw error;
226
+ }
227
+ }
228
+ return { requestId: request.requestId, accepted: true, duplicate: false };
229
+ }
230
+ acceptResponse(responder, job, requestId, message) {
231
+ validateRequestId(requestId);
232
+ validateMessage(message, "Subagent response");
233
+ const request = this.requests.get(requestId);
234
+ if (!request || request.expectedResponder !== responder || job && (request.jobId !== job.jobId || request.generation !== job.generation)) {
235
+ throw new Error("Unknown, expired, or unauthorized subagent request.");
236
+ }
237
+ if (request.response !== void 0) {
238
+ return { requestId, accepted: false, duplicate: true };
239
+ }
240
+ request.response = message;
241
+ if (responder === "child") {
242
+ try {
243
+ this.deliverInbound({
244
+ kind: "response",
245
+ requestId,
246
+ jobId: request.jobId,
247
+ message
248
+ });
249
+ this.markConsumed(request);
250
+ } catch (error) {
251
+ request.response = void 0;
252
+ throw error;
253
+ }
254
+ } else if (request.waiter) {
255
+ const socket = request.waiter.socket;
256
+ this.clearWaiter(request);
257
+ this.respond(socket, { ok: true, response: message }, () => this.markConsumed(request));
258
+ }
259
+ return { requestId, accepted: true, duplicate: false };
260
+ }
261
+ deliverInbound(message) {
262
+ this.options.onMessage(message);
263
+ if (message.kind === "response" && this.inboundMessageListeners.size === 0) {
264
+ this.pendingInboundResponse = true;
265
+ }
266
+ for (const listener of [...this.inboundMessageListeners]) {
267
+ try {
268
+ listener();
269
+ } catch {
270
+ }
271
+ }
272
+ }
273
+ accept(socket) {
274
+ if (!this.server || this.failure || this.sockets.size >= MAX_CONNECTIONS) {
275
+ socket.destroy();
276
+ return;
277
+ }
278
+ this.sockets.add(socket);
279
+ socket.setNoDelay(true);
280
+ let frame = Buffer.alloc(0);
281
+ let handled = false;
282
+ const frameTimer = setTimeout(() => {
283
+ if (handled) return;
284
+ handled = true;
285
+ this.respondError(socket, "Subagent broker request frame timed out.");
286
+ }, this.requestFrameTimeoutMs);
287
+ frameTimer.unref();
288
+ const cleanup = () => {
289
+ clearTimeout(frameTimer);
290
+ this.sockets.delete(socket);
291
+ for (const request of this.requests.values()) {
292
+ if (request.waiter?.socket === socket) this.clearWaiter(request);
293
+ }
294
+ };
295
+ socket.on("data", (chunk) => {
296
+ if (handled) return;
297
+ frame = Buffer.concat([frame, chunk]);
298
+ if (frame.byteLength > MAX_FRAME_BYTES) {
299
+ handled = true;
300
+ clearTimeout(frameTimer);
301
+ this.respondError(socket, "Subagent broker request exceeded its size limit.");
302
+ return;
303
+ }
304
+ const newline = frame.indexOf(10);
305
+ if (newline < 0) return;
306
+ handled = true;
307
+ clearTimeout(frameTimer);
308
+ socket.removeAllListeners("data");
309
+ const trailing = frame.subarray(newline + 1).toString("utf8").trim();
310
+ if (trailing) {
311
+ this.respondError(socket, "Subagent broker accepts one request per connection.");
312
+ return;
313
+ }
314
+ this.handleFrame(socket, frame.subarray(0, newline).toString("utf8"));
315
+ });
316
+ socket.once("close", cleanup);
317
+ socket.once("error", cleanup);
318
+ }
319
+ handleFrame(socket, frame) {
320
+ let request;
321
+ try {
322
+ const parsed = JSON.parse(frame);
323
+ if (!isRecord(parsed)) throw new Error();
324
+ request = parsed;
325
+ } catch {
326
+ this.respondError(socket, "Malformed subagent broker request.");
327
+ return;
328
+ }
329
+ const job = typeof request.token === "string" ? this.jobsByToken.get(request.token) : void 0;
330
+ if (!job) {
331
+ this.respondError(socket, "Unauthenticated subagent broker request.");
332
+ return;
333
+ }
334
+ try {
335
+ if (request.type === "send") {
336
+ this.handleSend(socket, job, request);
337
+ return;
338
+ }
339
+ if (request.type === "wait") {
340
+ this.handleWait(socket, job, request);
341
+ return;
342
+ }
343
+ throw new Error("Unsupported subagent broker request.");
344
+ } catch (error) {
345
+ this.respondError(socket, error instanceof Error ? error.message : String(error));
346
+ }
347
+ }
348
+ handleSend(socket, job, request) {
349
+ if (typeof request.message !== "string") {
350
+ throw new Error("subagent_send requires a message string.");
351
+ }
352
+ const hasRecipient = typeof request.recipient === "string";
353
+ const hasRequestId = typeof request.requestId === "string";
354
+ if (hasRecipient === hasRequestId) {
355
+ throw new Error("subagent_send requires exactly one of recipient or requestId.");
356
+ }
357
+ const acknowledgement = hasRecipient ? request.recipient === "main" ? this.createRequest(job, "child", request.message) : (() => {
358
+ throw new Error('A subagent may send new requests only to recipient "main".');
359
+ })() : this.acceptResponse("child", job, request.requestId ?? "", request.message);
360
+ this.respond(socket, { ok: true, ...acknowledgement });
361
+ }
362
+ handleWait(socket, job, request) {
363
+ if (typeof request.requestId !== "string") {
364
+ throw new Error("Subagent wait requires a request ID.");
365
+ }
366
+ validateRequestId(request.requestId);
367
+ if (request.timeoutMs !== void 0) validateTimeout(request.timeoutMs);
368
+ const record = this.requests.get(request.requestId);
369
+ if (record?.origin !== "child" || record.jobId !== job.jobId || record.generation !== job.generation) {
370
+ throw new Error("Unknown or expired subagent request.");
371
+ }
372
+ if (record.consumedAt !== void 0 && record.response !== void 0) {
373
+ this.respond(socket, { ok: true, response: record.response });
374
+ return;
375
+ }
376
+ if (record.response !== void 0) {
377
+ this.respond(
378
+ socket,
379
+ { ok: true, response: record.response },
380
+ () => this.markConsumed(record)
381
+ );
382
+ return;
383
+ }
384
+ if (this.hasQueuedRequestForChild(job.jobId)) {
385
+ this.respondError(socket, CHILD_WAIT_INTERRUPTED_ERROR);
386
+ return;
387
+ }
388
+ if (record.waiter) {
389
+ throw new Error(`A wait is already active for subagent request ${request.requestId}.`);
390
+ }
391
+ const waiter = { socket };
392
+ record.waiter = waiter;
393
+ if (request.timeoutMs !== void 0) {
394
+ waiter.timer = setTimeout(() => {
395
+ if (record.waiter !== waiter) return;
396
+ this.clearWaiter(record);
397
+ this.respondError(socket, "Subagent response wait timed out.");
398
+ }, request.timeoutMs);
399
+ waiter.timer.unref();
400
+ }
401
+ }
402
+ markConsumed(request) {
403
+ if (this.requests.get(request.requestId) !== request || request.response === void 0) return;
404
+ request.consumedAt ??= this.now();
405
+ const consumed = [...this.requests.values()].filter(
406
+ (candidate) => candidate.jobId === request.jobId && candidate.consumedAt !== void 0
407
+ ).sort((left, right) => (left.consumedAt ?? 0) - (right.consumedAt ?? 0));
408
+ for (const expired of consumed.slice(
409
+ 0,
410
+ Math.max(0, consumed.length - MAX_RETAINED_CONSUMED_REQUESTS)
411
+ )) {
412
+ this.requests.delete(expired.requestId);
413
+ }
414
+ }
415
+ clearWaiter(request) {
416
+ if (request.waiter?.timer) clearTimeout(request.waiter.timer);
417
+ request.waiter = void 0;
418
+ }
419
+ respondError(socket, error) {
420
+ this.respond(socket, { ok: false, error: truncateError(error) });
421
+ }
422
+ respond(socket, value, onFlushed) {
423
+ if (socket.destroyed) return;
424
+ let content = `${JSON.stringify(value)}
425
+ `;
426
+ if (Buffer.byteLength(content, "utf8") > MAX_FRAME_BYTES) {
427
+ content = `${JSON.stringify({ ok: false, error: "Subagent broker response exceeded its size limit." })}
428
+ `;
429
+ }
430
+ socket.end(content, onFlushed);
431
+ }
432
+ fail(error) {
433
+ this.failure = truncateError(error.message);
434
+ for (const jobId of [...this.tokenByJob.keys()]) {
435
+ this.revokeJob(jobId, "Subagent message broker failed.");
436
+ }
437
+ for (const socket of this.sockets) socket.destroy();
438
+ this.sockets.clear();
439
+ this.address = void 0;
440
+ }
441
+ };
442
+ function validateMessage(message, label) {
443
+ if (!message.trim()) throw new Error(`${label} is required.`);
444
+ if (message.includes("\0")) throw new Error(`${label} must not contain NUL bytes.`);
445
+ if (Buffer.byteLength(message, "utf8") > MAX_MESSAGE_BYTES) {
446
+ throw new Error(`${label} must be at most ${MAX_MESSAGE_BYTES} UTF-8 bytes.`);
447
+ }
448
+ if (lineCount(message) > MAX_MESSAGE_LINES) {
449
+ throw new Error(`${label} must contain at most ${MAX_MESSAGE_LINES} lines.`);
450
+ }
451
+ }
452
+ function sanitizeTerminalText(value) {
453
+ return [...value].filter((character) => {
454
+ const codePoint = character.codePointAt(0) ?? 0;
455
+ if (character === "\n" || character === " ") return true;
456
+ if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) return false;
457
+ return !(codePoint >= 8234 && codePoint <= 8238 || codePoint >= 8294 && codePoint <= 8297);
458
+ }).join("");
459
+ }
460
+ function validateRequestId(requestId) {
461
+ if (requestId.length > MAX_IDENTIFIER_LENGTH || !/^req_[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u.test(requestId)) {
462
+ throw new Error("Invalid subagent request ID.");
463
+ }
464
+ }
465
+ function validateTimeout(timeoutMs) {
466
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > MAX_TIMEOUT_MS) {
467
+ throw new Error("Subagent wait timeout is outside the supported range.");
468
+ }
469
+ }
470
+ function lineCount(value) {
471
+ let count = 1;
472
+ for (const character of value) if (character === "\n") count++;
473
+ return count;
474
+ }
475
+ function truncateError(error) {
476
+ const bytes = Buffer.from(error, "utf8");
477
+ if (bytes.length <= MAX_ERROR_BYTES) return error;
478
+ return `${bytes.subarray(0, Math.max(0, MAX_ERROR_BYTES - 18)).toString("utf8").replace(/�+$/gu, "")}
479
+ \u2026 [truncated]`;
480
+ }
481
+ function isRecord(value) {
482
+ return typeof value === "object" && value !== null && !Array.isArray(value);
483
+ }
484
+ function isLoopbackAddress(address) {
485
+ return Boolean(address && typeof address !== "string" && address.address === BROKER_HOST);
486
+ }
487
+
488
+ // src/broker-credentials.ts
489
+ import * as fs from "node:fs";
490
+ var BROKER_CREDENTIAL_FD = 3;
491
+ var BROKER_CREDENTIAL_FD_ENV = "PI_SUBAGENT_BROKER_FD";
492
+ var MAX_CREDENTIAL_BYTES = 1024;
493
+ function brokerCredentialEnvironment() {
494
+ return { [BROKER_CREDENTIAL_FD_ENV]: String(BROKER_CREDENTIAL_FD) };
495
+ }
496
+ function serializeBrokerCredentials(credentials) {
497
+ return JSON.stringify(credentials);
498
+ }
499
+ function captureBrokerCredentials(readCredentials = readCredentialPipe) {
500
+ const descriptor = process.env[BROKER_CREDENTIAL_FD_ENV];
501
+ delete process.env[BROKER_CREDENTIAL_FD_ENV];
502
+ if (descriptor === void 0) return void 0;
503
+ if (descriptor !== String(BROKER_CREDENTIAL_FD)) {
504
+ throw new Error("Invalid pi-subagents broker credential descriptor.");
505
+ }
506
+ let serialized;
507
+ try {
508
+ serialized = readCredentials();
509
+ } catch {
510
+ throw new Error("Unable to read pi-subagents broker credentials.");
511
+ }
512
+ if (Buffer.byteLength(serialized, "utf8") > MAX_CREDENTIAL_BYTES) {
513
+ throw new Error("Invalid pi-subagents broker credentials.");
514
+ }
515
+ let value;
516
+ try {
517
+ value = JSON.parse(serialized);
518
+ } catch {
519
+ throw new Error("Invalid pi-subagents broker credentials.");
520
+ }
521
+ if (!isBrokerCredentials(value)) {
522
+ throw new Error("Invalid pi-subagents broker credentials.");
523
+ }
524
+ return value;
525
+ }
526
+ function readCredentialPipe() {
527
+ try {
528
+ return fs.readFileSync(BROKER_CREDENTIAL_FD, "utf8");
529
+ } finally {
530
+ try {
531
+ fs.closeSync(BROKER_CREDENTIAL_FD);
532
+ } catch {
533
+ }
534
+ }
535
+ }
536
+ function isBrokerCredentials(value) {
537
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
538
+ const candidate = value;
539
+ return Object.keys(candidate).length === 3 && candidate.host === "127.0.0.1" && Number.isSafeInteger(candidate.port) && candidate.port >= 1 && candidate.port <= 65535 && typeof candidate.token === "string" && /^[a-f0-9]{64}$/u.test(candidate.token);
540
+ }
541
+
542
+ // src/child-communication-tools.ts
543
+ import { Type } from "typebox";
544
+ var CHILD_COMMUNICATION_TOOL_NAMES = ["subagent_send", "subagent_wait"];
545
+ var MAX_TIMEOUT_MS2 = 2147483647;
546
+ var MAX_TIMEOUT_SECONDS = MAX_TIMEOUT_MS2 / 1e3;
547
+ var SendParameters = Type.Object(
548
+ {
549
+ requestId: Type.Optional(
550
+ Type.String({
551
+ description: "Pending main-agent request to answer. Omit when starting a new request.",
552
+ minLength: 1,
553
+ maxLength: MAX_IDENTIFIER_LENGTH
554
+ })
555
+ ),
556
+ message: Type.String({
557
+ description: "Plain-text request or response. Maximum 48 KiB of UTF-8 text and 1,992 lines.",
558
+ minLength: 1,
559
+ maxLength: MAX_MESSAGE_BYTES
560
+ })
561
+ },
562
+ { additionalProperties: false }
563
+ );
564
+ var WaitParameters = Type.Object(
565
+ {
566
+ requestId: Type.String({
567
+ description: "Request ID returned by subagent_send.",
568
+ minLength: 1,
569
+ maxLength: MAX_IDENTIFIER_LENGTH
570
+ }),
571
+ timeout: Type.Optional(
572
+ Type.Number({ description: "Timeout in seconds (optional, no default timeout)" })
573
+ )
574
+ },
575
+ { additionalProperties: false }
576
+ );
577
+ function createChildCommunicationExtension(client) {
578
+ return (pi) => {
579
+ pi.registerTool({
580
+ name: "subagent_send",
581
+ label: "Subagent \xB7 Send to Main",
582
+ description: "Use subagent_send to send one request to the main agent or answer one pending main-agent request. Omit requestId to start a request. Provide requestId to answer that request.",
583
+ promptSnippet: "Use subagent_send to send or answer one main-agent message",
584
+ parameters: SendParameters,
585
+ async execute(_toolCallId, params, signal) {
586
+ validateMessage(params.message, "Subagent message");
587
+ const requestId = optionalIdentifier(params.requestId, "requestId");
588
+ const acknowledgement = await client.send(
589
+ requestId === void 0 ? { recipient: "main", message: params.message } : { requestId, message: params.message },
590
+ signal
591
+ );
592
+ return {
593
+ content: [{ type: "text", text: JSON.stringify(acknowledgement) }],
594
+ details: acknowledgement
595
+ };
596
+ }
597
+ });
598
+ pi.registerTool({
599
+ name: "subagent_wait",
600
+ label: "Subagent \xB7 Wait for Main Agent",
601
+ description: "Use subagent_wait with a request ID from subagent_send to wait for the main agent's plain-text response. A timeout, caller cancellation, or incoming main-agent request stops only this wait and does not cancel the original request. Retry the wait when its response is still needed.",
602
+ promptSnippet: "Use subagent_wait to receive a requested main-agent response",
603
+ parameters: WaitParameters,
604
+ prepareArguments: prepareWaitArguments,
605
+ async execute(_toolCallId, params, signal) {
606
+ const requestId = requiredIdentifier(params.requestId, "requestId");
607
+ const response = await client.wait(requestId, resolveTimeoutMs(params.timeout), signal);
608
+ return {
609
+ content: [{ type: "text", text: sanitizeTerminalText(response) }],
610
+ details: { requestId }
611
+ };
612
+ }
613
+ });
614
+ };
615
+ }
616
+ function resolveTimeoutMs(timeout) {
617
+ if (timeout === void 0) return void 0;
618
+ if (!Number.isFinite(timeout) || timeout <= 0) {
619
+ throw new Error("Invalid timeout: must be a finite number of seconds");
620
+ }
621
+ const timeoutMs = timeout * 1e3;
622
+ if (timeoutMs > MAX_TIMEOUT_MS2) {
623
+ throw new Error(`Invalid timeout: maximum is ${MAX_TIMEOUT_SECONDS} seconds`);
624
+ }
625
+ return timeoutMs;
626
+ }
627
+ function prepareWaitArguments(args) {
628
+ if (!args || typeof args !== "object") return args;
629
+ if (!Object.hasOwn(args, "timeoutMs")) return args;
630
+ const record = args;
631
+ if (typeof record.timeoutMs !== "number") return record;
632
+ const { timeoutMs, ...prepared } = record;
633
+ if (prepared.timeout === void 0) {
634
+ return { ...prepared, timeout: timeoutMs / 1e3 };
635
+ }
636
+ return prepared;
637
+ }
638
+ function optionalIdentifier(value, field) {
639
+ return value === void 0 ? void 0 : requiredIdentifier(value, field);
640
+ }
641
+ function requiredIdentifier(value, field) {
642
+ if (typeof value !== "string" || !value.trim()) throw new Error(`Subagent ${field} is required.`);
643
+ const identifier = value.trim();
644
+ if (identifier.length > MAX_IDENTIFIER_LENGTH || [...identifier].some((character) => {
645
+ const codePoint = character.codePointAt(0) ?? 0;
646
+ return codePoint <= 31 || codePoint >= 127 && codePoint <= 159;
647
+ })) {
648
+ throw new Error(`Subagent ${field} is invalid.`);
649
+ }
650
+ return identifier;
651
+ }
652
+
653
+ export {
654
+ MAX_MESSAGE_BYTES,
655
+ MAX_FRAME_BYTES,
656
+ MAX_IDENTIFIER_LENGTH,
657
+ MessageBroker,
658
+ validateMessage,
659
+ sanitizeTerminalText,
660
+ BROKER_CREDENTIAL_FD,
661
+ brokerCredentialEnvironment,
662
+ serializeBrokerCredentials,
663
+ captureBrokerCredentials,
664
+ CHILD_COMMUNICATION_TOOL_NAMES,
665
+ createChildCommunicationExtension
666
+ };
667
+ //# sourceMappingURL=chunk-UKTWUQRM.js.map