@narumitw/pi-subagents 3.0.0 → 3.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.
package/README.md CHANGED
@@ -20,7 +20,6 @@ Pi Subagents runs Pi jobs in separate child processes and supports authenticated
20
20
  ## 📦 Install
21
21
 
22
22
  The version 3 runtime documented here is not yet published to npm.
23
-
24
23
  The npm package still contains the legacy 2.x runtime and does not provide the tools below.
25
24
 
26
25
  Install the repository source as one Pi package:
@@ -49,39 +48,27 @@ pi --no-extensions -e ./packages/pi-subagents
49
48
  ```
50
49
 
51
50
  The package entry is generated at `dist/index.ts` and loaded through Pi's Jiti runtime.
52
-
53
51
  An unbuilt local package directory cannot load its declared extension entry.
54
52
 
55
53
  Pi extensions and children with `bash`, `powershell`, `edit`, or `write` execute with your user permissions.
56
-
57
54
  Review the source before installing or invoking the extension.
58
55
 
59
56
  ## 🚀 Quick start
60
57
 
61
58
  Call `subagent_spawn` with a self-contained task and only the work tools that task needs.
62
59
 
63
- The package intentionally does not register or publish a skill.
64
-
65
- Create a project skill under `.pi/skills/<your-skill>/SKILL.md` or a global skill under `~/.pi/agent/skills/<your-skill>/SKILL.md` when you want reusable delegation policy.
66
-
67
- Choose a name, trigger description, tool policy, task format, and verification workflow for your own use case.
68
-
69
- The repository-only [`using-pi-subagents` example](https://github.com/narumiruna/pi-extensions/tree/main/packages/pi-subagents/skills/using-pi-subagents) demonstrates one possible design without imposing it on installed users.
70
-
71
60
  The call returns a `jobId` immediately, and the job continues in the background.
72
-
73
61
  Continue useful main-agent work until the result is required or a completion arrives.
74
62
 
75
- Call `subagent_send` with `recipient: jobId` to ask an active child a question.
76
-
77
- If `subagent_wait` returns `reason: "subagent_message"`, handle the visible request or response and wait for the job again only when needed.
63
+ Use messaging only when needed:
78
64
 
79
- Answer a child-originated request by calling `subagent_send` with its `requestId`.
65
+ - Call `subagent_send` with `recipient: jobId` to ask an active child a question.
66
+ - If `subagent_wait` returns `reason: "subagent_message"`, handle the visible request or response and wait for the job again only when needed.
67
+ - Answer a child-originated request by calling `subagent_send` with its `requestId`.
80
68
 
81
69
  Completion messages follow Pi's global tool-output expansion state and the `app.tools.expand` binding (`Ctrl+O` by default).
82
70
 
83
71
  In TUI mode, the above-editor widget shows each queued or running job's ID, state, elapsed time, timeout, and selected work tools.
84
-
85
72
  The widget omits the fixed communication tools, disappears when no jobs remain active, and clears when the session ends.
86
73
 
87
74
  ## 🛠️ Tools
@@ -103,34 +90,23 @@ Every child exposes these communication tools in addition to its selected work t
103
90
  | `subagent_send` | optional `requestId`, plus `message` | Omit `requestId` to send a new request to main, or provide it to answer one pending main-agent request. |
104
91
  | `subagent_wait` | `requestId`, optional `timeout` | Wait for the main agent's plain-text response to a child-originated request. |
105
92
 
106
- Main and child processes receive separate provider-visible `subagent_send` definitions for their own context.
107
-
108
- The main agent starts a request with an active job ID as `recipient` and omits `requestId`.
109
-
110
- The main agent answers a child request with `requestId` and omits `recipient`.
111
-
112
- A child starts a request to main by omitting `requestId`.
93
+ Main and child processes receive separate provider-visible `subagent_send` definitions for their own context:
113
94
 
114
- A child answers a main-agent request by providing `requestId`.
95
+ - The main agent starts a request with an active job ID as `recipient` and omits `requestId`.
96
+ - The main agent answers a child request with `requestId` and omits `recipient`.
97
+ - A child starts a request to main by omitting `requestId`.
98
+ - A child answers a main-agent request by providing `requestId`.
115
99
 
116
100
  Execution and wait timeouts use seconds, accept finite numbers greater than zero through 2,147,483.647, and have no default.
117
-
118
101
  Omitting a job execution timeout lets the child run until it exits, is cancelled, the session shuts down, or the Pi process exits.
119
-
120
102
  A wait timeout or caller cancellation stops only that wait and does not cancel its job or message request.
121
-
122
103
  An incoming main-agent request interrupts an active child `subagent_wait` after RPC steering is queued so the child can receive the new request.
123
-
124
104
  The interrupted child-originated request remains active and may be waited on again.
125
105
 
126
106
  Tasks are limited to 50 KiB of UTF-8 text.
127
-
128
107
  Requests and responses are limited to 48 KiB and 1,992 lines so their protocol envelopes fit Pi's 50 KiB and 2,000-line model-text bounds without truncating accepted content.
129
-
130
108
  Each job may have up to four unresolved or answered-but-not-consumed requests across both directions.
131
-
132
109
  The terminal states are `completed`, `partial`, `failed`, `timed_out`, and `cancelled`.
133
-
134
110
  `subagent_inspect` never returns complete task text, child output, prompts, selected tools, context, credentials, environment variables, requests, responses, or secrets.
135
111
 
136
112
  See [`docs/tools.md`](./docs/tools.md) for the concise schema reference.
@@ -138,85 +114,60 @@ See [`docs/tools.md`](./docs/tools.md) for the concise schema reference.
138
114
  ## ⚙️ Job configuration
139
115
 
140
116
  The task should state the child's role, objective, scope, constraints, and expected result.
117
+ For reusable delegation policy, you can create your own project skill under `.pi/skills/<your-skill>/SKILL.md` or global skill under `~/.pi/agent/skills/<your-skill>/SKILL.md`.
118
+ Choose its name, trigger, tool policy, task format, and verification workflow for your use case.
119
+ The package intentionally registers and publishes no skill; the repository-only [`using-pi-subagents` example](https://github.com/narumiruna/pi-extensions/tree/main/packages/pi-subagents/skills/using-pi-subagents) is an optional starting point.
141
120
 
142
- The optional `tools` list limits what the child can do.
143
-
144
- Accepted names are `read`, `bash`, `powershell`, `edit`, `write`, `grep`, `find`, and `ls`.
121
+ The optional `tools` list limits what the child can do:
145
122
 
146
- Unavailable or extension-only tool names are rejected before a job is queued.
147
-
148
- Omitting `tools` selects `read`, `grep`, `find`, and `ls`.
149
-
150
- Passing an empty list gives the child no work tools.
151
-
152
- The runtime always adds `subagent_send` and child `subagent_wait` and removes duplicate names.
123
+ - Accepted names are `read`, `bash`, `powershell`, `edit`, `write`, `grep`, `find`, and `ls`.
124
+ - Unavailable or extension-only tool names are rejected before a job is queued.
125
+ - Omitting `tools` selects `read`, `grep`, `find`, and `ls`.
126
+ - Passing an empty list gives the child no work tools.
127
+ - The runtime always adds `subagent_send` and child `subagent_wait` and removes duplicate names.
153
128
 
154
129
  Adding `edit` or `write` lets the child modify files.
155
-
156
130
  Adding `bash` or `powershell` grants unrestricted command execution and can also modify the workspace.
157
131
 
158
132
  The optional `thinkingLevel` accepts `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`.
159
-
160
133
  Omitting `thinkingLevel` captures the main agent's effective level when `subagent_spawn` executes.
161
-
162
134
  The child inherits the main agent's effective provider and model when `subagent_spawn` executes.
163
135
 
164
136
  Spawn rejects providers registered by a parent extension because child processes disable unrelated extensions.
165
-
166
137
  Spawn also rejects process-local runtime API keys, including a parent-only `--api-key` value.
167
-
168
138
  Use stored or environment credentials that child processes can read.
169
-
170
139
  The extension does not expose a per-job model override.
171
140
 
172
141
  ## 🔄 Messaging, lifecycle, and retention
173
142
 
174
143
  The session starts one TCP broker on `127.0.0.1` with an operating-system-assigned ephemeral port.
175
-
176
144
  Each job receives one cryptographically random token bound to its job identity and session generation.
177
-
178
145
  The parent passes the broker credentials once through a private inherited pipe instead of placing them in the child's initial environment or command line.
179
-
180
146
  The child bridge reads and closes that descriptor before model tool execution.
181
147
 
182
148
  Each child runs in Pi RPC mode so the parent can inject a main-originated request through `steer` after the initial prompt is accepted.
183
-
184
149
  Each child broker call uses one request-scoped connection, while a response wait uses an abortable long poll.
185
-
186
150
  A main-originated request to a queued job waits for RPC readiness before delivery is accepted.
187
-
188
151
  After RPC accepts the steering message, the runtime interrupts active child response waits so the queued request can reach the child model.
189
-
190
152
  Caller cancellation before RPC delivery starts rolls the request back.
191
-
192
153
  Once RPC delivery starts, cancellation stops only the caller's wait; the request may still arrive and remains answerable until delivery fails or the job terminates.
193
-
194
154
  The interrupted child-originated requests remain active and retryable.
195
155
 
196
156
  The first accepted `subagent_send` response wins.
197
-
198
157
  Repeated responses acknowledge the existing answer without replacing it.
199
-
200
158
  A child may retry `subagent_wait` after a wait timeout because the underlying request remains active.
201
159
 
202
160
  A new job starts as `queued`, transitions to `running`, and reaches exactly one terminal state.
203
-
204
161
  The runtime retains up to 32 recent terminal records for up to 24 hours within the current extension session.
205
-
206
162
  Inspection reports older records removed by retention bounds through `omitted.jobs`.
207
-
208
163
  Cancelling or terminalizing a job revokes its token and rejects pending child waits before stale output can replace the terminal state.
209
-
210
164
  Session replacement and shutdown cancel active work, suppress stale completion delivery, revoke credentials, close sockets, and stop the broker.
211
165
 
212
166
  ## 🔀 Migrating from 2.x
213
167
 
214
168
  Version 3.0 replaces the previous orchestration runtime.
215
-
216
169
  It does not migrate legacy settings, persisted jobs, retained conversations, or recovery state.
217
-
218
170
  Finish or record any required work before upgrading, then start a fresh Pi session so stored calls do not request removed tool names.
219
-
220
171
  Use these replacements where the new job model supports the previous intent:
221
172
 
222
173
  | Previous interface | Version 3 interface |
@@ -229,73 +180,57 @@ Use these replacements where the new job model supports the previous intent:
229
180
  | Running main-to-child questions | Main and child `subagent_send` |
230
181
 
231
182
  The version 3 `subagent_send` contracts are not compatible with the legacy retained-agent follow-up tool of the same name.
232
-
233
183
  The `/subagents` command, extension settings, legacy retained follow-ups, `subagent_mailbox`, `subagent_consult`, custom agent catalogs, advanced orchestration, alternate transports, trust-aware cwd policy, and extension-owned worktrees have no direct replacement.
234
-
235
184
  Describe the child's specialization in `task` and grant only the required work tools through `tools`.
236
185
 
237
186
  ## 🔒 Security and privacy
238
187
 
239
188
  The selected work tools run in the current working directory.
240
-
241
189
  The default list contains no shell or file-mutation tool.
242
-
243
190
  It is not a filesystem sandbox because its read tools can inspect files available to the user account.
244
-
245
191
  Selecting `bash`, `powershell`, `edit`, or `write` permits workspace mutation with the Pi process environment and user permissions.
246
192
 
247
193
  Every child disables session persistence, unrelated extensions, skills, and prompt templates.
248
-
249
194
  Provider selection therefore supports Pi's child-visible built-in and configured providers, not providers registered only by a parent extension.
250
-
251
195
  Credentials must be available independently to the child through Pi's stored credentials or its inherited environment.
252
196
 
253
197
  The broker accepts only loopback TCP connections with an active per-job token.
254
-
255
198
  The token is bootstrapped through a private inherited pipe and is absent from the child's initial environment and command line.
256
199
 
257
200
  A child request or response is visible main-agent model context, but its envelope explicitly identifies it as untrusted subagent content rather than user authorization.
258
-
259
201
  A child message cannot grant permission for writes, shell commands, credential access, or other privileged actions.
260
-
261
202
  A main-agent request is visible child model context, but it cannot expand the child's selected tools or grant capabilities the child did not receive at spawn time.
262
203
 
263
204
  Terminal controls and bidirectional controls are stripped before untrusted child text is displayed.
264
-
265
205
  Tasks, repository context, requests, responses, and inspected file content may be sent to the selected model provider.
266
-
267
206
  Parallel writers require disjoint ownership or workspace isolation outside this extension.
268
207
 
269
208
  ## 🚧 Limitations
270
209
 
271
- The extension does not load arbitrary extension tools or parent-registered model providers in child processes.
272
-
273
- Process-local runtime API keys are not forwarded to children.
274
-
275
- The extension does not provide custom agents, per-job models, custom system prompts, peer-to-peer child messaging, retained conversations, user-directed follow-up work, mailboxes, Agent Teams, chains, fan-in aggregators, panels, workflow DAGs, dynamic scheduling, verification orchestration, nested subagents, or extension-owned semantic memory.
276
-
277
- Bidirectional messages use request-response coordination, not a retained conversational session.
278
-
279
- The main agent must verify child claims against the actual diff and deterministic checks.
280
-
281
- Child requests and responses trigger a main-agent turn, but asynchronous job completions do not wake an otherwise idle model turn automatically.
282
-
283
- Jobs, broker requests, and retained results do not survive extension reload, session replacement, or process exit.
210
+ - The extension does not load arbitrary extension tools or parent-registered model providers in child processes.
211
+ - Process-local runtime API keys are not forwarded to children.
212
+ - The extension does not provide custom agents, per-job models, custom system prompts, peer-to-peer child messaging, retained conversations, user-directed follow-up work, mailboxes, Agent Teams, chains, fan-in aggregators, panels, workflow DAGs, dynamic scheduling, verification orchestration, nested subagents, or extension-owned semantic memory.
213
+ - Bidirectional messages use request-response coordination, not a retained conversational session.
214
+ - The main agent must verify child claims against the actual diff and deterministic checks.
215
+ - Child requests and responses trigger a main-agent turn, but asynchronous job completions do not wake an otherwise idle model turn automatically.
216
+ - Jobs, broker requests, and retained results do not survive extension reload, session replacement, or process exit.
284
217
 
285
218
  ## 🗂️ Package layout
286
219
 
287
220
  ```text
