@opengeni/sdk 3.1.0 → 3.1.2

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 (295) hide show
  1. package/README.md +1037 -71
  2. package/dist/accounts.d.ts +5 -1
  3. package/dist/accounts.js +13 -1
  4. package/dist/accounts.js.map +1 -1
  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/app-links.d.ts +42 -0
  18. package/dist/app-links.js +66 -0
  19. package/dist/app-links.js.map +1 -0
  20. package/dist/artifact-catalog.d.ts +40 -0
  21. package/dist/artifact-client.d.ts +20 -8
  22. package/dist/artifacts.d.ts +1 -1
  23. package/dist/artifacts.js +8 -6
  24. package/dist/automations.js +8 -2
  25. package/dist/automations.js.map +1 -1
  26. package/dist/azure-live-transport.d.ts +32 -0
  27. package/dist/browser.d.ts +7 -2
  28. package/dist/browser.js +27 -5
  29. package/dist/chat/fold.d.ts +75 -0
  30. package/dist/chat/handler.d.ts +41 -0
  31. package/dist/chat/http.d.ts +67 -0
  32. package/dist/chat/ids.d.ts +34 -0
  33. package/dist/chat/index.d.ts +9 -0
  34. package/dist/chat/index.js +1703 -0
  35. package/dist/chat/index.js.map +1 -0
  36. package/dist/chat/openai.d.ts +30 -0
  37. package/dist/chat/opengeni.d.ts +129 -0
  38. package/dist/chat/types.d.ts +207 -0
  39. package/dist/chat/vercel.d.ts +49 -0
  40. package/dist/chats.d.ts +8 -0
  41. package/dist/chunk-4AHR4KGA.js +301 -0
  42. package/dist/chunk-4AHR4KGA.js.map +1 -0
  43. package/dist/chunk-6HZGAIUE.js +1665 -0
  44. package/dist/chunk-6HZGAIUE.js.map +1 -0
  45. package/dist/chunk-7EWT3PV6.js +368 -0
  46. package/dist/chunk-7EWT3PV6.js.map +1 -0
  47. package/dist/{chunk-VYCTL62C.js → chunk-GZQSWAKD.js} +1 -1
  48. package/dist/chunk-GZQSWAKD.js.map +1 -0
  49. package/dist/chunk-JXXCTW5W.js +1392 -0
  50. package/dist/chunk-JXXCTW5W.js.map +1 -0
  51. package/dist/{chunk-YTAWBDO2.js → chunk-KADZ5PGG.js} +28 -2
  52. package/dist/chunk-KADZ5PGG.js.map +1 -0
  53. package/dist/{chunk-YKZME56C.js → chunk-KWADQ227.js} +3 -3
  54. package/dist/{chunk-YKZME56C.js.map → chunk-KWADQ227.js.map} +1 -1
  55. package/dist/{chunk-7ZXBPJZP.js → chunk-NEM5N6C6.js} +3902 -1457
  56. package/dist/chunk-NEM5N6C6.js.map +1 -0
  57. package/dist/{chunk-GW3EJ2GP.js → chunk-O7KANXC3.js} +86 -13
  58. package/dist/chunk-O7KANXC3.js.map +1 -0
  59. package/dist/{chunk-VUQZAB3O.js → chunk-OAKHWFSV.js} +28 -32
  60. package/dist/chunk-OAKHWFSV.js.map +1 -0
  61. package/dist/chunk-P7UWKORG.js +561 -0
  62. package/dist/chunk-P7UWKORG.js.map +1 -0
  63. package/dist/chunk-QGEIL4TR.js +195 -0
  64. package/dist/chunk-QGEIL4TR.js.map +1 -0
  65. package/dist/chunk-RJHCBZF7.js +270 -0
  66. package/dist/chunk-RJHCBZF7.js.map +1 -0
  67. package/dist/chunk-S3D75WSQ.js +340 -0
  68. package/dist/chunk-S3D75WSQ.js.map +1 -0
  69. package/dist/chunk-UM4ZXXJR.js +9 -0
  70. package/dist/chunk-UM4ZXXJR.js.map +1 -0
  71. package/dist/chunk-VPVMLM7Q.js +15 -0
  72. package/dist/chunk-VPVMLM7Q.js.map +1 -0
  73. package/dist/{chunk-C2H7HBNP.js → chunk-WVCJRSGJ.js} +119 -14
  74. package/dist/chunk-WVCJRSGJ.js.map +1 -0
  75. package/dist/chunk-XA7HVIHI.js +126 -0
  76. package/dist/chunk-XA7HVIHI.js.map +1 -0
  77. package/dist/{chunk-TX3EIENU.js → chunk-YDVPI7WT.js} +73 -2
  78. package/dist/chunk-YDVPI7WT.js.map +1 -0
  79. package/dist/chunk-YKIHNLWD.js +153 -0
  80. package/dist/chunk-YKIHNLWD.js.map +1 -0
  81. package/dist/chunk-ZDUBPV33.js +277 -0
  82. package/dist/chunk-ZDUBPV33.js.map +1 -0
  83. package/dist/client.d.ts +1065 -124
  84. package/dist/codex-realtime-controller.d.ts +13 -0
  85. package/dist/codex-realtime-controller.js +4 -2
  86. package/dist/codex-realtime-v3-wire.d.ts +3 -2
  87. package/dist/codex-realtime.d.ts +5 -1
  88. package/dist/company-brain.d.ts +1 -11
  89. package/dist/company-profile.d.ts +13 -0
  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/feedback.d.ts +23 -0
  102. package/dist/gateway-realtime-transport.js +1 -1
  103. package/dist/github-repositories.d.ts +10 -0
  104. package/dist/github-repositories.js +36 -0
  105. package/dist/github-repositories.js.map +1 -0
  106. package/dist/index.d.ts +64 -11
  107. package/dist/index.js +566 -141
  108. package/dist/index.js.map +1 -1
  109. package/dist/insights-usage.d.ts +33 -0
  110. package/dist/insights-usage.js +7 -0
  111. package/dist/insights-usage.js.map +1 -0
  112. package/dist/interaction.d.ts +103 -71
  113. package/dist/interaction.js +4 -2
  114. package/dist/knowledge.d.ts +7 -0
  115. package/dist/knowledge.js +20 -0
  116. package/dist/knowledge.js.map +1 -0
  117. package/dist/known-tools.d.ts +4 -0
  118. package/dist/message-links.d.ts +68 -0
  119. package/dist/model-context.d.ts +68 -0
  120. package/dist/model-display.d.ts +2 -0
  121. package/dist/model-display.js +17 -0
  122. package/dist/model-display.js.map +1 -0
  123. package/dist/model-picker-order.d.ts +1 -0
  124. package/dist/model-picker-order.js +10 -0
  125. package/dist/model-picker-order.js.map +1 -0
  126. package/dist/organization-integration-policy.d.ts +26 -0
  127. package/dist/organization-integration-policy.js +26 -0
  128. package/dist/organization-integration-policy.js.map +1 -0
  129. package/dist/pr-review-client.d.ts +1 -1
  130. package/dist/pr-review.d.ts +1 -1
  131. package/dist/pr-review.js.map +1 -1
  132. package/dist/preference-registry.d.ts +1 -1
  133. package/dist/prepared-mcp-setup.d.ts +5 -0
  134. package/dist/proxy.d.ts +13 -11
  135. package/dist/realtime.d.ts +4 -2
  136. package/dist/realtime.js +253 -7
  137. package/dist/realtime.js.map +1 -1
  138. package/dist/session-history-import.d.ts +22 -0
  139. package/dist/session-history-import.js +36 -0
  140. package/dist/session-history-import.js.map +1 -0
  141. package/dist/session-list-entries.d.ts +1 -0
  142. package/dist/session-list-entries.js +7 -0
  143. package/dist/session-list-entries.js.map +1 -0
  144. package/dist/session-message-search.d.ts +53 -0
  145. package/dist/session-proxy-client.d.ts +28 -0
  146. package/dist/session-proxy.d.ts +334 -0
  147. package/dist/session-proxy.js +24 -0
  148. package/dist/session-proxy.js.map +1 -0
  149. package/dist/session-titles.d.ts +2 -0
  150. package/dist/session-usage-limits.d.ts +10 -0
  151. package/dist/session-usage-limits.js +43 -0
  152. package/dist/session-usage-limits.js.map +1 -0
  153. package/dist/shared-catalog-loader.d.ts +34 -0
  154. package/dist/site-bridge-host.d.ts +112 -0
  155. package/dist/site-bridge-host.js +285 -0
  156. package/dist/site-bridge-host.js.map +1 -0
  157. package/dist/site-browser-entry.d.ts +1 -0
  158. package/dist/site-browser-runtime.gen.d.ts +1 -0
  159. package/dist/site-data.d.ts +178 -0
  160. package/dist/site-document.d.ts +5 -0
  161. package/dist/site-document.js +20 -0
  162. package/dist/site-document.js.map +1 -0
  163. package/dist/site-document.test.d.ts +1 -0
  164. package/dist/site-http.d.ts +17 -0
  165. package/dist/site-sql.d.ts +31 -0
  166. package/dist/site-tool-bridge.d.ts +57 -0
  167. package/dist/site.d.ts +182 -0
  168. package/dist/site.js +62 -0
  169. package/dist/site.js.map +1 -0
  170. package/dist/skills.d.ts +75 -0
  171. package/dist/sse.d.ts +1 -1
  172. package/dist/stream.d.ts +2 -0
  173. package/dist/tenant-workspaces.d.ts +47 -0
  174. package/dist/tenant-workspaces.js +8 -0
  175. package/dist/tenant-workspaces.js.map +1 -0
  176. package/dist/tool-auth.d.ts +87 -0
  177. package/dist/tool-auth.js +23 -0
  178. package/dist/tool-auth.js.map +1 -0
  179. package/dist/tool-display-metadata.d.ts +3 -0
  180. package/dist/tools-37DCTCNZ.js +12 -0
  181. package/dist/tools-37DCTCNZ.js.map +1 -0
  182. package/dist/tools.d.ts +81 -0
  183. package/dist/transcription.d.ts +1 -1
  184. package/dist/types.d.ts +2848 -573
  185. package/dist/usage-allowances.d.ts +36 -0
  186. package/dist/usage-allowances.js +80 -0
  187. package/dist/usage-allowances.js.map +1 -0
  188. package/dist/vault-types.d.ts +236 -0
  189. package/dist/vaults-api.d.ts +57 -0
  190. package/dist/workspace-artifacts.d.ts +47 -5
  191. package/dist/workspace-instruction-policies.d.ts +2 -2
  192. package/dist/workspace-integrations.d.ts +74 -0
  193. package/dist/workspace-integrations.js +65 -0
  194. package/dist/workspace-integrations.js.map +1 -0
  195. package/dist/workspace-state.d.ts +8 -71
  196. package/package.json +99 -5
  197. package/src/accounts.ts +18 -0
  198. package/src/adapters/express.ts +136 -0
  199. package/src/adapters/hono.ts +18 -0
  200. package/src/adapters/next.ts +42 -0
  201. package/src/allowance-refusal.ts +5 -0
  202. package/src/app-links.ts +117 -0
  203. package/src/artifact-catalog.ts +51 -0
  204. package/src/artifact-client.ts +40 -49
  205. package/src/artifacts.ts +1 -0
  206. package/src/automations-client.ts +8 -2
  207. package/src/azure-live-transport.ts +286 -0
  208. package/src/browser.ts +37 -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 +88 -0
  214. package/src/chat/openai.ts +439 -0
  215. package/src/chat/opengeni.ts +737 -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 +5822 -1847
  220. package/src/codex-realtime-controller.ts +163 -8
  221. package/src/codex-realtime-v3-wire.ts +4 -3
  222. package/src/codex-realtime-v3.ts +12 -3
  223. package/src/codex-realtime.ts +11 -3
  224. package/src/company-brain.ts +0 -40
  225. package/src/company-profile.ts +13 -0
  226. package/src/core.ts +20 -0
  227. package/src/deprecation.ts +149 -0
  228. package/src/document-authority-client.ts +104 -1
  229. package/src/editable-artifacts/controller.ts +36 -2
  230. package/src/editable-artifacts/index.ts +1 -0
  231. package/src/editable-artifacts/types.ts +29 -16
  232. package/src/embedding-client.ts +519 -0
  233. package/src/errors.ts +303 -4
  234. package/src/feedback.ts +20 -0
  235. package/src/gateway-realtime-transport.ts +3 -3
  236. package/src/github-repositories.ts +60 -0
  237. package/src/index.ts +611 -64
  238. package/src/insights-usage.ts +61 -0
  239. package/src/interaction.ts +274 -93
  240. package/src/knowledge.ts +72 -0
  241. package/src/known-tools.ts +279 -0
  242. package/src/message-links.ts +178 -0
  243. package/src/model-context.ts +113 -0
  244. package/src/model-display.ts +11 -0
  245. package/src/model-picker-order.ts +6 -0
  246. package/src/organization-integration-policy.ts +54 -0
  247. package/src/pr-review-client.ts +1 -1
  248. package/src/pr-review.ts +1 -1
  249. package/src/preference-registry.ts +2 -0
  250. package/src/prepared-mcp-setup.ts +123 -0
  251. package/src/proxy.ts +23 -12
  252. package/src/realtime.ts +16 -6
  253. package/src/session-history-import.ts +84 -0
  254. package/src/session-list-entries.ts +1 -0
  255. package/src/session-message-search.ts +47 -0
  256. package/src/session-proxy-client.ts +68 -0
  257. package/src/session-proxy.ts +2098 -0
  258. package/src/session-titles.ts +10 -0
  259. package/src/session-usage-limits.ts +71 -0
  260. package/src/shared-catalog-loader.ts +169 -0
  261. package/src/site-bridge-host.ts +422 -0
  262. package/src/site-browser-entry.ts +6 -0
  263. package/src/site-browser-runtime.gen.ts +2 -0
  264. package/src/site-data.ts +372 -0
  265. package/src/site-document.test.ts +64 -0
  266. package/src/site-document.ts +18 -0
  267. package/src/site-http.ts +171 -0
  268. package/src/site-sql.ts +153 -0
  269. package/src/site-tool-bridge.ts +401 -0
  270. package/src/site.ts +867 -0
  271. package/src/skills.ts +69 -0
  272. package/src/sse.ts +9 -3
  273. package/src/stream.ts +33 -10
  274. package/src/tenant-workspaces.ts +148 -0
  275. package/src/tool-auth.ts +301 -0
  276. package/src/tool-display-metadata.ts +27 -0
  277. package/src/tools.ts +452 -0
  278. package/src/transcription.ts +3 -0
  279. package/src/types.ts +3216 -581
  280. package/src/usage-allowances.ts +189 -0
  281. package/src/vault-types.ts +293 -0
  282. package/src/vaults-api.ts +288 -0
  283. package/src/workspace-artifacts.ts +55 -6
  284. package/src/workspace-instruction-policies.ts +2 -1
  285. package/src/workspace-integrations.ts +402 -0
  286. package/src/workspace-state.ts +8 -82
  287. package/dist/chunk-7ZXBPJZP.js.map +0 -1
  288. package/dist/chunk-C2H7HBNP.js.map +0 -1
  289. package/dist/chunk-C4DJPZRU.js +0 -119
  290. package/dist/chunk-C4DJPZRU.js.map +0 -1
  291. package/dist/chunk-GW3EJ2GP.js.map +0 -1
  292. package/dist/chunk-TX3EIENU.js.map +0 -1
  293. package/dist/chunk-VUQZAB3O.js.map +0 -1
  294. package/dist/chunk-VYCTL62C.js.map +0 -1
  295. package/dist/chunk-YTAWBDO2.js.map +0 -1
