@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,117 @@
1
+ // Opengeni web links that a native app (phone or desktop) can show itself, and
2
+ // the account each belongs to. Pure: no platform modules, so every app shares it.
3
+
4
+ /** A deployment address as typed: trimmed, https by default, no trailing slash. */
5
+ export function normalizeServerUrl(input: string): string | null {
6
+ const raw = input.trim();
7
+ if (!raw) return null;
8
+ const withScheme = /^[a-z][a-z0-9+.-]*:\/\//iu.test(raw) ? raw : `https://${raw}`;
9
+ const match = /^(https?):\/\/([a-z0-9.-]+(?::\d{1,5})?)(?:[/?#].*)?$/iu.exec(withScheme);
10
+ return match ? `${match[1]!.toLowerCase()}://${match[2]!.toLowerCase()}` : null;
11
+ }
12
+
13
+ /** The host a person recognizes, e.g. app.opengeni.ai. */
14
+ export function serverLabel(baseUrl: string): string {
15
+ return baseUrl.replace(/^https?:\/\//iu, "");
16
+ }
17
+
18
+ /** The part of a signed-in app account that link routing reads. */
19
+ export interface AppLinkAccount {
20
+ id: string;
21
+ /** The deployment's web origin, e.g. https://app.opengeni.ai. */
22
+ baseUrl: string;
23
+ /** The workspace last used with this account. */
24
+ workspaceId: string | null;
25
+ /** Set when the deployment rejected the credential. */
26
+ signedOut?: boolean;
27
+ }
28
+
29
+ /**
30
+ * A web link the app can show itself: a conversation or a workspace on some
31
+ * deployment. Everything else on the web (settings, organization, artifacts)
32
+ * stays in the browser.
33
+ */
34
+ export interface AppLink {
35
+ /** The deployment's origin, normalized like a stored account's baseUrl. */
36
+ origin: string;
37
+ /** Absent for the web's workspace-less `/sessions/:id` links. */
38
+ workspaceId: string | null;
39
+ /** Absent for a link to the workspace itself. */
40
+ sessionId: string | null;
41
+ /** The session moment the link points at (`?at=`). */
42
+ at: number | null;
43
+ /** The web address the link came from, for the browser fallback. */
44
+ webUrl: string;
45
+ }
46
+
47
+ /** The app's own scheme for links handed over from the web: opengeni://open?url=… */
48
+ const HANDOFF = /^opengeni:\/\/open\/?\?(.*)$/iu;
49
+ const WEB_URL = /^(https?:\/\/[^/?#]+)(\/[^?#]*)?(\?[^#]*)?(#.*)?$/iu;
50
+ const ID = "([A-Za-z0-9][A-Za-z0-9_-]{0,127})";
51
+ const SESSION_PATH = new RegExp(`^/workspaces/${ID}/sessions/${ID}/?$`, "u");
52
+ const WORKSPACE_PATH = new RegExp(`^/workspaces/${ID}(?:/sessions)?/?$`, "u");
53
+ const BARE_SESSION_PATH = new RegExp(`^/sessions/${ID}/?$`, "u");
54
+
55
+ function queryParam(query: string | undefined, name: string): string | null {
56
+ for (const part of (query ?? "").replace(/^\?/u, "").split("&")) {
57
+ const [key, value = ""] = part.split("=");
58
+ if (key !== name) continue;
59
+ try {
60
+ return decodeURIComponent(value.replace(/\+/gu, " "));
61
+ } catch {
62
+ return null;
63
+ }
64
+ }
65
+ return null;
66
+ }
67
+
68
+ /** The web link a raw URL points at, unwrapping the web's "Open in app" handoff. */
69
+ export function parseAppLink(raw: string): AppLink | null {
70
+ const trimmed = raw.trim();
71
+ const handoff = HANDOFF.exec(trimmed);
72
+ const webUrl = handoff ? queryParam(handoff[1], "url") : trimmed;
73
+ if (!webUrl) return null;
74
+ const match = WEB_URL.exec(webUrl);
75
+ if (!match) return null;
76
+ const origin = normalizeServerUrl(match[1]!);
77
+ if (!origin) return null;
78
+ const path = match[2] ?? "/";
79
+ const atRaw = queryParam(match[3], "at");
80
+ const at = atRaw && /^[1-9][0-9]{0,15}$/u.test(atRaw) ? Number(atRaw) : null;
81
+ const session = SESSION_PATH.exec(path);
82
+ if (session) return { origin, workspaceId: session[1]!, sessionId: session[2]!, at, webUrl };
83
+ const bare = BARE_SESSION_PATH.exec(path);
84
+ if (bare) return { origin, workspaceId: null, sessionId: bare[1]!, at, webUrl };
85
+ const workspace = WORKSPACE_PATH.exec(path);
86
+ if (workspace) return { origin, workspaceId: workspace[1]!, sessionId: null, at: null, webUrl };
87
+ return null;
88
+ }
89
+
90
+ /**
91
+ * The signed-in account a link belongs to, or null when the app has none on
92
+ * that deployment (the browser opens it instead). With several accounts on the
93
+ * same deployment: the one last used in the link's workspace, else the active
94
+ * one, else the first.
95
+ */
96
+ export function accountForAppLink<Account extends AppLinkAccount>(
97
+ link: AppLink,
98
+ accounts: readonly Account[],
99
+ activeId: string | null,
100
+ ): Account | null {
101
+ const candidates = accounts.filter(
102
+ (account) => !account.signedOut && normalizeServerUrl(account.baseUrl) === link.origin,
103
+ );
104
+ return (
105
+ (link.workspaceId
106
+ ? candidates.find((account) => account.workspaceId === link.workspaceId)
107
+ : undefined) ??
108
+ candidates.find((account) => account.id === activeId) ??
109
+ candidates[0] ??
110
+ null
111
+ );
112
+ }
113
+
114
+ /** The web's handoff link that opens a web page in the app. */
115
+ export function appHandoffUrl(webUrl: string): string {
116
+ return `opengeni://open?url=${encodeURIComponent(webUrl)}`;
117
+ }
@@ -0,0 +1,51 @@
1
+ import type { RetainedArtifactReference } from "./types";
2
+
3
+ export type ArtifactCatalogKind =
4
+ | "site"
5
+ | "document"
6
+ | "spreadsheet"
7
+ | "presentation"
8
+ | "image"
9
+ | "file";
10
+
11
+ /** Native IDs are unique within a kind; use `${kind}:${id}` as a UI key. */
12
+ export type ArtifactCatalogItem = {
13
+ id: string;
14
+ kind: ArtifactCatalogKind;
15
+ title: string;
16
+ createdAt: string;
17
+ updatedAt: string;
18
+ status: "active" | "archived";
19
+ /** Shared workspace pin; absent on older servers. Never grants content access. */
20
+ pinned?: boolean;
21
+ /** Sites only: "private" when only its owner (the viewer) can see it. */
22
+ visibility?: "private" | "workspace";
23
+ /** Present only when the viewer can read this session. */
24
+ sourceSessionId?: string;
25
+ versionId?: string;
26
+ file?: RetainedArtifactReference;
27
+ filename?: string;
28
+ contentType?: string;
29
+ sizeBytes?: number;
30
+ };
31
+
32
+ export type ArtifactCatalogListOptions = {
33
+ sourceSessionId?: string;
34
+ q?: string;
35
+ kind?: ArtifactCatalogKind;
36
+ sort?: "updated" | "newest" | "title";
37
+ status?: "active" | "archived";
38
+ limit?: number;
39
+ cursor?: string;
40
+ };
41
+
42
+ export type ArtifactCatalogListResponse = {
43
+ items: ArtifactCatalogItem[];
44
+ nextCursor: string | null;
45
+ };
46
+
47
+ export type ArtifactPinResponse = {
48
+ kind: ArtifactCatalogKind;
49
+ artifactId: string;
50
+ pinned: boolean;
51
+ };
@@ -1,4 +1,13 @@
1
1
  import { OpenGeniDocumentAuthorityClient } from "./document-authority-client";
2
+ import type { FetchResponse } from "./client";
3
+ import type { SiteToolCallRequest } from "./site-tool-bridge";
4
+ import type { ToolGatewayCallResponse } from "./types";
5
+ import type {
6
+ CreateWorkspaceArtifactRequest,
7
+ PublishWorkspaceArtifactVersionRequest,
8
+ WorkspaceArtifactContentResponse,
9
+ WorkspaceArtifactMutationResponse,
10
+ } from "./workspace-artifacts";
2
11
  import type {
3
12
  CreateEditableArtifactMaterializationRequest,
4
13
  CreateEditableArtifactResourceRequest,
@@ -12,16 +21,6 @@ import type {
12
21
  ReadEditableArtifactMaterializationOptions,
13
22
  ReadEditableArtifactResourceOptions,
14
23
  } from "./editable-artifact-resources";
15
- import type {
16
- CreateWorkspaceArtifactRequest,
17
- PublishWorkspaceArtifactVersionRequest,
18
- RollbackWorkspaceArtifactRequest,
19
- WorkspaceArtifactContentResponse,
20
- WorkspaceArtifactDetailResponse,
21
- WorkspaceArtifactListOptions,
22
- WorkspaceArtifactListResponse,
23
- WorkspaceArtifactMutationResponse,
24
- } from "./workspace-artifacts";
25
24
 
26
25
  /** Public SDK client. Optional operator and artifact operations stay out of the console core. */
27
26
  export class OpenGeniClient extends OpenGeniDocumentAuthorityClient {
@@ -132,7 +131,7 @@ export class OpenGeniClient extends OpenGeniDocumentAuthorityClient {
132
131
  artifactId: string,
133
132
  jobId: string,
134
133
  options: ReadEditableArtifactMaterializationOptions,
135
- ): Promise<Response> {
134
+ ): Promise<FetchResponse> {
136
135
  return await this.requestResponse(
137
136
  "GET",
138
137
  `/v1/workspaces/${encodeURIComponent(workspaceId)}/editable-artifacts/${encodeURIComponent(artifactId)}/materializations/${encodeURIComponent(jobId)}/download`,
@@ -140,51 +139,52 @@ export class OpenGeniClient extends OpenGeniDocumentAuthorityClient {
140
139
  options,
141
140
  );
142
141
  }
143
-
144
- async listWorkspaceArtifacts(
145
- workspaceId: string,
146
- options: WorkspaceArtifactListOptions = {},
147
- ): Promise<WorkspaceArtifactListResponse> {
148
- const query = new URLSearchParams();
149
- if (options.limit !== undefined) query.set("limit", String(options.limit));
150
- if (options.cursor) query.set("cursor", options.cursor);
151
- const suffix = query.size > 0 ? `?${query.toString()}` : "";
152
- return await this.requestJson<WorkspaceArtifactListResponse>(
153
- "GET",
154
- `/v1/workspaces/${workspaceId}/published-artifacts${suffix}`,
155
- );
156
- }
157
-
158
- async getWorkspaceArtifact(
142
+ /** Exact Site-version gateway call. Keep this client on the authenticated host;
143
+ * the API enforces live viewer access and the version's declared tool allowlist. */
144
+ async callWorkspaceSiteTool(
159
145
  workspaceId: string,
160
- artifactId: string,
161
- ): Promise<WorkspaceArtifactDetailResponse> {
162
- return await this.requestJson<WorkspaceArtifactDetailResponse>(
163
- "GET",
164
- `/v1/workspaces/${workspaceId}/published-artifacts/${encodeURIComponent(artifactId)}`,
146
+ request: SiteToolCallRequest,
147
+ options: { signal?: AbortSignal } = {},
148
+ ): Promise<ToolGatewayCallResponse> {
149
+ return this.requestJson<ToolGatewayCallResponse>(
150
+ "POST",
151
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/tools/calls`,
152
+ request,
153
+ undefined,
154
+ options,
165
155
  );
166
156
  }
167
157
 
168
158
  async getWorkspaceArtifactContent(
169
159
  workspaceId: string,
170
160
  artifactId: string,
171
- versionId?: string,
161
+ versionOrOptions?: string | { versionId?: string; signal?: AbortSignal },
172
162
  ): Promise<WorkspaceArtifactContentResponse> {
173
- const query = versionId ? `?versionId=${encodeURIComponent(versionId)}` : "";
163
+ const options =
164
+ typeof versionOrOptions === "string"
165
+ ? { versionId: versionOrOptions }
166
+ : (versionOrOptions ?? {});
167
+ const query = options.versionId ? `?versionId=${encodeURIComponent(options.versionId)}` : "";
174
168
  return await this.requestJson<WorkspaceArtifactContentResponse>(
175
169
  "GET",
176
- `/v1/workspaces/${workspaceId}/published-artifacts/${encodeURIComponent(artifactId)}/content${query}`,
170
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/published-artifacts/${encodeURIComponent(artifactId)}/content${query}`,
171
+ undefined,
172
+ undefined,
173
+ options,
177
174
  );
178
175
  }
179
176
 
180
177
  async createWorkspaceArtifact(
181
178
  workspaceId: string,
182
179
  request: CreateWorkspaceArtifactRequest,
180
+ options: { signal?: AbortSignal } = {},
183
181
  ): Promise<WorkspaceArtifactMutationResponse> {
184
182
  return await this.requestJson<WorkspaceArtifactMutationResponse>(
185
183
  "POST",
186
- `/v1/workspaces/${workspaceId}/published-artifacts`,
184
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/published-artifacts`,
187
185
  request,
186
+ undefined,
187
+ options,
188
188
  );
189
189
  }
190
190
 
@@ -192,23 +192,14 @@ export class OpenGeniClient extends OpenGeniDocumentAuthorityClient {
192
192
  workspaceId: string,
193
193
  artifactId: string,
194
194
  request: PublishWorkspaceArtifactVersionRequest,
195
+ options: { signal?: AbortSignal } = {},
195
196
  ): Promise<WorkspaceArtifactMutationResponse> {
196
197
  return await this.requestJson<WorkspaceArtifactMutationResponse>(
197
198
  "POST",
198
- `/v1/workspaces/${workspaceId}/published-artifacts/${encodeURIComponent(artifactId)}/versions`,
199
- request,
200
- );
201
- }
202
-
203
- async rollbackWorkspaceArtifact(
204
- workspaceId: string,
205
- artifactId: string,
206
- request: RollbackWorkspaceArtifactRequest,
207
- ): Promise<WorkspaceArtifactMutationResponse> {
208
- return await this.requestJson<WorkspaceArtifactMutationResponse>(
209
- "POST",
210
- `/v1/workspaces/${workspaceId}/published-artifacts/${encodeURIComponent(artifactId)}/rollback`,
199
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/published-artifacts/${encodeURIComponent(artifactId)}/versions`,
211
200
  request,
201
+ undefined,
202
+ options,
212
203
  );
213
204
  }
214
205
  }
package/src/artifacts.ts CHANGED
@@ -16,6 +16,7 @@ export type {
16
16
  } from "./editable-artifact-resources";
17
17
  export type {
18
18
  FetchLike,
19
+ FetchResponse,
19
20
  GetSessionOptions,
20
21
  OpenGeniClientOptions,
21
22
  OpenGeniRequestOptions,
@@ -48,9 +48,12 @@ export class OpenGeniAutomationsClient {
48
48
  }
49
49
 
50
50
  async disableSource(workspaceId: string, sourceId: string): Promise<void> {
51
- await this.client.requestJson(
51
+ await this.client.requestJson<void>(
52
52
  "DELETE",
53
53
  `/v1/workspaces/${encodeURIComponent(workspaceId)}/automations/sources/${encodeURIComponent(sourceId)}`,
54
+ undefined,
55
+ {},
56
+ { responseType: "void" },
54
57
  );
55
58
  }
56
59
 
@@ -90,9 +93,12 @@ export class OpenGeniAutomationsClient {
90
93
  triggerId: string,
91
94
  expectedRevision: number,
92
95
  ): Promise<void> {
93
- await this.client.requestJson(
96
+ await this.client.requestJson<void>(
94
97
  "DELETE",
95
98
  `/v1/workspaces/${encodeURIComponent(workspaceId)}/automations/triggers/${encodeURIComponent(triggerId)}?expectedRevision=${expectedRevision}`,
99
+ undefined,
100
+ {},
101
+ { responseType: "void" },
96
102
  );
97
103
  }
98
104
 
@@ -0,0 +1,286 @@
1
+ import { startCodexRealtimeWebrtc, type StartCodexRealtimeWebrtcOptions } from "./codex-realtime";
2
+ import type { RealtimeControllerTransportStarter } from "./codex-realtime-controller";
3
+
4
+ type Envelope = Record<string, unknown>;
5
+ const MAX_FRAGMENT_BYTES = 64_000;
6
+
7
+ /** The most recent speech wins when the user talks for a long time between delegations. */
8
+ function takeUtf8Tail(text: string, maxBytes = MAX_FRAGMENT_BYTES): string {
9
+ const encoder = new TextEncoder();
10
+ if (encoder.encode(text).byteLength <= maxBytes) return text;
11
+ let tail = text.slice(-maxBytes);
12
+ while (encoder.encode(tail).byteLength > maxBytes) tail = tail.slice(1);
13
+ return tail;
14
+ }
15
+
16
+ /** Azure Live has timed transcript fragments, not provider-finalized turns. */
17
+ export class AzureLiveDataChannel extends EventTarget {
18
+ private pending: {
19
+ role: "user" | "assistant";
20
+ text: string;
21
+ startMs: number;
22
+ endMs: number;
23
+ } | null = null;
24
+ private timer: ReturnType<typeof setTimeout> | null = null;
25
+ private ordinal = 0;
26
+ private readonly prefix = crypto.randomUUID();
27
+ private closed = false;
28
+ private closeSent = false;
29
+ private providerClosed = false;
30
+ private readonly delegations = new Set<string>();
31
+ // Azure delegations carry no content, so the user's words since the previous
32
+ // delegation become the delegation input.
33
+ private userSinceDelegation = "";
34
+ private draining: Promise<void> | null = null;
35
+ private finishDrain: ((error?: Error) => void) | null = null;
36
+ private readonly onOpen = () => this.dispatchEvent(new Event("open"));
37
+ private readonly onClose = () => {
38
+ this.providerClosed = true;
39
+ this.flush();
40
+ this.finishDrain?.();
41
+ this.dispatchEvent(new Event("close"));
42
+ };
43
+ private readonly onError = () => this.dispatchEvent(new Event("error"));
44
+ private readonly onMessage = (event: MessageEvent) => {
45
+ if (typeof event.data !== "string" || event.data.length > 1_048_576) return;
46
+ let value: unknown;
47
+ try {
48
+ value = JSON.parse(event.data);
49
+ } catch {
50
+ return;
51
+ }
52
+ if (!value || typeof value !== "object") return;
53
+ this.receive(value as Envelope);
54
+ };
55
+ constructor(
56
+ private readonly raw: RTCDataChannel,
57
+ private readonly drainTimeoutMs = 5_000,
58
+ ) {
59
+ super();
60
+ raw.addEventListener("open", this.onOpen);
61
+ raw.addEventListener("close", this.onClose);
62
+ raw.addEventListener("error", this.onError);
63
+ raw.addEventListener("message", this.onMessage);
64
+ }
65
+ get readyState(): RTCDataChannelState {
66
+ return this.closed || this.providerClosed
67
+ ? "closed"
68
+ : this.closeSent
69
+ ? "closing"
70
+ : this.raw.readyState;
71
+ }
72
+ asRtcDataChannel(): RTCDataChannel {
73
+ return this as unknown as RTCDataChannel;
74
+ }
75
+ private emit(value: Envelope): void {
76
+ if (!this.closed)
77
+ this.dispatchEvent(new MessageEvent("message", { data: JSON.stringify(value) }));
78
+ }
79
+ private flush(): void {
80
+ if (this.timer) clearTimeout(this.timer);
81
+ this.timer = null;
82
+ const pending = this.pending;
83
+ this.pending = null;
84
+ if (!pending?.text) return;
85
+ this.emit({
86
+ type: "transcript.segment",
87
+ turn: {
88
+ id: `${this.prefix}:${++this.ordinal}`,
89
+ role: pending.role,
90
+ transcript: pending.text,
91
+ },
92
+ start_ms: pending.startMs,
93
+ end_ms: pending.endMs,
94
+ });
95
+ }
96
+ private receive(value: Envelope): void {
97
+ if (this.closed) return;
98
+ if (
99
+ value.type === "session.input_transcript.delta" ||
100
+ value.type === "session.output_transcript.delta"
101
+ ) {
102
+ if (
103
+ typeof value.delta !== "string" ||
104
+ typeof value.start_ms !== "number" ||
105
+ typeof value.end_ms !== "number"
106
+ )
107
+ return;
108
+ const role = value.type === "session.input_transcript.delta" ? "user" : "assistant";
109
+ if (role === "user")
110
+ this.userSinceDelegation = takeUtf8Tail(this.userSinceDelegation + value.delta);
111
+ if (
112
+ this.pending &&
113
+ (this.pending.role !== role ||
114
+ new TextEncoder().encode(this.pending.text + value.delta).byteLength > MAX_FRAGMENT_BYTES)
115
+ )
116
+ this.flush();
117
+ if (new TextEncoder().encode(value.delta).byteLength > MAX_FRAGMENT_BYTES) {
118
+ this.emit({
119
+ type: "error",
120
+ error: { message: "Voice transcript fragment exceeded the supported size" },
121
+ });
122
+ return;
123
+ }
124
+ this.pending = {
125
+ role,
126
+ text: (this.pending?.text ?? "") + value.delta,
127
+ startMs: this.pending?.startMs ?? value.start_ms,
128
+ endMs: value.end_ms,
129
+ };
130
+ // Application grouping only: never present silence as a provider turn boundary.
131
+ if (!this.timer) this.timer = setTimeout(() => this.flush(), 1_000);
132
+ return;
133
+ }
134
+ if (value.type === "session.delegation.created") {
135
+ const delegation = value.delegation as Envelope | undefined;
136
+ if (delegation?.target !== "client" || typeof delegation.id !== "string") return;
137
+ this.delegations.add(delegation.id);
138
+ this.flush();
139
+ const spoken = this.userSinceDelegation.trim();
140
+ this.userSinceDelegation = "";
141
+ this.emit({
142
+ type: "delegation.created",
143
+ item: {
144
+ id: delegation.id,
145
+ type: "delegation",
146
+ target: "client",
147
+ content: spoken ? [{ type: "input_text", text: spoken }] : [],
148
+ },
149
+ offset_ms: value.offset_ms,
150
+ });
151
+ return;
152
+ }
153
+ if (value.type === "session.closed") {
154
+ this.providerClosed = true;
155
+ this.flush();
156
+ this.finishDrain?.();
157
+ return;
158
+ }
159
+ if (
160
+ value.type === "session.started" ||
161
+ value.type === "session.updated" ||
162
+ value.type === "error"
163
+ )
164
+ this.emit(value);
165
+ }
166
+ send(payload: string): void {
167
+ if (this.readyState !== "open") throw Error("Hosted voice channel is not open");
168
+ const value = JSON.parse(payload) as Envelope;
169
+ if (value.type !== "session.context.append" && value.type !== "delegation.context.append")
170
+ throw Error("Unsupported hosted voice context event");
171
+ const content = Array.isArray(value.content)
172
+ ? value.content.map((part) => (typeof part?.text === "string" ? part.text : "")).join("")
173
+ : "";
174
+ // Existing bridge chunks are <=500 UTF-8 bytes, below Live's 500-token bound.
175
+ this.raw.send(
176
+ JSON.stringify({
177
+ type:
178
+ value.channel === "speakable" ? "session.commentary.append" : "session.thinking.append",
179
+ content,
180
+ // Replayed tasks from an earlier provider session are general context.
181
+ delegation_id:
182
+ value.type === "delegation.context.append" &&
183
+ typeof value.delegation_item_id === "string" &&
184
+ this.delegations.has(value.delegation_item_id)
185
+ ? value.delegation_item_id
186
+ : null,
187
+ }),
188
+ );
189
+ }
190
+ drain(): Promise<void> {
191
+ if (this.draining) return this.draining;
192
+ if (this.providerClosed || this.raw.readyState === "closed") {
193
+ this.flush();
194
+ return Promise.resolve();
195
+ }
196
+ if (this.closed || this.raw.readyState !== "open") {
197
+ return Promise.reject(new Error("Hosted voice close is not confirmed"));
198
+ }
199
+ const pending = new Promise<void>((resolve, reject) => {
200
+ const timeout = setTimeout(() => {
201
+ this.flush();
202
+ this.finishDrain?.(
203
+ new Error("Hosted voice is still closing; retry to preserve final speech"),
204
+ );
205
+ }, this.drainTimeoutMs);
206
+ this.finishDrain = (error) => {
207
+ clearTimeout(timeout);
208
+ this.finishDrain = null;
209
+ if (error) reject(error);
210
+ else resolve();
211
+ };
212
+ if (!this.closeSent) {
213
+ this.closeSent = true;
214
+ try {
215
+ this.raw.send(JSON.stringify({ type: "session.close" }));
216
+ } catch {
217
+ this.finishDrain(new Error("Hosted voice close could not be sent"));
218
+ }
219
+ }
220
+ });
221
+ this.draining = pending;
222
+ // An uncertain close remains retryable; never resend the provider mutation.
223
+ void pending.then(
224
+ () => {
225
+ if (this.draining === pending) this.draining = null;
226
+ },
227
+ () => {
228
+ if (this.draining === pending) this.draining = null;
229
+ },
230
+ );
231
+ return pending;
232
+ }
233
+ close(): void {
234
+ if (this.closed) return;
235
+ if (this.timer) clearTimeout(this.timer);
236
+ this.timer = null;
237
+ this.pending = null;
238
+ this.finishDrain?.(new Error("Hosted voice channel was disposed before close confirmation"));
239
+ this.closed = true;
240
+ this.raw.removeEventListener("open", this.onOpen);
241
+ this.raw.removeEventListener("close", this.onClose);
242
+ this.raw.removeEventListener("error", this.onError);
243
+ this.raw.removeEventListener("message", this.onMessage);
244
+ this.dispatchEvent(new Event("close"));
245
+ }
246
+ }
247
+
248
+ export function createAzureLiveTransportStarter(
249
+ options: Pick<StartCodexRealtimeWebrtcOptions, "remoteAudio" | "createPeerConnection"> = {},
250
+ ): RealtimeControllerTransportStarter {
251
+ return async (input) => {
252
+ let channel: AzureLiveDataChannel | undefined;
253
+ try {
254
+ const transport = await startCodexRealtimeWebrtc({
255
+ ...input,
256
+ ...options,
257
+ activateRemoteAudio: false,
258
+ expectedModel: "opengeni-azure/gpt-live-1",
259
+ onEventsCreated(raw) {
260
+ channel = new AzureLiveDataChannel(raw);
261
+ input.onEventsCreated(channel.asRtcDataChannel());
262
+ },
263
+ negotiate: (request, requestOptions) =>
264
+ input.client.negotiateCodexRealtimeWebrtc(
265
+ input.workspaceId,
266
+ input.sessionId,
267
+ request,
268
+ requestOptions,
269
+ ),
270
+ });
271
+ const events = channel!;
272
+ return {
273
+ ...transport,
274
+ events: events.asRtcDataChannel(),
275
+ drain: () => events.drain(),
276
+ stop() {
277
+ events.close();
278
+ transport.stop();
279
+ },
280
+ };
281
+ } catch (error) {
282
+ channel?.close();
283
+ throw error;
284
+ }
285
+ };
286
+ }
package/src/browser.ts CHANGED
@@ -1,7 +1,28 @@
1
1
  /** Browser-console client. Optional SDK surfaces must not enter this eager graph. */
2
2
  export { OpenGeniClient as OpenGeniBrowserClient } from "./client";
3
+ export type {
4
+ SessionMessageSearchRequest,
5
+ SessionMessageSearchMatch,
6
+ SessionMessageSearchResponse,
7
+ SessionMessagePreview,
8
+ SessionMessagePreviewReference,
9
+ } from "./session-message-search";
10
+ export {
11
+ OpenGeniToolCallError,
12
+ OpenGeniToolReapprovalRequiredError,
13
+ OpenGeniToolsClient,
14
+ } from "./tools";
15
+ export type {
16
+ OpenGeniGeneratedTools,
17
+ OpenGeniDynamicToolNode,
18
+ OpenGeniToolCallOptions,
19
+ OpenGeniToolFunction,
20
+ OpenGeniToolsFacade,
21
+ OpenGeniWorkspaceTools,
22
+ } from "./tools";
3
23
  export type {
4
24
  FetchLike,
25
+ FetchResponse,
5
26
  GetSessionOptions,
6
27
  OpenGeniClientOptions,
7
28
  OpenGeniRequestOptions,
@@ -13,9 +34,25 @@ export type {
13
34
  export {
14
35
  OpenGeniApiContractMismatchError,
15
36
  OpenGeniApiError,
37
+ OpenGeniSetupError,
38
+ OpenGeniAllowanceExhaustedError,
39
+ OpenGeniSessionUsageLimitReachedError,
40
+ OpenGeniSessionUsageLimitUnsupportedError,
41
+ OpenGeniSecureContextRequiredError,
16
42
  OpenGeniSessionListCursorError,
17
43
  OpenGeniStreamError,
44
+ formatErrorMessage,
18
45
  isRetryableStreamError,
19
46
  } from "./errors";
47
+ export type { OpenGeniSecureContextRequiredReason } from "./errors";
20
48
  export { resolveWorkspaceVoiceInputEnabled } from "./transcription";
21
49
  export { OPENGENI_API_CONTRACT_HEADER, OPENGENI_API_CONTRACT_REVISION } from "./types";
50
+
51
+ export type {
52
+ ConnectorToolPermission,
53
+ ConnectorToolPermissionEntry,
54
+ ConnectorToolPermissionsResponse,
55
+ UpdateConnectorToolPermissionsRequest,
56
+ SessionMcpToolPermissionsResponse,
57
+ UpdateSessionMcpToolPermissionsRequest,
58
+ } from "./types";