agents 0.27.0 → 0.28.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 (216) hide show
  1. package/dist/abortable-C1SpfVoi.js +21 -0
  2. package/dist/abortable-C1SpfVoi.js.map +1 -0
  3. package/dist/{agent-routing-Bhdbvf7s.d.ts → agent-routing-BMvWTFEp.d.ts} +21 -15
  4. package/dist/agent-routing.d.ts +1 -1
  5. package/dist/agent-tool-types.d.ts +1 -1
  6. package/dist/{agent-tools-bJZwBMfq.d.ts → agent-tools-ohoewW-B.d.ts} +2 -2
  7. package/dist/agent-tools.d.ts +1 -1
  8. package/dist/ai-ahruGw7e.d.ts +239 -0
  9. package/dist/{ai-sdk-OoGkFy3s.js → ai-sdk-C2iTAwUd.js} +44 -18
  10. package/dist/ai-sdk-C2iTAwUd.js.map +1 -0
  11. package/dist/browser/ai.d.ts +8 -227
  12. package/dist/browser/ai.js +259 -1
  13. package/dist/browser/ai.js.map +1 -0
  14. package/dist/browser/index.d.ts +56 -46
  15. package/dist/browser/index.js +4 -361
  16. package/dist/browser/{ai-sdk.d.ts → tools/ai-sdk.d.ts} +7 -7
  17. package/dist/browser/{ai-sdk.js → tools/ai-sdk.js} +5 -4
  18. package/dist/browser/tools/ai-sdk.js.map +1 -0
  19. package/dist/browser/tools/pi.d.ts +111 -0
  20. package/dist/browser/tools/pi.js +119 -0
  21. package/dist/browser/tools/pi.js.map +1 -0
  22. package/dist/browser/{tanstack-ai.d.ts → tools/tanstack-ai.d.ts} +39 -37
  23. package/dist/browser/{tanstack-ai.js → tools/tanstack-ai.js} +73 -59
  24. package/dist/browser/tools/tanstack-ai.js.map +1 -0
  25. package/dist/browser-CEdNlsaD.js +481 -0
  26. package/dist/browser-CEdNlsaD.js.map +1 -0
  27. package/dist/{browser-tmkcAAI3.d.ts → browser-D30VlpcA.d.ts} +63 -37
  28. package/dist/{browser-tool-CBqs6hqa.js → browser-tool-4iomavs_.js} +145 -49
  29. package/dist/browser-tool-4iomavs_.js.map +1 -0
  30. package/dist/{browser-tool-Bn-nzJQI.d.ts → browser-tool-vtrPOV8e.d.ts} +24 -5
  31. package/dist/{capability-B4WbF81e.js → capability-DBAKc6UZ.js} +1 -3
  32. package/dist/capability-DBAKc6UZ.js.map +1 -0
  33. package/dist/{capability-runner-O5VbQzqg.d.ts → capability-runner-BiVUtjqC.d.ts} +1 -7
  34. package/dist/chat/index.d.ts +4 -4
  35. package/dist/chat/index.js +1 -1
  36. package/dist/chat-sdk/index.d.ts +1 -1
  37. package/dist/chat-sdk/index.js +1 -1
  38. package/dist/{client-1tEQ1Oqz.js → client-BnYbNT3z.js} +3 -4
  39. package/dist/client-BnYbNT3z.js.map +1 -0
  40. package/dist/{client-DS3Dz9l0.d.ts → client-Bp-JwL3p.d.ts} +2 -2
  41. package/dist/client.d.ts +1 -1
  42. package/dist/{connector-58XDGvc3.js → connector-CtZylXdk.js} +3 -603
  43. package/dist/connector-CtZylXdk.js.map +1 -0
  44. package/dist/{connector-Cl-VqPmA.d.ts → connector-DEXzVoaY.d.ts} +9 -374
  45. package/dist/{conversations-DH0ut_8n.d.ts → conversations-FjHDRZyD.d.ts} +4 -4
  46. package/dist/{current-agent-C07C5o5Y.d.ts → current-agent-CKgT5d1O.d.ts} +3 -5
  47. package/dist/current-agent-DhoDkSnH.js.map +1 -1
  48. package/dist/{durable-object-lifecycle-DRqp475_.d.ts → durable-object-lifecycle-DOI_bzCH.d.ts} +2 -2
  49. package/dist/experimental/channels/index.d.ts +2 -2
  50. package/dist/experimental/channels/index.js +2 -2
  51. package/dist/experimental/channels/web/index.d.ts +2 -2
  52. package/dist/experimental/channels/web/index.js +1 -1
  53. package/dist/{gateway-BDC07gYO.d.ts → gateway-BFO6vRDn.d.ts} +2 -2
  54. package/dist/{handler-stateless-VvrWSAVA.js → handler-stateless-Bly_nSH3.js} +12 -3
  55. package/dist/handler-stateless-Bly_nSH3.js.map +1 -0
  56. package/dist/harness/ai-sdk/index.d.ts +2 -2
  57. package/dist/harness/ai-sdk/index.js +1 -1
  58. package/dist/harness/container/index.d.ts +2 -2
  59. package/dist/harness/container/index.js +3 -3
  60. package/dist/harness/opencode/index.d.ts +183 -7
  61. package/dist/harness/opencode/index.js +355 -24
  62. package/dist/harness/opencode/index.js.map +1 -1
  63. package/dist/harness/pi/index.d.ts +2 -2
  64. package/dist/harness/pi/index.js +3 -3
  65. package/dist/harness/store/index.d.ts +1 -1
  66. package/dist/harness/store/index.js +1 -1
  67. package/dist/harness/think/index.d.ts +2 -2
  68. package/dist/harness/think/index.js +363 -171
  69. package/dist/harness/think/index.js.map +1 -1
  70. package/dist/{images-Ce9SCu3X.js → images-C4hiIexM.js} +46 -4
  71. package/dist/images-C4hiIexM.js.map +1 -0
  72. package/dist/{index-D0A5tbWu.d.ts → index-BEL3ZV-s.d.ts} +2 -6
  73. package/dist/{index-Ib_4dwOo.d.ts → index-CBt8oRJt.d.ts} +3 -5
  74. package/dist/index.d.ts +4 -4
  75. package/dist/index.js +2 -2
  76. package/dist/input-schema-BQykTEp_.js +20 -0
  77. package/dist/input-schema-BQykTEp_.js.map +1 -0
  78. package/dist/{input-schema-DNrpTu49.js → input-schema-xBofjBKC.js} +3 -3
  79. package/dist/input-schema-xBofjBKC.js.map +1 -0
  80. package/dist/internal_context.d.ts +1 -1
  81. package/dist/lifecycle/index.d.ts +3 -3
  82. package/dist/lifecycle/index.js +2 -2
  83. package/dist/{lifecycle-CFu6OV03.js → lifecycle-DGorpAmA.js} +2 -4
  84. package/dist/lifecycle-DGorpAmA.js.map +1 -0
  85. package/dist/mcp/client/index.d.ts +1 -1
  86. package/dist/mcp/client/index.js +1 -1
  87. package/dist/mcp/index.d.ts +1 -1
  88. package/dist/mcp/index.js +18 -4
  89. package/dist/mcp/index.js.map +1 -1
  90. package/dist/mcp/server/index.js +1 -1
  91. package/dist/models/ai-sdk/index.d.ts +45 -17
  92. package/dist/models/ai-sdk/index.js +1 -1
  93. package/dist/models/opencode/index.d.ts +2 -2
  94. package/dist/models/opencode/index.js +1 -1
  95. package/dist/models/pi-ai/index.d.ts +8 -3
  96. package/dist/models/pi-ai/index.js +6 -6
  97. package/dist/models/pi-ai/index.js.map +1 -1
  98. package/dist/{options-pwTNq9z6.d.ts → options-CiIsJHXR.d.ts} +2 -6
  99. package/dist/queue/index.d.ts +1 -1
  100. package/dist/queue/index.js +1 -1
  101. package/dist/{queue-BB-zfIYF.js → queue-CcIjVYTE.js} +2 -2
  102. package/dist/{queue-BB-zfIYF.js.map → queue-CcIjVYTE.js.map} +1 -1
  103. package/dist/react.d.ts +2 -2
  104. package/dist/routing/index.d.ts +2 -2
  105. package/dist/routing/index.js +1 -1
  106. package/dist/{scheduler-CrFCnv_J.d.ts → scheduler-BCLESHSC.d.ts} +2 -12
  107. package/dist/{scheduler-DZ3xQfeK.js → scheduler-FIHv2-kJ.js} +2 -4
  108. package/dist/scheduler-FIHv2-kJ.js.map +1 -0
  109. package/dist/schedules/index.d.ts +1 -1
  110. package/dist/schedules/index.js +1 -1
  111. package/dist/serializable.d.ts +1 -1
  112. package/dist/session-store-Do4xkDcf.js +606 -0
  113. package/dist/session-store-Do4xkDcf.js.map +1 -0
  114. package/dist/session-store-DoPY12xM.d.ts +383 -0
  115. package/dist/sessions/index.d.ts +1 -1
  116. package/dist/sessions/index.js +1 -1
  117. package/dist/{sessions-B9pNuxdT.js → sessions-_vN5BEZX.js} +2 -2
  118. package/dist/{sessions-B9pNuxdT.js.map → sessions-_vN5BEZX.js.map} +1 -1
  119. package/dist/{settings-C45hDliX.js → settings-BjAiPd6Z.js} +7 -4
  120. package/dist/settings-BjAiPd6Z.js.map +1 -0
  121. package/dist/{settings-NgGwF7Qt.d.ts → settings-DnD__xuE.d.ts} +22 -4
  122. package/dist/{src-DgCbZtIR.js → src-CQxJFv4l.js} +8 -8
  123. package/dist/src-CQxJFv4l.js.map +1 -0
  124. package/dist/state/index.d.ts +1 -1
  125. package/dist/state/index.js +1 -3
  126. package/dist/state/index.js.map +1 -1
  127. package/dist/{store-DLeqKuj3.d.ts → store-BKM4Xm9M.d.ts} +23 -1
  128. package/dist/{store-vgcPYo8K.js → store-CslVzfN7.js} +28 -2
  129. package/dist/store-CslVzfN7.js.map +1 -0
  130. package/dist/streams/index.d.ts +1 -1
  131. package/dist/streams/index.js +1 -1
  132. package/dist/{streams-CITClVer.js → streams-lsHMJhRW.js} +2 -2
  133. package/dist/{streams-CITClVer.js.map → streams-lsHMJhRW.js.map} +1 -1
  134. package/dist/{streams-fbG61qM8.d.ts → streams-vrCtbUIn.d.ts} +2 -2
  135. package/dist/sub-routing.d.ts +1 -1
  136. package/dist/tasks/index.d.ts +1 -1
  137. package/dist/tasks/index.js +1 -1
  138. package/dist/{tasks-CkTZNaV1.js → tasks-BN_5AWqI.js} +2 -2
  139. package/dist/{tasks-CkTZNaV1.js.map → tasks-BN_5AWqI.js.map} +1 -1
  140. package/dist/{tasks-PtlB4Uyn.d.ts → tasks-E89KdwkS.d.ts} +2 -2
  141. package/dist/{tool-BPJEbwaX.d.ts → tool-CTp72Jb_.d.ts} +4 -4
  142. package/dist/tool-CxKsvxjm.js +1126 -0
  143. package/dist/tool-CxKsvxjm.js.map +1 -0
  144. package/dist/tool-DoVberpN.d.ts +301 -0
  145. package/dist/{tool-3PA8xjB_.js → tool-VF0qiO7q.js} +7 -18
  146. package/dist/tool-VF0qiO7q.js.map +1 -0
  147. package/dist/tool-helpers-O5BDVEAY.js +58 -0
  148. package/dist/tool-helpers-O5BDVEAY.js.map +1 -0
  149. package/dist/{transport-k2mFrtL8.d.ts → transport-DCyarnwm.d.ts} +2 -2
  150. package/dist/voice/index.d.ts +2 -2
  151. package/dist/web/fetch/index.d.ts +89 -0
  152. package/dist/web/fetch/index.js +20 -0
  153. package/dist/web/fetch/index.js.map +1 -0
  154. package/dist/web/fetch/tools/ai-sdk.d.ts +80 -0
  155. package/dist/web/fetch/tools/ai-sdk.js +47 -0
  156. package/dist/web/fetch/tools/ai-sdk.js.map +1 -0
  157. package/dist/web/fetch/tools/pi.d.ts +84 -0
  158. package/dist/web/fetch/tools/pi.js +88 -0
  159. package/dist/web/fetch/tools/pi.js.map +1 -0
  160. package/dist/web/fetch/tools/tanstack-ai.d.ts +78 -0
  161. package/dist/web/fetch/tools/tanstack-ai.js +45 -0
  162. package/dist/web/fetch/tools/tanstack-ai.js.map +1 -0
  163. package/dist/{websearch → web/search}/index.d.ts +1 -1
  164. package/dist/{websearch → web/search}/index.js +1 -1
  165. package/dist/{websearch → web/search}/tools/ai-sdk.d.ts +2 -2
  166. package/dist/{websearch → web/search}/tools/ai-sdk.js +3 -3
  167. package/dist/web/search/tools/ai-sdk.js.map +1 -0
  168. package/dist/{websearch → web/search}/tools/pi.d.ts +3 -3
  169. package/dist/{websearch → web/search}/tools/pi.js +2 -2
  170. package/dist/web/search/tools/pi.js.map +1 -0
  171. package/dist/{websearch → web/search}/tools/tanstack-ai.d.ts +2 -2
  172. package/dist/{websearch → web/search}/tools/tanstack-ai.js +3 -3
  173. package/dist/web/search/tools/tanstack-ai.js.map +1 -0
  174. package/dist/websockets/index.d.ts +2 -2
  175. package/dist/websockets/index.js +1 -1
  176. package/dist/{websockets-CmENGb-Z.js → websockets-C3zy8YR0.js} +3 -5
  177. package/dist/websockets-C3zy8YR0.js.map +1 -0
  178. package/dist/workflow-types.d.ts +1 -1
  179. package/dist/workflows.d.ts +1 -1
  180. package/dist/workflows.js +1 -1
  181. package/docs/browse-the-web.md +26 -1
  182. package/docs/fetch-the-web.md +276 -0
  183. package/docs/harnesses/pi.md +25 -0
  184. package/docs/index.md +99 -76
  185. package/docs/lifecycle.md +2 -3
  186. package/docs/mcp-client.md +1 -1
  187. package/docs/mcp-servers.md +1 -1
  188. package/docs/models-pi-ai.md +11 -0
  189. package/docs/models.md +45 -3
  190. package/docs/queue.md +2 -3
  191. package/docs/scheduling.md +2 -6
  192. package/docs/search-the-web.md +2 -0
  193. package/package.json +52 -27
  194. package/dist/ai-fm7xx1BK.js +0 -312
  195. package/dist/ai-fm7xx1BK.js.map +0 -1
  196. package/dist/ai-sdk-OoGkFy3s.js.map +0 -1
  197. package/dist/browser/ai-sdk.js.map +0 -1
  198. package/dist/browser/index.js.map +0 -1
  199. package/dist/browser/tanstack-ai.js.map +0 -1
  200. package/dist/browser-tool-CBqs6hqa.js.map +0 -1
  201. package/dist/capability-B4WbF81e.js.map +0 -1
  202. package/dist/client-1tEQ1Oqz.js.map +0 -1
  203. package/dist/connector-58XDGvc3.js.map +0 -1
  204. package/dist/handler-stateless-VvrWSAVA.js.map +0 -1
  205. package/dist/images-Ce9SCu3X.js.map +0 -1
  206. package/dist/input-schema-DNrpTu49.js.map +0 -1
  207. package/dist/lifecycle-CFu6OV03.js.map +0 -1
  208. package/dist/scheduler-DZ3xQfeK.js.map +0 -1
  209. package/dist/settings-C45hDliX.js.map +0 -1
  210. package/dist/src-DgCbZtIR.js.map +0 -1
  211. package/dist/store-vgcPYo8K.js.map +0 -1
  212. package/dist/tool-3PA8xjB_.js.map +0 -1
  213. package/dist/websearch/tools/ai-sdk.js.map +0 -1
  214. package/dist/websearch/tools/pi.js.map +0 -1
  215. package/dist/websearch/tools/tanstack-ai.js.map +0 -1
  216. package/dist/websockets-CmENGb-Z.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "../../classPrivateFieldGet2-DZBYAB34.js";
