@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
@@ -35,9 +35,10 @@ export const CODEX_REALTIME_V3_PENDING_MAX_ENTRIES = 256;
35
35
  export const CODEX_REALTIME_V3_PENDING_MAX_BYTES = 16 * 1024 * 1024;
36
36
  const REALTIME_DELEGATION_TRANSCRIPT_MAX_BYTES = 65_536;
37
37
  const REALTIME_DELEGATION_INPUT_MAX_BYTES = 65_536;
38
+ const REALTIME_MODEL_CONTEXT_MAX_CHARACTERS = 32_768;
38
39
 
39
40
  export type CodexRealtimeV3BridgeFatal = {
40
- code: "pending_overflow";
41
+ code: "pending_overflow" | "replay_journal_failed";
41
42
  message: string;
42
43
  };
43
44
 
@@ -72,6 +73,19 @@ export type CodexRealtimeV3BridgeOptions = {
72
73
  >;
73
74
  sync(request: SyncSessionRealtimeLedgerRequest): Promise<SyncSessionRealtimeLedgerResponse>;
74
75
  randomUUID?: (() => string) | undefined;
76
+ /** Model-visible application context captured once for each durable message-bearing entry. */
77
+ getModelContext?: (() => string | undefined) | undefined;
78
+ /** Controller-lifetime delegation identities shared across provider connection rotations. */
79
+ acceptedDelegationItemIds?: Set<string> | undefined;
80
+ /** Unsynced delegation snapshots retained exactly across provider connection rotations. */
81
+ pendingDelegations?: Map<string, SessionRealtimeInboundEntry> | undefined;
82
+ /** Persist exact delegation replay state before it becomes browser-reload-sensitive. */
83
+ onDelegationReplayStateChange?:
84
+ | ((state: {
85
+ acceptedDelegationItemIds: ReadonlySet<string>;
86
+ pendingDelegations: ReadonlyMap<string, SessionRealtimeInboundEntry>;
87
+ }) => void)
88
+ | undefined;
75
89
  /** The controller installs its activation FIFO first, then enables this listener synchronously. */
76
90
  listen?: boolean | undefined;
77
91
  onSnapshot?: ((snapshot: CodexRealtimeV3BridgeSnapshot) => void) | undefined;
@@ -125,9 +139,32 @@ export function createCodexRealtimeV3Bridge(
125
139
  const clientReceivedSequences = new Set<number>();
126
140
  const sentSequences = new Set<number>();
127
141
  const finalizedTurnIds = new Set<string>();
142
+ const acceptedDelegationItemIds = options.acceptedDelegationItemIds ?? new Set<string>();
143
+ const pendingDelegations = options.pendingDelegations ?? new Map();
144
+ const locallyQueuedDelegationItemIds = new Set<string>();
128
145
  let transcriptSinceDelegation: FinalizedTranscript[] = [];
129
- let pendingDelegationUserTranscript: { delegationItemId: string; text: string } | null = null;
146
+ let pendingDelegationUserTranscript: {
147
+ delegationItemId: string;
148
+ text: string;
149
+ } | null = null;
130
150
  const randomUUID = options.randomUUID ?? defaultRandomUUID;
151
+ const currentModelContext = (): string | undefined => {
152
+ let context: string | undefined;
153
+ try {
154
+ context = options.getModelContext?.()?.trim();
155
+ } catch {
156
+ lastError =
157
+ "Realtime model context callback failed; the provider message continued without application context";
158
+ return undefined;
159
+ }
160
+ if (!context) return undefined;
161
+ if (context.length > REALTIME_MODEL_CONTEXT_MAX_CHARACTERS) {
162
+ lastError =
163
+ "Realtime model context exceeded the 32768-character limit; the provider message continued without application context";
164
+ return undefined;
165
+ }
166
+ return context;
167
+ };
131
168
 
132
169
  const snapshot = (): CodexRealtimeV3BridgeSnapshot => ({
133
170
  connectionId: options.connectionId,
@@ -148,9 +185,9 @@ export function createCodexRealtimeV3Bridge(
148
185
  });
149
186
  const publish = (): void => options.onSnapshot?.(snapshot());
150
187
 
151
- const triggerFatal = (message: string): void => {
188
+ const triggerFatalCode = (code: CodexRealtimeV3BridgeFatal["code"], message: string): void => {
152
189
  if (closed || fatal) return;
153
- fatal = { code: "pending_overflow", message };
190
+ fatal = { code, message };
154
191
  lastError = message;
155
192
  publish();
156
193
  try {
@@ -161,6 +198,10 @@ export function createCodexRealtimeV3Bridge(
161
198
  }
162
199
  };
163
200
 
201
+ const triggerFatal = (message: string): void => {
202
+ triggerFatalCode("pending_overflow", message);
203
+ };
204
+
164
205
  const enqueue = (entry: SessionRealtimeInboundEntry): boolean => {
165
206
  if (closed || sealed || fatal) return false;
166
207
  const bytes = utf8ByteLength(JSON.stringify(entry));
@@ -177,6 +218,14 @@ export function createCodexRealtimeV3Bridge(
177
218
  return true;
178
219
  };
179
220
 
221
+ // Same-browser reload reconstructs this exact map from the persisted owner
222
+ // journal. Queue those first-frozen calls before listening to the replacement
223
+ // provider connection; startup proof or a duplicate call drives the normal
224
+ // flush path without resampling application context.
225
+ for (const [delegationItemId, entry] of pendingDelegations) {
226
+ if (enqueue(entry)) locallyQueuedDelegationItemIds.add(delegationItemId);
227
+ }
228
+
180
229
  const hasWork = (): boolean =>
181
230
  pendingInbound.length > 0 ||
182
231
  (!providerStartedAccepted && providerStarted !== undefined) ||
@@ -213,7 +262,46 @@ export function createCodexRealtimeV3Bridge(
213
262
  throw error;
214
263
  }
215
264
 
265
+ const acceptedAfterSync = new Set(acceptedDelegationItemIds);
266
+ const pendingAfterSync = new Map(pendingDelegations);
267
+ let delegationReplayChanged = false;
268
+ for (const item of batch) {
269
+ if (item.entry.kind === "delegation_call" && item.entry.delegationItemId) {
270
+ delegationReplayChanged = true;
271
+ acceptedAfterSync.add(item.entry.delegationItemId);
272
+ if (pendingAfterSync.get(item.entry.delegationItemId) === item.entry) {
273
+ pendingAfterSync.delete(item.entry.delegationItemId);
274
+ }
275
+ }
276
+ }
277
+ if (delegationReplayChanged) {
278
+ try {
279
+ options.onDelegationReplayStateChange?.({
280
+ acceptedDelegationItemIds: acceptedAfterSync,
281
+ pendingDelegations: pendingAfterSync,
282
+ });
283
+ } catch (error) {
284
+ // The server may already have admitted this exact batch. Keep it
285
+ // queued with the original operation identity and stop this bridge.
286
+ // Recovery can safely replay it because the prior pending journal
287
+ // state remains authoritative until the accepted transition writes.
288
+ pendingInbound = [...batch, ...pendingInbound];
289
+ triggerFatalCode(
290
+ "replay_journal_failed",
291
+ `Codex realtime delegation replay journal failed: ${safeError(error)}`,
292
+ );
293
+ return;
294
+ }
295
+ }
296
+
216
297
  for (const item of batch) {
298
+ if (item.entry.kind === "delegation_call" && item.entry.delegationItemId) {
299
+ acceptedDelegationItemIds.add(item.entry.delegationItemId);
300
+ if (pendingDelegations.get(item.entry.delegationItemId) === item.entry) {
301
+ pendingDelegations.delete(item.entry.delegationItemId);
302
+ }
303
+ locallyQueuedDelegationItemIds.delete(item.entry.delegationItemId);
304
+ }
217
305
  pendingInboundCount -= 1;
218
306
  pendingInboundBytes -= item.bytes;
219
307
  }
@@ -345,31 +433,67 @@ export function createCodexRealtimeV3Bridge(
345
433
  // These events are provider UI deltas. `turn.done` is the single
346
434
  // authoritative finalized transcript persisted below.
347
435
  } else if (event.type === "delegation.created") {
348
- activeDelegationId = event.delegationItemId;
349
- const transcript = delegationTranscript(transcriptSinceDelegation, event.inputTranscript);
350
- const coveredTurnIds = transcriptSinceDelegation.map((entry) => entry.turnId);
351
- durable = enqueue({
352
- operationId: randomUUID(),
353
- kind: "delegation_call",
354
- providerEventId: event.providerEventId,
355
- delegationItemId: event.delegationItemId,
356
- text: renderRealtimeDelegationInput(event.inputTranscript, transcript),
357
- payload: {
358
- offsetMs: event.offsetMs,
359
- inputTranscript: event.inputTranscript,
360
- transcriptFenceTurnIds: coveredTurnIds,
361
- },
362
- });
363
- if (durable) {
364
- const alreadyFinalized = transcriptSinceDelegation.some(
365
- (entry) =>
366
- entry.role === "user" &&
367
- normalizedTranscript(entry.text) === normalizedTranscript(event.inputTranscript),
368
- );
369
- pendingDelegationUserTranscript = alreadyFinalized
370
- ? null
371
- : { delegationItemId: event.delegationItemId, text: event.inputTranscript };
372
- transcriptSinceDelegation = [];
436
+ if (acceptedDelegationItemIds.has(event.delegationItemId)) {
437
+ ignoredEventCount += 1;
438
+ lastIgnoredEventType = event.type;
439
+ } else if (locallyQueuedDelegationItemIds.has(event.delegationItemId)) {
440
+ ignoredEventCount += 1;
441
+ lastIgnoredEventType = event.type;
442
+ durable = true;
443
+ } else {
444
+ let entry = pendingDelegations.get(event.delegationItemId);
445
+ if (!entry) {
446
+ const transcript = delegationTranscript(transcriptSinceDelegation, event.inputTranscript);
447
+ const coveredTurnIds = transcriptSinceDelegation.map((item) => item.turnId);
448
+ const modelContext = currentModelContext();
449
+ entry = {
450
+ operationId: randomUUID(),
451
+ kind: "delegation_call",
452
+ providerEventId: event.providerEventId,
453
+ delegationItemId: event.delegationItemId,
454
+ text: renderRealtimeDelegationInput(event.inputTranscript, transcript),
455
+ payload: {
456
+ offsetMs: event.offsetMs,
457
+ inputTranscript: event.inputTranscript,
458
+ transcriptFenceTurnIds: coveredTurnIds,
459
+ },
460
+ ...(modelContext ? { modelContext } : {}),
461
+ };
462
+ pendingDelegations.set(event.delegationItemId, entry);
463
+ }
464
+ try {
465
+ options.onDelegationReplayStateChange?.({
466
+ acceptedDelegationItemIds,
467
+ pendingDelegations,
468
+ });
469
+ } catch (error) {
470
+ triggerFatalCode(
471
+ "replay_journal_failed",
472
+ `Codex realtime delegation replay journal failed: ${safeError(error)}`,
473
+ );
474
+ return Promise.resolve();
475
+ }
476
+ durable = enqueue(entry);
477
+ if (durable) {
478
+ locallyQueuedDelegationItemIds.add(event.delegationItemId);
479
+ activeDelegationId = event.delegationItemId;
480
+ const frozenInputTranscript =
481
+ typeof entry.payload.inputTranscript === "string"
482
+ ? entry.payload.inputTranscript
483
+ : event.inputTranscript;
484
+ const alreadyFinalized = transcriptSinceDelegation.some(
485
+ (item) =>
486
+ item.role === "user" &&
487
+ normalizedTranscript(item.text) === normalizedTranscript(frozenInputTranscript),
488
+ );
489
+ pendingDelegationUserTranscript = alreadyFinalized
490
+ ? null
491
+ : {
492
+ delegationItemId: event.delegationItemId,
493
+ text: frozenInputTranscript,
494
+ };
495
+ transcriptSinceDelegation = [];
496
+ }
373
497
  }
374
498
  } else if (event.type === "output_audio.delta") {
375
499
  speaking = true;
@@ -383,7 +507,9 @@ export function createCodexRealtimeV3Bridge(
383
507
  normalizedTranscript(pendingDelegationUserTranscript.text)
384
508
  ? pendingDelegationUserTranscript.delegationItemId
385
509
  : null;
386
- durable = enqueue(finalTranscript(randomUUID, event, coveredByDelegationItemId));
510
+ durable = enqueue(
511
+ finalTranscript(randomUUID, event, coveredByDelegationItemId, currentModelContext()),
512
+ );
387
513
  if (durable) {
388
514
  finalizedTurnIds.add(event.turnId);
389
515
  if (coveredByDelegationItemId) {
@@ -446,6 +572,7 @@ function finalTranscript(
446
572
  randomUUID: () => string,
447
573
  event: Extract<CodexRealtimeV3Event, { type: "turn.done" }>,
448
574
  coveredByDelegationItemId: string | null,
575
+ modelContext: string | undefined,
449
576
  ): SessionRealtimeInboundEntry {
450
577
  return {
451
578
  operationId: randomUUID(),
@@ -456,6 +583,7 @@ function finalTranscript(
456
583
  turnId: event.turnId,
457
584
  ...(coveredByDelegationItemId ? { coveredByDelegationItemId } : {}),
458
585
  },
586
+ ...(modelContext ? { modelContext } : {}),
459
587
  };
460
588
  }
461
589
 
@@ -539,7 +667,10 @@ function sendOutbound(events: RTCDataChannel, entry: SessionRealtimeLedgerEntry)
539
667
  text,
540
668
  channel: payloadChannel ?? "speakable",
541
669
  })
542
- : encodeCodexRealtimeV3SessionContextAppend({ text, channel: payloadChannel });
670
+ : encodeCodexRealtimeV3SessionContextAppend({
671
+ text,
672
+ channel: payloadChannel,
673
+ });
543
674
  for (const message of messages) events.send(JSON.stringify(message));
544
675
  }
545
676
 
@@ -261,7 +261,7 @@ export async function startCodexRealtimeWebrtc(
261
261
  );
262
262
  throwIfAborted(options.signal);
263
263
  if (answer.version !== "v3" || answer.model !== "gpt-live-1-boulder-alpha" || !answer.sdp) {
264
- throw new Error("OpenGeni returned an incompatible Codex realtime answer");
264
+ throw new Error("Opengeni returned an incompatible Codex realtime answer");
265
265
  }
266
266
  await peerConnection.setRemoteDescription({
267
267
  type: "answer",
@@ -0,0 +1,59 @@
1
+ import type {
2
+ CompanyBrainContextReceiptPage as ContractCompanyBrainContextReceiptPage,
3
+ CompanyBrainKnowledgeProposalPage as ContractCompanyBrainKnowledgeProposalPage,
4
+ CompanyBrainOkfPackage as ContractCompanyBrainOkfPackage,
5
+ } from "@opengeni/contracts";
6
+
7
+ export type CompanyBrainOkfPackage = ContractCompanyBrainOkfPackage;
8
+ export type CompanyBrainContextReceiptPage = ContractCompanyBrainContextReceiptPage;
9
+ export type CompanyBrainKnowledgeProposalPage = ContractCompanyBrainKnowledgeProposalPage;
10
+
11
+ export type CompanyBrainContextReceiptListOptions = {
12
+ attemptId?: string;
13
+ cursor?: string;
14
+ limit?: number;
15
+ };
16
+
17
+ export type CompanyBrainKnowledgeProposalListOptions = {
18
+ limit?: number;
19
+ };
20
+
21
+ export type CompanyBrainInspectorTransport = {
22
+ requestJson<T>(method: string, path: string, body?: unknown): Promise<T>;
23
+ };
24
+
25
+ function inspectorPath(workspaceId: string, suffix: string): string {
26
+ return `/v1/workspaces/${workspaceId}/company-brain/${suffix}`;
27
+ }
28
+
29
+ export function listCompanyBrainContextReceipts(
30
+ client: CompanyBrainInspectorTransport,
31
+ workspaceId: string,
32
+ options: CompanyBrainContextReceiptListOptions = {},
33
+ ): Promise<CompanyBrainContextReceiptPage> {
34
+ const params = new URLSearchParams();
35
+ if (options.attemptId) params.set("attemptId", options.attemptId);
36
+ if (options.cursor) params.set("cursor", options.cursor);
37
+ if (options.limit !== undefined) params.set("limit", String(options.limit));
38
+ const query = params.toString();
39
+ return client.requestJson(
40
+ "GET",
41
+ `${inspectorPath(workspaceId, "context-receipts")}${query ? `?${query}` : ""}`,
42
+ );
43
+ }
44
+
45
+ export function listCompanyBrainKnowledgeProposals(
46
+ client: CompanyBrainInspectorTransport,
47
+ workspaceId: string,
48
+ options: CompanyBrainKnowledgeProposalListOptions = {},
49
+ ): Promise<CompanyBrainKnowledgeProposalPage> {
50
+ const query =
51
+ options.limit === undefined ? "" : `?limit=${encodeURIComponent(String(options.limit))}`;
52
+ return client.requestJson("GET", `${inspectorPath(workspaceId, "knowledge-proposals")}${query}`);
53
+ }
54
+
55
+ export type CompanyBrainOkfDownload = {
56
+ content: string;
57
+ contentType: string;
58
+ filename: string;
59
+ };
@@ -21,7 +21,10 @@ export type CompanyProfileRevision = CompanyProfileRevisionIdentity & {
21
21
  accountId: string;
22
22
  intent: "active" | "proposal";
23
23
  profile: CompanyProfileContent;
24
- provenance: { source: "human" | "durable_learning" | "migration"; sourceId: string | null };
24
+ provenance: {
25
+ source: "human" | "agent_admin" | "durable_learning" | "migration";
26
+ sourceId: string | null;
27
+ };
25
28
  supersedesRevisionId: string | null;
26
29
  createdBySubjectId: string;
27
30
  createdAt: string;
@@ -79,6 +82,19 @@ export type CompanyProfileMutationResponse = {
79
82
  head: CompanyProfileHead | null;
80
83
  event: CompanyProfileActivationEvent | null;
81
84
  };
85
+ export type CompanyProfileAgentPolicyMode = "off" | "suggest" | "automatic";
86
+ export type CompanyProfileAgentPolicy = {
87
+ organizationId: string;
88
+ mode: CompanyProfileAgentPolicyMode;
89
+ version: number;
90
+ updatedAt: string;
91
+ changed?: boolean;
92
+ };
93
+ export type UpdateCompanyProfileAgentPolicyRequest = {
94
+ mode: CompanyProfileAgentPolicyMode;
95
+ expectedVersion: number;
96
+ operationId: string;
97
+ };
82
98
  export type CompanyProfileDiffRequest = { fromRevisionId: string; toRevisionId: string };
83
99
  export type CompanyProfileDiffResponse = {
84
100
  from: CompanyProfileRevision;
package/src/core.ts CHANGED
@@ -1,6 +1,22 @@
1
- export { OpenGeniClient as OpenGeniCoreClient } from "./client";
1
+ /** Backward-compatible non-artifact client surface. */
2
+ export { OpenGeniDocumentAuthorityClient as OpenGeniCoreClient } from "./document-authority-client";
3
+ export {
4
+ OpenGeniToolCallError,
5
+ OpenGeniToolReapprovalRequiredError,
6
+ OpenGeniToolsClient,
7
+ } from "./tools";
8
+ export type {
9
+ OpenGeniGeneratedTools,
10
+ OpenGeniDynamicToolNode,
11
+ OpenGeniToolCallOptions,
12
+ OpenGeniToolFunction,
13
+ OpenGeniToolsFacade,
14
+ OpenGeniWorkspaceTools,
15
+ } from "./tools";
2
16
  export type {
3
17
  FetchLike,
18
+ FetchResponse,
19
+ GetSessionOptions,
4
20
  OpenGeniClientOptions,
5
21
  OpenGeniRequestOptions,
6
22
  SendMessageInput,
@@ -11,9 +27,15 @@ export type {
11
27
  export {
12
28
  OpenGeniApiContractMismatchError,
13
29
  OpenGeniApiError,
30
+ OpenGeniSetupError,
31
+ OpenGeniSecureContextRequiredError,
14
32
  OpenGeniSessionListCursorError,
15
33
  OpenGeniStreamError,
34
+ formatErrorMessage,
16
35
  isRetryableStreamError,
17
36
  } from "./errors";
37
+ export type { OpenGeniSecureContextRequiredReason } from "./errors";
38
+ export { parseDeprecationNotice } from "./deprecation";
39
+ export type { OpenGeniDeprecationHandler, OpenGeniDeprecationNotice } from "./deprecation";
18
40
  export { resolveWorkspaceVoiceInputEnabled } from "./transcription";
19
41
  export { OPENGENI_API_CONTRACT_HEADER, OPENGENI_API_CONTRACT_REVISION } from "./types";
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Deprecation notices advertised by the OpenGeni API.
3
+ *
4
+ * Per the public API compatibility policy, a route whose behaviour is scheduled
5
+ * for removal answers with the standard `Deprecation` (RFC 9745) and `Sunset`
6
+ * (RFC 8594) headers plus `Link: <notes>; rel="deprecation"`. The client
7
+ * surfaces them through `OpenGeniClientOptions.onDeprecation`, or by default
8
+ * as a one-time `console.warn` per route, so an integrator pinned to an older
9
+ * SDK learns about a removal well before it happens.
10
+ */
11
+
12
+ export type OpenGeniDeprecationNotice = {
13
+ /** Request method, upper case. */
14
+ method: string;
15
+ /** Request path with ids collapsed (`/v1/workspaces/:id/...`), stable per route. */
16
+ route: string;
17
+ /** Exact request path. */
18
+ path: string;
19
+ /** When the deprecation was announced, if the header carried a date. */
20
+ deprecatedAt: Date | null;
21
+ /** Earliest removal on the server, if advertised. */
22
+ sunset: Date | null;
23
+ /** Migration notes (`rel="deprecation"`), if advertised. */
24
+ link: string | null;
25
+ /** Replacement (`rel="successor-version"`), if advertised. */
26
+ successor: string | null;
27
+ };
28
+
29
+ /** `false` silences notices; a function receives each route's notice once per client. */
30
+ export type OpenGeniDeprecationHandler = (notice: OpenGeniDeprecationNotice) => void;
31
+
32
+ type HeaderBag = { get(name: string): string | null };
33
+
34
+ const ID_SEGMENT =
35
+ /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|\d+|[A-Za-z0-9_-]{20,})$/i;
36
+
37
+ function routeKey(path: string): string {
38
+ return path
39
+ .split("/")
40
+ .map((segment) => (ID_SEGMENT.test(segment) ? ":id" : segment))
41
+ .join("/");
42
+ }
43
+
44
+ function parseDeprecationDate(value: string): Date | null {
45
+ const trimmed = value.trim();
46
+ // RFC 9745 structured date `@<unix seconds>`; older drafts used `true` or an HTTP-date.
47
+ const structured = /^@(-?\d+)$/.exec(trimmed);
48
+ if (structured) return new Date(Number(structured[1]) * 1000);
49
+ const parsed = Date.parse(trimmed);
50
+ return Number.isNaN(parsed) ? null : new Date(parsed);
51
+ }
52
+
53
+ function parseLinks(value: string | null): Map<string, string> {
54
+ const links = new Map<string, string>();
55
+ if (!value) return links;
56
+ for (const match of value.matchAll(/<([^>]*)>\s*((?:;\s*[^;,]+)*)/g)) {
57
+ const rel = /;\s*rel="?([^";,]+)"?/i.exec(match[2] ?? "")?.[1];
58
+ if (!rel) continue;
59
+ for (const name of rel.toLowerCase().split(/\s+/)) {
60
+ if (!links.has(name)) links.set(name, match[1]!);
61
+ }
62
+ }
63
+ return links;
64
+ }
65
+
66
+ /** Read a deprecation notice from response headers; `null` when none is advertised. */
67
+ export function parseDeprecationNotice(
68
+ method: string,
69
+ url: string,
70
+ headers: HeaderBag,
71
+ ): OpenGeniDeprecationNotice | null {
72
+ const deprecation = headers.get("deprecation");
73
+ const sunsetHeader = headers.get("sunset");
74
+ if (!deprecation && !sunsetHeader) return null;
75
+ let path = url;
76
+ try {
77
+ path = new URL(url, "http://opengeni.invalid").pathname;
78
+ } catch {
79
+ // Keep the raw value; the notice is advisory.
80
+ }
81
+ const sunset = sunsetHeader ? Date.parse(sunsetHeader) : Number.NaN;
82
+ const links = parseLinks(headers.get("link"));
83
+ return {
84
+ method: method.toUpperCase(),
85
+ route: routeKey(path),
86
+ path,
87
+ deprecatedAt: deprecation ? parseDeprecationDate(deprecation) : null,
88
+ sunset: Number.isNaN(sunset) ? null : new Date(sunset),
89
+ link: links.get("deprecation") ?? links.get("sunset") ?? null,
90
+ successor: links.get("successor-version") ?? null,
91
+ };
92
+ }
93
+
94
+ const warnedRoutes = new Set<string>();
95
+
96
+ /** The default handler: one `console.warn` per route per process. */
97
+ export function warnDeprecationOnce(notice: OpenGeniDeprecationNotice): void {
98
+ const key = `${notice.method} ${notice.route}`;
99
+ if (warnedRoutes.has(key)) return;
100
+ warnedRoutes.add(key);
101
+ const sunset = notice.sunset ? ` and will be removed after ${notice.sunset.toISOString()}` : "";
102
+ const notes = notice.link ? ` Migration notes: ${notice.link}.` : "";
103
+ console.warn(
104
+ `[@opengeni/sdk] ${key} is deprecated${sunset}.${notes} Upgrade @opengeni/sdk, or pass onDeprecation to handle this notice.`,
105
+ );
106
+ }
107
+
108
+ type FetchFunction<R extends { headers: HeaderBag }> = (
109
+ input: string | URL | Request,
110
+ init?: RequestInit,
111
+ ) => Promise<R>;
112
+
113
+ /**
114
+ * Wrap a fetch implementation so every response is inspected for a deprecation
115
+ * notice. The handler runs at most once per route for this wrapper and never
116
+ * affects the request: a throwing handler is swallowed.
117
+ */
118
+ export function withDeprecationNotices<R extends { headers: HeaderBag }>(
119
+ fetchImpl: FetchFunction<R>,
120
+ handler: OpenGeniDeprecationHandler | false | undefined,
121
+ ): FetchFunction<R> {
122
+ if (handler === false) return fetchImpl;
123
+ const notify = handler ?? warnDeprecationOnce;
124
+ const seen = new Set<string>();
125
+ return async (input, init) => {
126
+ const response = await fetchImpl(input, init);
127
+ try {
128
+ const headers = response.headers;
129
+ if (headers && (headers.get("deprecation") || headers.get("sunset"))) {
130
+ const method =
131
+ init?.method ??
132
+ (typeof Request !== "undefined" && input instanceof Request ? input.method : "GET");
133
+ const url =
134
+ typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
135
+ const notice = parseDeprecationNotice(method, url, headers);
136
+ if (notice) {
137
+ const key = `${notice.method} ${notice.route}`;
138
+ if (!seen.has(key)) {
139
+ seen.add(key);
140
+ notify(notice);
141
+ }
142
+ }
143
+ }
144
+ } catch {
145
+ // Deprecation notices are advisory and must never fail a request.
146
+ }
147
+ return response;
148
+ };
149
+ }
package/src/desktop.ts CHANGED
@@ -71,13 +71,23 @@ export interface DesktopRfbLike {
71
71
  type: "connect" | "disconnect" | "securityfailure",
72
72
  cb: (e?: unknown) => void,
73
73
  ) => void;
74
+ /** Send clipboard text over the already-open RFB connection. */
75
+ clipboardPasteFrom?(text: string): void;
76
+ /** Send one RFB key event. A missing `down` emits a complete key press. */
77
+ sendKey?(keysym: number, code: string, down?: boolean): void;
78
+ /** Focus or release the RFB keyboard sink without reconnecting. */
79
+ focus?(options?: FocusOptions): void;
80
+ blur?(): void;
74
81
  disconnect(): void;
75
82
  }
76
83
 
77
84
  export type DesktopRfbFactory = (
78
85
  target: HTMLElement,
79
86
  url: string,
80
- opts: { credentials?: { password?: string | undefined } | undefined },
87
+ opts: {
88
+ credentials?: { password?: string | undefined } | undefined;
89
+ wsProtocols?: string[] | undefined;
90
+ },
81
91
  ) => DesktopRfbLike;
82
92
 
83
93
  export type DesktopConnectionState =