288
221
  packages/pi-subagents/
289
- ├── dist/ # Generated Jiti runtime and child bridge
290
- ├── docs/ # Concise tools and design references
291
- ├── scripts/ # Deterministic runtime builder
292
- ├── skills/using-pi-subagents/ # Repository-only example delegation skill
293
- ├── src/ # Extension, broker, child bridge, and subprocess runtime
294
- ├── test/ # Protocol, lifecycle, process, and policy tests
295
- ├── package.json # Pi extension declaration
296
- └── README.md # User guide and safety boundaries
222
+ ├── src/ # Authoritative implementation and helpers
223
+ ├── index.ts # Thin Pi entrypoint
224
+ │ └── subagents.ts # Job, broker, and child lifecycle
225
+ ├── dist/ # Generated Jiti runtime and child bridge
226
+ ├── scripts/build-runtime.mjs # Runtime builder
227
+ ├── docs/ # Published reference documentation
228
+ ├── skills/using-pi-subagents/ # Repository-only example; not published
229
+ └── test/ # Behavior and lifecycle coverage
297
230
  ```
298
231
 
232
+ The generated runtime is built from `src/index.ts` and does not import back into `src`.
233
+
299
234
  ## 🔎 Keywords
300
235
 
301
236
  Pi, subagents, delegation, subagent jobs, least privilege, main-agent messaging, cancellation, job lifecycle.
@@ -5,7 +5,7 @@ import {
5
5
  MAX_IDENTIFIER_LENGTH,
6
6
  captureBrokerCredentials,
7
7
  createChildCommunicationExtension
8
- } from "./chunks/chunk-UKTWUQRM.js";
8
+ } from "./chunks/chunk-7JQOB375.ts";
9
9
 
10
10
  // src/child-communication-bridge.ts
11
11
  import net from "node:net";
@@ -79,10 +79,7 @@ function requestBroker(credentials, request, signal, responseTimeoutMs) {
79
79
  socket.once("connect", () => {
80
80
  clearTimeout(connectTimer);
81
81
  if (responseTimeoutMs !== void 0) {
82
- responseTimer = setTimeout(
83
- () => finish(new Error("Subagent broker response timed out.")),
84
- responseTimeoutMs
85
- );
82
+ responseTimer = setTimeout(() => finish(new Error("Subagent broker response timed out.")), responseTimeoutMs);
86
83
  responseTimer.unref();
87
84
  }
88
85
  socket.write(`${JSON.stringify(request)}