2
2
  import { t as _classPrivateMethodInitSpec } from "../../classPrivateMethodInitSpec-qMjJ6sHQ.js";
3
- import { t as LifecycleCapability } from "../../capability-B4WbF81e.js";
4
- import "../../lifecycle-CFu6OV03.js";
3
+ import { t as LifecycleCapability } from "../../capability-DBAKc6UZ.js";
4
+ import "../../lifecycle-DGorpAmA.js";
5
5
  //#region src/harness/table-prefix.ts
6
6
  /**
7
7
  * A view of `storage` whose SQL is rewritten into `prefix`'s namespace.
@@ -284,6 +284,268 @@ function closing(sql, start, close) {
284
284
  return sql.length;
285
285
  }
286
286
  //#endregion
287
+ //#region src/harness/opencode/operation-id.ts
288
+ const OPERATION_ID = /^[A-Za-z0-9._~-]+$/;
289
+ /** OpenCode's id for the user message an operation submits. */
290
+ function messageIdOf(operationId) {
291
+ if (!OPERATION_ID.test(operationId)) throw new TypeError(`Invalid operation id ${JSON.stringify(operationId)}: use letters, digits, ".", "_", "~" and "-"`);
292
+ return `msg_${operationId}`;
293
+ }
294
+ /** The operation id of a message or inbox item, the inverse of `messageIdOf`. */
295
+ function operationIdOf(messageId) {
296
+ return messageId.startsWith("msg_") ? messageId.slice(4) : messageId;
297
+ }
298
+ //#endregion
299
+ //#region src/harness/opencode/events.ts
300
+ /** The text parts of a tool's result, joined. */
301
+ function toolText(content) {
302
+ return (content ?? []).map((part) => "text" in part ? part.text : "").join("\n");
303
+ }
304
+ /** The session an OpenCode event belongs to, if it belongs to one. */
305
+ function sessionIdOf(event) {
306
+ const data = event.data;
307
+ return typeof data === "object" && data !== null && "sessionID" in data && typeof data.sessionID === "string" ? data.sessionID : void 0;
308
+ }
309
+ function answerOf(message) {
310
+ if (message.type !== "assistant") return void 0;
311
+ const text = /* @__PURE__ */ new Map();
312
+ for (const part of message.content) if (part.type === "text") text.set(text.size, part.text);
313
+ return {
314
+ id: message.id,
315
+ text,
316
+ error: message.error?.message
317
+ };
318
+ }
319
+ var _session = /* @__PURE__ */ new WeakMap();
320
+ var _toolNames = /* @__PURE__ */ new WeakMap();
321
+ var _answering = /* @__PURE__ */ new WeakMap();
322
+ var _ended = /* @__PURE__ */ new WeakMap();
323
+ var _answered = /* @__PURE__ */ new WeakMap();
324
+ var _answer = /* @__PURE__ */ new WeakMap();
325
+ var _SessionEventProjector_brand = /* @__PURE__ */ new WeakSet();
326
+ /**
327
+ * Translates one session's OpenCode events into `OpenCodeSessionEvent`s.
328
+ *
329
+ * OpenCode's events leave out some of what the translated ones carry, so
330
+ * the projector keeps it: tool names (`session.tool.called` has only the
331
+ * call id), and which inputs the current answer is for, so it can report
332
+ * `operation_end`. It starts from the stream's snapshot, so a stream opened
333
+ * mid-run knows the run's inputs and tools.
334
+ *
335
+ * `operation_end` follows the rule `wait()` uses on the transcript: an
336
+ * input's answer ends at the next input that joins after an assistant
337
+ * message, or at the end of the run.
338
+ *
339
+ * Events that arrive while the snapshot is read are projected after it, so
340
+ * some repeat what the snapshot shows. Projection is idempotent for those:
341
+ * an input the projector already knows is not started or ended again.
342
+ */
343
+ var SessionEventProjector = class {
344
+ constructor(snapshot) {
345
+ _classPrivateMethodInitSpec(this, _SessionEventProjector_brand);
346
+ _classPrivateFieldInitSpec(this, _session, void 0);
347
+ _classPrivateFieldInitSpec(this, _toolNames, /* @__PURE__ */ new Map());
348
+ _classPrivateFieldInitSpec(this, _answering, []);
349
+ _classPrivateFieldInitSpec(this, _ended, /* @__PURE__ */ new Set());
350
+ _classPrivateFieldInitSpec(this, _answered, false);
351
+ _classPrivateFieldInitSpec(this, _answer, void 0);
352
+ _classPrivateFieldSet2(_session, this, snapshot.session);
353
+ for (const message of snapshot.messages) {
354
+ if (message.type !== "assistant") continue;
355
+ for (const part of message.content) if (part.type === "tool") _classPrivateFieldGet2(_toolNames, this).set(part.id, part.name);
356
+ }
357
+ _classPrivateFieldSet2(_answering, this, snapshot.pending.filter((operation) => operation.status === "running").map((operation) => operation.operationId));
358
+ if (_classPrivateFieldGet2(_answering, this).length > 0) {
359
+ const last = snapshot.messages.at(-1);
360
+ _classPrivateFieldSet2(_answer, this, last === void 0 ? void 0 : answerOf(last));
361
+ _classPrivateFieldSet2(_answered, this, _classPrivateFieldGet2(_answer, this) !== void 0);
362
+ }
363
+ }
364
+ /** The translated events for one OpenCode event; often none. */
365
+ project(event) {
366
+ switch (event.type) {
367
+ case "session.inbox.enqueued": return event.data.item.type === "user" ? [{
368
+ type: "operation_queued",
369
+ operationId: operationIdOf(event.data.inboxID)
370
+ }] : [];
371
+ case "session.inbox.cancelled": return [{
372
+ type: "operation_withdrawn",
373
+ operationId: operationIdOf(event.data.inboxID)
374
+ }];
375
+ case "session.inbox.delivered": {
376
+ const operationId = operationIdOf(event.data.inboxID);
377
+ if (_classPrivateFieldGet2(_answering, this).includes(operationId) || _classPrivateFieldGet2(_ended, this).has(operationId)) return [];
378
+ const ended = _classPrivateFieldGet2(_answered, this) ? _assertClassBrand(_SessionEventProjector_brand, this, _settle).call(this, "succeeded") : [];
379
+ _classPrivateFieldGet2(_answering, this).push(operationId);
380
+ return [...ended, {
381
+ type: "operation_start",
382
+ operationId
383
+ }];
384
+ }
385
+ case "session.execution.started":
386
+ if (_classPrivateFieldGet2(_answering, this).length === 0) {
387
+ _classPrivateFieldSet2(_answer, this, void 0);
388
+ _classPrivateFieldSet2(_answered, this, false);
389
+ }
390
+ return [{ type: "run_start" }];
391
+ case "session.execution.succeeded": return [..._assertClassBrand(_SessionEventProjector_brand, this, _settle).call(this, "succeeded"), runEnd("succeeded")];
392
+ case "session.execution.failed": return [..._assertClassBrand(_SessionEventProjector_brand, this, _settle).call(this, "failed", event.data.error.message), runEnd("failed", event.data.error.message)];
393
+ case "session.execution.interrupted": return [..._assertClassBrand(_SessionEventProjector_brand, this, _settle).call(this, "interrupted"), runEnd("interrupted")];
394
+ case "session.step.started":
395
+ _classPrivateFieldSet2(_answered, this, true);
396
+ _classPrivateFieldSet2(_answer, this, {
397
+ id: event.data.assistantMessageID,
398
+ text: /* @__PURE__ */ new Map(),
399
+ error: void 0
400
+ });
401
+ return [{
402
+ type: "message_start",
403
+ messageId: event.data.assistantMessageID,
404
+ agent: event.data.agent,
405
+ model: {
406
+ providerID: event.data.model.providerID,
407
+ id: event.data.model.id
408
+ }
409
+ }];
410
+ case "session.step.ended": return [{
411
+ type: "message_end",
412
+ messageId: event.data.assistantMessageID,
413
+ finish: event.data.finish
414
+ }];
415
+ case "session.step.failed":
416
+ if (_classPrivateFieldGet2(_answer, this)?.id === event.data.assistantMessageID) _classPrivateFieldGet2(_answer, this).error = event.data.error.message;
417
+ return [{
418
+ type: "message_end",
419
+ messageId: event.data.assistantMessageID,
420
+ finish: "error",
421
+ error: event.data.error.message
422
+ }];
423
+ case "session.text.delta":
424
+ case "session.reasoning.delta": return [{
425
+ type: event.type === "session.text.delta" ? "text_delta" : "reasoning_delta",
426
+ messageId: event.data.assistantMessageID,
427
+ ordinal: event.data.ordinal,
428
+ delta: event.data.delta
429
+ }];
430
+ case "session.text.ended":
431
+ if (_classPrivateFieldGet2(_answer, this)?.id === event.data.assistantMessageID) _classPrivateFieldGet2(_answer, this).text.set(event.data.ordinal, event.data.text);
432
+ return [{
433
+ type: "text_end",
434
+ messageId: event.data.assistantMessageID,
435
+ ordinal: event.data.ordinal,
436
+ text: event.data.text
437
+ }];
438
+ case "session.reasoning.ended": return [{
439
+ type: "reasoning_end",
440
+ messageId: event.data.assistantMessageID,
441
+ ordinal: event.data.ordinal,
442
+ text: event.data.text
443
+ }];
444
+ case "session.tool.input.started":
445
+ _classPrivateFieldGet2(_toolNames, this).set(event.data.id, event.data.name);
446
+ return [];
447
+ case "session.tool.called": return [{
448
+ type: "tool_start",
449
+ messageId: event.data.assistantMessageID,
450
+ toolCallId: event.data.id,
451
+ name: _classPrivateFieldGet2(_toolNames, this).get(event.data.id) ?? "",
452
+ input: event.data.input
453
+ }];
454
+ case "session.tool.success": return [{
455
+ type: "tool_end",
456
+ messageId: event.data.assistantMessageID,
457
+ toolCallId: event.data.id,
458
+ name: _classPrivateFieldGet2(_toolNames, this).get(event.data.id) ?? "",
459
+ error: false,
460
+ output: toolText(event.data.content)
461
+ }];
462
+ case "session.tool.failed": return [{
463
+ type: "tool_end",
464
+ messageId: event.data.assistantMessageID,
465
+ toolCallId: event.data.id,
466
+ name: _classPrivateFieldGet2(_toolNames, this).get(event.data.id) ?? "",
467
+ error: true,
468
+ output: event.data.error.message
469
+ }];
470
+ case "session.retry.scheduled": return [{
471
+ type: "retry_scheduled",
472
+ messageId: event.data.assistantMessageID,
473
+ attempt: event.data.attempt,
474
+ at: event.data.at,
475
+ error: event.data.error.message
476
+ }];
477
+ case "session.compaction.started": return [{
478
+ type: "compaction_start",
479
+ reason: event.data.reason
480
+ }];
481
+ case "session.compaction.ended": return [{
482
+ type: "transcript_reset",
483
+ reason: "compaction"
484
+ }];
485
+ case "session.compaction.failed": return [{
486
+ type: "fault",
487
+ code: "compaction_failed",
488
+ message: event.data.error.message
489
+ }];
490
+ case "permission.asked": return [{
491
+ type: "permission_asked",
492
+ permission: {
493
+ id: event.data.id,
494
+ session: event.data.sessionID,
495
+ action: event.data.action,
496
+ resources: event.data.resources,
497
+ ...event.data.message === void 0 ? {} : { message: event.data.message }
498
+ }
499
+ }];
500
+ case "permission.replied": return [{
501
+ type: "permission_replied",
502
+ permissionId: event.data.requestID,
503
+ reply: event.data.reply
504
+ }];
505
+ default: return [];
506
+ }
507
+ }
508
+ };
509
+ /** End every input the latest answer was for. */
510
+ function _settle(outcome, runError) {
511
+ const answer = _classPrivateFieldGet2(_answer, this);
512
+ const text = [...(answer?.text ?? /* @__PURE__ */ new Map()).entries()].sort(([a], [b]) => a - b).map(([, part]) => part).join("");
513
+ const error = answer?.error ?? runError;
514
+ const ended = _classPrivateFieldGet2(_answering, this).map((operationId) => {
515
+ _classPrivateFieldGet2(_ended, this).add(operationId);
516
+ return {
517
+ type: "operation_end",
518
+ result: resultOf(_classPrivateFieldGet2(_session, this), operationId, outcome, text, error)
519
+ };
520
+ });
521
+ _classPrivateFieldSet2(_answering, this, []);
522
+ _classPrivateFieldSet2(_answered, this, false);
523
+ _classPrivateFieldSet2(_answer, this, void 0);
524
+ return ended;
525
+ }
526
+ function runEnd(outcome, error) {
527
+ return {
528
+ type: "run_end",
529
+ outcome,
530
+ ...error === void 0 ? {} : { error }
531
+ };
532
+ }
533
+ /** The result `wait()` would return for the same ending. */
534
+ function resultOf(session, operationId, outcome, text, error) {
535
+ if (outcome === "succeeded" && error === void 0) return {
536
+ operationId,
537
+ session,
538
+ status: "done",
539
+ text
540
+ };
541
+ return {
542
+ operationId,
543
+ session,
544
+ status: "unanswered",
545
+ reason: outcome === "interrupted" ? "interrupted" : error ?? "failed"
546
+ };
547
+ }
548
+ //#endregion
287
549
  //#region src/harness/opencode/harness.ts
