@narumitw/pi-subagents 3.3.3 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +74 -25
  2. package/dist/child-communication-bridge.ts +3 -2
  3. package/dist/child-communication-bridge.ts.map +1 -1
  4. package/dist/child-readiness-probe.ts +114 -17
  5. package/dist/child-readiness-probe.ts.map +2 -2
  6. package/dist/chunks/{chunk-FY5HIU6Y.ts → chunk-5OXDVXXO.ts} +1 -1
  7. package/dist/chunks/{chunk-FY5HIU6Y.ts.map → chunk-5OXDVXXO.ts.map} +1 -1
  8. package/dist/chunks/chunk-B3RWNGDX.ts +192 -0
  9. package/dist/chunks/chunk-B3RWNGDX.ts.map +7 -0
  10. package/dist/chunks/{chunk-ZOAFWLDJ.ts → chunk-PRIDTAJL.ts} +4 -16
  11. package/dist/chunks/chunk-PRIDTAJL.ts.map +7 -0
  12. package/dist/chunks/{chunk-YMVSJ5GE.ts → chunk-YV2P6XJX.ts} +46 -17
  13. package/dist/chunks/chunk-YV2P6XJX.ts.map +7 -0
  14. package/dist/chunks/{menu-KAIUEWL7.ts → menu-2UH4ICLL.ts} +74 -3
  15. package/dist/chunks/menu-2UH4ICLL.ts.map +7 -0
  16. package/dist/index.ts +554 -293
  17. package/dist/index.ts.map +3 -3
  18. package/docs/attachments.md +9 -3
  19. package/docs/design-principles.md +3 -1
  20. package/docs/messaging.md +3 -1
  21. package/docs/tools.md +15 -1
  22. package/package.json +3 -3
  23. package/src/broker-credentials.ts +44 -13
  24. package/src/child-communication-tools.ts +2 -19
  25. package/src/child-readiness-probe.ts +144 -18
  26. package/src/child-readiness.ts +118 -0
  27. package/src/menu.ts +82 -3
  28. package/src/message-broker.ts +23 -10
  29. package/src/process.ts +59 -167
  30. package/src/resource-attachments.ts +1 -3
  31. package/src/rpc-line-decoder.ts +61 -0
  32. package/src/runtime.ts +22 -10
  33. package/src/settings.ts +2 -2
  34. package/src/subagents.ts +110 -18
  35. package/src/tools.ts +83 -37
  36. package/src/types.ts +1 -0
  37. package/src/widget-renderer.ts +119 -0
  38. package/src/widget.ts +245 -121
  39. package/dist/chunks/chunk-3FCHXUKZ.ts +0 -98
  40. package/dist/chunks/chunk-3FCHXUKZ.ts.map +0 -7
  41. package/dist/chunks/chunk-YMVSJ5GE.ts.map +0 -7
  42. package/dist/chunks/chunk-ZOAFWLDJ.ts.map +0 -7
  43. package/dist/chunks/menu-KAIUEWL7.ts.map +0 -7
package/README.md CHANGED
@@ -11,12 +11,12 @@ Pi Subagents runs Pi jobs in separate child processes and supports authenticated
11
11
  - Defaults work tools to `read`, `grep`, `find`, and `ls`.
12
12
  - Can attach validated local skills and trusted local extensions to one job without enabling automatic discovery.
13
13
  - Verifies requested extension tools before sending the task to the child model.
14
- - Inherits the main agent's effective model and uses its thinking level by default.
14
+ - Supports exact per-job provider and model selection, with independent inheritance and no fallback.
15
15
  - Gives the main agent and every child a context-specific `subagent_send` contract for bidirectional requests and responses.
16
16
  - Gives every child `subagent_wait` for an answer to a child-originated request.
17
17
  - Lets the main agent question a queued or running job through Pi RPC steering without retaining the child after completion.
18
18
  - Publishes one asynchronous terminal completion and shows active-job progress above the editor.
19
- - Provides a job manager with confirmed cancellation and immediate widget display settings.
19
+ - Provides a job manager with confirmed cancellation, immediate display settings, and session-local widget controls.
20
20
  - Exposes privacy-filtered metadata without task text, output, prompts, selected tools, or broker credentials.
21
21
  - Cancels session-owned work and closes the broker during replacement, reload, or shutdown.
22
22
 
@@ -62,12 +62,9 @@ Call `subagent_spawn` with a self-contained task and only the work tools that ta
62
62
 
63
63
  The call returns a `jobId` immediately, and the job continues in the background.
64
64
  Continue useful main-agent work until the result is required or a completion arrives.
65
+ A completion starts a new main-agent model turn if the main agent is idle.
65
66
 
66
- In TUI mode, each active-job row shows a preview of its existing `task` after the job ID by default; no new parameter is required.
67
- The preview removes terminal controls, collapses whitespace, and uses at most 40 terminal columns, including an ellipsis when shortened.
68
- It describes the assigned task, not live child activity; the full task sent to the child is unchanged.
69
- Task text is visible in this local widget, but `subagent_inspect` continues to omit it.
70
- Rows are clipped to the available terminal width, so trailing state, thinking level, timing, or tools can be hidden on narrow terminals.
67
+ In TUI mode, the widget above the editor shows queued and running tasks; no new parameter is required.
71
68
 
72
69
  Use messaging only when needed:
73
70
 
@@ -79,11 +76,6 @@ Completion messages and child requests and responses follow Pi's global tool-out
79
76
  Collapsed messages show a summary and the configured expansion key; expanded messages show the full content.
80
77
  This display state does not change the content sent to the model.
81
78
 
82
- In TUI mode, the above-editor widget shows each queued or running job's ID, state, thinking level, elapsed time, timeout, and selected core and extension tool names.
83
- The `thinking: <level>` field shows the resolved configuration passed at spawn, including `off`, even when IDs, timing, and tools are hidden.
84
- Later main-agent changes do not change this field; it does not track child-side normalization or later setting changes.
85
- It omits fixed communication tools, attachment paths, and resource totals, disappears when no jobs remain active, and clears when the session ends.
86
-
87
79
  ## 💬 Commands
