agents 0.21.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/README.md +21 -1
  2. package/dist/{agent-tool-types-CzGGB-20.d.ts → agent-routing-DE5zmCQ8.d.ts} +1844 -1336
  3. package/dist/agent-routing.d.ts +14 -0
  4. package/dist/agent-routing.js +187 -0
  5. package/dist/agent-routing.js.map +1 -0
  6. package/dist/agent-tool-types.d.ts +26 -26
  7. package/dist/{agent-tools-zR2d5uij.d.ts → agent-tools-DtXMTDGM.d.ts} +7 -7
  8. package/dist/agent-tools.d.ts +21 -21
  9. package/dist/agent-tools.js +2 -1
  10. package/dist/agent-tools.js.map +1 -1
  11. package/dist/browser/ai.js +6 -2
  12. package/dist/browser/ai.js.map +1 -1
  13. package/dist/browser/tanstack-ai.js.map +1 -1
  14. package/dist/callable-decorator-DP__HhBA.d.ts +72 -0
  15. package/dist/callable-decorator.d.ts +18 -0
  16. package/dist/callable-decorator.js +71 -0
  17. package/dist/callable-decorator.js.map +1 -0
  18. package/dist/capability-BjSKYpzg.js +42 -0
  19. package/dist/capability-BjSKYpzg.js.map +1 -0
  20. package/dist/capability-runner-Be_-PLR1.d.ts +459 -0
  21. package/dist/channel-Bnm4S7T2.d.ts +491 -0
  22. package/dist/channels/ai-sdk.d.ts +46 -0
  23. package/dist/channels/ai-sdk.js +120 -0
  24. package/dist/channels/ai-sdk.js.map +1 -0
  25. package/dist/channels/email.d.ts +95 -0
  26. package/dist/channels/email.js +323 -0
  27. package/dist/channels/email.js.map +1 -0
  28. package/dist/channels/index.d.ts +233 -0
  29. package/dist/channels/index.js +608 -0
  30. package/dist/channels/index.js.map +1 -0
  31. package/dist/channels/slack.d.ts +140 -0
  32. package/dist/channels/slack.js +614 -0
  33. package/dist/channels/slack.js.map +1 -0
  34. package/dist/channels/tanstack-ai.d.ts +39 -0
  35. package/dist/channels/tanstack-ai.js +17 -0
  36. package/dist/channels/tanstack-ai.js.map +1 -0
  37. package/dist/channels/telegram.d.ts +106 -0
  38. package/dist/channels/telegram.js +427 -0
  39. package/dist/channels/telegram.js.map +1 -0
  40. package/dist/channels/voice.d.ts +45 -0
  41. package/dist/channels/voice.js +122 -0
  42. package/dist/channels/voice.js.map +1 -0
  43. package/dist/chat/index.d.ts +2328 -2015
  44. package/dist/chat/index.js +891 -521
  45. package/dist/chat/index.js.map +1 -1
  46. package/dist/chat/react.d.ts +14 -1
  47. package/dist/chat/react.js +82 -52
  48. package/dist/chat/react.js.map +1 -1
  49. package/dist/chat/transport.js +1 -1
  50. package/dist/chat-sdk/index.d.ts +7 -7
  51. package/dist/chat-sdk/index.js +1 -1
  52. package/dist/{client-zqKcsyFa.js → client-jagG8a9_.js} +129 -37
  53. package/dist/client-jagG8a9_.js.map +1 -0
  54. package/dist/client.d.ts +1 -1
  55. package/dist/client.js +1 -1
  56. package/dist/{cloudflare-BduZwmYK.js → cloudflare-Dzvc7V2N.js} +10 -3
  57. package/dist/{cloudflare-BduZwmYK.js.map → cloudflare-Dzvc7V2N.js.map} +1 -1
  58. package/dist/context/index.d.ts +216 -0
  59. package/dist/context/index.js +454 -0
  60. package/dist/context/index.js.map +1 -0
  61. package/dist/current-agent-Da_C9a3b.d.ts +266 -0
  62. package/dist/current-agent-DhoDkSnH.js +51 -0
  63. package/dist/current-agent-DhoDkSnH.js.map +1 -0
  64. package/dist/diagnostics-BzvaX2UT.js +45 -0
  65. package/dist/diagnostics-BzvaX2UT.js.map +1 -0
  66. package/dist/diagnostics-C4jcz3VK.js +360 -0
  67. package/dist/diagnostics-C4jcz3VK.js.map +1 -0
  68. package/dist/{do-oauth-client-provider-VTZj2VtM.d.ts → do-oauth-client-provider-Tmf1vgKz.d.ts} +2 -2
  69. package/dist/{email-CL27preh.d.ts → email-7TatiTnl.d.ts} +38 -9
  70. package/dist/email-send.d.ts +15 -0
  71. package/dist/email-send.js +32 -0
  72. package/dist/email-send.js.map +1 -0
  73. package/dist/email.d.ts +14 -10
  74. package/dist/email.js.map +1 -1
  75. package/dist/{handler-stateless-C_bo-Ytq.d.ts → handler-stateless-DxYpJ_XF.d.ts} +3 -3
  76. package/dist/{handler-stateless-CIkKPETH.js → handler-stateless-VvrWSAVA.js} +5 -5
  77. package/dist/handler-stateless-VvrWSAVA.js.map +1 -0
  78. package/dist/index-BB0kqhIz.d.ts +101 -0
  79. package/dist/index-XDkuQ7zm.d.ts +89 -0
  80. package/dist/{index-BRnybD6X.d.ts → index-YSKgfgg9.d.ts} +21 -31
  81. package/dist/index.d.ts +113 -101
  82. package/dist/index.js +11 -7234
  83. package/dist/ingress-BfetZbMO.js +83 -0
  84. package/dist/ingress-BfetZbMO.js.map +1 -0
  85. package/dist/internal-CYlgHl1l.js +59 -0
  86. package/dist/internal-CYlgHl1l.js.map +1 -0
  87. package/dist/internal_context-BlxFEWfn.d.ts +19 -0
  88. package/dist/internal_context.d.ts +10 -4
  89. package/dist/internal_context.js +1 -10
  90. package/dist/{client-invoker-BNSZxAkv.d.ts → invoker-CG0_p_Wq.d.ts} +2 -2
  91. package/dist/{client-invoker-VNZ7X0nn.js → invoker-CHMnoxIA.js} +2 -2
  92. package/dist/invoker-CHMnoxIA.js.map +1 -0
  93. package/dist/lifecycle/index.d.ts +66 -0
  94. package/dist/lifecycle/index.js +4 -0
  95. package/dist/lifecycle-CMRGjZdw.js +1299 -0
  96. package/dist/lifecycle-CMRGjZdw.js.map +1 -0
  97. package/dist/mcp/{do-oauth-client-provider.d.ts → client/do-oauth-client-provider.d.ts} +1 -1
  98. package/dist/mcp/{do-oauth-client-provider.js → client/do-oauth-client-provider.js} +1 -1
  99. package/dist/mcp/client/do-oauth-client-provider.js.map +1 -0
  100. package/dist/mcp/client/index.d.ts +42 -0
  101. package/dist/mcp/{client.js → client/index.js} +1 -1
  102. package/dist/mcp/{x402.d.ts → client/x402.d.ts} +2 -2
  103. package/dist/mcp/{x402.js → client/x402.js} +2 -2
  104. package/dist/mcp/client/x402.js.map +1 -0
  105. package/dist/mcp/index.d.ts +36 -36
  106. package/dist/mcp/index.js +14 -16
  107. package/dist/mcp/index.js.map +1 -1
  108. package/dist/mcp/{server.d.ts → server/index.d.ts} +1 -1
  109. package/dist/mcp/{server.js → server/index.js} +1 -1
  110. package/dist/observability/ai/index.js +50 -35
  111. package/dist/observability/ai/index.js.map +1 -1
  112. package/dist/observability/index.d.ts +4 -4
  113. package/dist/observability/index.js +3 -50
  114. package/dist/observability/index.js.map +1 -1
  115. package/dist/{protocol-Dqc2MQxo.js → protocol-B0nh6KNf.js} +19 -21
  116. package/dist/protocol-B0nh6KNf.js.map +1 -0
  117. package/dist/react.d.ts +4 -4
  118. package/dist/react.js +1 -1
  119. package/dist/{retries-CAvxtG9d.d.ts → retries-D9Ds-1lz.d.ts} +17 -6
  120. package/dist/retries.d.ts +8 -6
  121. package/dist/retries.js +13 -1
  122. package/dist/retries.js.map +1 -1
  123. package/dist/routing/index.d.ts +137 -0
  124. package/dist/routing/index.js +244 -0
  125. package/dist/routing/index.js.map +1 -0
  126. package/dist/sanitize-D9TujEK8.js +79 -0
  127. package/dist/sanitize-D9TujEK8.js.map +1 -0
  128. package/dist/schedule.d.ts +25 -94
  129. package/dist/schedule.js +1 -98
  130. package/dist/schedule.js.map +1 -1
  131. package/dist/scheduler-DD9NdYbF.js +665 -0
  132. package/dist/scheduler-DD9NdYbF.js.map +1 -0
  133. package/dist/scheduler-Dwh85ZGl.d.ts +223 -0
  134. package/dist/schedules/index.d.ts +22 -0
  135. package/dist/schedules/index.js +2 -0
  136. package/dist/schedules/parser.d.ts +79 -0
  137. package/dist/schedules/parser.js +103 -0
  138. package/dist/schedules/parser.js.map +1 -0
  139. package/dist/sentence-chunker-BAidJ4DA.d.ts +68 -0
  140. package/dist/serializable.d.ts +1 -1
  141. package/dist/sessions/index.d.ts +441 -0
  142. package/dist/sessions/index.js +2063 -0
  143. package/dist/sessions/index.js.map +1 -0
  144. package/dist/skills/index.d.ts +99 -0
  145. package/dist/skills/index.js +254 -5
  146. package/dist/skills/index.js.map +1 -1
  147. package/dist/sql-error-CPY-GXyI.d.ts +12 -0
  148. package/dist/sql-error.d.ts +2 -0
  149. package/dist/sql-error.js +16 -0
  150. package/dist/sql-error.js.map +1 -0
  151. package/dist/src-DlSHshb2.js +6963 -0
  152. package/dist/src-DlSHshb2.js.map +1 -0
  153. package/dist/streams/index.d.ts +120 -0
  154. package/dist/streams/index.js +107 -0
  155. package/dist/streams/index.js.map +1 -0
  156. package/dist/streams-D6tJ0NN9.d.ts +370 -0
  157. package/dist/streams-DZKgAj9b.js +709 -0
  158. package/dist/streams-DZKgAj9b.js.map +1 -0
  159. package/dist/sub-routing.d.ts +12 -12
  160. package/dist/surface-bZZJqBka.js +17 -0
  161. package/dist/surface-bZZJqBka.js.map +1 -0
  162. package/dist/tasks/index.d.ts +64 -0
  163. package/dist/tasks/index.js +2 -0
  164. package/dist/tasks-BRJ5zgya.d.ts +517 -0
  165. package/dist/tasks-ylZgBjhj.js +1656 -0
  166. package/dist/tasks-ylZgBjhj.js.map +1 -0
  167. package/dist/text-segment-joiner-BtAFQSA_.js +57 -0
  168. package/dist/text-segment-joiner-BtAFQSA_.js.map +1 -0
  169. package/dist/text-stream-CpdiKrJB.js +272 -0
  170. package/dist/text-stream-CpdiKrJB.js.map +1 -0
  171. package/dist/tokens-nHAKcN6M.js +52 -0
  172. package/dist/tokens-nHAKcN6M.js.map +1 -0
  173. package/dist/tool-schema-CBjGPrsQ.js +31 -0
  174. package/dist/tool-schema-CBjGPrsQ.js.map +1 -0
  175. package/dist/types-B7LojTe4.d.ts +202 -0
  176. package/dist/types-_Faxb570.d.ts +439 -0
  177. package/dist/voice/client.d.ts +226 -0
  178. package/dist/voice/client.js +932 -0
  179. package/dist/voice/client.js.map +1 -0
  180. package/dist/voice/errors.d.ts +43 -0
  181. package/dist/voice/errors.js +41 -0
  182. package/dist/voice/errors.js.map +1 -0
  183. package/dist/voice/index.d.ts +271 -0
  184. package/dist/voice/index.js +1812 -0
  185. package/dist/voice/index.js.map +1 -0
  186. package/dist/voice/react.d.ts +167 -0
  187. package/dist/voice/react.js +234 -0
  188. package/dist/voice/react.js.map +1 -0
  189. package/dist/voice/sfu.d.ts +71 -0
  190. package/dist/voice/sfu.js +157 -0
  191. package/dist/voice/sfu.js.map +1 -0
  192. package/dist/voice/text.d.ts +6 -0
  193. package/dist/voice/text.js +2 -0
  194. package/dist/voice/types.d.ts +58 -0
  195. package/dist/voice/types.js +18 -0
  196. package/dist/voice/types.js.map +1 -0
  197. package/dist/voice/workers-ai.d.ts +136 -0
  198. package/dist/voice/workers-ai.js +568 -0
  199. package/dist/voice/workers-ai.js.map +1 -0
  200. package/dist/websockets/index.d.ts +192 -0
  201. package/dist/websockets/index.js +2 -0
  202. package/dist/websockets-DUfRHPRq.js +502 -0
  203. package/dist/websockets-DUfRHPRq.js.map +1 -0
  204. package/dist/workflow-types.d.ts +25 -25
  205. package/dist/workflows.d.ts +22 -22
  206. package/dist/workflows.js +2 -1
  207. package/dist/workflows.js.map +1 -1
  208. package/dist/{ws-chat-transport-CIoOBbO7.js → ws-chat-transport-rWwta645.js} +152 -15
  209. package/dist/ws-chat-transport-rWwta645.js.map +1 -0
  210. package/docs/agent-class.md +29 -87
  211. package/docs/agent-tools.md +2 -1
  212. package/docs/channels.md +323 -0
  213. package/docs/chat-agents.md +19 -25
  214. package/docs/context.md +131 -0
  215. package/docs/durable-execution.md +1 -1
  216. package/docs/http-websockets.md +1 -11
  217. package/docs/human-in-the-loop.md +1 -1
  218. package/docs/index.md +16 -12
  219. package/docs/lifecycle.md +370 -0
  220. package/docs/long-running-agents.md +4 -6
  221. package/docs/mcp-client.md +55 -0
  222. package/docs/mcp-servers.md +5 -1
  223. package/docs/observability.md +11 -11
  224. package/docs/resumable-streaming.md +2 -2
  225. package/docs/routing.md +105 -0
  226. package/docs/scheduling.md +175 -15
  227. package/docs/server-driven-messages.md +1 -1
  228. package/docs/sessions.md +237 -871
  229. package/docs/streams.md +213 -0
  230. package/docs/sub-agents.md +185 -125
  231. package/docs/tasks.md +246 -0
  232. package/docs/voice.md +745 -0
  233. package/package.json +144 -33
  234. package/dist/cli/index.js +0 -26
  235. package/dist/cli/index.js.map +0 -1
  236. package/dist/client-invoker-VNZ7X0nn.js.map +0 -1
  237. package/dist/client-zqKcsyFa.js.map +0 -1
  238. package/dist/compaction-helpers-iiKMr2TQ.js +0 -340
  239. package/dist/compaction-helpers-iiKMr2TQ.js.map +0 -1
  240. package/dist/compaction-helpers-wUz6M3us.d.ts +0 -621
  241. package/dist/experimental/memory/session/index.d.ts +0 -670
  242. package/dist/experimental/memory/session/index.js +0 -2374
  243. package/dist/experimental/memory/session/index.js.map +0 -1
  244. package/dist/experimental/memory/utils/index.d.ts +0 -96
  245. package/dist/experimental/memory/utils/index.js +0 -79
  246. package/dist/experimental/memory/utils/index.js.map +0 -1
  247. package/dist/handler-stateless-CIkKPETH.js.map +0 -1
  248. package/dist/index.js.map +0 -1
  249. package/dist/internal_context-Dg4Cgjcu.d.ts +0 -37
  250. package/dist/internal_context.js.map +0 -1
  251. package/dist/mcp/client.d.ts +0 -42
  252. package/dist/mcp/do-oauth-client-provider.js.map +0 -1
  253. package/dist/mcp/x402.js.map +0 -1
  254. package/dist/protocol-Dqc2MQxo.js.map +0 -1
  255. package/dist/tool-output-truncation-CNnnGZQ3.js +0 -98
  256. package/dist/tool-output-truncation-CNnnGZQ3.js.map +0 -1
  257. package/dist/ws-chat-transport-CIoOBbO7.js.map +0 -1
  258. /package/dist/{cli/index.d.ts → index-BVVgDSdq.d.ts} +0 -0