288
550
  /** The root session's id. OpenCode session ids start with `ses`. */
289
551
  const ROOT_SESSION = "ses_root";
@@ -319,16 +581,6 @@ function wakeJobId(session) {
319
581
  function sessionOfJob(payload) {
320
582
  return typeof payload === "object" && payload !== null && "session" in payload && typeof payload.session === "string" ? payload.session : void 0;
321
583
  }
322
- const OPERATION_ID = /^[A-Za-z0-9._~-]+$/;
323
- /** OpenCode's id for the user message an operation submits. */
324
- function messageIdOf(operationId) {
325
- if (!OPERATION_ID.test(operationId)) throw new TypeError(`Invalid operation id ${JSON.stringify(operationId)}: use letters, digits, ".", "_", "~" and "-"`);
326
- return `msg_${operationId}`;
327
- }
328
- /** The operation id of a message or inbox item, the inverse of `messageIdOf`. */
329
- function operationIdOf(messageId) {
330
- return messageId.startsWith("msg_") ? messageId.slice(4) : messageId;
331
- }
332
584
  /** Whether an OpenCode client error is the tagged error `tag`. */
333
585
  function isTagged(error, tag) {
334
586
  return typeof error === "object" && error !== null && "_tag" in error && error._tag === tag;
@@ -343,11 +595,6 @@ function textOf(message) {
343
595
  if (message?.type !== "assistant") return "";
344
596
  return message.content.map((part) => part.type === "text" ? part.text : "").join("");
345
597
  }
346
- function sessionIdOf(event) {
347
- if (!("data" in event)) return void 0;
348
- const data = event.data;
349
- return typeof data === "object" && data !== null && "sessionID" in data && typeof data.sessionID === "string" ? data.sessionID : void 0;
350
- }
351
598
  var _options = /* @__PURE__ */ new WeakMap();
352
599
  var _waits = /* @__PURE__ */ new WeakMap();
353
600
  var _admitting = /* @__PURE__ */ new WeakMap();
@@ -910,6 +1157,7 @@ function delay(ms, signal) {
910
1157
  });
911
1158
  }
