@opengeni/sdk 0.52.1 → 1.0.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 (300) hide show
  1. package/README.md +1078 -33
  2. package/dist/accounts.d.ts +153 -0
  3. package/dist/accounts.js +307 -0
  4. package/dist/accounts.js.map +1 -0
  5. package/dist/adapters/express.d.ts +31 -0
  6. package/dist/adapters/express.js +87 -0
  7. package/dist/adapters/express.js.map +1 -0
  8. package/dist/adapters/hono.d.ts +16 -0
  9. package/dist/adapters/hono.js +8 -0
  10. package/dist/adapters/hono.js.map +1 -0
  11. package/dist/adapters/next.d.ts +29 -0
  12. package/dist/adapters/next.js +22 -0
  13. package/dist/adapters/next.js.map +1 -0
  14. package/dist/allowance-refusal.d.ts +2 -0
  15. package/dist/allowance-refusal.js +50 -0
  16. package/dist/allowance-refusal.js.map +1 -0
  17. package/dist/artifact-catalog.d.ts +31 -0
  18. package/dist/artifact-client.d.ts +23 -11
  19. package/dist/artifacts.d.ts +1 -1
  20. package/dist/artifacts.js +7 -5
  21. package/dist/automations-client.d.ts +17 -0
  22. package/dist/automations.d.ts +3 -0
  23. package/dist/automations.js +84 -0
  24. package/dist/automations.js.map +1 -0
  25. package/dist/browser.d.ts +11 -0
  26. package/dist/browser.js +47 -0
  27. package/dist/browser.js.map +1 -0
  28. package/dist/chat/fold.d.ts +75 -0
  29. package/dist/chat/handler.d.ts +41 -0
  30. package/dist/chat/http.d.ts +67 -0
  31. package/dist/chat/ids.d.ts +34 -0
  32. package/dist/chat/index.d.ts +9 -0
  33. package/dist/chat/index.js +1694 -0
  34. package/dist/chat/index.js.map +1 -0
  35. package/dist/chat/openai.d.ts +30 -0
  36. package/dist/chat/opengeni.d.ts +128 -0
  37. package/dist/chat/types.d.ts +207 -0
  38. package/dist/chat/vercel.d.ts +49 -0
  39. package/dist/chats.d.ts +8 -0
  40. package/dist/{chunk-KIHGPM7H.js → chunk-2UXZUCEZ.js} +309 -46
  41. package/dist/chunk-2UXZUCEZ.js.map +1 -0
  42. package/dist/chunk-4SMEOV3P.js +246 -0
  43. package/dist/chunk-4SMEOV3P.js.map +1 -0
  44. package/dist/{chunk-FHI4DFIG.js → chunk-AH5D5Q5V.js} +31 -35
  45. package/dist/chunk-AH5D5Q5V.js.map +1 -0
  46. package/dist/chunk-APXVSSSY.js +301 -0
  47. package/dist/chunk-APXVSSSY.js.map +1 -0
  48. package/dist/chunk-DUVIYER4.js +639 -0
  49. package/dist/chunk-DUVIYER4.js.map +1 -0
  50. package/dist/{chunk-ILQZR5N6.js → chunk-FG3OO5LM.js} +3484 -750
  51. package/dist/chunk-FG3OO5LM.js.map +1 -0
  52. package/dist/chunk-GZYZT22T.js +260 -0
  53. package/dist/chunk-GZYZT22T.js.map +1 -0
  54. package/dist/chunk-HMGADJGZ.js +150 -0
  55. package/dist/chunk-HMGADJGZ.js.map +1 -0
  56. package/dist/{chunk-DXDL7EEW.js → chunk-KWADQ227.js} +198 -114
  57. package/dist/chunk-KWADQ227.js.map +1 -0
  58. package/dist/chunk-LY2K6ELJ.js +126 -0
  59. package/dist/chunk-LY2K6ELJ.js.map +1 -0
  60. package/dist/chunk-MOTJYIYL.js +340 -0
  61. package/dist/chunk-MOTJYIYL.js.map +1 -0
  62. package/dist/{chunk-MZWTWOX6.js → chunk-NC57YMUO.js} +447 -3
  63. package/dist/chunk-NC57YMUO.js.map +1 -0
  64. package/dist/chunk-RWKB6YZG.js +1270 -0
  65. package/dist/chunk-RWKB6YZG.js.map +1 -0
  66. package/dist/chunk-U6CV2SXO.js +195 -0
  67. package/dist/chunk-U6CV2SXO.js.map +1 -0
  68. package/dist/chunk-UM4ZXXJR.js +9 -0
  69. package/dist/chunk-UM4ZXXJR.js.map +1 -0
  70. package/dist/chunk-V6GIY62B.js +229 -0
  71. package/dist/chunk-V6GIY62B.js.map +1 -0
  72. package/dist/chunk-WU6GQG25.js +268 -0
  73. package/dist/chunk-WU6GQG25.js.map +1 -0
  74. package/dist/{chunk-VWE2QIVO.js → chunk-XNG7YGR3.js} +23 -6
  75. package/dist/chunk-XNG7YGR3.js.map +1 -0
  76. package/dist/{chunk-FRJFNDIR.js → chunk-YIKA2QT4.js} +37 -2
  77. package/dist/chunk-YIKA2QT4.js.map +1 -0
  78. package/dist/chunk-ZKPY6YAJ.js +135 -0
  79. package/dist/chunk-ZKPY6YAJ.js.map +1 -0
  80. package/dist/client.d.ts +843 -107
  81. package/dist/codex-realtime-controller.d.ts +6 -0
  82. package/dist/codex-realtime-controller.js +2 -2
  83. package/dist/codex-realtime-v3.d.ts +13 -2
  84. package/dist/company-brain.d.ts +22 -0
  85. package/dist/company-profile.d.ts +14 -1
  86. package/dist/core.d.ts +9 -3
  87. package/dist/core.js +28 -9
  88. package/dist/deprecation.d.ts +47 -0
  89. package/dist/desktop.d.ts +8 -0
  90. package/dist/document-authority-client.d.ts +51 -0
  91. package/dist/document-authority.d.ts +2 -0
  92. package/dist/document-authority.js +12 -0
  93. package/dist/document-authority.js.map +1 -0
  94. package/dist/editable-artifacts/browser-session.d.ts +7 -3
  95. package/dist/editable-artifacts/controller.d.ts +4 -1
  96. package/dist/editable-artifacts/errors.d.ts +1 -1
  97. package/dist/editable-artifacts/http-live-transport.d.ts +6 -2
  98. package/dist/editable-artifacts/index.d.ts +2 -0
  99. package/dist/editable-artifacts/open-failure.d.ts +9 -0
  100. package/dist/editable-artifacts/types.d.ts +6 -3
  101. package/dist/editable-artifacts/worker/kernel-adapter.d.ts +1 -1
  102. package/dist/editable-artifacts-worker.js +44 -17
  103. package/dist/editable-artifacts-worker.js.map +1 -1
  104. package/dist/editable-artifacts.js +243 -124
  105. package/dist/editable-artifacts.js.map +1 -1
  106. package/dist/embedding-client.d.ts +129 -0
  107. package/dist/errors.d.ts +36 -1
  108. package/dist/feedback.d.ts +23 -0
  109. package/dist/gateway-realtime-transport.d.ts +1 -0
  110. package/dist/gateway-realtime-transport.js +5 -3
  111. package/dist/github-repositories.d.ts +10 -0
  112. package/dist/github-repositories.js +36 -0
  113. package/dist/github-repositories.js.map +1 -0
  114. package/dist/index.d.ts +61 -12
  115. package/dist/index.js +277 -126
  116. package/dist/index.js.map +1 -1
  117. package/dist/interaction-revision-stream.d.ts +11 -0
  118. package/dist/interaction.d.ts +687 -5
  119. package/dist/interaction.js +32 -1
  120. package/dist/knowledge.d.ts +7 -0
  121. package/dist/knowledge.js +20 -0
  122. package/dist/knowledge.js.map +1 -0
  123. package/dist/message-links.d.ts +68 -0
  124. package/dist/model-context.d.ts +68 -0
  125. package/dist/model-display.d.ts +2 -0
  126. package/dist/model-display.js +15 -0
  127. package/dist/model-display.js.map +1 -0
  128. package/dist/model-picker-order.d.ts +1 -0
  129. package/dist/model-picker-order.js +10 -0
  130. package/dist/model-picker-order.js.map +1 -0
  131. package/dist/organization-integration-policy.d.ts +26 -0
  132. package/dist/organization-integration-policy.js +26 -0
  133. package/dist/organization-integration-policy.js.map +1 -0
  134. package/dist/organization-private-session-settings.d.ts +6 -0
  135. package/dist/organization-private-session-settings.js +22 -0
  136. package/dist/organization-private-session-settings.js.map +1 -0
  137. package/dist/organization-user-setup.d.ts +8 -0
  138. package/dist/organization-user-setup.js +16 -0
  139. package/dist/organization-user-setup.js.map +1 -0
  140. package/dist/pr-review-client.d.ts +16 -0
  141. package/dist/pr-review.d.ts +4 -0
  142. package/dist/pr-review.js +62 -0
  143. package/dist/pr-review.js.map +1 -0
  144. package/dist/preference-registry.d.ts +9 -1
  145. package/dist/proxy.d.ts +7 -5
  146. package/dist/realtime.d.ts +6 -4
  147. package/dist/realtime.js +10 -6
  148. package/dist/realtime.js.map +1 -1
  149. package/dist/retained-artifacts.d.ts +5 -1
  150. package/dist/session-history-import.d.ts +22 -0
  151. package/dist/session-history-import.js +36 -0
  152. package/dist/session-history-import.js.map +1 -0
  153. package/dist/session-list-entries.d.ts +1 -0
  154. package/dist/session-list-entries.js +7 -0
  155. package/dist/session-list-entries.js.map +1 -0
  156. package/dist/session-message-search.d.ts +53 -0
  157. package/dist/session-proxy-client.d.ts +24 -0
  158. package/dist/session-proxy.d.ts +245 -0
  159. package/dist/session-proxy.js +24 -0
  160. package/dist/session-proxy.js.map +1 -0
  161. package/dist/session-titles.d.ts +2 -0
  162. package/dist/site-browser-entry.d.ts +1 -0
  163. package/dist/site-browser-runtime.gen.d.ts +1 -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 +16 -0
  169. package/dist/site-tool-bridge.d.ts +44 -0
  170. package/dist/site.d.ts +101 -0
  171. package/dist/site.js +49 -0
  172. package/dist/site.js.map +1 -0
  173. package/dist/skills.d.ts +75 -0
  174. package/dist/stream.d.ts +2 -0
  175. package/dist/tenant-workspaces.d.ts +47 -0
  176. package/dist/tenant-workspaces.js +8 -0
  177. package/dist/tenant-workspaces.js.map +1 -0
  178. package/dist/tool-auth.d.ts +87 -0
  179. package/dist/tool-auth.js +23 -0
  180. package/dist/tool-auth.js.map +1 -0
  181. package/dist/tool-display-metadata.d.ts +3 -0
  182. package/dist/tools-FXBLUWAE.js +12 -0
  183. package/dist/tools-FXBLUWAE.js.map +1 -0
  184. package/dist/tools.d.ts +61 -0
  185. package/dist/types.d.ts +3048 -406
  186. package/dist/usage-allowances.d.ts +36 -0
  187. package/dist/usage-allowances.js +80 -0
  188. package/dist/usage-allowances.js.map +1 -0
  189. package/dist/workspace-artifacts.d.ts +33 -5
  190. package/dist/workspace-instruction-policies.d.ts +24 -2
  191. package/dist/workspace-integrations.d.ts +74 -0
  192. package/dist/workspace-integrations.js +65 -0
  193. package/dist/workspace-integrations.js.map +1 -0
  194. package/dist/workspace-learning.d.ts +124 -0
  195. package/dist/workspace-live-stream.d.ts +14 -0
  196. package/dist/workspace-state.d.ts +8 -71
  197. package/package.json +108 -3
  198. package/src/accounts.ts +443 -0
  199. package/src/adapters/express.ts +136 -0
  200. package/src/adapters/hono.ts +18 -0
  201. package/src/adapters/next.ts +42 -0
  202. package/src/allowance-refusal.ts +5 -0
  203. package/src/artifact-catalog.ts +41 -0
  204. package/src/artifact-client.ts +43 -52
  205. package/src/artifacts.ts +7 -1
  206. package/src/automations-client.ts +124 -0
  207. package/src/automations.ts +15 -0
  208. package/src/browser.ts +54 -0
  209. package/src/chat/fold.ts +431 -0
  210. package/src/chat/handler.ts +240 -0
  211. package/src/chat/http.ts +257 -0
  212. package/src/chat/ids.ts +85 -0
  213. package/src/chat/index.ts +87 -0
  214. package/src/chat/openai.ts +439 -0
  215. package/src/chat/opengeni.ts +722 -0
  216. package/src/chat/types.ts +219 -0
  217. package/src/chat/vercel.ts +204 -0
  218. package/src/chats.ts +16 -0
  219. package/src/client.ts +5162 -792
  220. package/src/codex-realtime-controller.ts +260 -12
  221. package/src/codex-realtime-lifecycle.ts +1 -0
  222. package/src/codex-realtime-v3.ts +162 -31
  223. package/src/codex-realtime.ts +1 -1
  224. package/src/company-brain.ts +59 -0
  225. package/src/company-profile.ts +17 -1
  226. package/src/core.ts +23 -1
  227. package/src/deprecation.ts +149 -0
  228. package/src/desktop.ts +11 -1
  229. package/src/document-authority-client.ts +219 -0
  230. package/src/document-authority.ts +17 -0
  231. package/src/editable-artifacts/browser-session.ts +36 -22
  232. package/src/editable-artifacts/controller.ts +102 -47
  233. package/src/editable-artifacts/errors.ts +2 -0
  234. package/src/editable-artifacts/http-live-transport.ts +62 -37
  235. package/src/editable-artifacts/index.ts +6 -0
  236. package/src/editable-artifacts/open-failure.ts +79 -0
  237. package/src/editable-artifacts/storage.ts +31 -40
  238. package/src/editable-artifacts/types.ts +6 -3
  239. package/src/editable-artifacts/worker/kernel-adapter.ts +23 -7
  240. package/src/editable-artifacts/worker/runtime.ts +26 -13
  241. package/src/editable-artifacts/worker/wire-codec.ts +23 -5
  242. package/src/embedding-client.ts +519 -0
  243. package/src/errors.ts +185 -4
  244. package/src/feedback.ts +20 -0
  245. package/src/gateway-realtime-transport.ts +253 -110
  246. package/src/github-repositories.ts +60 -0
  247. package/src/index.ts +603 -54
  248. package/src/interaction-revision-stream.ts +117 -0
  249. package/src/interaction.ts +1367 -51
  250. package/src/knowledge.ts +72 -0
  251. package/src/message-links.ts +178 -0
  252. package/src/model-context.ts +112 -0
  253. package/src/model-display.ts +10 -0
  254. package/src/model-picker-order.ts +6 -0
  255. package/src/organization-integration-policy.ts +54 -0
  256. package/src/organization-private-session-settings.ts +33 -0
  257. package/src/organization-user-setup.ts +31 -0
  258. package/src/pr-review-client.ts +92 -0
  259. package/src/pr-review.ts +17 -0
  260. package/src/preference-registry.ts +11 -0
  261. package/src/proxy.ts +17 -6
  262. package/src/realtime.ts +15 -4
  263. package/src/retained-artifacts.ts +101 -0
  264. package/src/session-history-import.ts +84 -0
  265. package/src/session-list-entries.ts +1 -0
  266. package/src/session-message-search.ts +47 -0
  267. package/src/session-proxy-client.ts +64 -0
  268. package/src/session-proxy.ts +1473 -0
  269. package/src/session-titles.ts +10 -0
  270. package/src/site-browser-entry.ts +6 -0
  271. package/src/site-browser-runtime.gen.ts +2 -0
  272. package/src/site-document.test.ts +64 -0
  273. package/src/site-document.ts +18 -0
  274. package/src/site-http.ts +162 -0
  275. package/src/site-tool-bridge.ts +146 -0
  276. package/src/site.ts +585 -0
  277. package/src/skills.ts +69 -0
  278. package/src/sse.ts +8 -2
  279. package/src/stream.ts +38 -4
  280. package/src/tenant-workspaces.ts +148 -0
  281. package/src/tool-auth.ts +301 -0
  282. package/src/tool-display-metadata.ts +19 -0
  283. package/src/tools.ts +396 -0
  284. package/src/types.ts +3607 -493
  285. package/src/usage-allowances.ts +189 -0
  286. package/src/workspace-artifacts.ts +40 -6
  287. package/src/workspace-instruction-policies.ts +26 -1
  288. package/src/workspace-integrations.ts +402 -0
  289. package/src/workspace-learning.ts +138 -0
  290. package/src/workspace-live-stream.ts +137 -0
  291. package/src/workspace-state.ts +8 -82
  292. package/dist/chunk-DXDL7EEW.js.map +0 -1
  293. package/dist/chunk-FHI4DFIG.js.map +0 -1
  294. package/dist/chunk-FRJFNDIR.js.map +0 -1
  295. package/dist/chunk-ILQZR5N6.js.map +0 -1
  296. package/dist/chunk-KIHGPM7H.js.map +0 -1
  297. package/dist/chunk-MZWTWOX6.js.map +0 -1
  298. package/dist/chunk-V5F253OG.js +0 -116
  299. package/dist/chunk-V5F253OG.js.map +0 -1
  300. package/dist/chunk-VWE2QIVO.js.map +0 -1