88
80
 
89
81
  `/subagents` opens a manager for current-session job metadata, confirmed cancellation of active jobs, display settings, status, and help.
@@ -95,13 +87,55 @@ Print and JSON modes reject these interactive commands with an error; the model
95
87
  Job lists and details always show job IDs, regardless of widget preferences, and omit task text and child output.
96
88
  Jobs do not survive reload or session replacement.
97
89
 
90
+ ## 🖥️ Widget presentation
91
+
92
+ The widget is TUI-only and contains only queued or running jobs. Each row starts with `▶` for running or `○` for queued, followed by a task preview. Job IDs and tool names are hidden by default.
93
+ For example, with a main-agent thinking level of `high` at spawn:
94
+
95
+ ```text
96
+ Subagents · 2 active
97
+ ▶ Review widget tests · 12s
98
+ ○ Audit settings · thinking: medium · queued
99
+ ```
100
+
101
+ The `provider: <id>`, `model: <id>`, and `thinking: <level>` fields each appear only when the resolved value differs from the main agent's effective value captured at spawn, including an `off` thinking override. Inherited values and explicit values equal to those defaults are hidden. An explicit provider/model pair without a selected main-agent model shows both IDs.
102
+ Later main-agent changes do not change these comparisons. The fields describe the configuration passed at spawn, not child-side normalization or later changes.
103
+ Running rows show elapsed time and a timeout only when one is set. Queued rows show `queued` and a configured timeout, without elapsed time. **Show timing** controls both time fields.
104
+
105
+ The task preview removes terminal controls, collapses whitespace, and uses at most 40 terminal columns, including an ellipsis when shortened. It describes the assigned task, not live child activity; the full task sent to the child is unchanged.
106
+ Task text is visible in this local widget, but `subagent_inspect` continues to omit it. Optional tool names include selected core and extension tools, not fixed communication tools.
107
+ The widget omits attachment paths and resource totals, disappears when no jobs remain active, and clears when the session ends.
108
+
109
+ Ordinary updates refresh the mounted widget without changing its position among other widgets. Hiding and showing it again can change that position.
110
+ The widget uses at most ten rows, including one separator, and reserves eight terminal rows for the editor and footer. This is a local height limit, not a calculation of space left by other widgets.
111
+ With fewer than two available rows it renders nothing. Short layouts use a summary with active, running, queued, and omitted-row counts. Narrow layouts clip each line to the terminal width.
112
+
113
+ In `/subagents`, **Widget view** provides details, summary, hide/show, pin/unpin, automatic compaction, and item-view reset controls.
114
+ These controls are session-local and do not write settings. Manual hide remains in effect across job changes until you show the widget again.
115
+ A pin prevents automatic compaction, but does not override `showWidget: false`, width limits, or row limits. Unpinning does not immediately compact the view.
116
+ An explicit details, summary, or hide/show choice cancels the pending automatic rule.
117
+
118
+ Automatic compaction is off by default. Choose **Next consumed user message** to compact when Pi emits `message_start` for a user message, including extension-generated user messages and queued messages when consumed. Input submission, rejected input, and unconsumed queues do not count.
119
+ Choose **Next eligible settled cycle** to wait for `agent_settled` after later consumed user activity in that same cycle. The cycle already active when the rule is armed is excluded, including run preparation before `agent_start` and a cycle that started during settings loading.
120
+ Retries, tool turns, continuations, automatic context compaction, and batched queued messages can share one cycle. Tree navigation and manual context compaction are not response cycles.
121
+ Eligibility requires a non-aborted settlement and a latest observed turn outcome other than error or abort; a non-aborted settlement alone is insufficient.
122
+ A pending rule rearms on meaningful active-job changes, but not elapsed-time refreshes, repaint, or resize. A rule that compacts is consumed once; otherwise it stays pending. Pins, disabled settings, and manual hide prevent automatic compaction.
123
+
124
+ If maintenance ends and an extension starts a custom run without an observed idle gap, the rule can wait one extra cycle. Pi exposes no exact run-activity query to extensions.
125
+
126
+ An active job's manager detail screen can compact or remove only that job's widget row. Removal does not cancel the job or suppress completion messages.
127
+ Removal remains in effect across active-job snapshots until **Reset item views**, or until the job ID leaves the active snapshot. Reset restores the current active rows and their item details, not the overall view, pin, or trigger.
128
+ If all items are removed, the widget and separator disappear. The summary counts include removed and otherwise omitted rows; the manager still lists the jobs.
129
+ Widget presentation choices reset on `session_start` (including reload and session replacement), `session_tree` navigation, and shutdown. Tree navigation resets presentation without cancelling active jobs.
130
+ Jobs, saved preferences, tool definitions, model context, and completion delivery are not changed by widget controls.
131
+
98
132
  ## 🛠️ Tools
99
133
 
100
134
  The main Pi session exposes five fixed tools:
101
135
 
102
136
  | Tool | Parameters | Purpose |
103
137
  | --- | --- | --- |
104
- | `subagent_spawn` | `task`, optional `tools`, `skills`, `extensions`, `thinkingLevel`, `timeout` | Start one subagent job and return its `jobId`. |
138
+ | `subagent_spawn` | `task`, optional `provider`, `model`, `tools`, `skills`, `extensions`, `thinkingLevel`, `timeout` | Start one subagent job and return its `jobId`. |
105
139
  | `subagent_inspect` | none | List privacy-filtered retained-job metadata. |
106
140
  | `subagent_cancel` | `jobId` | Idempotently cancel one queued or running job. |
107
141
  | `subagent_wait` | `jobId`, optional `timeout` | Wait for a job or return early for an incoming child message. |
