@opengeni/sdk 3.3.2 → 3.4.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 (299) hide show
  1. package/README.md +1007 -72
  2. package/dist/adapters/express.d.ts +31 -0
  3. package/dist/adapters/express.js +87 -0
  4. package/dist/adapters/express.js.map +1 -0
  5. package/dist/adapters/hono.d.ts +16 -0
  6. package/dist/adapters/hono.js +8 -0
  7. package/dist/adapters/hono.js.map +1 -0
  8. package/dist/adapters/next.d.ts +29 -0
  9. package/dist/adapters/next.js +22 -0
  10. package/dist/adapters/next.js.map +1 -0
  11. package/dist/allowance-refusal.d.ts +2 -0
  12. package/dist/allowance-refusal.js +50 -0
  13. package/dist/allowance-refusal.js.map +1 -0
  14. package/dist/app-links.d.ts +42 -0
  15. package/dist/app-links.js +66 -0
  16. package/dist/app-links.js.map +1 -0
  17. package/dist/artifact-catalog.d.ts +40 -0
  18. package/dist/artifact-client.d.ts +20 -8
  19. package/dist/artifacts.d.ts +1 -1
  20. package/dist/artifacts.js +8 -6
  21. package/dist/automations.js +8 -2
  22. package/dist/automations.js.map +1 -1
  23. package/dist/azure-live-transport.d.ts +32 -0
  24. package/dist/browser.d.ts +7 -2
  25. package/dist/browser.js +27 -5
  26. package/dist/chat/fold.d.ts +75 -0
  27. package/dist/chat/handler.d.ts +41 -0
  28. package/dist/chat/http.d.ts +67 -0
  29. package/dist/chat/ids.d.ts +34 -0
  30. package/dist/chat/index.d.ts +9 -0
  31. package/dist/chat/index.js +1369 -0
  32. package/dist/chat/index.js.map +1 -0
  33. package/dist/chat/openai.d.ts +30 -0
  34. package/dist/chat/opengeni.d.ts +129 -0
  35. package/dist/chat/types.d.ts +207 -0
  36. package/dist/chat/vercel.d.ts +49 -0
  37. package/dist/chats.d.ts +8 -0
  38. package/dist/chunk-4AHR4KGA.js +301 -0
  39. package/dist/chunk-4AHR4KGA.js.map +1 -0
  40. package/dist/chunk-6GYGMLX4.js +332 -0
  41. package/dist/chunk-6GYGMLX4.js.map +1 -0
  42. package/dist/chunk-7EWT3PV6.js +368 -0
  43. package/dist/chunk-7EWT3PV6.js.map +1 -0
  44. package/dist/chunk-FTWVVPR6.js +1665 -0
  45. package/dist/chunk-FTWVVPR6.js.map +1 -0
  46. package/dist/{chunk-VYCTL62C.js → chunk-GZQSWAKD.js} +1 -1
  47. package/dist/chunk-GZQSWAKD.js.map +1 -0
  48. package/dist/chunk-KGEABAID.js +71 -0
  49. package/dist/chunk-KGEABAID.js.map +1 -0
  50. package/dist/{chunk-YKZME56C.js → chunk-KWADQ227.js} +3 -3
  51. package/dist/{chunk-YKZME56C.js.map → chunk-KWADQ227.js.map} +1 -1
  52. package/dist/{chunk-JUS2UYRP.js → chunk-NCU5OAN7.js} +27 -2
  53. package/dist/chunk-NCU5OAN7.js.map +1 -0
  54. package/dist/{chunk-YXQX7RQT.js → chunk-OI5YLASH.js} +73 -2
  55. package/dist/chunk-OI5YLASH.js.map +1 -0
  56. package/dist/chunk-OV3POE62.js +359 -0
  57. package/dist/chunk-OV3POE62.js.map +1 -0
  58. package/dist/chunk-P7UWKORG.js +561 -0
  59. package/dist/chunk-P7UWKORG.js.map +1 -0
  60. package/dist/chunk-QGEIL4TR.js +195 -0
  61. package/dist/chunk-QGEIL4TR.js.map +1 -0
  62. package/dist/{chunk-TRNI7KEO.js → chunk-S2NLS3ES.js} +3669 -1281
  63. package/dist/chunk-S2NLS3ES.js.map +1 -0
  64. package/dist/chunk-UM4ZXXJR.js +9 -0
  65. package/dist/chunk-UM4ZXXJR.js.map +1 -0
  66. package/dist/{chunk-QT3KFVDP.js → chunk-UME3X7CP.js} +28 -32
  67. package/dist/chunk-UME3X7CP.js.map +1 -0
  68. package/dist/chunk-VT4YM4XQ.js +210 -0
  69. package/dist/chunk-VT4YM4XQ.js.map +1 -0
  70. package/dist/chunk-WSYYXONG.js +1602 -0
  71. package/dist/chunk-WSYYXONG.js.map +1 -0
  72. package/dist/{chunk-C2H7HBNP.js → chunk-WVCJRSGJ.js} +119 -14
  73. package/dist/chunk-WVCJRSGJ.js.map +1 -0
  74. package/dist/chunk-X5ITQVXE.js +15 -0
  75. package/dist/chunk-X5ITQVXE.js.map +1 -0
  76. package/dist/chunk-XA7HVIHI.js +126 -0
  77. package/dist/chunk-XA7HVIHI.js.map +1 -0
  78. package/dist/{chunk-KKRO2VCP.js → chunk-YJCHB7R3.js} +60 -12
  79. package/dist/chunk-YJCHB7R3.js.map +1 -0
  80. package/dist/chunk-YKIHNLWD.js +153 -0
  81. package/dist/chunk-YKIHNLWD.js.map +1 -0
  82. package/dist/chunk-ZDUBPV33.js +277 -0
  83. package/dist/chunk-ZDUBPV33.js.map +1 -0
  84. package/dist/client.d.ts +1068 -118
  85. package/dist/codex-realtime-controller.d.ts +13 -0
  86. package/dist/codex-realtime-controller.js +4 -2
  87. package/dist/codex-realtime-v3-wire.d.ts +3 -2
  88. package/dist/codex-realtime.d.ts +5 -1
  89. package/dist/company-brain.d.ts +1 -11
  90. package/dist/core.d.ts +7 -2
  91. package/dist/core.js +25 -6
  92. package/dist/deprecation.d.ts +47 -0
  93. package/dist/document-authority-client.d.ts +24 -2
  94. package/dist/document-authority.js +7 -5
  95. package/dist/editable-artifacts/index.d.ts +1 -1
  96. package/dist/editable-artifacts/types.d.ts +12 -2
  97. package/dist/editable-artifacts.js +19 -3
  98. package/dist/editable-artifacts.js.map +1 -1
  99. package/dist/embedding-client.d.ts +129 -0
  100. package/dist/errors.d.ts +76 -1
  101. package/dist/external-vault-receiver.d.ts +203 -0
  102. package/dist/external-vault-receiver.js +564 -0
  103. package/dist/external-vault-receiver.js.map +1 -0
  104. package/dist/feedback.d.ts +23 -0
  105. package/dist/gateway-realtime-transport.js +1 -1
  106. package/dist/github-repositories.d.ts +10 -0
  107. package/dist/github-repositories.js +36 -0
  108. package/dist/github-repositories.js.map +1 -0
  109. package/dist/index.d.ts +62 -11
  110. package/dist/index.js +557 -338
  111. package/dist/index.js.map +1 -1
  112. package/dist/insights-usage.d.ts +33 -0
  113. package/dist/insights-usage.js +7 -0
  114. package/dist/insights-usage.js.map +1 -0
  115. package/dist/interaction.d.ts +165 -71
  116. package/dist/interaction.js +2 -2
  117. package/dist/knowledge.d.ts +7 -0
  118. package/dist/knowledge.js +20 -0
  119. package/dist/knowledge.js.map +1 -0
  120. package/dist/known-tools.d.ts +4 -0
  121. package/dist/message-links.d.ts +68 -0
  122. package/dist/model-context.d.ts +68 -0
  123. package/dist/model-display.d.ts +2 -0
  124. package/dist/model-display.js +17 -0
  125. package/dist/model-display.js.map +1 -0
  126. package/dist/model-picker-order.d.ts +1 -0
  127. package/dist/model-picker-order.js +10 -0
  128. package/dist/model-picker-order.js.map +1 -0
  129. package/dist/organization-integration-policy.d.ts +26 -0
  130. package/dist/organization-integration-policy.js +26 -0
  131. package/dist/organization-integration-policy.js.map +1 -0
  132. package/dist/pr-review-client.d.ts +1 -1
  133. package/dist/pr-review.d.ts +1 -1
  134. package/dist/pr-review.js.map +1 -1
  135. package/dist/preference-registry.d.ts +1 -1
  136. package/dist/prepared-mcp-setup.d.ts +5 -0
  137. package/dist/proxy.d.ts +13 -11
  138. package/dist/realtime.d.ts +1 -1
  139. package/dist/realtime.js +253 -7
  140. package/dist/realtime.js.map +1 -1
  141. package/dist/session-history-import.d.ts +22 -0
  142. package/dist/session-history-import.js +36 -0
  143. package/dist/session-history-import.js.map +1 -0
  144. package/dist/session-list-entries.d.ts +1 -0
  145. package/dist/session-list-entries.js +7 -0
  146. package/dist/session-list-entries.js.map +1 -0
  147. package/dist/session-message-search.d.ts +53 -0
  148. package/dist/session-proxy-client.d.ts +28 -0
  149. package/dist/session-proxy.d.ts +334 -0
  150. package/dist/session-proxy.js +24 -0
  151. package/dist/session-proxy.js.map +1 -0
  152. package/dist/session-titles.d.ts +2 -28
  153. package/dist/session-usage-limits.d.ts +10 -0
  154. package/dist/session-usage-limits.js +43 -0
  155. package/dist/session-usage-limits.js.map +1 -0
  156. package/dist/shared-catalog-loader.d.ts +34 -0
  157. package/dist/site-ai.d.ts +35 -0
  158. package/dist/site-bridge-host.d.ts +112 -0
  159. package/dist/site-bridge-host.js +286 -0
  160. package/dist/site-bridge-host.js.map +1 -0
  161. package/dist/site-browser-entry.d.ts +1 -0
  162. package/dist/site-browser-runtime.gen.d.ts +1 -0
  163. package/dist/site-data.d.ts +178 -0
  164. package/dist/site-document.d.ts +5 -0
  165. package/dist/site-document.js +20 -0
  166. package/dist/site-document.js.map +1 -0
  167. package/dist/site-document.test.d.ts +1 -0
  168. package/dist/site-http.d.ts +17 -0
  169. package/dist/site-sql.d.ts +31 -0
  170. package/dist/site-tool-bridge.d.ts +57 -0
  171. package/dist/site.d.ts +186 -0
  172. package/dist/site.js +63 -0
  173. package/dist/site.js.map +1 -0
  174. package/dist/skills.d.ts +75 -0
  175. package/dist/sse.d.ts +1 -1
  176. package/dist/stream.d.ts +2 -0
  177. package/dist/tenant-workspaces.d.ts +47 -0
  178. package/dist/tenant-workspaces.js +8 -0
  179. package/dist/tenant-workspaces.js.map +1 -0
  180. package/dist/tool-auth.d.ts +87 -0
  181. package/dist/tool-auth.js +23 -0
  182. package/dist/tool-auth.js.map +1 -0
  183. package/dist/tool-display-metadata.d.ts +3 -0
  184. package/dist/tools-37DCTCNZ.js +12 -0
  185. package/dist/tools-37DCTCNZ.js.map +1 -0
  186. package/dist/tools.d.ts +81 -0
  187. package/dist/transcription.d.ts +1 -1
  188. package/dist/types.d.ts +2807 -583
  189. package/dist/usage-allowances.d.ts +36 -0
  190. package/dist/usage-allowances.js +80 -0
  191. package/dist/usage-allowances.js.map +1 -0
  192. package/dist/vault-types.d.ts +324 -0
  193. package/dist/vaults-api.d.ts +65 -0
  194. package/dist/workspace-artifacts.d.ts +47 -5
  195. package/dist/workspace-instruction-policies.d.ts +2 -2
  196. package/dist/workspace-integrations.d.ts +74 -0
  197. package/dist/workspace-integrations.js +67 -0
  198. package/dist/workspace-integrations.js.map +1 -0
  199. package/dist/workspace-state.d.ts +8 -71
  200. package/package.json +103 -5
  201. package/src/adapters/express.ts +136 -0
  202. package/src/adapters/hono.ts +18 -0
  203. package/src/adapters/next.ts +42 -0
  204. package/src/allowance-refusal.ts +5 -0
  205. package/src/app-links.ts +117 -0
  206. package/src/artifact-catalog.ts +51 -0
  207. package/src/artifact-client.ts +40 -49
  208. package/src/artifacts.ts +1 -0
  209. package/src/automations-client.ts +8 -2
  210. package/src/azure-live-transport.ts +286 -0
  211. package/src/browser.ts +37 -0
  212. package/src/chat/fold.ts +431 -0
  213. package/src/chat/handler.ts +240 -0
  214. package/src/chat/http.ts +257 -0
  215. package/src/chat/ids.ts +85 -0
  216. package/src/chat/index.ts +88 -0
  217. package/src/chat/openai.ts +439 -0
  218. package/src/chat/opengeni.ts +737 -0
  219. package/src/chat/types.ts +219 -0
  220. package/src/chat/vercel.ts +204 -0
  221. package/src/chats.ts +16 -0
  222. package/src/client.ts +5697 -1833
  223. package/src/codex-realtime-controller.ts +163 -8
  224. package/src/codex-realtime-v3-wire.ts +4 -3
  225. package/src/codex-realtime-v3.ts +12 -3
  226. package/src/codex-realtime.ts +11 -3
  227. package/src/company-brain.ts +0 -40
  228. package/src/core.ts +20 -0
  229. package/src/deprecation.ts +149 -0
  230. package/src/document-authority-client.ts +104 -1
  231. package/src/editable-artifacts/controller.ts +36 -2
  232. package/src/editable-artifacts/index.ts +1 -0
  233. package/src/editable-artifacts/types.ts +29 -16
  234. package/src/embedding-client.ts +519 -0
  235. package/src/errors.ts +303 -4
  236. package/src/external-vault-receiver.ts +914 -0
  237. package/src/feedback.ts +20 -0
  238. package/src/gateway-realtime-transport.ts +3 -3
  239. package/src/github-repositories.ts +60 -0
  240. package/src/index.ts +603 -65
  241. package/src/insights-usage.ts +64 -0
  242. package/src/interaction.ts +315 -93
  243. package/src/knowledge.ts +72 -0
  244. package/src/known-tools.ts +279 -0
  245. package/src/message-links.ts +178 -0
  246. package/src/model-context.ts +113 -0
  247. package/src/model-display.ts +11 -0
  248. package/src/model-picker-order.ts +6 -0
  249. package/src/organization-integration-policy.ts +54 -0
  250. package/src/pr-review-client.ts +1 -1
  251. package/src/pr-review.ts +1 -1
  252. package/src/preference-registry.ts +2 -0
  253. package/src/prepared-mcp-setup.ts +123 -0
  254. package/src/proxy.ts +23 -12
  255. package/src/realtime.ts +15 -6
  256. package/src/session-history-import.ts +84 -0
  257. package/src/session-list-entries.ts +1 -0
  258. package/src/session-message-search.ts +47 -0
  259. package/src/session-proxy-client.ts +68 -0
  260. package/src/session-proxy.ts +2098 -0
  261. package/src/session-titles.ts +8 -82
  262. package/src/session-usage-limits.ts +71 -0
  263. package/src/shared-catalog-loader.ts +169 -0
  264. package/src/site-ai.ts +284 -0
  265. package/src/site-bridge-host.ts +422 -0
  266. package/src/site-browser-entry.ts +6 -0
  267. package/src/site-browser-runtime.gen.ts +2 -0
  268. package/src/site-data.ts +372 -0
  269. package/src/site-document.test.ts +64 -0
  270. package/src/site-document.ts +18 -0
  271. package/src/site-http.ts +171 -0
  272. package/src/site-sql.ts +153 -0
  273. package/src/site-tool-bridge.ts +401 -0
  274. package/src/site.ts +878 -0
  275. package/src/skills.ts +69 -0
  276. package/src/sse.ts +9 -3
  277. package/src/stream.ts +33 -10
  278. package/src/tenant-workspaces.ts +148 -0
  279. package/src/tool-auth.ts +301 -0
  280. package/src/tool-display-metadata.ts +27 -0
  281. package/src/tools.ts +452 -0
  282. package/src/transcription.ts +3 -0
  283. package/src/types.ts +3170 -582
  284. package/src/usage-allowances.ts +189 -0
  285. package/src/vault-types.ts +379 -0
  286. package/src/vaults-api.ts +339 -0
  287. package/src/workspace-artifacts.ts +55 -6
  288. package/src/workspace-instruction-policies.ts +2 -1
  289. package/src/workspace-integrations.ts +402 -0
  290. package/src/workspace-state.ts +8 -82
  291. package/dist/chunk-C2H7HBNP.js.map +0 -1
  292. package/dist/chunk-C4DJPZRU.js +0 -119
  293. package/dist/chunk-C4DJPZRU.js.map +0 -1
  294. package/dist/chunk-JUS2UYRP.js.map +0 -1
  295. package/dist/chunk-KKRO2VCP.js.map +0 -1
  296. package/dist/chunk-QT3KFVDP.js.map +0 -1
  297. package/dist/chunk-TRNI7KEO.js.map +0 -1
  298. package/dist/chunk-VYCTL62C.js.map +0 -1
  299. package/dist/chunk-YXQX7RQT.js.map +0 -1