@@ -117,9 +114,7 @@ function requestBroker(credentials, request, signal, responseTimeoutMs) {
117
114
  });
118
115
  }
119
116
  function brokerError(response) {
120
- return new Error(
121
- typeof response.error === "string" ? response.error : "Subagent broker rejected the request."
122
- );
117
+ return new Error(typeof response.error === "string" ? response.error : "Subagent broker rejected the request.");
123
118
  }
124
119
  function abortError(message) {
125
120
  const error = new Error(message);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/child-communication-bridge.ts"],
4
- "sourcesContent": ["import net from \"node:net\";\nimport type { ExtensionFactory } from \"@earendil-works/pi-coding-agent\";\nimport { captureBrokerCredentials } from \"./broker-credentials.js\";\nimport {\n\ttype ChildCommunicationClient,\n\tcreateChildCommunicationExtension,\n} from \"./child-communication-tools.js\";\nimport { MAX_FRAME_BYTES, MAX_IDENTIFIER_LENGTH } from \"./message-broker.js\";\nimport type { BrokerCredentials } from \"./types.js\";\n\nconst CONNECT_TIMEOUT_MS = 2_000;\nconst SEND_RESPONSE_TIMEOUT_MS = 5_000;\n\nconst captured = captureBrokerCredentials();\n\nconst childCommunicationBridge: ExtensionFactory = captured\n\t? createChildCommunicationExtension(createBrokerClient(captured))\n\t: () => undefined;\n\nexport default childCommunicationBridge;\n\nexport function createBrokerClient(credentials: BrokerCredentials): ChildCommunicationClient {\n\treturn {\n\t\tasync send(params, signal) {\n\t\t\tconst response = await requestBroker(\n\t\t\t\tcredentials,\n\t\t\t\t{ type: \"send\", token: credentials.token, ...params },\n\t\t\t\tsignal,\n\t\t\t\tSEND_RESPONSE_TIMEOUT_MS,\n\t\t\t);\n\t\t\tif (response.ok !== true) throw brokerError(response);\n\t\t\tif (\n\t\t\t\ttypeof response.requestId !== \"string\" ||\n\t\t\t\t!response.requestId ||\n\t\t\t\tresponse.requestId.length > MAX_IDENTIFIER_LENGTH ||\n\t\t\t\ttypeof response.accepted !== \"boolean\" ||\n\t\t\t\ttypeof response.duplicate !== \"boolean\"\n\t\t\t) {\n\t\t\t\tthrow new Error(\"Subagent broker returned an invalid send acknowledgement.\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\trequestId: response.requestId,\n\t\t\t\taccepted: response.accepted,\n\t\t\t\tduplicate: response.duplicate,\n\t\t\t};\n\t\t},\n\t\tasync wait(requestId, timeoutMs, signal) {\n\t\t\tconst response = await requestBroker(\n\t\t\t\tcredentials,\n\t\t\t\t{\n\t\t\t\t\ttype: \"wait\",\n\t\t\t\t\ttoken: credentials.token,\n\t\t\t\t\trequestId,\n\t\t\t\t\t...(timeoutMs !== undefined ? { timeoutMs } : {}),\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (response.ok !== true) throw brokerError(response);\n\t\t\tif (typeof response.response !== \"string\") {\n\t\t\t\tthrow new Error(\"Subagent broker returned an invalid plain-text response.\");\n\t\t\t}\n\t\t\treturn response.response;\n\t\t},\n\t};\n}\n\nfunction requestBroker(\n\tcredentials: BrokerCredentials,\n\trequest: Record<string, unknown>,\n\tsignal?: AbortSignal,\n\tresponseTimeoutMs?: number,\n): Promise<Record<string, unknown>> {\n\tif (signal?.aborted) return Promise.reject(abortError(\"Subagent broker request was cancelled.\"));\n\treturn new Promise((resolve, reject) => {\n\t\tconst socket = net.createConnection({ host: credentials.host, port: credentials.port });\n\t\tlet response = Buffer.alloc(0);\n\t\tlet settled = false;\n\t\tlet responseTimer: NodeJS.Timeout | undefined;\n\t\tconst connectTimer = setTimeout(\n\t\t\t() => finish(new Error(\"Subagent broker connection timed out.\")),\n\t\t\tCONNECT_TIMEOUT_MS,\n\t\t);\n\t\tconnectTimer.unref();\n\t\tconst onAbort = () => finish(abortError(\"Subagent broker request was cancelled.\"));\n\t\tconst finish = (error?: Error, value?: Record<string, unknown>) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tclearTimeout(connectTimer);\n\t\t\tif (responseTimer) clearTimeout(responseTimer);\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\tsocket.destroy();\n\t\t\tif (error) reject(error);\n\t\t\telse resolve(value ?? {});\n\t\t};\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\tsocket.once(\"connect\", () => {\n\t\t\tclearTimeout(connectTimer);\n\t\t\tif (responseTimeoutMs !== undefined) {\n\t\t\t\tresponseTimer = setTimeout(\n\t\t\t\t\t() => finish(new Error(\"Subagent broker response timed out.\")),\n\t\t\t\t\tresponseTimeoutMs,\n\t\t\t\t);\n\t\t\t\tresponseTimer.unref();\n\t\t\t}\n\t\t\tsocket.write(`${JSON.stringify(request)}\\n`);\n\t\t});\n\t\tsocket.on(\"data\", (chunk: Buffer) => {\n\t\t\tif (settled) return;\n\t\t\tresponse = Buffer.concat([response, chunk]);\n\t\t\tif (response.byteLength > MAX_FRAME_BYTES) {\n\t\t\t\tfinish(new Error(\"Subagent broker response exceeded its size limit.\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst newline = response.indexOf(0x0a);\n\t\t\tif (newline < 0) return;\n\t\t\tconst trailing = response\n\t\t\t\t.subarray(newline + 1)\n\t\t\t\t.toString(\"utf8\")\n\t\t\t\t.trim();\n\t\t\tif (trailing) {\n\t\t\t\tfinish(new Error(\"Subagent broker returned more than one response frame.\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(response.subarray(0, newline).toString(\"utf8\")) as unknown;\n\t\t\t\tif (!isRecord(parsed)) throw new Error();\n\t\t\t\tfinish(undefined, parsed);\n\t\t\t} catch {\n\t\t\t\tfinish(new Error(\"Subagent broker returned malformed JSON.\"));\n\t\t\t}\n\t\t});\n\t\tsocket.once(\"error\", (error) => finish(error));\n\t\tsocket.once(\"close\", () => {\n\t\t\tif (!settled) finish(new Error(\"Subagent broker closed without a response.\"));\n\t\t});\n\t});\n}\n\nfunction brokerError(response: Record<string, unknown>): Error {\n\treturn new Error(\n\t\ttypeof response.error === \"string\" ? response.error : \"Subagent broker rejected the request.\",\n\t);\n}\n\nfunction abortError(message: string): Error {\n\tconst error = new Error(message);\n\terror.name = \"AbortError\";\n\treturn error;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import net from \"node:net\";\nimport type { ExtensionFactory } from \"@earendil-works/pi-coding-agent\";\nimport { captureBrokerCredentials } from \"./broker-credentials.js\";\nimport { type ChildCommunicationClient, createChildCommunicationExtension } from \"./child-communication-tools.js\";\nimport { MAX_FRAME_BYTES, MAX_IDENTIFIER_LENGTH } from \"./message-broker.js\";\nimport type { BrokerCredentials } from \"./types.js\";\n\nconst CONNECT_TIMEOUT_MS = 2_000;\nconst SEND_RESPONSE_TIMEOUT_MS = 5_000;\n\nconst captured = captureBrokerCredentials();\n\nconst childCommunicationBridge: ExtensionFactory = captured\n ? createChildCommunicationExtension(createBrokerClient(captured))\n : () => undefined;\n\nexport default childCommunicationBridge;\n\nexport function createBrokerClient(credentials: BrokerCredentials): ChildCommunicationClient {\n return {\n async send(params, signal) {\n const response = await requestBroker(\n credentials,\n { type: \"send\", token: credentials.token, ...params },\n signal,\n SEND_RESPONSE_TIMEOUT_MS,\n );\n if (response.ok !== true) throw brokerError(response);\n if (\n typeof response.requestId !== \"string\" ||\n !response.requestId ||\n response.requestId.length > MAX_IDENTIFIER_LENGTH ||\n typeof response.accepted !== \"boolean\" ||\n typeof response.duplicate !== \"boolean\"\n ) {\n throw new Error(\"Subagent broker returned an invalid send acknowledgement.\");\n }\n return {\n requestId: response.requestId,\n accepted: response.accepted,\n duplicate: response.duplicate,\n };\n },\n async wait(requestId, timeoutMs, signal) {\n const response = await requestBroker(\n credentials,\n {\n type: \"wait\",\n token: credentials.token,\n requestId,\n ...(timeoutMs !== undefined ? { timeoutMs } : {}),\n },\n signal,\n );\n if (response.ok !== true) throw brokerError(response);\n if (typeof response.response !== \"string\") {\n throw new Error(\"Subagent broker returned an invalid plain-text response.\");\n }\n return response.response;\n },\n };\n}\n\nfunction requestBroker(\n credentials: BrokerCredentials,\n request: Record<string, unknown>,\n signal?: AbortSignal,\n responseTimeoutMs?: number,\n): Promise<Record<string, unknown>> {\n if (signal?.aborted) return Promise.reject(abortError(\"Subagent broker request was cancelled.\"));\n return new Promise((resolve, reject) => {\n const socket = net.createConnection({ host: credentials.host, port: credentials.port });\n let response = Buffer.alloc(0);\n let settled = false;\n let responseTimer: NodeJS.Timeout | undefined;\n const connectTimer = setTimeout(\n () => finish(new Error(\"Subagent broker connection timed out.\")),\n CONNECT_TIMEOUT_MS,\n );\n connectTimer.unref();\n const onAbort = () => finish(abortError(\"Subagent broker request was cancelled.\"));\n const finish = (error?: Error, value?: Record<string, unknown>) => {\n if (settled) return;\n settled = true;\n clearTimeout(connectTimer);\n if (responseTimer) clearTimeout(responseTimer);\n signal?.removeEventListener(\"abort\", onAbort);\n socket.destroy();\n if (error) reject(error);\n else resolve(value ?? {});\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n socket.once(\"connect\", () => {\n clearTimeout(connectTimer);\n if (responseTimeoutMs !== undefined) {\n responseTimer = setTimeout(() => finish(new Error(\"Subagent broker response timed out.\")), responseTimeoutMs);\n responseTimer.unref();\n }\n socket.write(`${JSON.stringify(request)}\\n`);\n });\n socket.on(\"data\", (chunk: Buffer) => {\n if (settled) return;\n response = Buffer.concat([response, chunk]);\n if (response.byteLength > MAX_FRAME_BYTES) {\n finish(new Error(\"Subagent broker response exceeded its size limit.\"));\n return;\n }\n const newline = response.indexOf(0x0a);\n if (newline < 0) return;\n const trailing = response\n .subarray(newline + 1)\n .toString(\"utf8\")\n .trim();\n if (trailing) {\n finish(new Error(\"Subagent broker returned more than one response frame.\"));\n return;\n }\n try {\n const parsed = JSON.parse(response.subarray(0, newline).toString(\"utf8\")) as unknown;\n if (!isRecord(parsed)) throw new Error();\n finish(undefined, parsed);\n } catch {\n finish(new Error(\"Subagent broker returned malformed JSON.\"));\n }\n });\n socket.once(\"error\", (error) => finish(error));\n socket.once(\"close\", () => {\n if (!settled) finish(new Error(\"Subagent broker closed without a response.\"));\n });\n });\n}\n\nfunction brokerError(response: Record<string, unknown>): Error {\n return new Error(typeof response.error === \"string\" ? response.error : \"Subagent broker rejected the request.\");\n}\n\nfunction abortError(message: string): Error {\n const error = new Error(message);\n error.name = \"AbortError\";\n return error;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -129,9 +129,7 @@ var MessageBroker = class {
129
129
  }
130
130
  }