@@ -138,14 +172,14 @@ See [`docs/tools.md`](./docs/tools.md) for the concise schema reference, [`docs/
138
172
  ## ⚙️ Settings
139
173
 
140
174
  Use `/subagents settings` or the manager's Settings action to edit user display preferences.
141
- All four fields accept JSON booleans and default to `true`:
175
+ All four fields accept JSON booleans:
142
176
 
143
- | Field | Effect |
144
- | --- | --- |
145
- | `showWidget` | Show the above-editor widget. |
146
- | `showJobId` | Show job IDs in widget rows. |
147
- | `showTools` | Show selected tool names in widget rows. |
148
- | `showTiming` | Show elapsed time and timeout in widget rows. |
177
+ | Field | Default | Effect |
178
+ | --- | --- | --- |
179
+ | `showWidget` | `true` | Show the above-editor widget. |
180
+ | `showJobId` | `false` | Show job IDs in widget rows. |
181
+ | `showTools` | `false` | Show selected tool names in widget rows. |
182
+ | `showTiming` | `true` | Show running elapsed time and configured timeouts. |
149
183
 
150
184
  Successful UI saves apply immediately. Hiding the widget does not stop jobs, change model tools, or suppress completion messages.
151
185
  Showing it again displays currently active jobs with the other saved preferences. Job state and the task preview remain visible when the widget is enabled.
@@ -153,7 +187,7 @@ Escape returns or closes without undoing completed saves; Ctrl+C closes the enti
153
187
  Settings uses Pi's configured selection keys. Its footer shows only the hard-cancel key to avoid displaying fixed keys that do not match your bindings.
154
188
 
155
189
  Preferences are saved in `<getAgentDir()>/pi-subagents.json`, normally `~/.pi/agent/pi-subagents.json`.
156
- Only user settings are supported; project files and legacy settings are not read. User fields override code defaults.
190
+ Only user settings are supported; project files and legacy settings are not read. User fields override code defaults, including saved values from before a default change.
157
191
  Manual file edits are re-read on `session_start`, including `/reload`, and before each UI save.
158
192
  Reading defaults creates no file. Invalid values produce diagnostics and use their defaults; malformed documents block saves until repaired.
159
193
  Saves preserve unknown fields, publish atomically, and keep reads and writes ordered within one Pi process. Separate Pi processes are not locked.
@@ -171,6 +205,8 @@ The package intentionally registers and publishes no skill; the repository-only
171
205
  ```ts
172
206
  {
173
207
  task: string;
208
+ provider?: string;
209
+ model?: string;
174
210
  tools?: Array<"read" | "bash" | "powershell" | "edit" | "write" | "grep" | "find" | "ls" | "codemode">;
175
211
  skills?: string[];
176
212
  extensions?: Array<{ path: string; tools: string[] }>;
@@ -179,6 +215,18 @@ The package intentionally registers and publishes no skill; the repository-only
179
215
  }
180
216
  ```
181
217
 
218
+ `provider` and `model` are exact IDs. Each omitted field inherits independently from the main agent at spawn time; later parent changes do not affect the job.
219
+ A provider-only override retains the parent's model ID and fails if that pair is unavailable. To select another pair explicitly:
220
+
221
+ ```ts
222
+ { task: "Review the parser without changing files.", provider: "openai", model: "gpt-5.5" }
223
+ ```
224
+
225
+ Only the child checks exact model registration and current availability. Every job requires a registered chat model and child-visible credentials, including jobs that inherit both fields.
226
+ A missing or unavailable model fails the job after `subagent_spawn` returns its `jobId`, before the task reaches any model. Use `subagent_wait` to read the failure.
227
+ Unlisted custom IDs previously accepted by Pi's CLI now fail; register the exact model in Pi's `models.json` or attach a trusted extension that registers it in the child.
228
+ See [Model selection](./docs/tools.md#model-selection) for exact matching, error timing, and virtual-model behavior.
229
+
182
230
  The optional `tools` list selects Pi core work tools and the built-in `codemode` tool.
183
231
  Omitting it selects `read`, `grep`, `find`, and `ls`, while an empty list gives the child no core work tools.
184
232
  The runtime always adds `subagent_send` and child `subagent_wait` and removes duplicate names.
@@ -201,7 +249,7 @@ Attached extensions run with the child's user permissions and are not a sandbox.
201
249
  Attachments must be existing local paths, not npm, Git, or URL sources.
202
250
  Project-local attachments and resources resolved from their packages require project trust, including paths that symlink into the project.
203
251
  A job accepts up to 16 skill paths, 16 extension entries, and 64 selected work tools.
204
- The child inherits the main agent's effective model and thinking level by default; there is no per-job model override.
252
+ The child uses the main agent's thinking level unless `thinkingLevel` is supplied; Pi clamps it to the selected model's supported levels.
205
253
  Parent-only extension providers require an attached extension that registers them in the child.
206
254
  Process-local runtime API keys, including a parent-only `--api-key`, are unavailable to the child; use stored or inherited environment credentials.
207
255
 
@@ -271,10 +319,9 @@ Parallel writers require disjoint ownership or workspace isolation outside this
271
319
 
272
320
  - Attachments must be existing local files or directories; package, Git, URL, and automatic parent-resource inheritance are unsupported.
273
321
  - An attached extension may recreate a parent-registered provider, but parent in-memory extension state and runtime-only API keys are not forwarded.
274
- - 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.
322
+ - The extension does not provide custom agents, 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.
275
323
  - Bidirectional messages use request-response coordination, not a retained conversational session.
276
324
  - The main agent must verify child claims against the actual diff and deterministic checks.
277
- - Child requests and responses trigger a main-agent turn, but asynchronous job completions do not wake an otherwise idle model turn automatically.
278
325
  - Jobs, broker requests, and retained results do not survive extension reload, session replacement, or process exit.
279
326
 
280
327
  ## 🗂️ Package layout
@@ -284,7 +331,9 @@ packages/pi-subagents/
284
331
  ├── src/ # Authoritative implementation and helpers
285
332
  │ ├── index.ts # Thin Pi entrypoint
286
333
  │ ├── subagents.ts # Commands and session lifecycle
287
- │ ├── menu.ts # Job manager
334
+ │ ├── menu.ts # Job manager and session-local display controls
335
+ │ ├── widget.ts # Retained widget ownership and event policies
336
+ │ ├── widget-renderer.ts # Bounded rows and active-job summaries
288
337
  │ ├── settings.ts # User preferences and atomic storage
289
338
  │ └── settings-ui.ts # Native settings editor
290
339
  ├── dist/ # Generated Jiti runtime, child bridge, and readiness probe
@@ -2,12 +2,13 @@
2
2
  // @ts-nocheck -- generated entries use .ts extensions for Pi's Jiti loader.
3
3
  import {
4
4
  createChildCommunicationExtension
5
- } from "./chunks/chunk-ZOAFWLDJ.ts";
5
+ } from "./chunks/chunk-PRIDTAJL.ts";
6
6
  import {
7
7
  MAX_FRAME_BYTES,
8
8
  MAX_IDENTIFIER_LENGTH,
9
9
  captureChildBootstrap
10
- } from "./chunks/chunk-YMVSJ5GE.ts";
10
+ } from "./chunks/chunk-YV2P6XJX.ts";
11
+ import "./chunks/chunk-5OXDVXXO.ts";
11
12
 
12
13
  // src/child-communication-bridge.ts
13
14
  import net from "node:net";
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/child-communication-bridge.ts"],
4
4
  "sourcesContent": ["import net from \"node:net\";\nimport type { ExtensionFactory } from \"@earendil-works/pi-coding-agent\";\nimport { captureChildBootstrap } 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 = captureChildBootstrap();\n\nconst childCommunicationBridge: ExtensionFactory = captured\n ? createChildCommunicationExtension(createBrokerClient(captured.communication))\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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",
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,29 +1,38 @@
1
1
  // @generated by scripts/build-runtime.mjs; do not edit.
2
2
  // @ts-nocheck -- generated entries use .ts extensions for Pi's Jiti loader.
3
3
  import {
4
+ isChildModelPair,
4
5
  toolSourceId
5
- } from "./chunks/chunk-3FCHXUKZ.ts";
6
+ } from "./chunks/chunk-B3RWNGDX.ts";
6
7
  import {
7
8
  MAX_READINESS_FRAME_BYTES,
8
9
  takeCapturedReadiness
9
- } from "./chunks/chunk-YMVSJ5GE.ts";
10
+ } from "./chunks/chunk-YV2P6XJX.ts";
11
+ import "./chunks/chunk-5OXDVXXO.ts";
10
12
 
11
13
  // src/child-readiness-probe.ts
12
14
  import * as fs from "node:fs";
13
15
  var captured = takeCapturedReadiness();
14
16
  var childReadinessProbe = captured ? createChildReadinessProbe(captured) : () => void 0;
15
17
  var child_readiness_probe_default = childReadinessProbe;
18
+ var ReadinessError = class extends Error {
19
+ };
16
20
  function createChildReadinessProbe(readiness, writeFrame = writeReadinessFrame, close = closeDescriptor) {
17
21
  return (pi) => {
18
22
  let settled = false;
23
+ let started = false;
24
+ let controller;
25
+ let deadline;
19
26
  const publish = (value) => {
20
27
  if (settled) return;
21
28
  settled = true;
22
- const frame = `${JSON.stringify(value)}
29
+ if (deadline) clearTimeout(deadline);
30
+ controller?.abort();
31
+ let frame = `${JSON.stringify(value)}
23
32
  `;
24
33
  if (Buffer.byteLength(frame, "utf8") > MAX_READINESS_FRAME_BYTES) {
25
- close(readiness.fd);
26
- throw new Error("Pi-subagents readiness frame exceeded its size limit.");
34
+ frame = `${JSON.stringify({ ok: false, error: "Subagent readiness frame exceeded its size limit." })}
35
+ `;
27
36
  }
28
37
  try {
29
38
  writeFrame(readiness.fd, frame);
@@ -31,21 +40,109 @@ function createChildReadinessProbe(readiness, writeFrame = writeReadinessFrame,
31
40
  close(readiness.fd);
32
41
  }
33
42
  };
34
- pi.on("resources_discover", () => {
35
- const active = new Set(pi.getActiveTools());
36
- const missing = readiness.expectedTools.filter((tool) => !active.has(tool));
43
+ const toolState = () => {
44
+ const active = pi.getActiveTools();
45
+ const missing = readiness.expectedTools.filter((tool) => !active.includes(tool));
37
46
  if (missing.length > 0) {
38
- publish({ ok: false, error: `Unavailable subagent tools: ${missing.join(", ")}.` });
39
- return;
47
+ throw new ReadinessError(`Unavailable subagent tools: ${missing.join(", ").slice(0, 512)}.`);
40
48
  }
41
- const sources = new Map(pi.getAllTools().map((tool) => [tool.name, tool.sourceInfo.path]));
42
- publish({
43
- ok: true,
44
- sources: readiness.expectedTools.map((tool) => {
45
- const source = sources.get(tool);
46
- return source ? toolSourceId(source) : "";
47
- })
49
+ const all = new Map(pi.getAllTools().map((tool) => [tool.name, tool.sourceInfo.path]));
50
+ const sources = readiness.expectedTools.map((tool) => {
51
+ const source = all.get(tool);
52
+ if (!source) throw new ReadinessError("Subagent child tool provenance is unavailable.");
53
+ return toolSourceId(source);
48
54
  });
55
+ return { active, sources };
56
+ };
57
+ pi.on("resources_discover", async (_event, ctx) => {
58
+ if (settled || started) return;
59
+ started = true;
60
+ controller = new AbortController();
61
+ const signal = ctx.signal ? AbortSignal.any([controller.signal, ctx.signal]) : controller.signal;
62
+ deadline = setTimeout(() => publish({ ok: false, error: "Subagent child model readiness timed out." }), 3e4);
63
+ deadline.unref();
64
+ try {
65
+ const tools = toolState();
66
+ const initialModel = ctx.model;
67
+ const initialDefinition = JSON.stringify(initialModel);
68
+ const pair = { provider: readiness.selection.provider, id: readiness.selection.model };
69
+ const registry = ctx.modelRegistry;
70
+ const manager = ctx.sessionManager;
71
+ const sessionId = manager.getSessionId();
72
+ const cwd = ctx.cwd;
73
+ const trusted = ctx.isProjectTrusted();
74
+ const nativeProvider = registry.getRegisteredNativeProvider(pair.provider);
75
+ const providerConfig = registry.getRegisteredProviderConfig(pair.provider);
76
+ const assertContext = () => {
77
+ signal.throwIfAborted();
78
+ if (ctx.modelRegistry !== registry || ctx.sessionManager !== manager || manager.getSessionId() !== sessionId || ctx.cwd !== cwd || ctx.isProjectTrusted() !== trusted || registry.getRegisteredNativeProvider(pair.provider) !== nativeProvider || registry.getRegisteredProviderConfig(pair.provider) !== providerConfig || JSON.stringify(toolState()) !== JSON.stringify(tools))
79
+ throw new ReadinessError("Subagent child context changed during model readiness.");
80
+ };
81
+ const assertInitialModel = () => {
82
+ assertContext();
83
+ if (ctx.model !== initialModel || JSON.stringify(ctx.model) !== initialDefinition) {
84
+ throw new ReadinessError("Subagent child context changed during model readiness.");
85
+ }
86
+ };
87
+ await registry.refresh({ providers: [pair.provider], allowNetwork: false, signal });
88
+ if (settled) return;
89
+ assertInitialModel();
90
+ const registration = registry.find(pair.provider, pair.id);
91
+ if (!registration) {
92
+ throw new ReadinessError("Subagent child model is not registered as an exact chat model.");
93
+ }
94
+ const registeredDefinition = JSON.stringify(registration);
95
+ const assertRegistration = () => {
96
+ if (JSON.stringify(registry.find(pair.provider, pair.id)) !== registeredDefinition) {
97
+ throw new ReadinessError("Subagent child registration changed during model readiness.");
98
+ }
99
+ };
100
+ const available = await registry.getAvailableOfType("chat", pair.provider, { signal });
101
+ if (settled) return;
102
+ assertInitialModel();
103
+ assertRegistration();
104
+ if (!available.some((entry) => entry.provider === pair.provider && entry.id === pair.id)) {
105
+ throw new ReadinessError(
106
+ "Subagent child model is unavailable as an exact chat model with current credentials."
107
+ );
108
+ }
109
+ let selectedModel = ctx.model;
110
+ if (!isChildModelPair(selectedModel) || selectedModel.provider !== pair.provider || selectedModel.id !== pair.id || JSON.stringify(selectedModel) !== registeredDefinition) {
111
+ const selected = await pi.setModel(registration);
112
+ if (settled) return;
113
+ assertContext();
114
+ assertRegistration();
115
+ if (!selected) throw new ReadinessError("Subagent child could not select the exact requested model.");
116
+ selectedModel = registration;
117
+ }
118
+ const assertSelected = () => {
119
+ assertContext();
120
+ assertRegistration();
121
+ const model = ctx.model;
122
+ if (model !== selectedModel || !isChildModelPair(model) || model.provider !== pair.provider || model.id !== pair.id || JSON.stringify(model) !== registeredDefinition)
123
+ throw new ReadinessError("Subagent child model changed during exact initial selection.");
124
+ };
125
+ assertSelected();
126
+ pi.setThinkingLevel(readiness.selection.thinkingLevel);
127
+ assertSelected();
128
+ const availableAfterSelection = await registry.getAvailableOfType("chat", pair.provider, { signal });
129
+ if (settled) return;
130
+ assertSelected();
131
+ if (!availableAfterSelection.some((entry) => entry.provider === pair.provider && entry.id === pair.id)) {
132
+ throw new ReadinessError(
133
+ "Subagent child model is unavailable as an exact chat model with current credentials."
134
+ );
135
+ }
136
+ publish({ ok: true, sources: tools.sources, model: pair });
137
+ } catch (error) {
138
+ publish({
139
+ ok: false,
140
+ error: error instanceof ReadinessError ? error.message : "Subagent child model readiness failed."
141
+ });
142
+ } finally {
143
+ if (deadline) clearTimeout(deadline);
144
+ controller.abort();
145
+ }
49
146
  });
50
147
  pi.on("session_shutdown", () => {
51
148
  publish({ ok: false, error: "Subagent child shut down before readiness completed." });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/child-readiness-probe.ts"],
4
- "sourcesContent": ["import * as fs from \"node:fs\";\nimport type { ExtensionFactory } from \"@earendil-works/pi-coding-agent\";\nimport { toolSourceId } from \"./attachment-utils.js\";\nimport { MAX_READINESS_FRAME_BYTES, takeCapturedReadiness } from \"./broker-credentials.js\";\n\nexport interface ChildReadinessState {\n fd: number;\n expectedTools: string[];\n}\n\nconst captured = takeCapturedReadiness();\n\nconst childReadinessProbe: ExtensionFactory = captured ? createChildReadinessProbe(captured) : () => undefined;\n\nexport default childReadinessProbe;\n\nexport function createChildReadinessProbe(\n readiness: ChildReadinessState,\n writeFrame: (fd: number, frame: string) => void = writeReadinessFrame,\n close: (fd: number) => void = closeDescriptor,\n): ExtensionFactory {\n return (pi) => {\n let settled = false;\n const publish = (value: { ok: true; sources: string[] } | { ok: false; error: string }) => {\n if (settled) return;\n settled = true;\n const frame = `${JSON.stringify(value)}\\n`;\n if (Buffer.byteLength(frame, \"utf8\") > MAX_READINESS_FRAME_BYTES) {\n close(readiness.fd);\n throw new Error(\"Pi-subagents readiness frame exceeded its size limit.\");\n }\n try {\n writeFrame(readiness.fd, frame);\n } finally {\n close(readiness.fd);\n }\n };\n\n pi.on(\"resources_discover\", () => {\n const active = new Set(pi.getActiveTools());\n const missing = readiness.expectedTools.filter((tool) => !active.has(tool));\n if (missing.length > 0) {\n publish({ ok: false, error: `Unavailable subagent tools: ${missing.join(\", \")}.` });\n return;\n }\n const sources = new Map(pi.getAllTools().map((tool) => [tool.name, tool.sourceInfo.path]));\n publish({\n ok: true,\n sources: readiness.expectedTools.map((tool) => {\n const source = sources.get(tool);\n return source ? toolSourceId(source) : \"\";\n }),\n });\n });\n\n pi.on(\"session_shutdown\", () => {\n publish({ ok: false, error: \"Subagent child shut down before readiness completed.\" });\n });\n };\n}\n\nfunction writeReadinessFrame(fd: number, frame: string): void {\n fs.writeFileSync(fd, frame, \"utf8\");\n}\n\nfunction closeDescriptor(fd: number): void {\n try {\n fs.closeSync(fd);\n } catch {\n // The descriptor may already be closed after a failed write.\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;AAAA,YAAY,QAAQ;AAUpB,IAAM,WAAW,sBAAsB;AAEvC,IAAM,sBAAwC,WAAW,0BAA0B,QAAQ,IAAI,MAAM;AAErG,IAAO,gCAAQ;AAER,SAAS,0BACd,WACA,aAAkD,qBAClD,QAA8B,iBACZ;AAClB,SAAO,CAAC,OAAO;AACb,QAAI,UAAU;AACd,UAAM,UAAU,CAAC,UAA0E;AACzF,UAAI,QAAS;AACb,gBAAU;AACV,YAAM,QAAQ,GAAG,KAAK,UAAU,KAAK,CAAC;AAAA;AACtC,UAAI,OAAO,WAAW,OAAO,MAAM,IAAI,2BAA2B;AAChE,cAAM,UAAU,EAAE;AAClB,cAAM,IAAI,MAAM,uDAAuD;AAAA,MACzE;AACA,UAAI;AACF,mBAAW,UAAU,IAAI,KAAK;AAAA,MAChC,UAAE;AACA,cAAM,UAAU,EAAE;AAAA,MACpB;AAAA,IACF;AAEA,OAAG,GAAG,sBAAsB,MAAM;AAChC,YAAM,SAAS,IAAI,IAAI,GAAG,eAAe,CAAC;AAC1C,YAAM,UAAU,UAAU,cAAc,OAAO,CAAC,SAAS,CAAC,OAAO,IAAI,IAAI,CAAC;AAC1E,UAAI,QAAQ,SAAS,GAAG;AACtB,gBAAQ,EAAE,IAAI,OAAO,OAAO,+BAA+B,QAAQ,KAAK,IAAI,CAAC,IAAI,CAAC;AAClF;AAAA,MACF;AACA,YAAM,UAAU,IAAI,IAAI,GAAG,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC;AACzF,cAAQ;AAAA,QACN,IAAI;AAAA,QACJ,SAAS,UAAU,cAAc,IAAI,CAAC,SAAS;AAC7C,gBAAM,SAAS,QAAQ,IAAI,IAAI;AAC/B,iBAAO,SAAS,aAAa,MAAM,IAAI;AAAA,QACzC,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAED,OAAG,GAAG,oBAAoB,MAAM;AAC9B,cAAQ,EAAE,IAAI,OAAO,OAAO,uDAAuD,CAAC;AAAA,IACtF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,oBAAoB,IAAY,OAAqB;AAC5D,EAAG,iBAAc,IAAI,OAAO,MAAM;AACpC;AAEA,SAAS,gBAAgB,IAAkB;AACzC,MAAI;AACF,IAAG,aAAU,EAAE;AAAA,EACjB,QAAQ;AAAA,EAER;AACF;",
4
+ "sourcesContent": ["import * as fs from \"node:fs\";\nimport type { ExtensionFactory } from \"@earendil-works/pi-coding-agent\";\nimport { toolSourceId } from \"./attachment-utils.js\";\nimport { type ChildSelection, MAX_READINESS_FRAME_BYTES, takeCapturedReadiness } from \"./broker-credentials.js\";\nimport { type ChildReadinessFrame, isChildModelPair } from \"./child-readiness.js\";\n\nexport interface ChildReadinessState {\n fd: number;\n expectedTools: string[];\n selection: ChildSelection;\n}\n\nconst captured = takeCapturedReadiness();\n\nconst childReadinessProbe: ExtensionFactory = captured ? createChildReadinessProbe(captured) : () => undefined;\n\nexport default childReadinessProbe;\n\nclass ReadinessError extends Error {}\n\nexport function createChildReadinessProbe(\n readiness: ChildReadinessState,\n writeFrame: (fd: number, frame: string) => void = writeReadinessFrame,\n close: (fd: number) => void = closeDescriptor,\n): ExtensionFactory {\n return (pi) => {\n let settled = false;\n let started = false;\n let controller: AbortController | undefined;\n let deadline: NodeJS.Timeout | undefined;\n const publish = (value: ChildReadinessFrame) => {\n if (settled) return;\n settled = true;\n if (deadline) clearTimeout(deadline);\n controller?.abort();\n let frame = `${JSON.stringify(value)}\\n`;\n if (Buffer.byteLength(frame, \"utf8\") > MAX_READINESS_FRAME_BYTES) {\n frame = `${JSON.stringify({ ok: false, error: \"Subagent readiness frame exceeded its size limit.\" })}\\n`;\n }\n try {\n writeFrame(readiness.fd, frame);\n } finally {\n close(readiness.fd);\n }\n };\n const toolState = () => {\n const active = pi.getActiveTools();\n const missing = readiness.expectedTools.filter((tool) => !active.includes(tool));\n if (missing.length > 0) {\n throw new ReadinessError(`Unavailable subagent tools: ${missing.join(\", \").slice(0, 512)}.`);\n }\n const all = new Map(pi.getAllTools().map((tool) => [tool.name, tool.sourceInfo.path]));\n const sources = readiness.expectedTools.map((tool) => {\n const source = all.get(tool);\n if (!source) throw new ReadinessError(\"Subagent child tool provenance is unavailable.\");\n return toolSourceId(source);\n });\n return { active, sources };\n };\n\n pi.on(\"resources_discover\", async (_event, ctx) => {\n if (settled || started) return;\n started = true;\n controller = new AbortController();\n const signal = ctx.signal ? AbortSignal.any([controller.signal, ctx.signal]) : controller.signal;\n deadline = setTimeout(() => publish({ ok: false, error: \"Subagent child model readiness timed out.\" }), 30_000);\n deadline.unref();\n try {\n const tools = toolState();\n const initialModel = ctx.model;\n const initialDefinition = JSON.stringify(initialModel);\n const pair = { provider: readiness.selection.provider, id: readiness.selection.model };\n const registry = ctx.modelRegistry;\n const manager = ctx.sessionManager;\n const sessionId = manager.getSessionId();\n const cwd = ctx.cwd;\n const trusted = ctx.isProjectTrusted();\n const nativeProvider = registry.getRegisteredNativeProvider(pair.provider);\n const providerConfig = registry.getRegisteredProviderConfig(pair.provider);\n const assertContext = () => {\n signal.throwIfAborted();\n if (\n ctx.modelRegistry !== registry ||\n ctx.sessionManager !== manager ||\n manager.getSessionId() !== sessionId ||\n ctx.cwd !== cwd ||\n ctx.isProjectTrusted() !== trusted ||\n registry.getRegisteredNativeProvider(pair.provider) !== nativeProvider ||\n registry.getRegisteredProviderConfig(pair.provider) !== providerConfig ||\n JSON.stringify(toolState()) !== JSON.stringify(tools)\n )\n throw new ReadinessError(\"Subagent child context changed during model readiness.\");\n };\n const assertInitialModel = () => {\n assertContext();\n if (ctx.model !== initialModel || JSON.stringify(ctx.model) !== initialDefinition) {\n throw new ReadinessError(\"Subagent child context changed during model readiness.\");\n }\n };\n // The public setter checks the configured-auth snapshot before checking fresh auth.\n // Refresh it without network access; refresh can recompose registered model objects.\n await registry.refresh({ providers: [pair.provider], allowNetwork: false, signal });\n if (settled) return;\n assertInitialModel();\n const registration = registry.find(pair.provider, pair.id);\n if (!registration) {\n throw new ReadinessError(\"Subagent child model is not registered as an exact chat model.\");\n }\n const registeredDefinition = JSON.stringify(registration);\n const assertRegistration = () => {\n if (JSON.stringify(registry.find(pair.provider, pair.id)) !== registeredDefinition) {\n throw new ReadinessError(\"Subagent child registration changed during model readiness.\");\n }\n };\n // Use a fresh provider-scoped availability check, not the cached chat snapshot.\n const available = await registry.getAvailableOfType(\"chat\", pair.provider, { signal });\n if (settled) return;\n assertInitialModel();\n assertRegistration();\n if (!available.some((entry) => entry.provider === pair.provider && entry.id === pair.id)) {\n throw new ReadinessError(\n \"Subagent child model is unavailable as an exact chat model with current credentials.\",\n );\n }\n // CLI matching is not literal. Bind only the exact available registration before any task.\n // setModel has no signal; the parent startup deadline terminates the isolated child.\n let selectedModel = ctx.model;\n if (\n !isChildModelPair(selectedModel) ||\n selectedModel.provider !== pair.provider ||\n selectedModel.id !== pair.id ||\n JSON.stringify(selectedModel) !== registeredDefinition\n ) {\n const selected = await pi.setModel(registration);\n if (settled) return;\n assertContext();\n assertRegistration();\n if (!selected) throw new ReadinessError(\"Subagent child could not select the exact requested model.\");\n selectedModel = registration;\n }\n const assertSelected = () => {\n assertContext();\n assertRegistration();\n const model = ctx.model;\n if (\n model !== selectedModel ||\n !isChildModelPair(model) ||\n model.provider !== pair.provider ||\n model.id !== pair.id ||\n JSON.stringify(model) !== registeredDefinition\n )\n throw new ReadinessError(\"Subagent child model changed during exact initial selection.\");\n };\n assertSelected();\n // setModel applies model/global defaults and awaits model_select hooks. Restore the request\n // only after verifying their result; Pi clamps it to this exact model's capabilities.\n pi.setThinkingLevel(readiness.selection.thinkingLevel);\n assertSelected();\n // Selection hooks can change credentials or filters without replacing registration. Include\n // synchronous thinking hooks; Pi does not await their later asynchronous continuations.\n const availableAfterSelection = await registry.getAvailableOfType(\"chat\", pair.provider, { signal });\n if (settled) return;\n assertSelected();\n if (!availableAfterSelection.some((entry) => entry.provider === pair.provider && entry.id === pair.id)) {\n throw new ReadinessError(\n \"Subagent child model is unavailable as an exact chat model with current credentials.\",\n );\n }\n publish({ ok: true, sources: tools.sources, model: pair });\n } catch (error) {\n // Provider/auth errors can contain secrets and paths. Publish only bounded probe-owned diagnostics.\n publish({\n ok: false,\n error: error instanceof ReadinessError ? error.message : \"Subagent child model readiness failed.\",\n });\n } finally {\n if (deadline) clearTimeout(deadline);\n controller.abort();\n }\n });\n\n pi.on(\"session_shutdown\", () => {\n publish({ ok: false, error: \"Subagent child shut down before readiness completed.\" });\n });\n };\n}\n\nfunction writeReadinessFrame(fd: number, frame: string): void {\n fs.writeFileSync(fd, frame, \"utf8\");\n}\n\nfunction closeDescriptor(fd: number): void {\n try {\n fs.closeSync(fd);\n } catch {\n // The descriptor may already be closed after a failed write.\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -39,4 +39,4 @@ export {
39
39
  DEFAULT_SUBAGENT_TOOLS,
40
40
  SUBAGENT_THINKING_LEVELS
41
41
  };
42
- //# sourceMappingURL=chunk-FY5HIU6Y.ts.map
42
+ //# sourceMappingURL=chunk-5OXDVXXO.ts.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/types.ts"],
4
- "sourcesContent": ["import type { ModelThinkingLevel } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAttachment } from \"./resource-attachments.js\";\n\nexport const JOB_STATES = [\"queued\", \"running\", \"completed\", \"partial\", \"failed\", \"timed_out\", \"cancelled\"] as const;\n\nexport type SubagentJobState = (typeof JOB_STATES)[number];\n\nexport const TERMINAL_JOB_STATES = new Set<SubagentJobState>([\n \"completed\",\n \"partial\",\n \"failed\",\n \"timed_out\",\n \"cancelled\",\n]);\n\nexport const CHILD_CORE_TOOL_NAMES = [\n \"read\",\n \"bash\",\n \"powershell\",\n \"edit\",\n \"write\",\n \"grep\",\n \"find\",\n \"ls\",\n \"codemode\",\n] as const;\nexport const DEFAULT_SUBAGENT_TOOLS = [\"read\", \"grep\", \"find\", \"ls\"] as const;\nexport const SUBAGENT_THINKING_LEVELS = [\n \"off\",\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n] as const satisfies readonly ModelThinkingLevel[];\nexport type SubagentThinkingLevel = (typeof SUBAGENT_THINKING_LEVELS)[number];\n\nexport interface ChildResult {\n state: Extract<SubagentJobState, \"completed\" | \"partial\" | \"failed\" | \"timed_out\" | \"cancelled\">;\n result?: string;\n error?: string;\n limitations: string[];\n truncated: boolean;\n}\n\nexport interface BrokerCredentials {\n host: \"127.0.0.1\";\n port: number;\n token: string;\n}\n\nexport interface ChildControl {\n send(message: string, signal?: AbortSignal): Promise<void>;\n}\n\nexport interface ChildRequest {\n task: string;\n tools: string[];\n skills: string[];\n extensions: ExtensionAttachment[];\n toolSources: Record<string, string[]>;\n model: string;\n thinkingLevel: SubagentThinkingLevel;\n cwd: string;\n timeout?: number;\n projectTrusted: boolean;\n communication: BrokerCredentials;\n signal: AbortSignal;\n onControl?: (control: ChildControl) => void;\n}\n\nexport interface JobSummary {\n jobId: string;\n state: SubagentJobState;\n createdAt: number;\n startedAt?: number;\n finishedAt?: number;\n timeout?: number;\n resultSummary?: string;\n errorSummary?: string;\n}\n"],
4
+ "sourcesContent": ["import type { ModelThinkingLevel } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAttachment } from \"./resource-attachments.js\";\n\nexport const JOB_STATES = [\"queued\", \"running\", \"completed\", \"partial\", \"failed\", \"timed_out\", \"cancelled\"] as const;\n\nexport type SubagentJobState = (typeof JOB_STATES)[number];\n\nexport const TERMINAL_JOB_STATES = new Set<SubagentJobState>([\n \"completed\",\n \"partial\",\n \"failed\",\n \"timed_out\",\n \"cancelled\",\n]);\n\nexport const CHILD_CORE_TOOL_NAMES = [\n \"read\",\n \"bash\",\n \"powershell\",\n \"edit\",\n \"write\",\n \"grep\",\n \"find\",\n \"ls\",\n \"codemode\",\n] as const;\nexport const DEFAULT_SUBAGENT_TOOLS = [\"read\", \"grep\", \"find\", \"ls\"] as const;\nexport const SUBAGENT_THINKING_LEVELS = [\n \"off\",\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n] as const satisfies readonly ModelThinkingLevel[];\nexport type SubagentThinkingLevel = (typeof SUBAGENT_THINKING_LEVELS)[number];\n\nexport interface ChildResult {\n state: Extract<SubagentJobState, \"completed\" | \"partial\" | \"failed\" | \"timed_out\" | \"cancelled\">;\n result?: string;\n error?: string;\n limitations: string[];\n truncated: boolean;\n}\n\nexport interface BrokerCredentials {\n host: \"127.0.0.1\";\n port: number;\n token: string;\n}\n\nexport interface ChildControl {\n send(message: string, signal?: AbortSignal): Promise<void>;\n}\n\nexport interface ChildRequest {\n task: string;\n tools: string[];\n skills: string[];\n extensions: ExtensionAttachment[];\n toolSources: Record<string, string[]>;\n provider: string;\n model: string;\n thinkingLevel: SubagentThinkingLevel;\n cwd: string;\n timeout?: number;\n projectTrusted: boolean;\n communication: BrokerCredentials;\n signal: AbortSignal;\n onControl?: (control: ChildControl) => void;\n}\n\nexport interface JobSummary {\n jobId: string;\n state: SubagentJobState;\n createdAt: number;\n startedAt?: number;\n finishedAt?: number;\n timeout?: number;\n resultSummary?: string;\n errorSummary?: string;\n}\n"],
5
5
  "mappings": ";;;;AAGO,IAAM,aAAa,CAAC,UAAU,WAAW,aAAa,WAAW,UAAU,aAAa,WAAW;AAInG,IAAM,sBAAsB,oBAAI,IAAsB;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,wBAAwB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACO,IAAM,yBAAyB,CAAC,QAAQ,QAAQ,QAAQ,IAAI;AAC5D,IAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;",
6
6
  "names": []
7
7
  }