@@ -0,0 +1,49 @@
1
+ import { type ChatResolve } from "./http.js";
2
+ import type { Opengeni } from "./opengeni.js";
3
+ import type { ChatChunk } from "./types.js";
4
+ /**
5
+ * Vercel AI SDK UI message stream (protocol v1, as consumed by `useChat` with
6
+ * the default transport in AI SDK 5, 6, and 7; approval requests need 6+).
7
+ * Parts are `data: <json>` SSE
8
+ * lines terminated by `data: [DONE]`, under the
9
+ * `x-vercel-ai-ui-message-stream: v1` header.
10
+ */
11
+ export declare const UI_MESSAGE_STREAM_HEADER = "x-vercel-ai-ui-message-stream";
12
+ export declare const UI_MESSAGE_STREAM_VERSION = "v1";
13
+ export type UIMessageStreamOptions = {
14
+ /** Assistant message id announced in the `start` part. Defaults to a random UUID. */
15
+ messageId?: string | undefined;
16
+ /**
17
+ * Emit Opengeni's own tool activity as tool parts. Off by default: those
18
+ * tools are not in the app's typed tool set. When on, parts are marked
19
+ * `dynamic` and `providerExecuted`, so `useChat` renders them as
20
+ * `dynamic-tool` parts and never tries to execute them. Approval requests
21
+ * are always emitted (as dynamic tool parts) because answering them is part
22
+ * of the conversation.
23
+ */
24
+ toolParts?: boolean | undefined;
25
+ /**
26
+ * Emit the `start` / `start-step` / `finish-step` / `finish` framing. Set to
27
+ * false when writing into an existing AI SDK stream that owns its framing
28
+ * (for example `createUIMessageStream({ execute: ({ writer }) => ... })`).
29
+ * Defaults to true.
30
+ */
31
+ framing?: boolean | undefined;
32
+ };
33
+ /** Protocol parts for one reply, in order. */
34
+ export declare function uiMessageStreamParts(chunks: AsyncIterable<ChatChunk>, options?: UIMessageStreamOptions): AsyncGenerator<Record<string, unknown>, void, void>;
35
+ export declare function uiMessageStreamBlocks(chunks: AsyncIterable<ChatChunk>, options?: UIMessageStreamOptions): AsyncGenerator<string, void, void>;
36
+ export declare function chatChunksToUIMessageStream(chunks: AsyncIterable<ChatChunk>, options?: UIMessageStreamOptions & {
37
+ onCancel?: (() => void) | undefined;
38
+ }): ReadableStream<Uint8Array>;
39
+ export declare function uiMessageStreamResponse(chunks: AsyncIterable<ChatChunk>, options?: UIMessageStreamOptions): Response;
40
+ /** Text of the last user `UIMessage` (`parts` of type `text`, joined). */
41
+ export declare function lastUIMessageText(messages: unknown): string | null;
42
+ /**
43
+ * `useChat` request handler: body `{ id, messages, trigger, messageId }`.
44
+ * Conversation: the host's `resolve`, else the `x-opengeni-conversation`
45
+ * header, else the chat `id`. Only the last user message is sent; the
46
+ * messages before it are imported once as context when this request creates
47
+ * the session. `regenerate-message` steers instead of queueing.
48
+ */
49
+ export declare function handleVercelChatRequest(og: Opengeni, request: Request, resolve: ChatResolve, options?: Pick<UIMessageStreamOptions, "toolParts">): Promise<Response>;
@@ -0,0 +1,8 @@
1
+ import type { CreateSessionRequest } from "./types.js";
2
+ /**
3
+ * Private chats use personal Knowledge and session-only agent reach; shared chats
4
+ * use workspace Knowledge and reach. Isolated adds a separate workspace per user.
5
+ */
6
+ export type Chats = "private" | "shared" | "isolated";
7
+ /** SDK defaults only: the API still authorizes visibility, agent reach and Knowledge separately. */
8
+ export declare function chatDefaults(chats: Chats): Required<Pick<CreateSessionRequest, "visibility" | "agentAccess" | "memoryScope">>;
@@ -0,0 +1,301 @@
1
+ import {
2
+ OpenGeniStreamError,
3
+ isAbortError,
4
+ isRetryableStreamError
5
+ } from "./chunk-7EWT3PV6.js";
6
+
7
+ // src/sse.ts
8
+ async function* parseSseStream(stream) {
9
+ const reader = stream.getReader();
10
+ const decoder = new TextDecoder();
11
+ let buffer = "";
12
+ let id;
13
+ let event;
14
+ let dataLines = null;
15
+ const dispatch = () => {
16
+ const message = dataLines === null ? null : {
17
+ ...id !== void 0 ? { id } : {},
18
+ ...event !== void 0 ? { event } : {},
19
+ data: dataLines.join("\n")
20
+ };
21
+ id = void 0;
22
+ event = void 0;
23
+ dataLines = null;
24
+ return message;
25
+ };
26
+ const handleLine = (line) => {
27
+ if (line === "") {
28
+ return dispatch();
29
+ }
30
+ if (line.startsWith(":")) {
31
+ return null;
32
+ }
33
+ const colon = line.indexOf(":");
34
+ const field = colon === -1 ? line : line.slice(0, colon);
35
+ let value = colon === -1 ? "" : line.slice(colon + 1);
36
+ if (value.startsWith(" ")) {
37
+ value = value.slice(1);
38
+ }
39
+ if (field === "data") {
40
+ (dataLines ??= []).push(value);
41
+ } else if (field === "event") {
42
+ event = value;
43
+ } else if (field === "id") {
44
+ id = value;
45
+ }
46
+ return null;
47
+ };
48
+ try {
49
+ while (true) {
50
+ const { done, value } = await reader.read();
51
+ if (done) {
52
+ break;
53
+ }
54
+ buffer += decoder.decode(value, { stream: true });
55
+ let newline = buffer.indexOf("\n");
56
+ while (newline !== -1) {
57
+ let line = buffer.slice(0, newline);
58
+ buffer = buffer.slice(newline + 1);
59
+ if (line.endsWith("\r")) {
60
+ line = line.slice(0, -1);
61
+ }
62
+ const message = handleLine(line);
63
+ if (message) {
64
+ yield message;
65
+ }
66
+ newline = buffer.indexOf("\n");
67
+ }
68
+ }
69
+ } finally {
70
+ void reader.cancel().catch(() => {
71
+ });
72
+ try {
73
+ reader.releaseLock();
74
+ } catch {
75
+ }
76
+ }
77
+ }
78
+
79
+ // src/stream.ts
80
+ var SESSION_EVENT_STREAM_COVERAGE = Symbol.for(
81
+ "@opengeni/sdk/session-event-stream-covered-through"
82
+ );
83
+ async function* streamSessionEvents(transport, options = {}) {
84
+ const signal = options.signal;
85
+ const reconnect = options.reconnect ?? true;
86
+ const baseDelayMs = options.reconnectDelayMs ?? 500;
87
+ const maxDelayMs = options.maxReconnectDelayMs ?? 1e4;
88
+ const jitterRatio = options.reconnectJitterRatio ?? 0.2;
89
+ const beforeLiveTimeoutMs = options.beforeLiveTimeoutMs ?? 15e3;
90
+ const heartbeatTimeoutMs = options.heartbeatTimeoutMs ?? 45e3;
91
+ const maxAttempts = options.maxReconnectAttempts ?? Number.POSITIVE_INFINITY;
92
+ let cursor = options.after ?? 0;
93
+ let failedAttempts = 0;
94
+ let delayMs = baseDelayMs;
95
+ let everConnected = false;
96
+ while (true) {
97
+ if (signal?.aborted) break;
98
+ options.onStateChange?.(everConnected || failedAttempts > 0 ? "reconnecting" : "connecting");
99
+ const cursorAtOpen = cursor;
100
+ try {
101
+ const body = await transport.openStream(cursor, signal);
102
+ everConnected = true;
103
+ failedAttempts = 0;
104
+ delayMs = baseDelayMs;
105
+ try {
106
+ options.onOpen?.();
107
+ } catch {
108
+ }
109
+ await runBeforeLive(options.beforeLive, beforeLiveTimeoutMs, signal);
110
+ options.onStateChange?.("live");
111
+ for await (const message of parseSseStream(
112
+ withStreamInactivityTimeout(body, heartbeatTimeoutMs, signal)
113
+ )) {
114
+ if (signal?.aborted) {
115
+ return;
116
+ }
117
+ const event = parseSessionEvent(message.data);
118
+ if (!event) {
119
+ continue;
120
+ }
121
+ const coveredSequence = trustedSseSequence(message.id, event.sequence);
122
+ markSessionEventStreamCoverage(event, coveredSequence);
123
+ if (coveredSequence <= cursor) continue;
124
+ if (event.sequence > cursor + 1) {
125
+ for await (const missed of backfillEvents(transport, cursor, event.sequence - 1)) {
126
+ cursor = missed.sequence;
127
+ yield missed;
128
+ if (signal?.aborted) {
129
+ return;
130
+ }
131
+ }
132
+ }
133
+ cursor = coveredSequence;
134
+ yield event;
135
+ }
136
+ if (!reconnect) {
137
+ return;
138
+ }
139
+ if (cursor === cursorAtOpen) {
140
+ await sleep(jitteredDelay(baseDelayMs, jitterRatio), signal);
141
+ }
142
+ continue;
143
+ } catch (error) {
144
+ if (signal?.aborted || isAbortError(error)) {
145
+ return;
146
+ }
147
+ if (!reconnect || !isRetryableStreamError(error)) {
148
+ throw error;
149
+ }
150
+ failedAttempts += 1;
151
+ if (failedAttempts > maxAttempts) {
152
+ throw new OpenGeniStreamError(
153
+ `event stream gave up after ${maxAttempts} consecutive failed reconnect attempts: ${error instanceof Error ? error.message : String(error)}`
154
+ );
155
+ }
156
+ }
157
+ await sleep(jitteredDelay(delayMs, jitterRatio), signal);
158
+ delayMs = Math.min(Math.max(delayMs * 2, baseDelayMs), maxDelayMs);
159
+ }
160
+ }
161
+ async function runBeforeLive(beforeLive, timeoutMs, signal) {
162
+ if (!beforeLive) return;
163
+ let timer;
164
+ let abortListener;
165
+ const timeout = new Promise((_resolve, reject) => {
166
+ timer = setTimeout(
167
+ () => reject(new TypeError(`stream reconciliation timed out after ${timeoutMs}ms`)),
168
+ timeoutMs
169
+ );
170
+ if (signal) {
171
+ abortListener = () => reject(new DOMException("Aborted", "AbortError"));
172
+ signal.addEventListener("abort", abortListener, { once: true });
173
+ }
174
+ });
175
+ try {
176
+ await Promise.race([Promise.resolve().then(beforeLive), timeout]);
177
+ } finally {
178
+ if (timer !== void 0) clearTimeout(timer);
179
+ if (signal && abortListener) signal.removeEventListener("abort", abortListener);
180
+ }
181
+ }
182
+ function jitteredDelay(delayMs, ratio) {
183
+ if (delayMs <= 0 || ratio <= 0) return delayMs;
184
+ const boundedRatio = Math.min(ratio, 1);
185
+ const spread = delayMs * boundedRatio;
186
+ return Math.max(0, delayMs - spread + Math.random() * spread * 2);
187
+ }
188
+ function withStreamInactivityTimeout(stream, timeoutMs, signal) {
189
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0) {
190
+ throw new RangeError("stream heartbeat timeout must be a positive safe integer");
191
+ }
192
+ const reader = stream.getReader();
193
+ return new ReadableStream({
194
+ pull: async (controller) => {
195
+ let timer;
196
+ let abortListener;
197
+ try {
198
+ const result = await Promise.race([
199
+ reader.read(),
200
+ new Promise((_resolve, reject) => {
201
+ timer = setTimeout(
202
+ () => reject(new TypeError(`event stream heartbeat timed out after ${timeoutMs}ms`)),
203
+ timeoutMs
204
+ );
205
+ if (signal) {
206
+ abortListener = () => reject(new DOMException("Aborted", "AbortError"));
207
+ signal.addEventListener("abort", abortListener, { once: true });
208
+ }
209
+ })
210
+ ]);
211
+ if (result.done) controller.close();
212
+ else controller.enqueue(result.value);
213
+ } catch (error) {
214
+ void reader.cancel(error).catch(() => {
215
+ });
216
+ controller.error(error);
217
+ } finally {
218
+ if (timer !== void 0) clearTimeout(timer);
219
+ if (signal && abortListener) signal.removeEventListener("abort", abortListener);
220
+ }
221
+ },
222
+ cancel: (reason) => {
223
+ void reader.cancel(reason).catch(() => {
224
+ });
225
+ }
226
+ });
227
+ }
228
+ async function* backfillEvents(transport, fromExclusive, toInclusive) {
229
+ let cursor = fromExclusive;
230
+ while (cursor < toInclusive) {
231
+ const page = await transport.listEvents(cursor, Math.min(500, toInclusive - cursor));
232
+ const advancing = page.filter((event) => event.sequence > cursor && event.sequence <= toInclusive).sort((a, b) => a.sequence - b.sequence);
233
+ if (advancing.length === 0) {
234
+ throw new OpenGeniStreamError(
235
+ `event replay backfill stalled: expected sequences ${cursor + 1}..${toInclusive} but the replay endpoint returned none of them`
236
+ );
237
+ }
238
+ for (const event of advancing) {
239
+ if (event.sequence !== cursor + 1) {
240
+ throw new OpenGeniStreamError(
241
+ `event replay backfill is missing sequence ${cursor + 1} (replay endpoint skipped to ${event.sequence}); refusing to deliver with a gap`
242
+ );
243
+ }
244
+ cursor = event.sequence;
245
+ yield event;
246
+ }
247
+ }
248
+ }
249
+ function parseSessionEvent(data) {
250
+ let parsed;
251
+ try {
252
+ parsed = JSON.parse(data);
253
+ } catch {
254
+ return null;
255
+ }
256
+ if (typeof parsed !== "object" || parsed === null || typeof parsed.sequence !== "number" || typeof parsed.type !== "string" || typeof parsed.id !== "string") {
257
+ return null;
258
+ }
259
+ return parsed;
260
+ }
261
+ function sessionEventStreamCoveredThrough(event) {
262
+ const covered = event[SESSION_EVENT_STREAM_COVERAGE];
263
+ return typeof covered === "number" && Number.isSafeInteger(covered) && covered >= event.sequence ? covered : null;
264
+ }
265
+ function trustedSseSequence(id, sequence) {
266
+ if (id === void 0 || !/^\d+$/.test(id)) return sequence;
267
+ const covered = Number(id);
268
+ return Number.isSafeInteger(covered) && covered >= sequence ? covered : sequence;
269
+ }
270
+ function markSessionEventStreamCoverage(event, covered) {
271
+ Object.defineProperty(event, SESSION_EVENT_STREAM_COVERAGE, {
272
+ value: covered,
273
+ enumerable: false,
274
+ configurable: false,
275
+ writable: false
276
+ });
277
+ }
278
+ async function sleep(delayMs, signal) {
279
+ if (signal?.aborted || delayMs <= 0) {
280
+ return;
281
+ }
282
+ await new Promise((resolve) => {
283
+ const timer = setTimeout(done, delayMs);
284
+ function done() {
285
+ clearTimeout(timer);
286
+ signal?.removeEventListener("abort", done);
287
+ resolve();
288
+ }
289
+ signal?.addEventListener("abort", done, { once: true });
290
+ });
291
+ }
292
+
293
+ export {
294
+ parseSseStream,
295
+ streamSessionEvents,
296
+ runBeforeLive,
297
+ jitteredDelay,
298
+ withStreamInactivityTimeout,
299
+ sessionEventStreamCoveredThrough
300
+ };
301
+ //# sourceMappingURL=chunk-4AHR4KGA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sse.ts","../src/stream.ts"],"sourcesContent":["/**\n * Minimal incremental Server-Sent Events parser over a byte stream.\n *\n * Implements the parts of the SSE wire format Opengeni uses: `id`, `event`,\n * and `data` fields, multi-line data, comment lines, and both LF and CRLF\n * line endings. Messages without any `data` (comments, id-only blocks) are\n * not emitted.\n */\nexport type SseMessage = {\n id?: string;\n event?: string;\n data: string;\n};\n\nexport async function* parseSseStream(\n stream: ReadableStream<Uint8Array>,\n): AsyncGenerator<SseMessage, void, void> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let id: string | undefined;\n let event: string | undefined;\n let dataLines: string[] | null = null;\n\n const dispatch = (): SseMessage | null => {\n const message =\n dataLines === null\n ? null\n : {\n ...(id !== undefined ? { id } : {}),\n ...(event !== undefined ? { event } : {}),\n data: dataLines.join(\"\\n\"),\n };\n id = undefined;\n event = undefined;\n dataLines = null;\n return message;\n };\n\n const handleLine = (line: string): SseMessage | null => {\n if (line === \"\") {\n return dispatch();\n }\n if (line.startsWith(\":\")) {\n return null;\n }\n const colon = line.indexOf(\":\");\n const field = colon === -1 ? line : line.slice(0, colon);\n let value = colon === -1 ? \"\" : line.slice(colon + 1);\n if (value.startsWith(\" \")) {\n value = value.slice(1);\n }\n if (field === \"data\") {\n (dataLines ??= []).push(value);\n } else if (field === \"event\") {\n event = value;\n } else if (field === \"id\") {\n id = value;\n }\n // Other fields (e.g. `retry`) are ignored; reconnect pacing is the\n // streaming layer's concern.\n return null;\n };\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n buffer += decoder.decode(value, { stream: true });\n let newline = buffer.indexOf(\"\\n\");\n while (newline !== -1) {\n let line = buffer.slice(0, newline);\n buffer = buffer.slice(newline + 1);\n if (line.endsWith(\"\\r\")) {\n line = line.slice(0, -1);\n }\n const message = handleLine(line);\n if (message) {\n yield message;\n }\n newline = buffer.indexOf(\"\\n\");\n }\n }\n // Per the SSE spec, a block is only dispatched on a blank line. Anything\n // still pending at end-of-stream came from a truncated connection and is\n // discarded — the streaming layer replays from its cursor on reconnect.\n } finally {\n // Never await cancel(): some fetch bodies settle it only once their request\n // aborts, which would deadlock the consumer's unwinding.\n void reader.cancel().catch(() => {});\n try {\n reader.releaseLock();\n } catch {\n // A pending read (older stream implementations) keeps the lock; cancel releases it.\n }\n }\n}\n","import { isAbortError, isRetryableStreamError, OpenGeniStreamError } from \"./errors\";\nimport { parseSseStream } from \"./sse\";\nimport type { SessionEvent } from \"./types\";\n\nconst SESSION_EVENT_STREAM_COVERAGE = Symbol.for(\n \"@opengeni/sdk/session-event-stream-covered-through\",\n);\n\n/**\n * Transport boundary for the streaming core. The client implements it with\n * `fetch`; unit tests script it directly.\n */\nexport type SessionEventStreamTransport = {\n /** Open the SSE stream, replaying durable events after `after` first. */\n openStream: (\n after: number,\n signal: AbortSignal | undefined,\n ) => Promise<ReadableStream<Uint8Array>>;\n /** Replay durable events by sequence (`GET .../events?after=&limit=`). */\n listEvents: (after: number, limit: number) => Promise<SessionEvent[]>;\n};\n\nexport type StreamConnectionState = \"connecting\" | \"live\" | \"reconnecting\";\n\nexport type StreamSessionEventsOptions = {\n /** Resume after this sequence number (exclusive). Defaults to 0 (full replay). */\n after?: number;\n /** Aborting ends the stream gracefully (the generator returns). */\n signal?: AbortSignal;\n /** Reconnect on transient drops. Defaults to true. */\n reconnect?: boolean;\n /** Initial reconnect backoff. Defaults to 500ms. */\n reconnectDelayMs?: number;\n /** Backoff ceiling. Defaults to 10s. */\n maxReconnectDelayMs?: number;\n /** Random backoff spread as a fraction of the delay. Defaults to 0.2. */\n reconnectJitterRatio?: number;\n /**\n * Give up after this many consecutive failed reconnect attempts (i.e. N\n * reconnects = N+1 total open-stream calls). Defaults to unlimited.\n */\n maxReconnectAttempts?: number;\n /**\n * Notify the consumer as soon as the SSE response body is open. This callback\n * is deliberately synchronous and non-blocking: use it to start projection\n * reconciliation without delaying consumption of live event bytes.\n */\n onOpen?: (() => void) | undefined;\n /** Await authoritative client reconciliation before exposing `live`. */\n beforeLive?: (() => void | Promise<void>) | undefined;\n /** Maximum reconciliation time before reconnecting. Defaults to 15s. */\n beforeLiveTimeoutMs?: number;\n /** Maximum time without any SSE bytes before reconnecting. Defaults to 45s. */\n heartbeatTimeoutMs?: number;\n onStateChange?: (state: StreamConnectionState) => void;\n};\n\n/**\n * Stream a session's events with exactly-once, in-order delivery.\n *\n * Guarantees, anchored on the per-session contiguous `sequence`:\n * - **No duplicates**: events at or below the cursor are dropped, so server\n * replay overlap and reconnect overlap never re-yield.\n * - **No gaps**: each reconnect resumes from the last seen sequence, and a\n * gap observed inside one connection is backfilled from the durable replay\n * endpoint before the newer event is yielded (events are durable before\n * they are published live, so the backfill always finds them).\n * - **Ordered**: sequences are yielded strictly ascending.\n *\n * The generator ends when `signal` aborts, when the server closes and\n * `reconnect` is false, or with an error for non-retryable failures.\n */\nexport async function* streamSessionEvents(\n transport: SessionEventStreamTransport,\n options: StreamSessionEventsOptions = {},\n): AsyncGenerator<SessionEvent, void, void> {\n const signal = options.signal;\n const reconnect = options.reconnect ?? true;\n const baseDelayMs = options.reconnectDelayMs ?? 500;\n const maxDelayMs = options.maxReconnectDelayMs ?? 10_000;\n const jitterRatio = options.reconnectJitterRatio ?? 0.2;\n const beforeLiveTimeoutMs = options.beforeLiveTimeoutMs ?? 15_000;\n const heartbeatTimeoutMs = options.heartbeatTimeoutMs ?? 45_000;\n const maxAttempts = options.maxReconnectAttempts ?? Number.POSITIVE_INFINITY;\n let cursor = options.after ?? 0;\n let failedAttempts = 0;\n let delayMs = baseDelayMs;\n let everConnected = false;\n\n while (true) {\n if (signal?.aborted) break;\n options.onStateChange?.(everConnected || failedAttempts > 0 ? \"reconnecting\" : \"connecting\");\n const cursorAtOpen = cursor;\n try {\n const body = await transport.openStream(cursor, signal);\n everConnected = true;\n failedAttempts = 0;\n delayMs = baseDelayMs;\n try {\n options.onOpen?.();\n } catch {\n // A notification observer cannot own or interrupt the event transport.\n }\n await runBeforeLive(options.beforeLive, beforeLiveTimeoutMs, signal);\n options.onStateChange?.(\"live\");\n for await (const message of parseSseStream(\n withStreamInactivityTimeout(body, heartbeatTimeoutMs, signal),\n )) {\n // Re-check after every yield resumption: an abort from the consumer\n // must not let already-buffered events keep flowing.\n if (signal?.aborted) {\n return;\n }\n const event = parseSessionEvent(message.data);\n if (!event) {\n continue;\n }\n const coveredSequence = trustedSseSequence(message.id, event.sequence);\n markSessionEventStreamCoverage(event, coveredSequence);\n if (coveredSequence <= cursor) continue;\n if (event.sequence > cursor + 1) {\n for await (const missed of backfillEvents(transport, cursor, event.sequence - 1)) {\n cursor = missed.sequence;\n yield missed;\n if (signal?.aborted) {\n return;\n }\n }\n }\n cursor = coveredSequence;\n yield event;\n }\n if (!reconnect) {\n return;\n }\n // Clean server close: reconnect immediately when the connection made\n // progress (servers legitimately cycle long SSE connections); pace\n // empty closes so a misbehaving server is not hammered in a hot loop.\n if (cursor === cursorAtOpen) {\n await sleep(jitteredDelay(baseDelayMs, jitterRatio), signal);\n }\n continue;\n } catch (error) {\n if (signal?.aborted || isAbortError(error)) {\n return;\n }\n if (!reconnect || !isRetryableStreamError(error)) {\n throw error;\n }\n failedAttempts += 1;\n if (failedAttempts > maxAttempts) {\n throw new OpenGeniStreamError(\n `event stream gave up after ${maxAttempts} consecutive failed reconnect attempts: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n await sleep(jitteredDelay(delayMs, jitterRatio), signal);\n delayMs = Math.min(Math.max(delayMs * 2, baseDelayMs), maxDelayMs);\n }\n}\n\nexport async function runBeforeLive(\n beforeLive: (() => void | Promise<void>) | undefined,\n timeoutMs: number,\n signal: AbortSignal | undefined,\n): Promise<void> {\n if (!beforeLive) return;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let abortListener: (() => void) | undefined;\n const timeout = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(\n () => reject(new TypeError(`stream reconciliation timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n if (signal) {\n abortListener = () => reject(new DOMException(\"Aborted\", \"AbortError\"));\n signal.addEventListener(\"abort\", abortListener, { once: true });\n }\n });\n try {\n await Promise.race([Promise.resolve().then(beforeLive), timeout]);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n if (signal && abortListener) signal.removeEventListener(\"abort\", abortListener);\n }\n}\n\nexport function jitteredDelay(delayMs: number, ratio: number): number {\n if (delayMs <= 0 || ratio <= 0) return delayMs;\n const boundedRatio = Math.min(ratio, 1);\n const spread = delayMs * boundedRatio;\n return Math.max(0, delayMs - spread + Math.random() * spread * 2);\n}\n\nexport function withStreamInactivityTimeout(\n stream: ReadableStream<Uint8Array>,\n timeoutMs: number,\n signal: AbortSignal | undefined,\n): ReadableStream<Uint8Array> {\n if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0) {\n throw new RangeError(\"stream heartbeat timeout must be a positive safe integer\");\n }\n const reader = stream.getReader();\n return new ReadableStream<Uint8Array>({\n pull: async (controller) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n let abortListener: (() => void) | undefined;\n try {\n const result = await Promise.race([\n reader.read(),\n new Promise<never>((_resolve, reject) => {\n timer = setTimeout(\n () => reject(new TypeError(`event stream heartbeat timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n if (signal) {\n abortListener = () => reject(new DOMException(\"Aborted\", \"AbortError\"));\n signal.addEventListener(\"abort\", abortListener, { once: true });\n }\n }),\n ]);\n if (result.done) controller.close();\n else controller.enqueue(result.value);\n } catch (error) {\n void reader.cancel(error).catch(() => {});\n controller.error(error);\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n if (signal && abortListener) signal.removeEventListener(\"abort\", abortListener);\n }\n },\n cancel: (reason) => {\n // Do not wait for the underlying body: it may settle cancel() only after\n // its request aborts (see parseSseStream).\n void reader.cancel(reason).catch(() => {});\n },\n });\n}\n\n/**\n * Yield the durable events with `fromExclusive < sequence <= toInclusive`,\n * in order. Sequences are contiguous, so every one of them must exist in the\n * replay endpoint; if any is missing the function throws instead of skipping\n * it — continuing would silently break the gap-free delivery guarantee.\n */\nasync function* backfillEvents(\n transport: SessionEventStreamTransport,\n fromExclusive: number,\n toInclusive: number,\n): AsyncGenerator<SessionEvent, void, void> {\n let cursor = fromExclusive;\n while (cursor < toInclusive) {\n const page = await transport.listEvents(cursor, Math.min(500, toInclusive - cursor));\n const advancing = page\n .filter((event) => event.sequence > cursor && event.sequence <= toInclusive)\n .sort((a, b) => a.sequence - b.sequence);\n if (advancing.length === 0) {\n throw new OpenGeniStreamError(\n `event replay backfill stalled: expected sequences ${cursor + 1}..${toInclusive} but the replay endpoint returned none of them`,\n );\n }\n for (const event of advancing) {\n if (event.sequence !== cursor + 1) {\n throw new OpenGeniStreamError(\n `event replay backfill is missing sequence ${cursor + 1} (replay endpoint skipped to ${event.sequence}); refusing to deliver with a gap`,\n );\n }\n cursor = event.sequence;\n yield event;\n }\n }\n}\n\nfunction parseSessionEvent(data: string): SessionEvent | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch {\n return null;\n }\n if (\n typeof parsed !== \"object\" ||\n parsed === null ||\n typeof (parsed as { sequence?: unknown }).sequence !== \"number\" ||\n typeof (parsed as { type?: unknown }).type !== \"string\" ||\n typeof (parsed as { id?: unknown }).id !== \"string\"\n ) {\n return null;\n }\n return parsed as SessionEvent;\n}\n\n/** Trusted SSE coverage attached non-enumerably to a streamed event. */\nexport function sessionEventStreamCoveredThrough(event: SessionEvent): number | null {\n const covered = (event as SessionEvent & { [SESSION_EVENT_STREAM_COVERAGE]?: unknown })[\n SESSION_EVENT_STREAM_COVERAGE\n ];\n return typeof covered === \"number\" && Number.isSafeInteger(covered) && covered >= event.sequence\n ? covered\n : null;\n}\n\nfunction trustedSseSequence(id: string | undefined, sequence: number): number {\n if (id === undefined || !/^\\d+$/.test(id)) return sequence;\n const covered = Number(id);\n return Number.isSafeInteger(covered) && covered >= sequence ? covered : sequence;\n}\n\nfunction markSessionEventStreamCoverage(event: SessionEvent, covered: number): void {\n Object.defineProperty(event, SESSION_EVENT_STREAM_COVERAGE, {\n value: covered,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n}\n\nasync function sleep(delayMs: number, signal: AbortSignal | undefined): Promise<void> {\n if (signal?.aborted || delayMs <= 0) {\n return;\n }\n await new Promise<void>((resolve) => {\n const timer = setTimeout(done, delayMs);\n function done(): void {\n clearTimeout(timer);\n signal?.removeEventListener(\"abort\", done);\n resolve();\n }\n signal?.addEventListener(\"abort\", done, { once: true });\n });\n}\n"],"mappings":"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","names":[]}