@@ -0,0 +1,120 @@
1
+ import {
2
+ a as StreamJson,
3
+ c as StreamReadBatchesOptions,
4
+ d as StreamState,
5
+ f as StreamStatus,
6
+ i as StreamChunk,
7
+ l as StreamReadOptions,
8
+ n as Streams,
9
+ o as StreamListOptions,
10
+ p as StreamWriter,
11
+ r as StreamsOptions,
12
+ s as StreamOpenOptions,
13
+ t as DEFAULT_MAX_CHUNK_BYTES,
14
+ u as StreamSettleOptions
15
+ } from "../streams-D6tJ0NN9.js";
16
+
17
+ //#region src/streams/errors.d.ts
18
+ /**
19
+ * Error classes for the Streams capability. Each carries a stable `name` so
20
+ * hosts and tests can classify failures without depending on message text.
21
+ */
22
+ /**
23
+ * Thrown when `open()` targets a terminal stream, or an append reaches a
24
+ * stream that settled (or was deleted) after the writer was created.
25
+ *
26
+ * @experimental The API surface may change before stabilizing.
27
+ */
28
+ declare class StreamClosedError extends Error {
29
+ /** The stream that no longer accepts writes. */
30
+ readonly streamId: string;
31
+ constructor(streamId: string, detail: string);
32
+ }
33
+ /**
34
+ * Thrown when `read()` targets a stream that was never opened (or was
35
+ * deleted). `status()` returns `null` instead, for existence probes.
36
+ *
37
+ * @experimental The API surface may change before stabilizing.
38
+ */
39
+ declare class StreamNotFoundError extends Error {
40
+ readonly streamId: string;
41
+ constructor(streamId: string);
42
+ }
43
+ /**
44
+ * Thrown when a chunk or metadata value is not JSON-serializable or exceeds
45
+ * the configured size limit.
46
+ *
47
+ * @experimental The API surface may change before stabilizing.
48
+ */
49
+ declare class StreamSerializationError extends Error {
50
+ constructor(context: string, detail: string);
51
+ }
52
+ //#endregion
53
+ //#region src/streams/sse.d.ts
54
+ /**
55
+ * Options accepted by {@link sseResponse}.
56
+ *
57
+ * @experimental The API surface may change before stabilizing.
58
+ */
59
+ interface SSEResponseOptions {
60
+ /**
61
+ * The incoming request. Used for resume (the `Last-Event-ID` header a
62
+ * reconnecting `EventSource` sends, or a `?from=` query parameter) and to
63
+ * abort the tail when the client disconnects (`request.signal`).
64
+ */
65
+ request?: Request;
66
+ /** First sequence number to yield. Overrides request-derived resume. */
67
+ from?: number;
68
+ /** Extra abort signal; composed with `request.signal`. */
69
+ signal?: AbortSignal;
70
+ /** Maximum chunks per write. Defaults to the read batch size (100). */
71
+ batchSize?: number;
72
+ /**
73
+ * Milliseconds between `: heartbeat` comment frames while tailing, keeping
74
+ * idle proxies from killing the connection. 0 disables. Default: 30000.
75
+ */
76
+ heartbeatMs?: number;
77
+ }
78
+ /**
79
+ * Serve one durable stream as a Server-Sent Events response: replay from the
80
+ * resume point, emit an `up-to-date` control event on reaching the tail,
81
+ * tail live appends, and finish with `done` (completed) or `error` (errored,
82
+ * carrying the recorded reason). Returns a 404 response when the stream does
83
+ * not exist.
84
+ *
85
+ * ```ts
86
+ * async onRequest(request: Request) {
87
+ * return sseResponse(this.streams, "reply:123", { request });
88
+ * }
89
+ * // client: new EventSource(url) — reconnect resume is automatic.
90
+ * ```
91
+ *
92
+ * @experimental The API surface may change before stabilizing.
93
+ */
94
+ declare function sseResponse(
95
+ streams: Streams,
96
+ streamId: string,
97
+ options?: SSEResponseOptions
98
+ ): Promise<Response>;
99
+ //#endregion
100
+ export {
101
+ DEFAULT_MAX_CHUNK_BYTES,
102
+ type SSEResponseOptions,
103
+ type StreamChunk,
104
+ StreamClosedError,
105
+ type StreamJson,
106
+ type StreamListOptions,
107
+ StreamNotFoundError,
108
+ type StreamOpenOptions,
109
+ type StreamReadBatchesOptions,
110
+ type StreamReadOptions,
111
+ StreamSerializationError,
112
+ type StreamSettleOptions,
113
+ type StreamState,
114
+ type StreamStatus,
115
+ type StreamWriter,
116
+ Streams,
117
+ type StreamsOptions,
118
+ sseResponse
119
+ };
120
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,107 @@
1
+ import { a as StreamSerializationError, i as StreamNotFoundError, n as Streams, r as StreamClosedError, t as DEFAULT_MAX_CHUNK_BYTES } from "../streams-DZKgAj9b.js";
2
+ //#region src/streams/sse.ts
3
+ const encoder = new TextEncoder();
4
+ function resumeFrom(options) {
5
+ if (options.from !== void 0) return Math.max(0, options.from);
6
+ const request = options.request;
7
+ if (request) {
8
+ const header = request.headers.get("Last-Event-ID");
9
+ if (header !== null && header !== "") {
10
+ const lastEventId = Number(header);
11
+ if (Number.isInteger(lastEventId) && lastEventId >= 0) return lastEventId + 1;
12
+ }
13
+ const fromParam = new URL(request.url).searchParams.get("from");
14
+ if (fromParam !== null) {
15
+ const from = Number(fromParam);
16
+ if (Number.isInteger(from) && from >= 0) return from;
17
+ }
18
+ }
19
+ return 0;
20
+ }
21
+ function frame(seq, chunk) {
22
+ return `id: ${seq}\ndata: ${JSON.stringify(chunk)}\n\n`;
23
+ }
24
+ function controlFrame(event, data) {
25
+ return `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
26
+ }
27
+ /**
28
+ * Serve one durable stream as a Server-Sent Events response: replay from the
29
+ * resume point, emit an `up-to-date` control event on reaching the tail,
30
+ * tail live appends, and finish with `done` (completed) or `error` (errored,
31
+ * carrying the recorded reason). Returns a 404 response when the stream does
32
+ * not exist.
33
+ *
34
+ * ```ts
35
+ * async onRequest(request: Request) {
36
+ * return sseResponse(this.streams, "reply:123", { request });
37
+ * }
38
+ * // client: new EventSource(url) — reconnect resume is automatic.
39
+ * ```
40
+ *
41
+ * @experimental The API surface may change before stabilizing.
42
+ */
43
+ async function sseResponse(streams, streamId, options = {}) {
44
+ if (await streams.status(streamId) === null) return new Response(`Stream "${streamId}" does not exist`, { status: 404 });
45
+ const from = resumeFrom(options);
46
+ const heartbeatMs = options.heartbeatMs ?? 3e4;
47
+ const abort = new AbortController();
48
+ const onUpstreamAbort = () => abort.abort();
49
+ if (options.signal?.aborted || options.request?.signal.aborted) abort.abort();
50
+ else {
51
+ options.signal?.addEventListener("abort", onUpstreamAbort, { once: true });
52
+ options.request?.signal.addEventListener("abort", onUpstreamAbort, { once: true });
53
+ }
54
+ let open = true;
55
+ const body = new ReadableStream({
56
+ start: (controller) => {
57
+ const write = (text) => {
58
+ if (!open) return;
59
+ try {
60
+ controller.enqueue(encoder.encode(text));
61
+ } catch {
62
+ open = false;
63
+ }
64
+ };
65
+ const heartbeat = heartbeatMs > 0 ? setInterval(() => write(": heartbeat\n\n"), heartbeatMs) : null;
66
+ const finish = () => {
67
+ if (heartbeat !== null) clearInterval(heartbeat);
68
+ options.signal?.removeEventListener("abort", onUpstreamAbort);
69
+ options.request?.signal.removeEventListener("abort", onUpstreamAbort);
70
+ if (open) {
71
+ open = false;
72
+ try {
73
+ controller.close();
74
+ } catch {}
75
+ }
76
+ };
77
+ (async () => {
78
+ try {
79
+ const batches = streams.readBatches(streamId, {
80
+ from,
81
+ signal: abort.signal,
82
+ batchSize: options.batchSize,
83
+ onUpToDate: () => write(controlFrame("up-to-date", {}))
84
+ });
85
+ for await (const batch of batches) write(batch.map((chunk) => frame(chunk.seq, chunk.chunk)).join(""));
86
+ const status = await streams.status(streamId);
87
+ if (status?.state === "errored") write(controlFrame("error", { reason: status.error ?? null }));
88
+ else write(controlFrame("done", {}));
89
+ } catch {} finally {
90
+ finish();
91
+ }
92
+ })();
93
+ },
94
+ cancel: () => {
95
+ open = false;
96
+ abort.abort();
97
+ }
98
+ });
99
+ return new Response(body, { headers: {
100
+ "content-type": "text/event-stream; charset=utf-8",
101
+ "cache-control": "no-store"
102
+ } });
103
+ }
104
+ //#endregion
105
+ export { DEFAULT_MAX_CHUNK_BYTES, StreamClosedError, StreamNotFoundError, StreamSerializationError, Streams, sseResponse };
106
+
107
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/streams/sse.ts"],"sourcesContent":["/**\n * Server-Sent Events serving for durable streams: turn one stream into an\n * SSE `Response` with resume built into the protocol. Every chunk is emitted\n * with its sequence number as the SSE `id:` field, so a browser\n * `EventSource` that reconnects sends `Last-Event-ID` automatically and the\n * helper resumes from the next chunk — cursor persistence with zero client\n * code. Control events mark the replay→live transition (`up-to-date`) and\n * settlement (`done` / `error`), mirroring the stream's own lifecycle.\n */\n\nimport type { Streams } from \"./streams\";\nimport type { StreamJson } from \"./types\";\n\nconst encoder = new TextEncoder();\n\n/**\n * Options accepted by {@link sseResponse}.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport interface SSEResponseOptions {\n /**\n * The incoming request. Used for resume (the `Last-Event-ID` header a\n * reconnecting `EventSource` sends, or a `?from=` query parameter) and to\n * abort the tail when the client disconnects (`request.signal`).\n */\n request?: Request;\n /** First sequence number to yield. Overrides request-derived resume. */\n from?: number;\n /** Extra abort signal; composed with `request.signal`. */\n signal?: AbortSignal;\n /** Maximum chunks per write. Defaults to the read batch size (100). */\n batchSize?: number;\n /**\n * Milliseconds between `: heartbeat` comment frames while tailing, keeping\n * idle proxies from killing the connection. 0 disables. Default: 30000.\n */\n heartbeatMs?: number;\n}\n\nfunction resumeFrom(options: SSEResponseOptions): number {\n if (options.from !== undefined) return Math.max(0, options.from);\n const request = options.request;\n if (request) {\n // A fresh EventSource sends no Last-Event-ID at all; Number(null) is 0,\n // so the header must be checked for presence before parsing or every\n // first connection would skip chunk 0.\n const header = request.headers.get(\"Last-Event-ID\");\n if (header !== null && header !== \"\") {\n const lastEventId = Number(header);\n // Last-Event-ID names the last chunk the client received; resume after.\n if (Number.isInteger(lastEventId) && lastEventId >= 0) {\n return lastEventId + 1;\n }\n }\n const fromParam = new URL(request.url).searchParams.get(\"from\");\n if (fromParam !== null) {\n const from = Number(fromParam);\n if (Number.isInteger(from) && from >= 0) return from;\n }\n }\n return 0;\n}\n\nfunction frame(seq: number, chunk: StreamJson): string {\n // JSON.stringify never emits raw newlines, so one data line is always safe.\n return `id: ${seq}\\ndata: ${JSON.stringify(chunk)}\\n\\n`;\n}\n\nfunction controlFrame(event: string, data: StreamJson): string {\n return `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n}\n\n/**\n * Serve one durable stream as a Server-Sent Events response: replay from the\n * resume point, emit an `up-to-date` control event on reaching the tail,\n * tail live appends, and finish with `done` (completed) or `error` (errored,\n * carrying the recorded reason). Returns a 404 response when the stream does\n * not exist.\n *\n * ```ts\n * async onRequest(request: Request) {\n * return sseResponse(this.streams, \"reply:123\", { request });\n * }\n * // client: new EventSource(url) — reconnect resume is automatic.\n * ```\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport async function sseResponse(\n streams: Streams,\n streamId: string,\n options: SSEResponseOptions = {}\n): Promise<Response> {\n if ((await streams.status(streamId)) === null) {\n return new Response(`Stream \"${streamId}\" does not exist`, { status: 404 });\n }\n\n const from = resumeFrom(options);\n const heartbeatMs = options.heartbeatMs ?? 30_000;\n const abort = new AbortController();\n const onUpstreamAbort = () => abort.abort();\n // A listener added to an already-aborted signal never fires: check first,\n // or a pre-aborted request would tail a live stream forever.\n if (options.signal?.aborted || options.request?.signal.aborted) {\n abort.abort();\n } else {\n options.signal?.addEventListener(\"abort\", onUpstreamAbort, { once: true });\n options.request?.signal.addEventListener(\"abort\", onUpstreamAbort, {\n once: true\n });\n }\n\n let open = true;\n const body = new ReadableStream<Uint8Array>({\n start: (controller) => {\n const write = (text: string) => {\n if (!open) return;\n try {\n controller.enqueue(encoder.encode(text));\n } catch {\n // The stream was cancelled between the check and the write (a\n // heartbeat tick racing a client disconnect): stop writing.\n open = false;\n }\n };\n const heartbeat =\n heartbeatMs > 0\n ? setInterval(() => write(\": heartbeat\\n\\n\"), heartbeatMs)\n : null;\n const finish = () => {\n if (heartbeat !== null) clearInterval(heartbeat);\n options.signal?.removeEventListener(\"abort\", onUpstreamAbort);\n options.request?.signal.removeEventListener(\"abort\", onUpstreamAbort);\n if (open) {\n open = false;\n try {\n controller.close();\n } catch {\n // Already cancelled by the consumer.\n }\n }\n };\n\n void (async () => {\n try {\n const batches = streams.readBatches(streamId, {\n from,\n signal: abort.signal,\n batchSize: options.batchSize,\n onUpToDate: () => write(controlFrame(\"up-to-date\", {}))\n });\n for await (const batch of batches) {\n write(batch.map((chunk) => frame(chunk.seq, chunk.chunk)).join(\"\"));\n }\n const status = await streams.status(streamId);\n if (status?.state === \"errored\") {\n write(controlFrame(\"error\", { reason: status.error ?? null }));\n } else {\n write(controlFrame(\"done\", {}));\n }\n } catch {\n // The client disconnected or the caller aborted: nothing to send.\n } finally {\n finish();\n }\n })();\n },\n cancel: () => {\n open = false;\n abort.abort();\n }\n });\n\n return new Response(body, {\n headers: {\n \"content-type\": \"text/event-stream; charset=utf-8\",\n \"cache-control\": \"no-store\"\n }\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,370 @@
1
+ import { s as LifecycleCapability } from "./capability-runner-Be_-PLR1.js";
2
+
3
+ //#region src/streams/types.d.ts
4
+ /**
5
+ * JSON-serializable data accepted as stream chunks and metadata.
6
+ *
7
+ * @experimental The API surface may change before stabilizing.
8
+ */
9
+ type StreamJson =
10
+ | string
11
+ | number
12
+ | boolean
13
+ | null
14
+ | StreamJson[]
15
+ | {
16
+ [key: string]: StreamJson;
17
+ };
18
+ /**
19
+ * States a stream moves through. A stream is `streaming` from `open()` until
20
+ * its producer settles it; both terminal states keep the chunk log readable.
21
+ *
22
+ * @experimental The API surface may change before stabilizing.
23
+ */
24
+ type StreamState = "streaming" | "completed" | "errored";
25
+ /**
26
+ * One durable chunk. `seq` is the stream's monotonic cursor: 0-based,
27
+ * assigned at append time, and stable across replays.
28
+ *
29
+ * @experimental The API surface may change before stabilizing.
30
+ */
31
+ interface StreamChunk {
32
+ readonly seq: number;
33
+ readonly chunk: StreamJson;
34
+ }
35
+ /**
36
+ * Read-only status of one stream — the recovery-evidence surface a Task's
37
+ * `recover` callback consults.
38
+ *
39
+ * @experimental The API surface may change before stabilizing.
40
+ */
41
+ interface StreamStatus {
42
+ streamId: string;
43
+ state: StreamState;
44
+ /** The next sequence number to be assigned == durable chunk count. */
45
+ cursor: number;
46
+ /** Application lookup key assigned at `open()`, when one was. */
47
+ tag?: string;
48
+ metadata?: Record<string, StreamJson>;
49
+ /** Reason recorded by `error()`, when the state is `errored`. */
50
+ error?: string;
51
+ createdAt: number;
52
+ /**
53
+ * Last write activity: advances with every append and with settlement.
54
+ * The liveness signal retention policies key off — a `streaming` stream
55
+ * whose `updatedAt` is old has a producer that stopped appending. (For a
56
+ * live stream this is derived from the chunk log's newest entry; the
57
+ * stored row is only stamped at open and settle.)
58
+ */
59
+ updatedAt: number;
60
+ closedAt?: number;
61
+ }
62
+ /**
63
+ * Producer handle returned by `Streams.open()`. Appends are synchronous
64
+ * durable writes; a terminal stream rejects further appends.
65
+ *
66
+ * @experimental The API surface may change before stabilizing.
67
+ */
68
+ interface StreamWriter {
69
+ readonly streamId: string;
70
+ /** The next sequence number to be assigned. */
71
+ readonly cursor: number;
72
+ /** Durably append one chunk and wake live readers. Returns its `seq`. */
73
+ append(chunk: StreamJson): number;
74
+ /**
75
+ * Settle the stream as completed. No-op if already terminal or deleted:
76
+ * `options.commit` runs only when this call ends the stream.
77
+ */
78
+ close(options?: StreamSettleOptions): void;
79
+ /** Settle the stream as errored. Same no-op contract as {@link close}. */
80
+ error(reason?: string, options?: StreamSettleOptions): void;
81
+ }
82
+ /**
83
+ * The cutover: settle a stream, run the caller's own synchronous writes
84
+ * (typically persisting the finished message), and discard the stream's
85
+ * rows, all in ONE SQLite transaction. A crash leaves either the live
86
+ * stream or the finished message, never neither. `commit` must not await
87
+ * and must not throw for a reason it wants ignored: a throw rolls the
88
+ * settle back and leaves the stream live.
89
+ *
90
+ * Settlement stays idempotent: on a stream already terminal or deleted,
91
+ * `commit` does not run and nothing is discarded. Events and reader wakeups
92
+ * fire after the transaction commits, never for a rolled-back cutover.
93
+ *
94
+ * @experimental The API surface may change before stabilizing.
95
+ */
96
+ interface StreamSettleOptions {
97
+ /** Synchronous writes to commit with the settlement. */
98
+ readonly commit?: () => void;
99
+ /**
100
+ * Delete the stream's rows in the same transaction. The stream ceases
101
+ * to exist (`status()` returns null); readers tailing it end. Use when
102
+ * the chunks have been handed off, so nothing is left to sweep later.
103
+ */
104
+ readonly discard?: boolean;
105
+ }
106
+ /** Options accepted by `Streams.open()`. */
107
+ interface StreamOpenOptions {
108
+ /** JSON metadata retained with the stream. */
109
+ metadata?: Record<string, StreamJson>;
110
+ /**
111
+ * Indexed application lookup key, set once at creation. Deliberately not
112
+ * unique: an operation that produces successive streams (a retried turn, a
113
+ * regenerated reply) stamps each with the same tag, and
114
+ * `list({ tag, limit: 1 })` finds the latest. Reopening a live stream with
115
+ * a *different* tag throws — a config conflict, not a new stream.
116
+ */
117
+ tag?: string;
118
+ }
119
+ /** Options accepted by `Streams.read()`. */
120
+ interface StreamReadOptions {
121
+ /** First sequence number to yield (inclusive). Defaults to 0. */
122
+ from?: number;
123
+ /** Abort a read that is tailing a live stream. */
124
+ signal?: AbortSignal;
125
+ }
126
+ /** Options accepted by `Streams.readBatches()`. */
127
+ interface StreamReadBatchesOptions extends StreamReadOptions {
128
+ /** Maximum chunks per yielded batch. Defaults to 100. */
129
+ batchSize?: number;
130
+ /**
131
+ * Invoked once, the first time the reader reaches the durable tail —
132
+ * i.e. every chunk stored so far has been yielded. Distinct from the
133
+ * stream ending: a live stream is "up to date" while tailing. Useful as a
134
+ * transition signal (flush replayed UI, show a live indicator).
135
+ */
136
+ onUpToDate?: () => void;
137
+ }
138
+ /** Filters accepted by `Streams.list()`. */
139
+ interface StreamListOptions {
140
+ state?: StreamState | StreamState[];
141
+ /** Only streams opened with this exact tag (indexed). */
142
+ tag?: string;
143
+ limit?: number;
144
+ }
145
+ /**
146
+ * @internal Raw `cf_agents_streams` SQLite row.
147
+ *
148
+ * While `state` is `streaming`, `chunk_count` and `updated_at` are NOT
149
+ * maintained per append (appends write only the chunk log; the log's tail
150
+ * is authoritative — see `Streams.#tail`). Both are stamped exact by the
151
+ * settle UPDATE, so terminal rows read straight through. Consumers of a
152
+ * live row must derive cursor/liveness rather than trust these columns.
153
+ */
154
+ type StreamRow = {
155
+ stream_id: string;
156
+ state: StreamState;
157
+ tag: string | null;
158
+ metadata: string | null;
159
+ error_message: string | null;
160
+ chunk_count: number;
161
+ created_at: number;
162
+ updated_at: number;
163
+ closed_at: number | null;
164
+ };
165
+ /** @internal One chunk as read back from a `cf_agents_stream_blocks` row. */
166
+ type StreamChunkRow = {
167
+ stream_id: string;
168
+ seq: number;
169
+ chunk: string;
170
+ created_at: number;
171
+ };
172
+ //#endregion
173
+ //#region src/streams/streams.d.ts
174
+ /** Default ceiling for one serialized chunk (1 MiB). */
175
+ declare const DEFAULT_MAX_CHUNK_BYTES = 1048576;
176
+ /**
177
+ * Policy for a Streams capability.
178
+ *
179
+ * @experimental The API surface may change before stabilizing.
180
+ */
181
+ interface StreamsOptions {
182
+ /** Ceiling for one serialized chunk. Default: 1 MiB. */
183
+ readonly maxChunkBytes?: number;
184
+ }
185
+ /**
186
+ * @internal Synchronous operations returned by
187
+ * {@link Streams.__DO_NOT_USE_WILL_BREAK__sync}. For same-isolate first-party
188
+ * machinery only (the chat `ResumableStream` adapter); every method bypasses
189
+ * `lifecycle.ready()`, so the caller owns startup ordering.
190
+ */
191
+ interface StreamsSyncInternal {
192
+ /** Idempotent DDL — safe to call before the Lifecycle starts. */
193
+ ensureTables(): void;
194
+ getStream(streamId: string): StreamRow | undefined;
195
+ /** Insert a live stream row (no idempotency — caller checks first). */
196
+ insertStream(
197
+ streamId: string,
198
+ tag: string | null,
199
+ metadata: Record<string, StreamJson> | undefined
200
+ ): void;
201
+ /** The read-fenced append: one chunk insert at the log tail, reader wakeup. */
202
+ append(streamId: string, chunk: StreamJson): number;
203
+ /**
204
+ * The newest chunk's timestamp, or null for an empty log. One PK-served
205
+ * read — the per-append liveness signal retention sweeps verify against
206
+ * (a live row's `updated_at` is set at open and not bumped by appends).
207
+ */
208
+ lastChunkAt(streamId: string): number | null;
209
+ /**
210
+ * Segments durably appended so far: the chunk log's tail, read in the
211
+ * calling synchronous block. Zero for an unknown stream.
212
+ */
213
+ cursor(streamId: string): number;
214
+ /**
215
+ * Observe every deletion of a stream's rows — the public `delete()`, the
216
+ * aperture's own deletes, and a cutover's discard — with the row and its
217
+ * cursor as they were just before removal, in the same synchronous block
218
+ * (and, for a cutover, the same transaction). Hooks must be synchronous
219
+ * and must not await: the cutover runs them inside `transactionSync`.
220
+ * The chat adapter uses this to keep its recovery progress marker exact
221
+ * however a chat row leaves the table. Returns the unsubscribe: an owner
222
+ * constructed again (a host whose startup retried) must drop its earlier
223
+ * hook, or a deletion is observed once per construction.
224
+ */
225
+ onDelete(hook: (row: StreamRow, cursor: number) => void): () => void;
226
+ /**
227
+ * Idempotent settlement with events and reader wakeup. With `options`,
228
+ * the settle, the caller's `commit` writes and the log discard run in
229
+ * one SQLite transaction (see {@link StreamSettleOptions}). Returns
230
+ * whether the stream transitioned; on a repeat or a deleted stream the
231
+ * `commit` callback does not run.
232
+ */
233
+ settle(
234
+ streamId: string,
235
+ state: "completed" | "errored",
236
+ reason: string | null,
237
+ options?: StreamSettleOptions
238
+ ): boolean;
239
+ /** Delete a stream and its chunks regardless of state. */
240
+ deleteUnchecked(streamId: string): void;
241
+ /** Delete many streams and their chunks regardless of state, silently. */
242
+ deleteMany(streamIds: string[]): void;
243
+ /**
244
+ * One page of a stream's chunk log from `fromSeq` (inclusive), ordered by
245
+ * seq. Paged rather than read-it-all so replaying a large stream holds
246
+ * one page of segment bodies in memory, not the whole turn.
247
+ */
248
+ readChunks(
249
+ streamId: string,
250
+ fromSeq: number,
251
+ limit: number
252
+ ): StreamChunkRow[];
253
+ /** Every stream row, newest first (created_at, then insertion order). */
254
+ listRows(): StreamRow[];
255
+ /**
256
+ * Every row carrying a tag, newest first, optionally narrowed to one
257
+ * state. Tags are non-unique and the table is shared across producers,
258
+ * so callers apply their own ownership filter (e.g. chat's metadata
259
+ * marker) rather than trusting the newest row.
260
+ */
261
+ rowsByTag(tag: string, state?: StreamState): StreamRow[];
262
+ /**
263
+ * Import one historical stream row verbatim (migrations, test seeding):
264
+ * explicit timestamps and count, no events, no wakeups.
265
+ */
266
+ importStream(row: {
267
+ streamId: string;
268
+ state: StreamState;
269
+ tag: string | null;
270
+ metadata: Record<string, StreamJson> | undefined;
271
+ chunkCount: number;
272
+ createdAt: number;
273
+ updatedAt: number;
274
+ closedAt: number | null;
275
+ }): void;
276
+ /**
277
+ * Import one historical chunk at the log's tail: one INSERT, nothing else.
278
+ * The stream row is not touched — importers pass the final `chunkCount`
279
+ * and `updatedAt` to {@link importStream}, so the row is exact at rest
280
+ * without a per-chunk row write.
281
+ */
282
+ importChunk(streamId: string, chunk: StreamJson, createdAt: number): void;
283
+ }
284
+ /**
285
+ * Durable incremental output for a Lifecycle Object.
286
+ *
287
+ * `open()` a stream, `append()` chunks (synchronous durable writes that wake
288
+ * live readers), and settle it with `close()` or `error()`. `read()` replays
289
+ * persisted chunks from a cursor and then tails live appends; `status()`
290
+ * reports the state and cursor — the recovery evidence a Task's `recover`
291
+ * callback consults after its producer was interrupted.
292
+ *
293
+ * @experimental The API surface may change before stabilizing.
294
+ */
295
+ declare class Streams extends LifecycleCapability {
296
+ #private;
297
+ constructor(options?: StreamsOptions);
298
+ /** Migrate stream storage during Lifecycle startup. */
299
+ onStart(): Promise<void>;
300
+ /**
301
+ * Open a stream for writing. Idempotent on the id: reopening a live stream
302
+ * returns a writer positioned at its current cursor; reopening a terminal
303
+ * stream throws {@link StreamClosedError}.
304
+ */
305
+ open(streamId: string, options?: StreamOpenOptions): Promise<StreamWriter>;
306
+ /**
307
+ * Replay persisted chunks from `from` (inclusive), then tail live appends
308
+ * until the stream settles. Ends when the stream reaches a terminal state
309
+ * and every durable chunk has been yielded; a read of an `errored` stream
310
+ * still yields its chunks and then simply ends — consult {@link status}
311
+ * for the terminal outcome. Aborting `options.signal` throws its reason.
312
+ */
313
+ read(
314
+ streamId: string,
315
+ options?: StreamReadOptions
316
+ ): AsyncGenerator<StreamChunk, void, undefined>;
317
+ /**
318
+ * Batched form of {@link read}: yields non-empty arrays of consecutive
319
+ * chunks instead of one chunk at a time. Replay yields up to
320
+ * `options.batchSize` chunks per array; a live tail yields everything
321
+ * that accumulated since the last wakeup as one array — so a consumer
322
+ * paying per write (an SSE flush, an RPC hop, a history append) pays
323
+ * once per backlog, not once per chunk. Same lifecycle as {@link read}:
324
+ * ends when the stream settles and every durable chunk has been
325
+ * yielded; aborting `options.signal` throws its reason.
326
+ */
327
+ readBatches(
328
+ streamId: string,
329
+ options?: StreamReadBatchesOptions
330
+ ): AsyncGenerator<StreamChunk[], void, undefined>;
331
+ /** Read one stream's state and cursor, or null when it does not exist. */
332
+ status(streamId: string): Promise<StreamStatus | null>;
333
+ /** List streams, newest first. */
334
+ list(options?: StreamListOptions): Promise<StreamStatus[]>;
335
+ /**
336
+ * Delete one terminal stream and its chunk log.
337
+ *
338
+ * @returns True when a terminal stream was deleted; false when none
339
+ * exists. Throws on a live stream — settle it first.
340
+ */
341
+ delete(streamId: string): Promise<boolean>;
342
+ /**
343
+ * @internal Synchronous storage operations for same-isolate first-party
344
+ * machinery — today the chat `ResumableStream` adapter, whose whole public
345
+ * surface is synchronous and constructed before the Lifecycle starts.
346
+ * Bypasses `lifecycle.ready()`: the caller owns startup ordering. The
347
+ * invariant-bearing writes (append fence, settlement, wakeups, events) go
348
+ * through the same private methods as the public API, so live readers and
349
+ * diagnostics observe aperture writes exactly like capability writes. Will
350
+ * break without notice; never use from application code.
351
+ */
352
+ __DO_NOT_USE_WILL_BREAK__sync(): StreamsSyncInternal;
353
+ }
354
+ //#endregion
355
+ export {
356
+ StreamJson as a,
357
+ StreamReadBatchesOptions as c,
358
+ StreamState as d,
359
+ StreamStatus as f,
360
+ StreamChunk as i,
361
+ StreamReadOptions as l,
362
+ Streams as n,
363
+ StreamListOptions as o,
364
+ StreamWriter as p,
365
+ StreamsOptions as r,
366
+ StreamOpenOptions as s,
367
+ DEFAULT_MAX_CHUNK_BYTES as t,
368
+ StreamSettleOptions as u
369
+ };
370
+ //# sourceMappingURL=streams-D6tJ0NN9.d.ts.map