912
1159
  var _harness = /* @__PURE__ */ new WeakMap();
1160
+ var _OpenCodeSession_brand = /* @__PURE__ */ new WeakSet();
913
1161
  /** One OpenCode session, addressed through the harness. */
914
1162
  var OpenCodeSession = class {
915
1163
  /**
@@ -917,6 +1165,7 @@ var OpenCodeSession = class {
917
1165
  * @param id - The session's id.
918
1166
  */
919
1167
  constructor(harness, id) {
1168
+ _classPrivateMethodInitSpec(this, _OpenCodeSession_brand);
920
1169
  _classPrivateFieldInitSpec(this, _harness, void 0);
921
1170
  _classPrivateFieldSet2(_harness, this, harness);
922
1171
  this.id = id;
@@ -1001,18 +1250,79 @@ var OpenCodeSession = class {
1001
1250
  });
1002
1251
  }
1003
1252
  /**
1004
- * OpenCode's events for this session as they happen, durable and live
1005
- * (text deltas, tool input), until `signal` aborts. Read the transcript
1006
- * with `messages()` first for a snapshot; use `log()` to resume from a
1007
- * durable position instead.
1253
+ * The session's state now, then everything that happens to it after, as
1254
+ * `OpenCodeSessionEvent`s: the same kinds of event `PiHarness` reports,
1255
+ * live text deltas included. The stream holds OpenCode open until
1256
+ * `stop()`. For OpenCode's own events, durable and resumable by sequence
1257
+ * number, use `log()`.
1008
1258
  */