131
131
  hasPendingMainRequest() {
132
- return [...this.requests.values()].some(
133
- (request) => request.origin === "child" && request.response === void 0
134
- );
132
+ return [...this.requests.values()].some((request) => request.origin === "child" && request.response === void 0);
135
133
  }
136
134
  takePendingInboundResponse() {
137
135
  const pending = this.pendingInboundResponse;
@@ -198,9 +196,7 @@ var MessageBroker = class {
198
196
  (request2) => request2.jobId === job.jobId && request2.consumedAt === void 0
199
197
  ).length;
200
198
  if (outstanding >= MAX_OUTSTANDING_REQUESTS) {
201
- throw new Error(
202
- `Subagent job may have at most ${MAX_OUTSTANDING_REQUESTS} outstanding requests.`
203
- );
199
+ throw new Error(`Subagent job may have at most ${MAX_OUTSTANDING_REQUESTS} outstanding requests.`);
204
200
  }
205
201
  const request = {
206
202
  requestId: `req_${randomUUID()}`,
@@ -374,11 +370,7 @@ var MessageBroker = class {
374
370
  return;
375
371
  }
376
372
  if (record.response !== void 0) {
377
- this.respond(
378
- socket,
379
- { ok: true, response: record.response },
380
- () => this.markConsumed(record)
381
- );
373
+ this.respond(socket, { ok: true, response: record.response }, () => this.markConsumed(record));
382
374
  return;
383
375
  }
384
376
  if (this.hasQueuedRequestForChild(job.jobId)) {
@@ -402,13 +394,8 @@ var MessageBroker = class {
402
394
  markConsumed(request) {
403
395
  if (this.requests.get(request.requestId) !== request || request.response === void 0) return;
404
396
  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
- )) {
397
+ const consumed = [...this.requests.values()].filter((candidate) => candidate.jobId === request.jobId && candidate.consumedAt !== void 0).sort((left, right) => (left.consumedAt ?? 0) - (right.consumedAt ?? 0));
398
+ for (const expired of consumed.slice(0, Math.max(0, consumed.length - MAX_RETAINED_CONSUMED_REQUESTS))) {
412
399
  this.requests.delete(expired.requestId);
413
400
  }
414
401
  }
@@ -568,9 +555,7 @@ var WaitParameters = Type.Object(
568
555
  minLength: 1,
569
556
  maxLength: MAX_IDENTIFIER_LENGTH
570
557
  }),
571
- timeout: Type.Optional(
572
- Type.Number({ description: "Timeout in seconds (optional, no default timeout)" })
573
- )
558
+ timeout: Type.Optional(Type.Number({ description: "Timeout in seconds (optional, no default timeout)" }))
574
559
  },
575
560
  { additionalProperties: false }
576
561
  );