package/src/proxy.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { OpenGeniClient } from "./client";
2
- import type { StreamSessionEventsOptions } from "./stream";
2
+ import { sessionEventStreamCoveredThrough, type StreamSessionEventsOptions } from "./stream";
3
3
  import type { SessionEvent } from "./types";
4
4
 
5
5
  /**
@@ -12,12 +12,22 @@ import type { SessionEvent } from "./types";
12
12
  * OpenGeni's own SSE stream (`id: <sequence>`, `event: <type>`,
13
13
  * `data: <event JSON>`), so the browser side can consume it with this same
14
14
  * SDK's streaming core (or a plain `EventSource`), including resume via
15
- * `?after=` / `Last-Event-ID`.
15
+ * `?after=` / `Last-Event-ID`. An ordinary event uses its own sequence as the
16
+ * SSE `id`; a compact event uses the server-owned sequence it covers through.
16
17
  */
17
18
 
18
- /** Format one event exactly as OpenGeni's API emits it over SSE. */
19
+ /** Format one event with the exact OpenGeni data and resume-cursor semantics. */
19
20
  export function formatSseEvent(event: SessionEvent): string {
20
- return `id: ${event.sequence}\nevent: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`;
21
+ const streamedCoverage = sessionEventStreamCoveredThrough(event);
22
+ const projectedCoverage = event.coveredThrough;
23
+ const coveredThrough =
24
+ streamedCoverage ??
25
+ (typeof projectedCoverage === "number" &&
26
+ Number.isSafeInteger(projectedCoverage) &&
27
+ projectedCoverage >= event.sequence
28
+ ? projectedCoverage
29
+ : event.sequence);
30
+ return `id: ${coveredThrough}\nevent: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`;
21
31
  }