@@ -0,0 +1,54 @@
1
+ import type { OpenGeniClient } from "./client";
2
+
3
+ export type OrganizationIntegrationPolicy = {
4
+ mode: "unrestricted" | "restricted";
5
+ allowedIntegrationKeys: string[];
6
+ revision: number;
7
+ };
8
+
9
+ export type UpdateOrganizationIntegrationPolicyRequest = {
10
+ mode: "unrestricted" | "restricted";
11
+ allowedIntegrationKeys: string[];
12
+ expectedRevision: number;
13
+ operationId: string;
14
+ };
15
+
16
+ type PolicyClient = Pick<OpenGeniClient, "requestJson">;
17
+
18
+ export type OrganizationIntegrationCatalog = {
19
+ integrations: Array<{ key: string; label: string; kind: "curated" | "custom" }>;
20
+ };
21
+
22
+ /** Discover stable policy identities; integrations must not guess provider identifiers. */
23
+ export async function getOrganizationIntegrationCatalog(
24
+ client: PolicyClient,
25
+ organizationId: string,
26
+ ): Promise<OrganizationIntegrationCatalog> {
27
+ return client.requestJson(
28
+ "GET",
29
+ `/v1/organizations/${encodeURIComponent(organizationId)}/integration-policy/catalog`,
30
+ );
31
+ }
32
+
33
+ export async function getOrganizationIntegrationPolicy(
34
+ client: PolicyClient,
35
+ organizationId: string,
36
+ ): Promise<OrganizationIntegrationPolicy> {
37
+ return client.requestJson(
38
+ "GET",
39
+ `/v1/organizations/${encodeURIComponent(organizationId)}/integration-policy`,
40
+ );
41
+ }
42
+
43
+ /** Retain operationId and the exact request when reconciling an uncertain outcome. */
44
+ export async function updateOrganizationIntegrationPolicy(
45
+ client: PolicyClient,
46
+ organizationId: string,
47
+ request: UpdateOrganizationIntegrationPolicyRequest,
48
+ ): Promise<OrganizationIntegrationPolicy> {
49
+ return client.requestJson(
50
+ "PUT",
51
+ `/v1/organizations/${encodeURIComponent(organizationId)}/integration-policy`,
52
+ request,
53
+ );
54
+ }
@@ -12,7 +12,7 @@ import type {
12
12
 
13
13
  export type OpenGeniPrReviewTransport = Pick<OpenGeniCoreClient, "requestJson" | "requestVoid">;
14
14
 
15
- /** Optional OpenGeni Review Bot API surface, isolated from the eager core client graph. */
15
+ /** Optional Opengeni Review Bot API surface, isolated from the eager core client graph. */
16
16
  export class OpenGeniPrReviewClient {
17
17
  constructor(private readonly client: OpenGeniPrReviewTransport) {}
18
18
 
package/src/pr-review.ts CHANGED
@@ -1,4 +1,4 @@
1
- /** Optional OpenGeni Review Bot API client; import this entry only where the capability is used. */
1
+ /** Optional Opengeni Review Bot API client; import this entry only where the capability is used. */
2
2
  export { OpenGeniPrReviewClient } from "./pr-review-client";
3
3
  export type { OpenGeniPrReviewTransport } from "./pr-review-client";
4
4
  export type {
@@ -10,6 +10,8 @@ export type PreferenceRegistryProvenanceSource =
10
10
  | "human"
11
11
  | "onboarding"
12
12
  | "knowledge_proposal"
13
+ | "agent"
14
+ | "portable_skill"
13
15
  | "imported_document"
14
16
  | "slack"
15
17
  | "meeting_transcript"
@@ -0,0 +1,123 @@
1
+ import type {
2
+ CustomMcpSetupRequest,
3
+ PreparedMcpSetup,
4
+ } from "@opengeni/contracts/prepared-mcp-setup";
5
+
6
+ const record = (value: unknown): value is Record<string, unknown> =>
7
+ value !== null && typeof value === "object" && !Array.isArray(value);
8
+ const keys = (value: Record<string, unknown>, allowed: string[]) =>
9
+ Object.keys(value).every((key) => allowed.includes(key));
10
+ const text = (value: unknown, max: number, min = 1): value is string =>
11
+ typeof value === "string" && value.length >= min && value.length <= max;
12
+ const trimmedText = (value: unknown, max: number): value is string =>
13
+ typeof value === "string" && text(value.trim(), max);
14
+ const headerPart = (value: unknown): value is string =>
15
+ text(value, 16_384, 0) && !/[\r\n\0]/.test(value);
16
+ const fieldId = (value: unknown): value is string =>
17
+ typeof value === "string" && /^[A-Za-z][A-Za-z0-9_]{0,63}$/.test(value);
18
+ const endpoint = (value: unknown): value is string => {
19
+ if (!text(value, 2048)) return false;
20
+ try {
21
+ const url = new URL(value);
22
+ return url.protocol === "https:" && !url.username && !url.password && !url.search && !url.hash;
23
+ } catch {
24
+ return false;
25
+ }
26
+ };
27
+
28
+ /** Browser/native-safe display projection. The API owns authoritative schema
29
+ * validation; parity tests keep this lightweight parser aligned without pulling
30
+ * schema runtimes into the SDK or replaying unknown fields into a secret form. */
31
+ export function parseCustomMcpSetupRequest(value: unknown): CustomMcpSetupRequest | null {
32
+ if (
33
+ !record(value) ||
34
+ !keys(value, ["kind", "name", "endpointUrl", "rationale", "ownership", "mcpSetup"]) ||
35
+ value.kind !== "mcp" ||
36
+ !trimmedText(value.name, 256) ||
37
+ !endpoint(value.endpointUrl) ||
38
+ !trimmedText(value.rationale, 2000)
39
+ )
40
+ return null;
41
+ const base = {
42
+ kind: "mcp" as const,
43
+ name: value.name.trim(),
44
+ endpointUrl: value.endpointUrl,
45
+ rationale: value.rationale.trim(),
46
+ };
47
+ if (value.ownership === undefined && value.mcpSetup === undefined) return base;
48
+ if (value.ownership !== "personal" && value.ownership !== "workspace") return null;
49
+ const setup = value.mcpSetup;
50
+ if (
51
+ !record(setup) ||
52
+ !keys(setup, ["name", "endpointUrl", "headers", "secretFields"]) ||
53
+ !trimmedText(setup.name, 256) ||
54
+ setup.name.trim() !== base.name ||
55
+ setup.endpointUrl !== base.endpointUrl ||
56
+ !Array.isArray(setup.headers) ||
57
+ setup.headers.length < 1 ||
58
+ setup.headers.length > 32 ||
59
+ !Array.isArray(setup.secretFields) ||
60
+ setup.secretFields.length > 32
61
+ )
62
+ return null;
63
+ const fields: PreparedMcpSetup["secretFields"] = [];
64
+ const fieldIds = new Set<string>();
65
+ for (const field of setup.secretFields) {
66
+ if (
67
+ !record(field) ||
68
+ !keys(field, ["id", "label"]) ||
69
+ !fieldId(field.id) ||
70
+ !trimmedText(field.label, 256) ||
71
+ fieldIds.has(field.id)
72
+ )
73
+ return null;
74
+ fieldIds.add(field.id);
75
+ fields.push({ id: field.id, label: field.label.trim() });
76
+ }
77
+ const headers: PreparedMcpSetup["headers"] = [];
78
+ const names = new Set<string>();
79
+ const used = new Set<string>();
80
+ for (const header of setup.headers) {
81
+ if (
82
+ !record(header) ||
83
+ !text(header.name, 256) ||
84
+ !/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(header.name)
85
+ )
86
+ return null;
87
+ const name = header.name.toLowerCase();
88
+ if (names.has(name)) return null;
89
+ names.add(name);
90
+ if ("value" in header) {
91
+ if (
92
+ !keys(header, ["name", "value"]) ||
93
+ !headerPart(header.value) ||
94
+ !header.value ||
95
+ ["authorization", "proxy-authorization", "cookie", "x-api-key", "api-key"].includes(name)
96
+ )
97
+ return null;
98
+ headers.push({ name: header.name, value: header.value });
99
+ } else {
100
+ if (
101
+ !keys(header, ["name", "secret", "prefix", "suffix"]) ||
102
+ !fieldId(header.secret) ||
103
+ !fieldIds.has(header.secret) ||
104
+ (header.prefix !== undefined && !headerPart(header.prefix)) ||
105
+ (header.suffix !== undefined && !headerPart(header.suffix))
106
+ )
107
+ return null;
108
+ used.add(header.secret);
109
+ headers.push({
110
+ name: header.name,
111
+ secret: header.secret,
112
+ ...(header.prefix !== undefined ? { prefix: header.prefix as string } : {}),
113
+ ...(header.suffix !== undefined ? { suffix: header.suffix as string } : {}),
114
+ });
115
+ }
116
+ }
117
+ if (used.size !== fieldIds.size) return null;
118
+ return {
119
+ ...base,
120
+ ownership: value.ownership,
121
+ mcpSetup: { name: base.name, endpointUrl: base.endpointUrl, headers, secretFields: fields },
122
+ };
123
+ }
package/src/proxy.ts CHANGED
@@ -1,23 +1,33 @@
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
  /**
6
6
  * Proxy-through-your-own-API helpers.
7
7
  *
8
- * The intended pattern: a customer's server consumes the OpenGeni event
8
+ * The intended pattern: a customer's server consumes the Opengeni event
9
9
  * stream with its own API key (`client.streamEvents(...)`) and re-emits it to
10
- * its browser clients over its own authenticated endpoint — the OpenGeni key
10
+ * its browser clients over its own authenticated endpoint — the Opengeni key
11
11
  * never reaches the browser. The re-emitted wire format is identical to
12
- * OpenGeni's own SSE stream (`id: <sequence>`, `event: <type>`,
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 = {
@@ -28,7 +38,7 @@ export type SseReStreamOptions = {
28
38
  heartbeatMs?: number;
29
39
  /**
30
40
  * Called when the downstream consumer cancels (e.g. the browser
31
- * disconnected). Use it to abort the upstream OpenGeni stream — an async
41
+ * disconnected). Use it to abort the upstream Opengeni stream — an async
32
42
  * iterator that is mid-`await` cannot be interrupted by `return()` alone.
33
43
  */
34
44
  onCancel?: () => void;
@@ -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);
@@ -136,12 +147,12 @@ export type ProxySessionEventStreamOptions = Omit<StreamSessionEventsOptions, "a
136
147
  };
137
148
 
138
149
  /**
139
- * One-call proxy: consume the OpenGeni stream server-side and return an SSE
150
+ * One-call proxy: consume the Opengeni stream server-side and return an SSE
140
151
  * `Response` for your own browser clients. Works anywhere WHATWG `Response`
141
152
  * is the handler return type (Hono, Next.js route handlers, Bun.serve,
142
153
  * Cloudflare Workers, ...).
143
154
  *
144
- * The upstream OpenGeni connection is torn down when the downstream client
155
+ * The upstream Opengeni connection is torn down when the downstream client
145
156
  * disconnects, and also when `options.signal` (e.g. the incoming request's
146
157
  * signal) aborts.
147
158
  */
package/src/realtime.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { createAzureLiveTransportStarter } from "./azure-live-transport";
1
2
  /**
2
3
  * Public, provider-neutral realtime browser SDK.
3
4
  *
@@ -30,10 +31,11 @@ import type { SessionRealtimeModel, WorkspaceRealtimeModelCatalogResponse } from
30
31
  export type SessionRealtimeClientLike = CodexRealtimeControllerClient & {
31
32
  getWorkspaceRealtimeModelCatalog(
32
33
  workspaceId: string,
34
+ options?: { signal?: AbortSignal | undefined },
33
35
  ): Promise<WorkspaceRealtimeModelCatalogResponse>;
34
36
  };
35
37
 
36
- export type SessionRealtimeTransportKind = "codex" | "gateway" | "xai-subscription";
38
+ export type SessionRealtimeTransportKind = "codex" | "gateway" | "xai-subscription" | "azure-live";
37
39
 
38
40
  /** Provider-neutral names for the existing, battle-tested controller projection. */
39
41
  export type SessionRealtimeController = CodexRealtimeController;
@@ -56,6 +58,7 @@ export type CreateSessionRealtimeControllerOptions = Omit<
56
58
  export function sessionRealtimeTransportKind(
57
59
  model: SessionRealtimeModel,
58
60
  ): SessionRealtimeTransportKind {
61
+ if (model === "opengeni-azure/gpt-live-1") return "azure-live";
59
62
  if (model === "gpt-live-1-boulder-alpha") return "codex";
60
63
  if (model === "supergrok/grok-voice-think-fast-2.0") return "xai-subscription";
61
64
  return "gateway";
@@ -73,11 +76,18 @@ export function createSessionRealtimeController(
73
76
  return createCodexRealtimeController({
74
77
  ...options,
75
78
  ownerStorageNamespace: sessionRealtimeOwnerStorageNamespace(options.model),
76
- ...(transport === "gateway"
77
- ? { startTransport: createGatewayRealtimeTransportStarter() }
78
- : transport === "xai-subscription"
79
- ? { startTransport: createXaiSubscriptionRealtimeTransportStarter() }
80
- : {}),
79
+ ...(transport === "azure-live"
80
+ ? {
81
+ startTransport: createAzureLiveTransportStarter({
82
+ remoteAudio: options.remoteAudio,
83
+ createPeerConnection: options.createPeerConnection,
84
+ }),
85
+ }
86
+ : transport === "gateway"
87
+ ? { startTransport: createGatewayRealtimeTransportStarter() }
88
+ : transport === "xai-subscription"
89
+ ? { startTransport: createXaiSubscriptionRealtimeTransportStarter() }
90
+ : {}),
81
91
  });
82
92
  }
83
93
 
@@ -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,68 @@
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
+ /**
35
+ * Exact association read. The API reauthorizes the source session on every
36
+ * call. `retained` proves a generated image or video, or a published sandbox
37
+ * file, originated in that session.
38
+ */
39
+ export function getSessionProxyArtifactAssociation(
40
+ client: Pick<OpenGeniEmbeddingClient, "requestJson">,
41
+ workspaceId: string,
42
+ sessionId: string,
43
+ kind: "editable" | "site" | "retained",
44
+ artifactId: string,
45
+ options: OpenGeniRequestOptions = {},
46
+ ): Promise<{ sessionId: string; artifactId: string; kind: "editable" | "site" | "retained" }> {
47
+ return client.requestJson(
48
+ "GET",
49
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/sessions/${encodeURIComponent(sessionId)}/artifact-associations/${encodeURIComponent(artifactId)}`,
50
+ undefined,
51
+ { kind },
52
+ options,
53
+ );
54
+ }
55
+
56
+ /** Authenticated response stream for the server proxy; does not buffer Site HTML. */
57
+ export function downloadSessionProxySiteHtml(
58
+ client: Pick<OpenGeniEmbeddingClient, "requestJsonResponse">,
59
+ workspaceId: string,
60
+ artifactId: string,
61
+ options: { versionId: string; signal?: AbortSignal },
62
+ ): Promise<FetchResponse> {
63
+ return client.requestJsonResponse(
64
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/published-artifacts/${encodeURIComponent(artifactId)}/html`,
65
+ { versionId: options.versionId },
66
+ options,
67
+ );
68
+ }