1009
- async *events(signal) {
1259
+ async events() {
1010
1260
  const release = _classPrivateFieldGet2(_harness, this).lease();
1261
+ const controller = new AbortController();
1262
+ const early = [];
1263
+ const pending = [];
1264
+ let projector;
1265
+ let listener;
1266
+ let stopped = false;
1267
+ const deliver = (events) => {
1268
+ if (events.length === 0 || stopped) return;
1269
+ if (listener === void 0) pending.push(...events);
1270
+ else listener(events);
1271
+ };
1272
+ let attached;
1273
+ const subscribed = new Promise((resolve) => {
1274
+ attached = resolve;
1275
+ });
1276
+ let pump = Promise.resolve();
1011
1277
  try {
1012
1278
  const opencode = await _classPrivateFieldGet2(_harness, this).opencode();
1013
- for await (const event of opencode.events.subscribe(signal ? { signal } : {})) if (sessionIdOf(event) === this.id) yield event;
1014
- } finally {
1279
+ pump = (async () => {
1280
+ try {
1281
+ for await (const event of opencode.events.subscribe({ signal: controller.signal })) {
1282
+ if (event.type === "server.connected") attached();
1283
+ if (sessionIdOf(event) !== this.id) continue;
1284
+ if (projector === void 0) early.push(event);
1285
+ else deliver(projector.project(event));
1286
+ }
1287
+ } catch (error) {
1288
+ if (!controller.signal.aborted) deliver([{
1289
+ type: "fault",
1290
+ code: "events_failed",
1291
+ message: describe(error)
1292
+ }]);
1293
+ } finally {
1294
+ attached();
1295
+ }
1296
+ })();
1297
+ await subscribed;
1298
+ const snapshot = await _assertClassBrand(_OpenCodeSession_brand, this, _snapshot).call(this, opencode);
1299
+ projector = new SessionEventProjector(snapshot);
1300
+ for (const event of early.splice(0)) deliver(projector.project(event));
1301
+ let stopping;
1302
+ return {
1303
+ snapshot,
1304
+ start: (next) => {
1305
+ if (listener !== void 0) throw new Error("OpenCodeEventStream.start() was already called");
1306
+ if (stopping !== void 0) return;
1307
+ listener = next;
1308
+ deliver(pending.splice(0));
1309
+ },
1310
+ stop: () => {
1311
+ stopping ??= (async () => {
1312
+ stopped = true;
1313
+ pending.length = 0;
1314
+ controller.abort();
1315
+ await pump;
1316
+ await release();
1317
+ })();
1318
+ return stopping;
1319
+ }
1320
+ };
1321
+ } catch (error) {
1322
+ controller.abort();
1323
+ await pump;
1015
1324
  await release();
1325
+ throw error;
1016
1326
  }
1017
1327
  }
1018
1328
  /**
@@ -1040,6 +1350,27 @@ var OpenCodeSession = class {
1040
1350
  return _classPrivateFieldGet2(_harness, this).use(async (opencode) => sessionBusy(opencode, this.id, await opencode.sessions.active()));
1041
1351
  }
1042
1352
  };
1353
+ async function _snapshot(opencode) {
1354
+ const [messages, busy, pending, permissions] = await Promise.all([
1355
+ this.history(),
1356
+ this.busy(),
1357
+ _classPrivateFieldGet2(_harness, this).pending({ session: this.id }),
1358
+ opencode.permission.list({ sessionID: this.id })
1359
+ ]);
1360
+ return {
1361
+ session: this.id,
1362
+ messages,
1363
+ busy,
1364
+ pending,
1365
+ permissions: permissions.map((request) => ({
1366
+ id: request.id,
1367
+ session: request.sessionID,
1368
+ action: request.action,
1369
+ resources: request.resources,
1370
+ ...request.message === void 0 ? {} : { message: request.message }
1371
+ }))
1372
+ };
1373
+ }
1043
1374
  var _harness2 = /* @__PURE__ */ new WeakMap();
1044
1375
  /** Every OpenCode session in this object. */
1045
1376
  var OpenCodeSessions = class {