@@ -664,4 +649,4 @@ export {
664
649
  CHILD_COMMUNICATION_TOOL_NAMES,
665
650
  createChildCommunicationExtension
666
651
  };
667
- //# sourceMappingURL=chunk-UKTWUQRM.js.map
652
+ //# sourceMappingURL=chunk-7JQOB375.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/message-broker.ts", "../../src/broker-credentials.ts", "../../src/child-communication-tools.ts"],
4
+ "sourcesContent": ["import { randomBytes, randomUUID } from \"node:crypto\";\nimport net, { type AddressInfo, type Server, type Socket } from \"node:net\";\nimport type { BrokerCredentials } from \"./types.js\";\n\nexport const BROKER_HOST = \"127.0.0.1\" as const;\nexport const MAX_MESSAGE_BYTES = 48 * 1024;\nexport const MAX_MESSAGE_LINES = 1_992;\nexport const MAX_FRAME_BYTES = 384 * 1024;\nexport const MAX_ERROR_BYTES = 8 * 1024;\nexport const MAX_OUTSTANDING_REQUESTS = 4;\nexport const MAX_IDENTIFIER_LENGTH = 128;\n\nconst MAX_CONNECTIONS = 32;\nconst REQUEST_FRAME_TIMEOUT_MS = 2_000;\nconst MAX_TIMEOUT_MS = 2_147_483_647;\nconst MAX_RETAINED_CONSUMED_REQUESTS = 4;\nconst CHILD_WAIT_INTERRUPTED_ERROR =\n \"Subagent wait was interrupted by an incoming main-agent request. The original request remains active.\";\n\nexport type BrokerRequestOrigin = \"main\" | \"child\";\n\nexport interface BrokerInboundMessage {\n kind: \"request\" | \"response\";\n requestId: string;\n jobId: string;\n message: string;\n}\n\nexport interface BrokerSendAcknowledgement {\n requestId: string;\n accepted: boolean;\n duplicate: boolean;\n}\n\nexport interface MessageBrokerOptions {\n onMessage(message: BrokerInboundMessage): void;\n createServer?: (listener: (socket: Socket) => void) => Server;\n now?: () => number;\n requestFrameTimeoutMs?: number;\n}\n\ninterface JobRecord {\n jobId: string;\n generation: number;\n token: string;\n}\n\ninterface RequestWaiter {\n socket: Socket;\n timer?: NodeJS.Timeout;\n}\n\ninterface RequestRecord {\n requestId: string;\n jobId: string;\n generation: number;\n origin: BrokerRequestOrigin;\n expectedResponder: BrokerRequestOrigin;\n message: string;\n createdAt: number;\n response?: string;\n consumedAt?: number;\n deliveryQueued?: boolean;\n waiter?: RequestWaiter;\n}\n\ntype BrokerRequest =\n | {\n type: \"send\";\n token: string;\n recipient?: string;\n requestId?: string;\n message: string;\n }\n | { type: \"wait\"; token: string; requestId: string; timeoutMs?: number };\n\n/** Session-scoped authenticated loopback transport for bidirectional requests and responses. */\nexport class MessageBroker {\n private server?: Server;\n private starting?: Promise<void>;\n private address?: { host: typeof BROKER_HOST; port: number };\n private failure?: string;\n private generation = 0;\n private readonly sockets = new Set<Socket>();\n private readonly jobsByToken = new Map<string, JobRecord>();\n private readonly tokenByJob = new Map<string, string>();\n private readonly requests = new Map<string, RequestRecord>();\n private readonly inboundMessageListeners = new Set<() => void>();\n private pendingInboundResponse = false;\n private readonly createServer: (listener: (socket: Socket) => void) => Server;\n private readonly now: () => number;\n private readonly requestFrameTimeoutMs: number;\n\n constructor(private readonly options: MessageBrokerOptions) {\n this.createServer = options.createServer ?? ((listener) => net.createServer(listener));\n this.now = options.now ?? Date.now;\n this.requestFrameTimeoutMs = options.requestFrameTimeoutMs ?? REQUEST_FRAME_TIMEOUT_MS;\n if (!Number.isFinite(this.requestFrameTimeoutMs) || this.requestFrameTimeoutMs <= 0) {\n throw new Error(\"Subagent broker frame timeout must be positive.\");\n }\n }\n\n async start(): Promise<void> {\n if (this.server && this.address && !this.failure) return;\n if (this.starting) return this.starting;\n const ownerGeneration = ++this.generation;\n this.failure = undefined;\n this.starting = new Promise<void>((resolve, reject) => {\n const server = this.createServer((socket) => this.accept(socket));\n server.maxConnections = MAX_CONNECTIONS;\n const onStartError = (error: Error) => {\n server.close(() => undefined);\n reject(error);\n };\n server.once(\"error\", onStartError);\n server.listen({ host: BROKER_HOST, port: 0 }, () => {\n server.off(\"error\", onStartError);\n if (ownerGeneration !== this.generation) {\n server.close(() => undefined);\n reject(new Error(\"Subagent message broker start was superseded.\"));\n return;\n }\n const address = server.address();\n if (!isLoopbackAddress(address)) {\n server.close(() => undefined);\n reject(new Error(\"Subagent message broker did not bind to loopback.\"));\n return;\n }\n this.server = server;\n this.address = { host: BROKER_HOST, port: address.port };\n server.on(\"error\", (error) => this.fail(error));\n server.unref();\n resolve();\n });\n })\n .catch((error) => {\n const message = truncateError(error instanceof Error ? error.message : String(error));\n this.failure = message;\n throw new Error(`Subagent message broker failed to start: ${message}`);\n })\n .finally(() => {\n this.starting = undefined;\n });\n return this.starting;\n }\n\n assertReady(): void {\n if (this.server && this.address && !this.failure) return;\n throw new Error(\n this.failure\n ? `Subagent messaging is unavailable: ${this.failure}`\n : \"Subagent messaging is unavailable because the session broker is not ready.\",\n );\n }\n\n issueCredentials(input: { jobId: string; generation: number }): BrokerCredentials {\n this.assertReady();\n if (this.tokenByJob.has(input.jobId)) {\n throw new Error(`Subagent messaging credentials already exist for ${input.jobId}.`);\n }\n const token = randomBytes(32).toString(\"hex\");\n const record: JobRecord = { ...input, token };\n this.jobsByToken.set(token, record);\n this.tokenByJob.set(input.jobId, token);\n return { host: BROKER_HOST, port: this.address?.port ?? 0, token };\n }\n\n createMainRequest(jobId: string, message: string): BrokerSendAcknowledgement {\n this.assertReady();\n const job = this.requireJob(jobId);\n return this.createRequest(job, \"main\", message);\n }\n\n replyFromMain(requestId: string, message: string): BrokerSendAcknowledgement {\n this.assertReady();\n return this.acceptResponse(\"main\", undefined, requestId, message);\n }\n\n rollbackMainRequest(requestId: string): void {\n const request = this.requests.get(requestId);\n if (request?.origin === \"main\" && request.response === undefined) {\n this.clearWaiter(request);\n this.requests.delete(requestId);\n }\n }\n\n revokeJob(jobId: string, reason = \"Subagent job is no longer active.\"): void {\n const token = this.tokenByJob.get(jobId);\n if (token) {\n this.tokenByJob.delete(jobId);\n this.jobsByToken.delete(token);\n }\n for (const request of [...this.requests.values()]) {\n if (request.jobId !== jobId) continue;\n if (request.waiter) this.respondError(request.waiter.socket, reason);\n this.clearWaiter(request);\n this.requests.delete(request.requestId);\n }\n }\n\n hasPendingMainRequest(): boolean {\n return [...this.requests.values()].some((request) => request.origin === \"child\" && request.response === undefined);\n }\n\n takePendingInboundResponse(): boolean {\n const pending = this.pendingInboundResponse;\n this.pendingInboundResponse = false;\n return pending;\n }\n\n markMainRequestQueued(requestId: string): boolean {\n const request = this.requests.get(requestId);\n if (request?.origin !== \"main\") {\n throw new Error(\"Unknown or expired main-agent subagent request.\");\n }\n request.deliveryQueued = true;\n return request.response === undefined;\n }\n\n interruptChildWaits(jobId: string): number {\n let interrupted = 0;\n for (const request of this.requests.values()) {\n if (request.jobId !== jobId || request.origin !== \"child\" || !request.waiter) continue;\n const socket = request.waiter.socket;\n this.clearWaiter(request);\n this.respondError(socket, CHILD_WAIT_INTERRUPTED_ERROR);\n interrupted++;\n }\n return interrupted;\n }\n\n subscribeInboundMessage(listener: () => void): () => void {\n this.inboundMessageListeners.add(listener);\n if (this.hasPendingMainRequest()) listener();\n return () => this.inboundMessageListeners.delete(listener);\n }\n\n async shutdown(): Promise<void> {\n ++this.generation;\n const starting = this.starting;\n if (starting) await starting.catch(() => undefined);\n for (const jobId of [...this.tokenByJob.keys()]) {\n this.revokeJob(jobId, \"Subagent session shut down.\");\n }\n this.requests.clear();\n this.inboundMessageListeners.clear();\n this.pendingInboundResponse = false;\n for (const socket of this.sockets) socket.destroy();\n this.sockets.clear();\n const server = this.server;\n this.server = undefined;\n this.address = undefined;\n this.failure = undefined;\n if (!server?.listening) return;\n await new Promise<void>((resolve) => server.close(() => resolve()));\n }\n\n private requireJob(jobId: string): JobRecord {\n const token = this.tokenByJob.get(jobId);\n const job = token ? this.jobsByToken.get(token) : undefined;\n if (!job) throw new Error(\"Unknown or inactive subagent job.\");\n return job;\n }\n\n private hasQueuedRequestForChild(jobId: string): boolean {\n return [...this.requests.values()].some(\n (request) =>\n request.jobId === jobId &&\n request.origin === \"main\" &&\n request.deliveryQueued === true &&\n request.response === undefined,\n );\n }\n\n private createRequest(job: JobRecord, origin: BrokerRequestOrigin, message: string): BrokerSendAcknowledgement {\n validateMessage(message, \"Subagent request\");\n const outstanding = [...this.requests.values()].filter(\n (request) => request.jobId === job.jobId && request.consumedAt === undefined,\n ).length;\n if (outstanding >= MAX_OUTSTANDING_REQUESTS) {\n throw new Error(`Subagent job may have at most ${MAX_OUTSTANDING_REQUESTS} outstanding requests.`);\n }\n const request: RequestRecord = {\n requestId: `req_${randomUUID()}`,\n jobId: job.jobId,\n generation: job.generation,\n origin,\n expectedResponder: origin === \"main\" ? \"child\" : \"main\",\n message,\n createdAt: this.now(),\n };\n this.requests.set(request.requestId, request);\n if (origin === \"child\") {\n try {\n this.deliverInbound({\n kind: \"request\",\n requestId: request.requestId,\n jobId: request.jobId,\n message: request.message,\n });\n } catch (error) {\n this.requests.delete(request.requestId);\n throw error;\n }\n }\n return { requestId: request.requestId, accepted: true, duplicate: false };\n }\n\n private acceptResponse(\n responder: BrokerRequestOrigin,\n job: JobRecord | undefined,\n requestId: string,\n message: string,\n ): BrokerSendAcknowledgement {\n validateRequestId(requestId);\n validateMessage(message, \"Subagent response\");\n const request = this.requests.get(requestId);\n if (\n !request ||\n request.expectedResponder !== responder ||\n (job && (request.jobId !== job.jobId || request.generation !== job.generation))\n ) {\n throw new Error(\"Unknown, expired, or unauthorized subagent request.\");\n }\n if (request.response !== undefined) {\n return { requestId, accepted: false, duplicate: true };\n }\n request.response = message;\n if (responder === \"child\") {\n try {\n this.deliverInbound({\n kind: \"response\",\n requestId,\n jobId: request.jobId,\n message,\n });\n this.markConsumed(request);\n } catch (error) {\n request.response = undefined;\n throw error;\n }\n } else if (request.waiter) {\n const socket = request.waiter.socket;\n this.clearWaiter(request);\n this.respond(socket, { ok: true, response: message }, () => this.markConsumed(request));\n }\n return { requestId, accepted: true, duplicate: false };\n }\n\n private deliverInbound(message: BrokerInboundMessage): void {\n this.options.onMessage(message);\n if (message.kind === \"response\" && this.inboundMessageListeners.size === 0) {\n this.pendingInboundResponse = true;\n }\n for (const listener of [...this.inboundMessageListeners]) {\n try {\n listener();\n } catch {\n // Runtime wait observers cannot interrupt broker delivery.\n }\n }\n }\n\n private accept(socket: Socket): void {\n if (!this.server || this.failure || this.sockets.size >= MAX_CONNECTIONS) {\n socket.destroy();\n return;\n }\n this.sockets.add(socket);\n socket.setNoDelay(true);\n let frame = Buffer.alloc(0);\n let handled = false;\n const frameTimer = setTimeout(() => {\n if (handled) return;\n handled = true;\n this.respondError(socket, \"Subagent broker request frame timed out.\");\n }, this.requestFrameTimeoutMs);\n frameTimer.unref();\n const cleanup = () => {\n clearTimeout(frameTimer);\n this.sockets.delete(socket);\n for (const request of this.requests.values()) {\n if (request.waiter?.socket === socket) this.clearWaiter(request);\n }\n };\n socket.on(\"data\", (chunk: Buffer) => {\n if (handled) return;\n frame = Buffer.concat([frame, chunk]);\n if (frame.byteLength > MAX_FRAME_BYTES) {\n handled = true;\n clearTimeout(frameTimer);\n this.respondError(socket, \"Subagent broker request exceeded its size limit.\");\n return;\n }\n const newline = frame.indexOf(0x0a);\n if (newline < 0) return;\n handled = true;\n clearTimeout(frameTimer);\n socket.removeAllListeners(\"data\");\n const trailing = frame\n .subarray(newline + 1)\n .toString(\"utf8\")\n .trim();\n if (trailing) {\n this.respondError(socket, \"Subagent broker accepts one request per connection.\");\n return;\n }\n this.handleFrame(socket, frame.subarray(0, newline).toString(\"utf8\"));\n });\n socket.once(\"close\", cleanup);\n socket.once(\"error\", cleanup);\n }\n\n private handleFrame(socket: Socket, frame: string): void {\n let request: BrokerRequest;\n try {\n const parsed = JSON.parse(frame) as unknown;\n if (!isRecord(parsed)) throw new Error();\n request = parsed as BrokerRequest;\n } catch {\n this.respondError(socket, \"Malformed subagent broker request.\");\n return;\n }\n const job = typeof request.token === \"string\" ? this.jobsByToken.get(request.token) : undefined;\n if (!job) {\n this.respondError(socket, \"Unauthenticated subagent broker request.\");\n return;\n }\n try {\n if (request.type === \"send\") {\n this.handleSend(socket, job, request);\n return;\n }\n if (request.type === \"wait\") {\n this.handleWait(socket, job, request);\n return;\n }\n throw new Error(\"Unsupported subagent broker request.\");\n } catch (error) {\n this.respondError(socket, error instanceof Error ? error.message : String(error));\n }\n }\n\n private handleSend(socket: Socket, job: JobRecord, request: Extract<BrokerRequest, { type: \"send\" }>): void {\n if (typeof request.message !== \"string\") {\n throw new Error(\"subagent_send requires a message string.\");\n }\n const hasRecipient = typeof request.recipient === \"string\";\n const hasRequestId = typeof request.requestId === \"string\";\n if (hasRecipient === hasRequestId) {\n throw new Error(\"subagent_send requires exactly one of recipient or requestId.\");\n }\n const acknowledgement = hasRecipient\n ? request.recipient === \"main\"\n ? this.createRequest(job, \"child\", request.message)\n : (() => {\n throw new Error('A subagent may send new requests only to recipient \"main\".');\n })()\n : this.acceptResponse(\"child\", job, request.requestId ?? \"\", request.message);\n this.respond(socket, { ok: true, ...acknowledgement });\n }\n\n private handleWait(socket: Socket, job: JobRecord, request: Extract<BrokerRequest, { type: \"wait\" }>): void {\n if (typeof request.requestId !== \"string\") {\n throw new Error(\"Subagent wait requires a request ID.\");\n }\n validateRequestId(request.requestId);\n if (request.timeoutMs !== undefined) validateTimeout(request.timeoutMs);\n const record = this.requests.get(request.requestId);\n if (record?.origin !== \"child\" || record.jobId !== job.jobId || record.generation !== job.generation) {\n throw new Error(\"Unknown or expired subagent request.\");\n }\n if (record.consumedAt !== undefined && record.response !== undefined) {\n this.respond(socket, { ok: true, response: record.response });\n return;\n }\n if (record.response !== undefined) {\n this.respond(socket, { ok: true, response: record.response }, () => this.markConsumed(record));\n return;\n }\n if (this.hasQueuedRequestForChild(job.jobId)) {\n this.respondError(socket, CHILD_WAIT_INTERRUPTED_ERROR);\n return;\n }\n if (record.waiter) {\n throw new Error(`A wait is already active for subagent request ${request.requestId}.`);\n }\n const waiter: RequestWaiter = { socket };\n record.waiter = waiter;\n if (request.timeoutMs !== undefined) {\n waiter.timer = setTimeout(() => {\n if (record.waiter !== waiter) return;\n this.clearWaiter(record);\n this.respondError(socket, \"Subagent response wait timed out.\");\n }, request.timeoutMs);\n waiter.timer.unref();\n }\n }\n\n private markConsumed(request: RequestRecord): void {\n if (this.requests.get(request.requestId) !== request || request.response === undefined) return;\n request.consumedAt ??= this.now();\n const consumed = [...this.requests.values()]\n .filter((candidate) => candidate.jobId === request.jobId && candidate.consumedAt !== undefined)\n .sort((left, right) => (left.consumedAt ?? 0) - (right.consumedAt ?? 0));\n for (const expired of consumed.slice(0, Math.max(0, consumed.length - MAX_RETAINED_CONSUMED_REQUESTS))) {\n this.requests.delete(expired.requestId);\n }\n }\n\n private clearWaiter(request: RequestRecord): void {\n if (request.waiter?.timer) clearTimeout(request.waiter.timer);\n request.waiter = undefined;\n }\n\n private respondError(socket: Socket, error: string): void {\n this.respond(socket, { ok: false, error: truncateError(error) });\n }\n\n private respond(socket: Socket, value: Record<string, unknown>, onFlushed?: () => void): void {\n if (socket.destroyed) return;\n let content = `${JSON.stringify(value)}\\n`;\n if (Buffer.byteLength(content, \"utf8\") > MAX_FRAME_BYTES) {\n content = `${JSON.stringify({ ok: false, error: \"Subagent broker response exceeded its size limit.\" })}\\n`;\n }\n socket.end(content, onFlushed);\n }\n\n private fail(error: Error): void {\n this.failure = truncateError(error.message);\n for (const jobId of [...this.tokenByJob.keys()]) {\n this.revokeJob(jobId, \"Subagent message broker failed.\");\n }\n for (const socket of this.sockets) socket.destroy();\n this.sockets.clear();\n this.address = undefined;\n }\n}\n\nexport function validateMessage(message: string, label: string): void {\n if (!message.trim()) throw new Error(`${label} is required.`);\n if (message.includes(\"\\0\")) throw new Error(`${label} must not contain NUL bytes.`);\n if (Buffer.byteLength(message, \"utf8\") > MAX_MESSAGE_BYTES) {\n throw new Error(`${label} must be at most ${MAX_MESSAGE_BYTES} UTF-8 bytes.`);\n }\n if (lineCount(message) > MAX_MESSAGE_LINES) {\n throw new Error(`${label} must contain at most ${MAX_MESSAGE_LINES} lines.`);\n }\n}\n\nexport function sanitizeTerminalText(value: string): string {\n return [...value]\n .filter((character) => {\n const codePoint = character.codePointAt(0) ?? 0;\n if (character === \"\\n\" || character === \"\\t\") return true;\n if (codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f)) return false;\n return !((codePoint >= 0x202a && codePoint <= 0x202e) || (codePoint >= 0x2066 && codePoint <= 0x2069));\n })\n .join(\"\");\n}\n\nfunction validateRequestId(requestId: string): void {\n if (\n requestId.length > MAX_IDENTIFIER_LENGTH ||\n !/^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)\n ) {\n throw new Error(\"Invalid subagent request ID.\");\n }\n}\n\nfunction validateTimeout(timeoutMs: number): void {\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > MAX_TIMEOUT_MS) {\n throw new Error(\"Subagent wait timeout is outside the supported range.\");\n }\n}\n\nfunction lineCount(value: string): number {\n let count = 1;\n for (const character of value) if (character === \"\\n\") count++;\n return count;\n}\n\nfunction truncateError(error: string): string {\n const bytes = Buffer.from(error, \"utf8\");\n if (bytes.length <= MAX_ERROR_BYTES) return error;\n return `${bytes\n .subarray(0, Math.max(0, MAX_ERROR_BYTES - 18))\n .toString(\"utf8\")\n .replace(/\uFFFD+$/gu, \"\")}\\n\u2026 [truncated]`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isLoopbackAddress(address: AddressInfo | string | null): address is AddressInfo {\n return Boolean(address && typeof address !== \"string\" && address.address === BROKER_HOST);\n}\n", "import * as fs from \"node:fs\";\nimport type { BrokerCredentials } from \"./types.js\";\n\nexport const BROKER_CREDENTIAL_FD = 3;\nexport const BROKER_CREDENTIAL_FD_ENV = \"PI_SUBAGENT_BROKER_FD\";\n\nconst MAX_CREDENTIAL_BYTES = 1_024;\n\nexport function brokerCredentialEnvironment(): NodeJS.ProcessEnv {\n return { [BROKER_CREDENTIAL_FD_ENV]: String(BROKER_CREDENTIAL_FD) };\n}\n\nexport function serializeBrokerCredentials(credentials: BrokerCredentials): string {\n return JSON.stringify(credentials);\n}\n\nexport function captureBrokerCredentials(\n readCredentials: () => string = readCredentialPipe,\n): BrokerCredentials | undefined {\n const descriptor = process.env[BROKER_CREDENTIAL_FD_ENV];\n delete process.env[BROKER_CREDENTIAL_FD_ENV];\n if (descriptor === undefined) return undefined;\n if (descriptor !== String(BROKER_CREDENTIAL_FD)) {\n throw new Error(\"Invalid pi-subagents broker credential descriptor.\");\n }\n let serialized: string;\n try {\n serialized = readCredentials();\n } catch {\n throw new Error(\"Unable to read pi-subagents broker credentials.\");\n }\n if (Buffer.byteLength(serialized, \"utf8\") > MAX_CREDENTIAL_BYTES) {\n throw new Error(\"Invalid pi-subagents broker credentials.\");\n }\n let value: unknown;\n try {\n value = JSON.parse(serialized);\n } catch {\n throw new Error(\"Invalid pi-subagents broker credentials.\");\n }\n if (!isBrokerCredentials(value)) {\n throw new Error(\"Invalid pi-subagents broker credentials.\");\n }\n return value;\n}\n\nfunction readCredentialPipe(): string {\n try {\n return fs.readFileSync(BROKER_CREDENTIAL_FD, \"utf8\");\n } finally {\n try {\n fs.closeSync(BROKER_CREDENTIAL_FD);\n } catch {\n // The descriptor may already be closed after a failed read.\n }\n }\n}\n\nfunction isBrokerCredentials(value: unknown): value is BrokerCredentials {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const candidate = value as Record<string, unknown>;\n return (\n Object.keys(candidate).length === 3 &&\n candidate.host === \"127.0.0.1\" &&\n Number.isSafeInteger(candidate.port) &&\n (candidate.port as number) >= 1 &&\n (candidate.port as number) <= 65_535 &&\n typeof candidate.token === \"string\" &&\n /^[a-f0-9]{64}$/u.test(candidate.token)\n );\n}\n", "import type { ExtensionFactory } from \"@earendil-works/pi-coding-agent\";\nimport { type Static, Type } from \"typebox\";\nimport {\n type BrokerSendAcknowledgement,\n MAX_IDENTIFIER_LENGTH,\n MAX_MESSAGE_BYTES,\n sanitizeTerminalText,\n validateMessage,\n} from \"./message-broker.js\";\n\nexport const CHILD_COMMUNICATION_TOOL_NAMES = [\"subagent_send\", \"subagent_wait\"] as const;\n\nconst MAX_TIMEOUT_MS = 2_147_483_647;\nconst MAX_TIMEOUT_SECONDS = MAX_TIMEOUT_MS / 1000;\n\nconst SendParameters = Type.Object(\n {\n requestId: Type.Optional(\n Type.String({\n description: \"Pending main-agent request to answer. Omit when starting a new request.\",\n minLength: 1,\n maxLength: MAX_IDENTIFIER_LENGTH,\n }),\n ),\n message: Type.String({\n description: \"Plain-text request or response. Maximum 48 KiB of UTF-8 text and 1,992 lines.\",\n minLength: 1,\n maxLength: MAX_MESSAGE_BYTES,\n }),\n },\n { additionalProperties: false },\n);\n\nconst WaitParameters = Type.Object(\n {\n requestId: Type.String({\n description: \"Request ID returned by subagent_send.\",\n minLength: 1,\n maxLength: MAX_IDENTIFIER_LENGTH,\n }),\n timeout: Type.Optional(Type.Number({ description: \"Timeout in seconds (optional, no default timeout)\" })),\n },\n { additionalProperties: false },\n);\n\ntype ChildBrokerSendArguments = { recipient: \"main\"; message: string } | { requestId: string; message: string };\n\ntype WaitArguments = Static<typeof WaitParameters>;\n\nexport interface ChildCommunicationClient {\n send(params: ChildBrokerSendArguments, signal?: AbortSignal): Promise<BrokerSendAcknowledgement>;\n wait(requestId: string, timeoutMs: number | undefined, signal?: AbortSignal): Promise<string>;\n}\n\nexport function createChildCommunicationExtension(client: ChildCommunicationClient): ExtensionFactory {\n return (pi) => {\n pi.registerTool({\n name: \"subagent_send\",\n label: \"Subagent \u00B7 Send to Main\",\n description:\n \"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.\",\n promptSnippet: \"Use subagent_send to send or answer one main-agent message\",\n parameters: SendParameters,\n async execute(_toolCallId, params, signal) {\n validateMessage(params.message, \"Subagent message\");\n const requestId = optionalIdentifier(params.requestId, \"requestId\");\n const acknowledgement = await client.send(\n requestId === undefined\n ? { recipient: \"main\", message: params.message }\n : { requestId, message: params.message },\n signal,\n );\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(acknowledgement) }],\n details: acknowledgement,\n };\n },\n });\n\n pi.registerTool({\n name: \"subagent_wait\",\n label: \"Subagent \u00B7 Wait for Main Agent\",\n description:\n \"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.\",\n promptSnippet: \"Use subagent_wait to receive a requested main-agent response\",\n parameters: WaitParameters,\n prepareArguments: prepareWaitArguments,\n async execute(_toolCallId, params, signal) {\n const requestId = requiredIdentifier(params.requestId, \"requestId\");\n const response = await client.wait(requestId, resolveTimeoutMs(params.timeout), signal);\n return {\n content: [{ type: \"text\" as const, text: sanitizeTerminalText(response) }],\n details: { requestId },\n };\n },\n });\n };\n}\n\nfunction resolveTimeoutMs(timeout: number | undefined): number | undefined {\n if (timeout === undefined) return undefined;\n if (!Number.isFinite(timeout) || timeout <= 0) {\n throw new Error(\"Invalid timeout: must be a finite number of seconds\");\n }\n const timeoutMs = timeout * 1000;\n if (timeoutMs > MAX_TIMEOUT_MS) {\n throw new Error(`Invalid timeout: maximum is ${MAX_TIMEOUT_SECONDS} seconds`);\n }\n return timeoutMs;\n}\n\nfunction prepareWaitArguments(args: unknown): WaitArguments {\n if (!args || typeof args !== \"object\") return args as WaitArguments;\n if (!Object.hasOwn(args, \"timeoutMs\")) return args as WaitArguments;\n const record = args as Record<string, unknown>;\n if (typeof record.timeoutMs !== \"number\") return record as WaitArguments;\n const { timeoutMs, ...prepared } = record;\n if (prepared.timeout === undefined) {\n return { ...prepared, timeout: timeoutMs / 1000 } as WaitArguments;\n }\n return prepared as WaitArguments;\n}\n\nfunction optionalIdentifier(value: unknown, field: string): string | undefined {\n return value === undefined ? undefined : requiredIdentifier(value, field);\n}\n\nfunction requiredIdentifier(value: unknown, field: string): string {\n if (typeof value !== \"string\" || !value.trim()) throw new Error(`Subagent ${field} is required.`);\n const identifier = value.trim();\n if (\n identifier.length > MAX_IDENTIFIER_LENGTH ||\n [...identifier].some((character) => {\n const codePoint = character.codePointAt(0) ?? 0;\n return codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f);\n })\n ) {\n throw new Error(`Subagent ${field} is invalid.`);\n }\n return identifier;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["request", "MAX_TIMEOUT_MS"]
7
+ }