22
32
 
23
33
  export type SseReStreamOptions = {
@@ -115,8 +125,9 @@ export function sessionEventsToSseResponse(
115
125
 
116
126
  /**
117
127
  * Read the resume cursor a reconnecting SSE client sent: the `after` query
118
- * parameter, or the standard `Last-Event-ID` header (the re-emitted stream
119
- * sets `id:` to the sequence). Returns 0 (full replay) when absent.
128
+ * parameter, or the standard `Last-Event-ID` header. Re-emitted streams set
129
+ * `id:` to the event sequence for ordinary events and the covered high-water
130
+ * sequence for compact events. Returns 0 (full replay) when absent.
120
131
  */
121
132
  export function resumeSequenceFromRequest(request: Request): number {
122
133
  const url = new URL(request.url);
package/src/realtime.ts CHANGED
@@ -20,17 +20,21 @@ import {
20
20
  type CreateCodexRealtimeControllerOptions,
21
21
  type RealtimeControllerTransportStarter,
22
22
  } from "./codex-realtime-controller";
23
- import { createGatewayRealtimeTransportStarter } from "./gateway-realtime-transport";
23
+ import {
24
+ createGatewayRealtimeTransportStarter,
25
+ createXaiSubscriptionRealtimeTransportStarter,
26
+ } from "./gateway-realtime-transport";
24
27
  import type { SessionRealtimeModel, WorkspaceRealtimeModelCatalogResponse } from "./types";
25
28
 
26
29
  /** Exact backend-facing methods required by the batteries-included realtime SDK. */
27
30
  export type SessionRealtimeClientLike = CodexRealtimeControllerClient & {
28
31
  getWorkspaceRealtimeModelCatalog(
29
32
  workspaceId: string,
33
+ options?: { signal?: AbortSignal | undefined },
30
34
  ): Promise<WorkspaceRealtimeModelCatalogResponse>;
31
35
  };
32
36
 
33
- export type SessionRealtimeTransportKind = "codex" | "gateway";
37
+ export type SessionRealtimeTransportKind = "codex" | "gateway" | "xai-subscription";
34
38
 
35
39
  /** Provider-neutral names for the existing, battle-tested controller projection. */
36
40
  export type SessionRealtimeController = CodexRealtimeController;
@@ -53,7 +57,9 @@ export type CreateSessionRealtimeControllerOptions = Omit<
53
57
  export function sessionRealtimeTransportKind(
54
58
  model: SessionRealtimeModel,
55
59
  ): SessionRealtimeTransportKind {
56
- return model === "gpt-live-1-boulder-alpha" ? "codex" : "gateway";
60
+ if (model === "gpt-live-1-boulder-alpha") return "codex";
61
+ if (model === "supergrok/grok-voice-think-fast-2.0") return "xai-subscription";
62
+ return "gateway";
57
63
  }
58
64
 
59
65
  /**
@@ -68,13 +74,18 @@ export function createSessionRealtimeController(
68
74
  return createCodexRealtimeController({
69
75
  ...options,
70
76
  ownerStorageNamespace: sessionRealtimeOwnerStorageNamespace(options.model),
71
- ...(transport === "gateway" ? { startTransport: createGatewayRealtimeTransportStarter() } : {}),
77
+ ...(transport === "gateway"
78
+ ? { startTransport: createGatewayRealtimeTransportStarter() }
79
+ : transport === "xai-subscription"
80
+ ? { startTransport: createXaiSubscriptionRealtimeTransportStarter() }
81
+ : {}),
72
82
  });
73
83
  }
74
84
 
75
85
  export {
76
86
  createCodexRealtimeController,
77
87
  createGatewayRealtimeTransportStarter,
88
+ createXaiSubscriptionRealtimeTransportStarter,
78
89
  hasStoredSessionRealtimeOwnerProof,
79
90
  sessionRealtimeOwnerStorageKey,
80
91
  sessionRealtimeOwnerStorageNamespace,
@@ -3,6 +3,7 @@ import type {
3
3
  GeneratedVideoReceipt,
4
4
  MediaGenerationResult,
5
5
  RetainedArtifactReference,
6
+ SandboxFileArtifactReceipt,
6
7
  } from "./types";
7
8
 
8
9
  const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
@@ -15,6 +16,94 @@ const MAX_VIDEO_BYTES = 512 * 1024 * 1024;
15
16
  const MAX_DIMENSION = 16_384;
16
17
  const MAX_PIXELS = 67_108_864;
17
18
  const MAX_RANGE_BYTES = 1024 * 1024;
19
+ const MAX_SANDBOX_FILE_BYTES = 25 * 1024 * 1024 - 1;
20
+
21
+ /** Zero-dependency validation for a permanent generic workspace-file receipt. */
22
+ export function parseRetainedWorkspaceFileReference(
23
+ value: unknown,
24
+ expectedWorkspaceId?: string,
25
+ ): RetainedArtifactReference | null {
26
+ if (!recordWithKeys(value, WORKSPACE_FILE_REFERENCE_KEYS)) return null;
27
+ const artifact = value as Record<string, unknown>;
28
+ if (
29
+ artifact.available !== true ||
30
+ artifact.kind !== "file" ||
31
+ typeof artifact.artifactId !== "string" ||
32
+ !UUID.test(artifact.artifactId) ||
33
+ typeof artifact.contentType !== "string" ||
34
+ !/^[a-z0-9][a-z0-9!#$&^_.+-]{0,62}\/[a-z0-9][a-z0-9!#$&^_.+-]{0,62}$/.test(
35
+ artifact.contentType,
36
+ ) ||
37
+ !safeIntegerBetween(artifact.originalBytes, 1, MAX_SANDBOX_FILE_BYTES) ||
38
+ typeof artifact.sha256 !== "string" ||
39
+ !SHA256.test(artifact.sha256) ||
40
+ typeof artifact.retainedAt !== "string" ||
41
+ artifact.retainedAt.length > 64 ||
42
+ !ISO_DATETIME_WITH_OFFSET.test(artifact.retainedAt) ||
43
+ !Number.isFinite(Date.parse(artifact.retainedAt)) ||
44
+ !recordWithKeys(artifact.retention, RETENTION_KEYS) ||
45
+ !recordWithKeys(artifact.retrieval, RETRIEVAL_KEYS)
46
+ ) {
47
+ return null;
48
+ }
49
+ const retention = artifact.retention as Record<string, unknown>;
50
+ if (retention.policy !== "workspace_file" || retention.expiresAt !== null) return null;
51
+ const retrieval = artifact.retrieval as Record<string, unknown>;
52
+ if (
53
+ retrieval.method !== "GET" ||
54
+ retrieval.acceptRanges !== "bytes" ||
55
+ retrieval.maxRangeBytes !== MAX_RANGE_BYTES ||
56
+ typeof retrieval.path !== "string" ||
57
+ retrieval.path.length > 256
58
+ ) {
59
+ return null;
60
+ }
61
+ const match = WORKSPACE_PATH.exec(retrieval.path);
62
+ if (
63
+ !match ||
64
+ !UUID.test(match[1] ?? "") ||
65
+ match[2] !== artifact.artifactId ||
66
+ (expectedWorkspaceId !== undefined && match[1] !== expectedWorkspaceId)
67
+ ) {
68
+ return null;
69
+ }
70
+ return value as RetainedArtifactReference;
71
+ }
72
+
73
+ /** Parse the closed result returned by sandbox_file_publish and the session API. */
74
+ export function parseSandboxFileArtifactReceipt(
75
+ value: unknown,
76
+ expectedWorkspaceId?: string,
77
+ ): SandboxFileArtifactReceipt | null {
78
+ if (typeof value === "string" && value.length <= 8_192) {
79
+ try {
80
+ return parseSandboxFileArtifactReceipt(JSON.parse(value), expectedWorkspaceId);
81
+ } catch {
82
+ return null;
83
+ }
84
+ }
85
+ if (!recordWithKeys(value, SANDBOX_FILE_RECEIPT_KEYS)) return null;
86
+ const artifact = parseRetainedWorkspaceFileReference(value.artifact, expectedWorkspaceId);
87
+ const pathSegments = typeof value.sandboxPath === "string" ? value.sandboxPath.split("/") : [];
88
+ if (
89
+ value.type !== "sandbox_file" ||
90
+ typeof value.sandboxPath !== "string" ||
91
+ !value.sandboxPath.startsWith("/workspace/") ||
92
+ value.sandboxPath.length > 4_096 ||
93
+ value.sandboxPath.includes("\0") ||
94
+ pathSegments.some(
95
+ (segment, index) => index > 1 && (!segment || segment === "." || segment === ".."),
96
+ ) ||
97
+ typeof value.filename !== "string" ||
98
+ value.filename.length < 1 ||
99
+ value.filename.length > 1_024 ||
100
+ pathSegments.at(-1) !== value.filename ||
101
+ !artifact
102
+ ) {
103
+ return null;
104
+ }
105
+ return value as SandboxFileArtifactReceipt;
106
+ }
18
107
 
19
108
  /** Zero-dependency validation for the SDK's permanent generated-image wire receipt. */
20
109
  export function parseRetainedGeneratedImageReference(
@@ -272,10 +361,22 @@ const GENERATED_IMAGE_REFERENCE_KEYS = new Set([
272
361
  "retention",
273
362
  "retrieval",
274
363
  ]);
364
+ const WORKSPACE_FILE_REFERENCE_KEYS = new Set([
365
+ "available",
366
+ "artifactId",
367
+ "kind",
368
+ "contentType",
369
+ "originalBytes",
370
+ "sha256",
371
+ "retainedAt",
372
+ "retention",
373
+ "retrieval",
374
+ ]);
275
375
  const DIMENSION_KEYS = new Set(["width", "height"]);
276
376
  const RETENTION_KEYS = new Set(["policy", "expiresAt"]);
277
377
  const RETRIEVAL_KEYS = new Set(["method", "path", "acceptRanges", "maxRangeBytes"]);
278
378
  const GENERATED_IMAGE_RECEIPT_KEYS = new Set(["type", "artifact", "sandboxPath"]);
379
+ const SANDBOX_FILE_RECEIPT_KEYS = new Set(["type", "sandboxPath", "filename", "artifact"]);
279
380
  const GENERATED_VIDEO_RECEIPT_KEYS = new Set([
280
381
  "type",
281
382
  "schemaVersion",
@@ -0,0 +1,84 @@
1
+ import type { OpenGeniClient } from "./client";
2
+ import type {
3
+ AppendArchivedSessionEventsRequest,
4
+ AppendArchivedSessionEventsResponse,
5
+ ImportArchivedSessionRequest,
6
+ ImportArchivedSessionResponse,
7
+ } from "@opengeni/contracts";
8
+
9
+ export type {
10
+ ArchivedSessionImportEvent,
11
+ AppendArchivedSessionEventsRequest,
12
+ AppendArchivedSessionEventsResponse,
13
+ ImportArchivedSessionRequest,
14
+ ImportArchivedSessionResponse,
15
+ SessionImportedArchive,
16
+ } from "@opengeni/contracts";
17
+
18
+ type SessionHistoryImportClient = Pick<OpenGeniClient, "requestJson">;
19
+
20
+ /**
21
+ * Server-only migration of a read-only archive, not model-facing conversation
22
+ * history. Use an asUser client to preserve the verified creator/owner. Persist
23
+ * importId and retry the exact request after an uncertain outcome.
24
+ * Requires sessions:create in the authenticated actor's permissions.
25
+ */
26
+ export function importArchivedSession(
27
+ client: SessionHistoryImportClient,
28
+ workspaceId: string,
29
+ request: ImportArchivedSessionRequest,
30
+ ): Promise<ImportArchivedSessionResponse> {
31
+ return client.requestJson(
32
+ "POST",
33
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/session-imports`,
34
+ request,
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Append historical events at the acknowledged nextOffset. Retrying the exact
40
+ * batchId, offset and events replays its receipt; conflicting reuse returns 409.
41
+ * Each request accepts at most 100 events / 1 MiB, with 256 KiB per event.
42
+ * Requires sessions:control and the same authenticated importer.
43
+ */
44
+ export function appendArchivedSessionEvents(
45
+ client: SessionHistoryImportClient,
46
+ workspaceId: string,
47
+ importId: string,
48
+ request: AppendArchivedSessionEventsRequest,
49
+ ): Promise<AppendArchivedSessionEventsResponse> {
50
+ return client.requestJson(
51
+ "POST",
52
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/session-imports/${encodeURIComponent(importId)}/events`,
53
+ request,
54
+ );
55
+ }
56
+
57
+ /** Import through an existing external tenant mapping; this does not onboard it. */
58
+ export function importExternalWorkspaceArchivedSession(
59
+ client: SessionHistoryImportClient,
60
+ source: string,
61
+ externalId: string,
62
+ request: ImportArchivedSessionRequest,
63
+ ): Promise<ImportArchivedSessionResponse> {
64
+ return client.requestJson(
65
+ "POST",
66
+ `/v1/workspaces/external/${encodeURIComponent(source)}/${encodeURIComponent(externalId)}/session-imports`,
67
+ request,
68
+ );
69
+ }
70
+
71
+ /** Append to an archive through the same external tenant mapping and actor. */
72
+ export function appendExternalWorkspaceArchivedSessionEvents(
73
+ client: SessionHistoryImportClient,
74
+ source: string,
75
+ externalId: string,
76
+ importId: string,
77
+ request: AppendArchivedSessionEventsRequest,
78
+ ): Promise<AppendArchivedSessionEventsResponse> {
79
+ return client.requestJson(
80
+ "POST",
81
+ `/v1/workspaces/external/${encodeURIComponent(source)}/${encodeURIComponent(externalId)}/session-imports/${encodeURIComponent(importId)}/events`,
82
+ request,
83
+ );
84
+ }
@@ -0,0 +1 @@
1
+ export { sessionListEntry } from "@opengeni/contracts/session-list-entries";
@@ -0,0 +1,47 @@
1
+ /** Literal Unicode case-insensitive substring. Whitespace is significant. */
2
+ export type SessionMessageSearchRequest = {
3
+ query: string;
4
+ sessionId?: string | undefined;
5
+ /** Workspace-only first hit per session; cannot combine with sessionId. */
6
+ groupBy?: "session" | undefined;
7
+ archiveStatus?: "active" | "archived" | "all" | undefined;
8
+ limit?: number | undefined;
9
+ cursor?: string | undefined;
10
+ };
11
+
12
+ export type SessionMessageSearchMatch = {
13
+ sessionId: string;
14
+ sessionTitle: string | null;
15
+ eventId: string;
16
+ sequence: number;
17
+ turnId: string | null;
18
+ role: "user" | "assistant";
19
+ messageId: string | null;
20
+ /** Zero-based UTF-16 offset in the complete visible message. */
21
+ messageMatchOffset: number;
22
+ /** Zero-based UTF-16 offsets in text; matchEnd is exclusive. */
23
+ snippet: { text: string; matchStart: number; matchEnd: number };
24
+ };
25
+
26
+ export type SessionMessageSearchResponse = {
27
+ matches: SessionMessageSearchMatch[];
28
+ nextCursor: string | null;
29
+ /** Empty advancing pages are valid. Continue until false. */
30
+ hasMore: boolean;
31
+ /** Cumulative distinct messages visited in this live traversal. */
32
+ scannedMessages: number;
33
+ /** Cumulative matching messages, or session representatives with groupBy=session. */
34
+ matchedMessageCount: number;
35
+ /** Cumulative occurrences, or session representatives with groupBy=session. */
36
+ matchedOccurrenceCount: number;
37
+ /** True only on exhaustion. Concurrent mutations require a fresh traversal. */
38
+ countIsExact: boolean;
39
+ };
40
+
41
+ /** Exact selected event reference from a search match; no payload fields are read. */
42
+ export type SessionMessagePreviewReference = { eventId: string; sequence: number };
43
+
44
+ /** A complete visible message, or an explicit over-12,000-UTF-16-unit result. */
45
+ export type SessionMessagePreview =
46
+ | { status: "available"; text: string }
47
+ | { status: "unavailable" };
@@ -0,0 +1,64 @@
1
+ import type { OpenGeniEmbeddingClient } from "./embedding-client";
2
+ import type { OpenGeniRequestOptions, FetchResponse } from "./client";
3
+ import type { AccessGrant } from "./types";
4
+
5
+ /** Maximum actual UTF-8 bytes forwarded for one embedded Site HTML response. */
6
+ export const SESSION_PROXY_SITE_HTML_MAX_BYTES = 25 * 1024 * 1024;
7
+
8
+ /** A streaming Site download exceeded the host proxy's actual-byte ceiling. */
9
+ export class SessionProxySiteHtmlTooLargeError extends Error {
10
+ readonly code = "site_html_too_large";
11
+ readonly limitBytes = SESSION_PROXY_SITE_HTML_MAX_BYTES;
12
+
13
+ constructor() {
14
+ super(`Site HTML exceeds the ${SESSION_PROXY_SITE_HTML_MAX_BYTES}-byte proxy limit.`);
15
+ this.name = "SessionProxySiteHtmlTooLargeError";
16
+ }
17
+ }
18
+
19
+ /** Server-only effective grant read; never derive external authority from access/me snapshots. */
20
+ export function getSessionProxyWorkspaceGrant(
21
+ client: Pick<OpenGeniEmbeddingClient, "requestJson">,
22
+ workspaceId: string,
23
+ options: OpenGeniRequestOptions = {},
24
+ ): Promise<AccessGrant> {
25
+ return client.requestJson(
26
+ "GET",
27
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/access/grant`,
28
+ undefined,
29
+ {},
30
+ options,
31
+ );
32
+ }
33
+
34
+ /** Exact association read. The API reauthorizes the source session on every call. */
35
+ export function getSessionProxyArtifactAssociation(
36
+ client: Pick<OpenGeniEmbeddingClient, "requestJson">,
37
+ workspaceId: string,
38
+ sessionId: string,
39
+ kind: "editable" | "site",
40
+ artifactId: string,
41
+ options: OpenGeniRequestOptions = {},
42
+ ): Promise<{ sessionId: string; artifactId: string; kind: "editable" | "site" }> {
43
+ return client.requestJson(
44
+ "GET",
45
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/sessions/${encodeURIComponent(sessionId)}/artifact-associations/${encodeURIComponent(artifactId)}`,
46
+ undefined,
47
+ { kind },
48
+ options,
49
+ );
50
+ }
51
+
52
+ /** Authenticated response stream for the server proxy; does not buffer Site HTML. */
53
+ export function downloadSessionProxySiteHtml(
54
+ client: Pick<OpenGeniEmbeddingClient, "requestJsonResponse">,
55
+ workspaceId: string,
56
+ artifactId: string,
57
+ options: { versionId: string; signal?: AbortSignal },
58
+ ): Promise<FetchResponse> {
59
+ return client.requestJsonResponse(
60
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/published-artifacts/${encodeURIComponent(artifactId)}/html`,
61
+ { versionId: options.versionId },
62
+ options,
63
+ );
64
+ }