@opengeni/react 0.48.0 → 0.57.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 (325) hide show
  1. package/README.md +138 -2
  2. package/dist/artifacts-document.d.ts +3 -0
  3. package/dist/artifacts-document.js +17 -0
  4. package/dist/artifacts-document.js.map +1 -0
  5. package/dist/artifacts-presentation.d.ts +3 -0
  6. package/dist/artifacts-presentation.js +17 -0
  7. package/dist/artifacts-presentation.js.map +1 -0
  8. package/dist/artifacts-spreadsheet.d.ts +3 -0
  9. package/dist/artifacts-spreadsheet.js +17 -0
  10. package/dist/artifacts-spreadsheet.js.map +1 -0
  11. package/dist/artifacts.d.ts +2 -0
  12. package/dist/artifacts.js +199 -0
  13. package/dist/artifacts.js.map +1 -0
  14. package/dist/{chunk-NJ7M2B6Z.js → chunk-5UQPNLIO.js} +16 -8
  15. package/dist/{chunk-NJ7M2B6Z.js.map → chunk-5UQPNLIO.js.map} +1 -1
  16. package/dist/{chunk-LHLYWG5R.js → chunk-6KLX2RH5.js} +461 -38
  17. package/dist/chunk-6KLX2RH5.js.map +1 -0
  18. package/dist/chunk-7WCLAEFV.js +2828 -0
  19. package/dist/chunk-7WCLAEFV.js.map +1 -0
  20. package/dist/{chunk-I4MPFDRP.js → chunk-B6WPZSTT.js} +104 -104
  21. package/dist/{chunk-I4MPFDRP.js.map → chunk-B6WPZSTT.js.map} +1 -1
  22. package/dist/{chunk-EKZH6IDG.js → chunk-C5ZPSSS5.js} +111 -1
  23. package/dist/chunk-C5ZPSSS5.js.map +1 -0
  24. package/dist/{chunk-OL6QVXGF.js → chunk-HA46CYQK.js} +152 -8
  25. package/dist/chunk-HA46CYQK.js.map +1 -0
  26. package/dist/chunk-HUIKIDM5.js +2148 -0
  27. package/dist/chunk-HUIKIDM5.js.map +1 -0
  28. package/dist/{chunk-FWXGSNXT.js → chunk-IGC6A2ZI.js} +585 -34
  29. package/dist/chunk-IGC6A2ZI.js.map +1 -0
  30. package/dist/chunk-JVYQRRC4.js +53 -0
  31. package/dist/chunk-JVYQRRC4.js.map +1 -0
  32. package/dist/chunk-KCGXPP5V.js +157 -0
  33. package/dist/chunk-KCGXPP5V.js.map +1 -0
  34. package/dist/chunk-LLOLUHVG.js +5937 -0
  35. package/dist/chunk-LLOLUHVG.js.map +1 -0
  36. package/dist/{chunk-WYA65Y3F.js → chunk-MKPIAGVL.js} +13 -3
  37. package/dist/chunk-MKPIAGVL.js.map +1 -0
  38. package/dist/chunk-PEI6RANI.js +3234 -0
  39. package/dist/chunk-PEI6RANI.js.map +1 -0
  40. package/dist/chunk-R3AZOAB5.js +933 -0
  41. package/dist/chunk-R3AZOAB5.js.map +1 -0
  42. package/dist/{chunk-O4VXOBGF.js → chunk-WSK7G5LE.js} +70 -2
  43. package/dist/chunk-WSK7G5LE.js.map +1 -0
  44. package/dist/{chunk-23EJ676W.js → chunk-XBZWOM2K.js} +9 -4
  45. package/dist/chunk-XBZWOM2K.js.map +1 -0
  46. package/dist/{chunk-XCNTXWBB.js → chunk-Y7OEDUJ5.js} +856 -338
  47. package/dist/chunk-Y7OEDUJ5.js.map +1 -0
  48. package/dist/client.d.ts +10 -2
  49. package/dist/clipboard.d.ts +1 -0
  50. package/dist/clipboard.js +7 -0
  51. package/dist/clipboard.js.map +1 -0
  52. package/dist/commands/index.d.ts +3 -3
  53. package/dist/commands/registry.d.ts +1 -1
  54. package/dist/commands/types.d.ts +1 -1
  55. package/dist/components/approval-surface.d.ts +2 -2
  56. package/dist/components/artifacts/artifact-surface.d.ts +18 -0
  57. package/dist/components/artifacts/document-editor.d.ts +172 -0
  58. package/dist/components/artifacts/editable-artifact-ui.d.ts +13 -0
  59. package/dist/components/artifacts/editable-artifact-workbench.d.ts +49 -0
  60. package/dist/components/artifacts/editable-document.d.ts +24 -0
  61. package/dist/components/artifacts/editable-presentation.d.ts +24 -0
  62. package/dist/components/artifacts/editable-spreadsheet.d.ts +32 -0
  63. package/dist/components/artifacts/index.d.ts +9 -0
  64. package/dist/components/artifacts/presentation-editor.d.ts +297 -0
  65. package/dist/components/artifacts/published-html-artifact-frame.d.ts +14 -0
  66. package/dist/components/artifacts/spreadsheet-canvas.d.ts +120 -0
  67. package/dist/components/artifacts/spreadsheet-grid.d.ts +113 -0
  68. package/dist/components/browser-input.d.ts +7 -0
  69. package/dist/components/browser-viewer.d.ts +30 -0
  70. package/dist/components/chat-composer.d.ts +8 -8
  71. package/dist/components/code-editor.d.ts +25 -3
  72. package/dist/components/command-palette.d.ts +2 -2
  73. package/dist/components/composer-transcription-control.d.ts +2 -2
  74. package/dist/components/composer.d.ts +17 -17
  75. package/dist/components/computer-viewer.d.ts +24 -0
  76. package/dist/components/copy-button.d.ts +2 -2
  77. package/dist/components/desktop-viewer.d.ts +50 -22
  78. package/dist/components/diff-view.d.ts +1 -1
  79. package/dist/components/enrollment-consent.d.ts +1 -1
  80. package/dist/components/enrollment-device-flow.d.ts +1 -1
  81. package/dist/components/file-browser.d.ts +2 -2
  82. package/dist/components/fleet-tile.d.ts +1 -1
  83. package/dist/components/generated-video-player.d.ts +10 -0
  84. package/dist/components/human-input-form.d.ts +1 -1
  85. package/dist/components/human-input-surface.d.ts +2 -2
  86. package/dist/components/interaction-intervention-banner.d.ts +11 -0
  87. package/dist/components/interactive-workbench-viewers.d.ts +2 -0
  88. package/dist/components/machine-card.d.ts +2 -2
  89. package/dist/components/machine-dock-bar.d.ts +3 -3
  90. package/dist/components/machine-health-pill.d.ts +2 -2
  91. package/dist/components/machine-input-display.d.ts +1 -1
  92. package/dist/components/machine-metrics.d.ts +2 -2
  93. package/dist/components/machine-status-pill.d.ts +4 -4
  94. package/dist/components/machines/health.d.ts +1 -1
  95. package/dist/components/machines/machine-detail.d.ts +3 -3
  96. package/dist/components/machines/metric-history-chart.d.ts +1 -1
  97. package/dist/components/machines/metric-sparkline.d.ts +2 -2
  98. package/dist/components/machines/series.d.ts +2 -2
  99. package/dist/components/machines-dashboard.d.ts +2 -2
  100. package/dist/components/markdown.d.ts +1 -1
  101. package/dist/components/message-timeline.d.ts +12 -5
  102. package/dist/components/model-picker.d.ts +2 -2
  103. package/dist/components/model-policy-picker.d.ts +7 -7
  104. package/dist/components/pierre-diff.d.ts +1 -1
  105. package/dist/components/pierre-file.d.ts +1 -1
  106. package/dist/components/queue-draft-policy.d.ts +1 -1
  107. package/dist/components/queue-surface-implementation.d.ts +3 -3
  108. package/dist/components/queue-surface-state.d.ts +4 -4
  109. package/dist/components/queue-surface.d.ts +5 -5
  110. package/dist/components/sandbox-files.d.ts +3 -3
  111. package/dist/components/sandbox-terminal.d.ts +24 -4
  112. package/dist/components/sandbox-workspace.d.ts +28 -9
  113. package/dist/components/session-chrome.d.ts +4 -4
  114. package/dist/components/session-status.d.ts +2 -2
  115. package/dist/components/timeline-annotation-selection.d.ts +9 -0
  116. package/dist/components/timeline-annotations-dialog.d.ts +16 -0
  117. package/dist/components/timeline-annotations.d.ts +13 -0
  118. package/dist/components/tooltip.d.ts +4 -4
  119. package/dist/components/user-message-body.d.ts +2 -2
  120. package/dist/components/workbench-changes.d.ts +2 -2
  121. package/dist/components/workspace-dock.d.ts +1 -1
  122. package/dist/composer.d.ts +11 -11
  123. package/dist/composer.js +7 -7
  124. package/dist/hooks/internal.d.ts +1 -1
  125. package/dist/hooks/use-attached-browsers.d.ts +21 -0
  126. package/dist/hooks/use-auth-runs.d.ts +32 -0
  127. package/dist/hooks/use-available-models.d.ts +2 -2
  128. package/dist/hooks/use-billing-usage.d.ts +1 -1
  129. package/dist/hooks/use-browser-downloads.d.ts +25 -0
  130. package/dist/hooks/use-browser-frame-stream.d.ts +28 -0
  131. package/dist/hooks/use-browser-identities.d.ts +30 -0
  132. package/dist/hooks/use-browser-session.d.ts +29 -0
  133. package/dist/hooks/use-browser-sessions.d.ts +32 -0
  134. package/dist/hooks/use-channels.d.ts +26 -0
  135. package/dist/hooks/use-codex-accounts.d.ts +2 -2
  136. package/dist/hooks/use-composer.d.ts +36 -9
  137. package/dist/hooks/use-computer-frame-stream.d.ts +24 -0
  138. package/dist/hooks/use-computer-session.d.ts +29 -0
  139. package/dist/hooks/use-computer-sessions.d.ts +28 -0
  140. package/dist/hooks/use-desktop-stream.d.ts +5 -1
  141. package/dist/hooks/use-environments.d.ts +1 -1
  142. package/dist/hooks/use-file-attachments.d.ts +1 -1
  143. package/dist/hooks/use-goal.d.ts +2 -2
  144. package/dist/hooks/use-human-input.d.ts +2 -2
  145. package/dist/hooks/use-interaction-interventions.d.ts +27 -0
  146. package/dist/hooks/use-interaction-invalidation.d.ts +19 -0
  147. package/dist/hooks/use-last-started-turn-policy.d.ts +2 -2
  148. package/dist/hooks/use-machine-chip.d.ts +2 -2
  149. package/dist/hooks/use-machines.d.ts +4 -4
  150. package/dist/hooks/use-network-routes.d.ts +25 -0
  151. package/dist/hooks/use-packs.d.ts +7 -2
  152. package/dist/hooks/use-rigs.d.ts +1 -1
  153. package/dist/hooks/use-sandbox-files.d.ts +6 -4
  154. package/dist/hooks/use-sandbox-git.d.ts +6 -5
  155. package/dist/hooks/use-sandbox-terminal.d.ts +1 -1
  156. package/dist/hooks/use-scheduled-tasks.d.ts +1 -1
  157. package/dist/hooks/use-session-capabilities.d.ts +5 -4
  158. package/dist/hooks/use-session-control.d.ts +1 -1
  159. package/dist/hooks/use-session-events.d.ts +2 -2
  160. package/dist/hooks/use-session-lineage.d.ts +1 -1
  161. package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
  162. package/dist/hooks/use-session.d.ts +2 -2
  163. package/dist/hooks/use-site-auth-connections.d.ts +25 -0
  164. package/dist/hooks/use-slash-commands.d.ts +1 -1
  165. package/dist/hooks/use-supergrok-accounts.d.ts +26 -0
  166. package/dist/hooks/use-terminal-stream.d.ts +11 -2
  167. package/dist/hooks/use-turn-queue.d.ts +2 -2
  168. package/dist/hooks/use-video-artifact-playback.d.ts +9 -0
  169. package/dist/hooks/use-voice-input.d.ts +1 -1
  170. package/dist/hooks/use-workspace-capture.d.ts +1 -1
  171. package/dist/hooks/use-workspace-edit.d.ts +1 -1
  172. package/dist/hooks/use-workspace-sessions.d.ts +1 -1
  173. package/dist/hooks/use-workspaces.d.ts +1 -1
  174. package/dist/index.d.ts +162 -155
  175. package/dist/index.js +1822 -1703
  176. package/dist/index.js.map +1 -1
  177. package/dist/interaction.d.ts +33 -0
  178. package/dist/interaction.js +550 -0
  179. package/dist/interaction.js.map +1 -0
  180. package/dist/interactive-workbench-viewers-TOHBXJEE.js +15 -0
  181. package/dist/interactive-workbench-viewers-TOHBXJEE.js.map +1 -0
  182. package/dist/lib/host-platform.d.ts +5 -0
  183. package/dist/lib/relay-wire.d.ts +24 -1
  184. package/dist/lib/sandbox-liveness.d.ts +9 -0
  185. package/dist/lib/terminal-capability.d.ts +5 -0
  186. package/dist/lib/xterm-theme.d.ts +1 -1
  187. package/dist/machines.d.ts +30 -30
  188. package/dist/machines.js +2 -2
  189. package/dist/model-policy.d.ts +1 -1
  190. package/dist/model-policy.js +1 -1
  191. package/dist/provider.d.ts +6 -5
  192. package/dist/{queue-surface-implementation-U5JFG7HT.js → queue-surface-implementation-2KVJTYXH.js} +100 -48
  193. package/dist/queue-surface-implementation-2KVJTYXH.js.map +1 -0
  194. package/dist/realtime/dropdown-menu.d.ts +8 -8
  195. package/dist/realtime/realtime-control.d.ts +8 -8
  196. package/dist/realtime.d.ts +4 -4
  197. package/dist/realtime.js +38 -11
  198. package/dist/realtime.js.map +1 -1
  199. package/dist/session-context.d.ts +28 -2
  200. package/dist/session-ui.d.ts +14 -14
  201. package/dist/session-ui.js +5 -4
  202. package/dist/session.d.ts +28 -28
  203. package/dist/session.js +10 -10
  204. package/dist/timeline/activity-rail.d.ts +5 -3
  205. package/dist/timeline/disclosure-context.d.ts +1 -1
  206. package/dist/timeline/fleet-decision-projection.d.ts +1 -1
  207. package/dist/timeline/fleet-decision-row.d.ts +3 -3
  208. package/dist/timeline/index.d.ts +19 -19
  209. package/dist/timeline/parsers.d.ts +4 -1
  210. package/dist/timeline/projection.d.ts +3 -3
  211. package/dist/timeline/registry.d.ts +8 -2
  212. package/dist/timeline/screenshot-lightbox.d.ts +2 -2
  213. package/dist/timeline/shared.d.ts +21 -10
  214. package/dist/timeline/tool-diff.d.ts +2 -2
  215. package/dist/timeline/tool-renderers.d.ts +1 -1
  216. package/dist/timeline/turn-summary.d.ts +3 -3
  217. package/dist/timeline/types.d.ts +44 -3
  218. package/dist/timeline-annotation-selection-3L7LHGG2.js +187 -0
  219. package/dist/timeline-annotation-selection-3L7LHGG2.js.map +1 -0
  220. package/dist/timeline-annotations-dialog-U7EVLR75.js +196 -0
  221. package/dist/timeline-annotations-dialog-U7EVLR75.js.map +1 -0
  222. package/package.json +36 -7
  223. package/src/artifacts-document.ts +31 -0
  224. package/src/artifacts-presentation.ts +36 -0
  225. package/src/artifacts-spreadsheet.ts +21 -0
  226. package/src/artifacts.ts +89 -0
  227. package/src/client.ts +157 -1
  228. package/src/clipboard.ts +2 -0
  229. package/src/components/artifacts/artifact-surface.tsx +93 -0
  230. package/src/components/artifacts/document-editor.tsx +2255 -0
  231. package/src/components/artifacts/editable-artifact-ui.tsx +89 -0
  232. package/src/components/artifacts/editable-artifact-workbench.tsx +203 -0
  233. package/src/components/artifacts/editable-document.tsx +657 -0
  234. package/src/components/artifacts/editable-presentation.tsx +1020 -0
  235. package/src/components/artifacts/editable-spreadsheet.tsx +733 -0
  236. package/src/components/artifacts/index.ts +104 -0
  237. package/src/components/artifacts/presentation-editor.tsx +3148 -0
  238. package/src/components/artifacts/published-html-artifact-frame.tsx +38 -0
  239. package/src/components/artifacts/spreadsheet-canvas.ts +799 -0
  240. package/src/components/artifacts/spreadsheet-grid.tsx +2129 -0
  241. package/src/components/browser-input.ts +65 -0
  242. package/src/components/browser-viewer.tsx +2702 -0
  243. package/src/components/chat-composer.tsx +13 -0
  244. package/src/components/code-editor.tsx +89 -30
  245. package/src/components/composer-transcription-control.tsx +10 -6
  246. package/src/components/computer-viewer.tsx +1636 -0
  247. package/src/components/desktop-viewer.tsx +215 -74
  248. package/src/components/generated-video-player.tsx +89 -0
  249. package/src/components/interaction-intervention-banner.tsx +99 -0
  250. package/src/components/interactive-workbench-viewers.ts +2 -0
  251. package/src/components/machine-input-display.ts +3 -0
  252. package/src/components/machines/machine-detail.tsx +1 -1
  253. package/src/components/message-timeline.tsx +289 -32
  254. package/src/components/model-policy-picker.tsx +15 -0
  255. package/src/components/queue-surface-implementation.tsx +116 -60
  256. package/src/components/sandbox-files.tsx +2 -2
  257. package/src/components/sandbox-terminal.tsx +128 -46
  258. package/src/components/sandbox-workspace.tsx +256 -90
  259. package/src/components/session-chrome.tsx +53 -13
  260. package/src/components/timeline-annotation-selection.tsx +221 -0
  261. package/src/components/timeline-annotations-dialog.tsx +213 -0
  262. package/src/components/timeline-annotations.tsx +84 -0
  263. package/src/components/workbench-changes.tsx +188 -31
  264. package/src/components/workspace-dock.tsx +59 -5
  265. package/src/hooks/use-attached-browsers.ts +154 -0
  266. package/src/hooks/use-auth-runs.ts +278 -0
  267. package/src/hooks/use-browser-downloads.ts +218 -0
  268. package/src/hooks/use-browser-frame-stream.ts +425 -0
  269. package/src/hooks/use-browser-identities.ts +266 -0
  270. package/src/hooks/use-browser-session.ts +543 -0
  271. package/src/hooks/use-browser-sessions.ts +286 -0
  272. package/src/hooks/use-channels.ts +99 -0
  273. package/src/hooks/use-composer.ts +769 -24
  274. package/src/hooks/use-computer-frame-stream.ts +434 -0
  275. package/src/hooks/use-computer-session.ts +462 -0
  276. package/src/hooks/use-computer-sessions.ts +251 -0
  277. package/src/hooks/use-desktop-stream.ts +39 -7
  278. package/src/hooks/use-interaction-interventions.ts +242 -0
  279. package/src/hooks/use-interaction-invalidation.ts +66 -0
  280. package/src/hooks/use-machine-chip.ts +15 -3
  281. package/src/hooks/use-machines.ts +33 -3
  282. package/src/hooks/use-network-routes.ts +214 -0
  283. package/src/hooks/use-packs.ts +51 -0
  284. package/src/hooks/use-sandbox-files.ts +98 -55
  285. package/src/hooks/use-sandbox-git.ts +93 -38
  286. package/src/hooks/use-sandbox-terminal.ts +3 -2
  287. package/src/hooks/use-session-capabilities.ts +59 -46
  288. package/src/hooks/use-site-auth-connections.ts +226 -0
  289. package/src/hooks/use-supergrok-accounts.ts +81 -0
  290. package/src/hooks/use-terminal-stream.ts +359 -47
  291. package/src/hooks/use-video-artifact-playback.ts +28 -0
  292. package/src/hooks/use-workspace-edit.ts +2 -1
  293. package/src/index.ts +18 -0
  294. package/src/interaction.ts +101 -0
  295. package/src/lib/host-platform.ts +10 -0
  296. package/src/lib/relay-wire.ts +47 -4
  297. package/src/lib/sandbox-liveness.ts +11 -0
  298. package/src/lib/terminal-capability.ts +10 -0
  299. package/src/model-policy.ts +19 -4
  300. package/src/provider.tsx +133 -1
  301. package/src/realtime/realtime-control.tsx +34 -6
  302. package/src/session-context.ts +156 -1
  303. package/src/timeline/activity-rail.tsx +25 -3
  304. package/src/timeline/index.ts +3 -0
  305. package/src/timeline/parsers.ts +14 -1
  306. package/src/timeline/projection.ts +269 -14
  307. package/src/timeline/registry.ts +13 -1
  308. package/src/timeline/screenshot-lightbox.tsx +19 -9
  309. package/src/timeline/shared.tsx +56 -8
  310. package/src/timeline/tool-renderers.tsx +303 -50
  311. package/src/timeline/types.ts +57 -3
  312. package/styles/compiled.css +312 -21
  313. package/styles/index.css +15 -0
  314. package/styles/responsive.css +13 -1
  315. package/dist/chunk-23EJ676W.js.map +0 -1
  316. package/dist/chunk-EKZH6IDG.js.map +0 -1
  317. package/dist/chunk-FWXGSNXT.js.map +0 -1
  318. package/dist/chunk-LHLYWG5R.js.map +0 -1
  319. package/dist/chunk-O4VXOBGF.js.map +0 -1
  320. package/dist/chunk-OL6QVXGF.js.map +0 -1
  321. package/dist/chunk-WYA65Y3F.js.map +0 -1
  322. package/dist/chunk-XCNTXWBB.js.map +0 -1
  323. package/dist/fleet-decision-projection-SLNZMS42.js +0 -241
  324. package/dist/fleet-decision-projection-SLNZMS42.js.map +0 -1
  325. package/dist/queue-surface-implementation-U5JFG7HT.js.map +0 -1
package/src/index.ts CHANGED
@@ -9,9 +9,12 @@
9
9
  // container-responsive composers additionally import responsive.css.
10
10
 
11
11
  export type {
12
+ EmbeddedBrowserInteractionClientLike,
13
+ EmbeddedComputerInteractionClientLike,
12
14
  EmbeddedFileAttachmentClientLike,
13
15
  EmbeddedGoalClientLike,
14
16
  EmbeddedHumanInputSessionClientLike,
17
+ EmbeddedInteractionClientLike,
15
18
  EmbeddedSessionEventClientLike,
16
19
  EmbeddedSessionLineageClientLike,
17
20
  EmbeddedSessionMcpApprovalPolicyClientLike,
@@ -22,6 +25,7 @@ export type {
22
25
  export { OpenGeniProvider } from "./provider";
23
26
  export type { OpenGeniProviderProps } from "./provider";
24
27
  export { useOpenGeni, useOpenGeniClient } from "./session-context";
28
+ export { useVideoArtifactPlaybackLoader } from "./hooks/use-video-artifact-playback";
25
29
  export type { ClientOverride, OpenGeniContextValue } from "./session-context";
26
30
  export { usePageLiveActivity } from "./hooks/internal";
27
31
 
@@ -171,6 +175,8 @@ export type {
171
175
  UseEnvironmentsOptions,
172
176
  UseEnvironmentsResult,
173
177
  } from "./hooks/use-environments";
178
+ export { useChannels } from "./hooks/use-channels";
179
+ export type { UseChannelsOptions, UseChannelsResult } from "./hooks/use-channels";
174
180
  export { useRigs, useRig, useRigVersions, useRigChanges } from "./hooks/use-rigs";
175
181
  export type {
176
182
  UseRigsOptions,
@@ -332,6 +338,9 @@ export {
332
338
  } from "./timeline";
333
339
  export type {
334
340
  CreateToolRegistryOptions,
341
+ RetainedArtifactLoader,
342
+ RetainedScreenshotLoader,
343
+ VideoArtifactPlaybackLoader,
335
344
  ToolRegistry,
336
345
  ToolRegistryEntry,
337
346
  ToolRenderer,
@@ -464,6 +473,8 @@ export {
464
473
  } from "./model-policy";
465
474
  export type { LatencyModeId, PickerBillingClass, PickerModelRow } from "./model-policy";
466
475
  export { MessageTimeline, TimelineRow } from "./components/message-timeline";
476
+ export { GeneratedVideoPlayer } from "./components/generated-video-player";
477
+ export type { GeneratedVideoPlayerProps } from "./components/generated-video-player";
467
478
  export type { MessageTimelineProps } from "./components/message-timeline";
468
479
  export { UserMessageBody, userMessageLikelyNeedsDisclosure } from "./components/user-message-body";
469
480
  export type { UserMessageBodyProps } from "./components/user-message-body";
@@ -511,6 +522,7 @@ export {
511
522
  WORKBENCH_TAB_CHANGES,
512
523
  WORKBENCH_TAB_FILES,
513
524
  WORKBENCH_TAB_TERMINAL,
525
+ WORKBENCH_TAB_BROWSER,
514
526
  WORKBENCH_TAB_DESKTOP,
515
527
  WORKBENCH_SURFACES,
516
528
  } from "./components/sandbox-workspace";
@@ -533,6 +545,12 @@ export type {
533
545
  UseCodexAccountsOptions,
534
546
  UseCodexAccountsResult,
535
547
  } from "./hooks/use-codex-accounts";
548
+ export { useSuperGrokAccounts } from "./hooks/use-supergrok-accounts";
549
+ export type {
550
+ SuperGrokAccountsClientLike,
551
+ UseSuperGrokAccountsOptions,
552
+ UseSuperGrokAccountsResult,
553
+ } from "./hooks/use-supergrok-accounts";
536
554
 
537
555
  // Sandbox helpers
538
556
  export { gitFileDiffToPatch } from "./lib/git-patch";
@@ -0,0 +1,101 @@
1
+ // @opengeni/react/interaction — standalone Browser/Computer resource UI.
2
+ // Framework hosts may pass a narrow structural client instead of the full provider.
3
+ export type {
4
+ EmbeddedBrowserInteractionClientLike,
5
+ EmbeddedComputerInteractionClientLike,
6
+ EmbeddedInteractionClientLike,
7
+ EmbeddedInterventionClientLike,
8
+ } from "./client";
9
+ export {
10
+ useEmbeddedBrowserInteraction,
11
+ useEmbeddedComputerInteraction,
12
+ useEmbeddedInteraction,
13
+ useEmbeddedInterventions,
14
+ } from "./session-context";
15
+ export type {
16
+ EmbeddedBrowserInteractionClientOverride,
17
+ EmbeddedComputerInteractionClientOverride,
18
+ EmbeddedInteractionClientOverride,
19
+ EmbeddedInterventionClientOverride,
20
+ } from "./session-context";
21
+ export { useNetworkRoutes } from "./hooks/use-network-routes";
22
+ export type {
23
+ NetworkRoutesClient,
24
+ UseNetworkRoutesOptions,
25
+ UseNetworkRoutesResult,
26
+ } from "./hooks/use-network-routes";
27
+ export { useSiteAuthConnections } from "./hooks/use-site-auth-connections";
28
+ export type {
29
+ SiteAuthConnectionsClient,
30
+ UseSiteAuthConnectionsOptions,
31
+ UseSiteAuthConnectionsResult,
32
+ } from "./hooks/use-site-auth-connections";
33
+ export { useAuthRuns } from "./hooks/use-auth-runs";
34
+ export type { AuthRunsClient, UseAuthRunsOptions, UseAuthRunsResult } from "./hooks/use-auth-runs";
35
+ export { useInteractionInterventions } from "./hooks/use-interaction-interventions";
36
+ export type {
37
+ InteractionInterventionsClient,
38
+ UseInteractionInterventionsOptions,
39
+ UseInteractionInterventionsResult,
40
+ } from "./hooks/use-interaction-interventions";
41
+ export { useAttachedBrowsers } from "./hooks/use-attached-browsers";
42
+ export type {
43
+ AttachedBrowsersClient,
44
+ UseAttachedBrowsersOptions,
45
+ UseAttachedBrowsersResult,
46
+ } from "./hooks/use-attached-browsers";
47
+ export { useBrowserSessions } from "./hooks/use-browser-sessions";
48
+ export type {
49
+ BrowserSessionsClient,
50
+ UseBrowserSessionsOptions,
51
+ UseBrowserSessionsResult,
52
+ } from "./hooks/use-browser-sessions";
53
+ export { useBrowserIdentities } from "./hooks/use-browser-identities";
54
+ export type {
55
+ BrowserIdentitiesClient,
56
+ UseBrowserIdentitiesOptions,
57
+ UseBrowserIdentitiesResult,
58
+ } from "./hooks/use-browser-identities";
59
+ export { useBrowserSession } from "./hooks/use-browser-session";
60
+ export type {
61
+ UseBrowserSessionOptions,
62
+ UseBrowserSessionResult,
63
+ } from "./hooks/use-browser-session";
64
+ export { useBrowserDownloads } from "./hooks/use-browser-downloads";
65
+ export type {
66
+ BrowserDownloadsClient,
67
+ BrowserDownloadSaveOptions,
68
+ UseBrowserDownloadsOptions,
69
+ UseBrowserDownloadsResult,
70
+ } from "./hooks/use-browser-downloads";
71
+ export { useBrowserFrameStream } from "./hooks/use-browser-frame-stream";
72
+ export type {
73
+ BrowserFrameConnectionState,
74
+ BrowserFrameWebSocket,
75
+ BrowserFrameWebSocketFactory,
76
+ UseBrowserFrameStreamOptions,
77
+ UseBrowserFrameStreamResult,
78
+ } from "./hooks/use-browser-frame-stream";
79
+ export { BrowserViewer } from "./components/browser-viewer";
80
+ export type { BrowserViewerNotification, BrowserViewerProps } from "./components/browser-viewer";
81
+ export { useComputerSessions } from "./hooks/use-computer-sessions";
82
+ export type {
83
+ ComputerSessionsClient,
84
+ UseComputerSessionsOptions,
85
+ UseComputerSessionsResult,
86
+ } from "./hooks/use-computer-sessions";
87
+ export { useComputerSession } from "./hooks/use-computer-session";
88
+ export type {
89
+ UseComputerSessionOptions,
90
+ UseComputerSessionResult,
91
+ } from "./hooks/use-computer-session";
92
+ export { useComputerFrameStream } from "./hooks/use-computer-frame-stream";
93
+ export type {
94
+ ComputerFrameConnectionState,
95
+ ComputerFrameWebSocket,
96
+ ComputerFrameWebSocketFactory,
97
+ UseComputerFrameStreamOptions,
98
+ UseComputerFrameStreamResult,
99
+ } from "./hooks/use-computer-frame-stream";
100
+ export { ComputerViewer } from "./components/computer-viewer";
101
+ export type { ComputerViewerNotification, ComputerViewerProps } from "./components/computer-viewer";
@@ -0,0 +1,10 @@
1
+ export type InteractionHostPlatform = "mac" | "other";
2
+
3
+ /** Physical client platform. Remote input adapters use this only to identify
4
+ * the user's primary shortcut modifier; the target platform is resolved
5
+ * separately. */
6
+ export function interactionHostPlatform(): InteractionHostPlatform {
7
+ if (typeof navigator === "undefined") return "other";
8
+ const platform = navigator.platform || navigator.userAgent;
9
+ return /Mac|iPhone|iPad|iPod/u.test(platform) ? "mac" : "other";
10
+ }
@@ -1,5 +1,5 @@
1
1
  // Minimal HAND-MIRROR of the relay stream wire messages the desktop frame client
2
- // needs (`StreamOpen` encode; `StreamOpenAck` + `StreamFrame` decode). It exists
2
+ // needs (`StreamOpen`/`StreamClose` encode; `StreamOpenAck` + `StreamFrame` decode). It exists
3
3
  // because the publish-closure guard (scripts/publish-closure-guard.ts) forbids
4
4
  // `@opengeni/react` from depending on `@opengeni/agent-proto` — the published SDK
5
5
  // closure may only reach `@opengeni/sdk` among `@opengeni/*` packages. So, exactly
@@ -13,12 +13,21 @@
13
13
  // StreamOpenAck: accepted=1(bool), error=2(AgentError msg), resumeFromSeq=3
14
14
  // AgentError: code=1, message=2, retryable=3, detail=4 (we read only message)
15
15
  // StreamFrame: channelId=1, seq=2, data=3(bytes), producedAtMs=4 (we read only data)
16
+ // StreamClose: channelId=1, reason=2(int32), message=3
16
17
  import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
17
18
 
18
19
  /** `StreamKind.STREAM_KIND_DESKTOP` (agent-proto enum value). */
19
20
  export const STREAM_KIND_DESKTOP = 2;
21
+ /** `StreamKind.STREAM_KIND_PTY` (agent-proto enum value). */
22
+ export const STREAM_KIND_PTY = 1;
23
+ /** `StreamKind.STREAM_KIND_BROWSER` (agent-proto enum value). */
24
+ export const STREAM_KIND_BROWSER = 3;
25
+ /** `StreamKind.STREAM_KIND_COMPUTER` (agent-proto enum value). */
26
+ export const STREAM_KIND_COMPUTER = 4;
20
27
  /** `StreamRole.STREAM_ROLE_CLIENT` (agent-proto enum value). */
21
28
  export const STREAM_ROLE_CLIENT = 2;
29
+ /** `StreamCloseReason.STREAM_CLOSE_REASON_NORMAL`. */
30
+ export const STREAM_CLOSE_REASON_NORMAL = 1;
22
31
 
23
32
  export interface RelayChannel {
24
33
  channelId: string;
@@ -54,6 +63,35 @@ export function encodeStreamOpen(message: RelayStreamOpen): Uint8Array {
54
63
  return writer.finish();
55
64
  }
56
65
 
66
+ /** Encode an intentional viewer detach. Transport loss omits this message so
67
+ * reconnect/resume remains available. */
68
+ export function encodeStreamClose(message: {
69
+ channelId: string;
70
+ reason: number;
71
+ message: string;
72
+ }): Uint8Array {
73
+ const writer = new BinaryWriter();
74
+ if (message.channelId !== "") writer.uint32(10).string(message.channelId);
75
+ if (message.reason !== 0) writer.uint32(16).int32(message.reason);
76
+ if (message.message !== "") writer.uint32(26).string(message.message);
77
+ return writer.finish();
78
+ }
79
+
80
+ /** Encode a viewer→agent PTY input `StreamFrame`. */
81
+ export function encodeStreamFrame(message: {
82
+ channelId: string;
83
+ seq: string;
84
+ data: Uint8Array;
85
+ producedAtMs: string;
86
+ }): Uint8Array {
87
+ const writer = new BinaryWriter();
88
+ if (message.channelId !== "") writer.uint32(10).string(message.channelId);
89
+ if (message.seq !== "0") writer.uint32(16).uint64(message.seq);
90
+ if (message.data.length > 0) writer.uint32(26).bytes(message.data);
91
+ if (message.producedAtMs !== "0") writer.uint32(32).uint64(message.producedAtMs);
92
+ return writer.finish();
93
+ }
94
+
57
95
  /** The only `AgentError` field we surface from a rejected ack. */
58
96
  function decodeAgentErrorMessage(reader: BinaryReader, length: number): { message?: string } {
59
97
  const end = reader.pos + length;
@@ -95,13 +133,18 @@ export function decodeStreamOpenAck(bytes: Uint8Array): {
95
133
  return error !== undefined ? { accepted, error } : { accepted };
96
134
  }
97
135
 
98
- /** Decode a `StreamFrame`, extracting only the `data` (framebuffer PNG) bytes. */
99
- export function decodeStreamFrame(bytes: Uint8Array): { data: Uint8Array } {
136
+ /** Decode the sequence plus `data` from a `StreamFrame`. */
137
+ export function decodeStreamFrame(bytes: Uint8Array): { seq: string; data: Uint8Array } {
100
138
  const reader = new BinaryReader(bytes);
101
139
  const end = reader.len;
140
+ let seq = "0";
102
141
  let data = new Uint8Array(0);
103
142
  while (reader.pos < end) {
104
143
  const tag = reader.uint32();
144
+ if (tag >>> 3 === 2 && tag === 16) {
145
+ seq = reader.uint64().toString();
146
+ continue;
147
+ }
105
148
  if (tag >>> 3 === 3 && tag === 26) {
106
149
  // Copy into a fresh ArrayBuffer-backed view: BinaryReader.bytes() returns
107
150
  // `Uint8Array<ArrayBufferLike>` (a view into the message buffer), which both
@@ -112,5 +155,5 @@ export function decodeStreamFrame(bytes: Uint8Array): { data: Uint8Array } {
112
155
  if ((tag & 7) === 4 || tag === 0) break;
113
156
  reader.skip(tag & 7);
114
157
  }
115
- return { data };
158
+ return { seq, data };
116
159
  }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * A sandbox is available for new I/O only after a holder has observed `warm`.
3
+ *
4
+ * `draining` means the holder count is zero and teardown owns the provider
5
+ * instance. The provider may disappear before the durable lease reaches `cold`,
6
+ * so treating `draining` as live races capture/termination. Explicit user intent
7
+ * reacquires a holder; only its subsequent `warm` state re-enables live I/O.
8
+ */
9
+ export function sandboxAcceptsLiveIo(liveness: string | null | undefined): boolean {
10
+ return liveness === "warm";
11
+ }
@@ -0,0 +1,10 @@
1
+ import type { TerminalCapability } from "@opengeni/sdk";
2
+
3
+ /** Whether an explicit viewer grant can upgrade this cell to a real PTY.
4
+ * Keep acquisition feasibility separate from the current transport: a cold
5
+ * real-PTY backend reports sse-events until the just-in-time grant warms it. */
6
+ export function terminalCanAcquirePty(cell: TerminalCapability | null | undefined): boolean {
7
+ if (!cell?.ptyCapable) return false;
8
+ if (cell.transport === "pty-ws" || cell.transport === "relay-pty") return true;
9
+ return cell.reason === "lease_cold" || cell.reason === "not_provisioned";
10
+ }
@@ -1,6 +1,10 @@
1
1
  import type { ClientModel, ReasoningEffort, WorkspaceModelCatalogModel } from "@opengeni/sdk";
2
2
 
3
- export type PickerBillingClass = "opengeni_credits" | "codex_subscription" | "byok";
3
+ export type PickerBillingClass =
4
+ | "opengeni_credits"
5
+ | "codex_subscription"
6
+ | "supergrok_subscription"
7
+ | "byok";
4
8
 
5
9
  export type PickerModelRow<TCatalog extends ClientModel = WorkspaceModelCatalogModel> = {
6
10
  id: string;
@@ -21,12 +25,14 @@ export type LatencyModeId = "standard" | "priority" | "fast";
21
25
  const BILLING_CLASS_ORDER: PickerBillingClass[] = [
22
26
  "opengeni_credits",
23
27
  "codex_subscription",
28
+ "supergrok_subscription",
24
29
  "byok",
25
30
  ];
26
31
 
27
32
  const BILLING_CLASS_LABELS: Record<PickerBillingClass, string> = {
28
33
  opengeni_credits: "OpenGeni",
29
34
  codex_subscription: "Codex",
35
+ supergrok_subscription: "SuperGrok",
30
36
  byok: "Your Gateway",
31
37
  };
32
38
 
@@ -41,6 +47,9 @@ const AVAILABILITY_REASON_LABELS: Record<string, string> = {
41
47
  };
42
48
 
43
49
  export function billingClassForModel(model: ClientModel): PickerBillingClass {
50
+ if (model.source === "supergrok") {
51
+ return "supergrok_subscription";
52
+ }
44
53
  if (model.source === "codex") {
45
54
  return "codex_subscription";
46
55
  }
@@ -48,7 +57,9 @@ export function billingClassForModel(model: ClientModel): PickerBillingClass {
48
57
  return "byok";
49
58
  }
50
59
  if (model.credentialSource?.kind === "connected_subscription") {
51
- return "codex_subscription";
60
+ return model.credentialSource.provider === "xai"
61
+ ? "supergrok_subscription"
62
+ : "codex_subscription";
52
63
  }
53
64
  if (model.credentialSource?.kind === "workspace_connection") {
54
65
  return "byok";
@@ -135,7 +146,9 @@ export function payerSummaryForModel(model: ClientModel): string {
135
146
  return "OpenGeni credits · automatic managed route";
136
147
  }
137
148
  if (billing.upstreamPayer === "connected_subscription") {
138
- return "Codex subscription · external billing";
149
+ return model.source === "supergrok"
150
+ ? "SuperGrok subscription · external billing"
151
+ : "Codex subscription · external billing";
139
152
  }
140
153
  if (billing.upstreamPayer === "workspace") {
141
154
  return "Billed to your AI Gateway";
@@ -149,7 +162,9 @@ export function advancedSourceSummary(model: ClientModel): string | null {
149
162
  return null;
150
163
  }
151
164
  if (source.kind === "connected_subscription") {
152
- return "Connected Codex subscription";
165
+ return source.provider === "xai"
166
+ ? "Connected SuperGrok subscription"
167
+ : "Connected Codex subscription";
153
168
  }
154
169
  if (source.kind === "workspace_connection") {
155
170
  return "Workspace AI Gateway";
package/src/provider.tsx CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  OPENGENI_API_CONTRACT_REVISION,
4
4
  type StreamConnectionState,
5
5
  type WorkspaceControlEvent,
6
+ type WorkspaceInteractionRevisionEvent,
6
7
  } from "@opengeni/sdk";
7
8
  import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react";
8
9
  import type { SessionClientLike } from "./client";
@@ -17,6 +18,7 @@ export type OpenGeniProviderProps = {
17
18
  client: SessionClientLike;
18
19
  workspaceId: string;
19
20
  onWorkspaceControlEvent?: ((event: WorkspaceControlEvent) => void) | undefined;
21
+ onWorkspaceInteractionEvent?: ((event: WorkspaceInteractionRevisionEvent) => void) | undefined;
20
22
  children?: ReactNode;
21
23
  };
22
24
 
@@ -28,6 +30,7 @@ export function OpenGeniProvider({
28
30
  client,
29
31
  workspaceId,
30
32
  onWorkspaceControlEvent,
33
+ onWorkspaceInteractionEvent,
31
34
  children,
32
35
  }: OpenGeniProviderProps) {
33
36
  const [workspaceControlEvent, setWorkspaceControlEvent] = useState<WorkspaceControlEvent | null>(
@@ -36,15 +39,25 @@ export function OpenGeniProvider({
36
39
  const [workspaceControlConnectionState, setWorkspaceControlConnectionState] = useState<
37
40
  StreamConnectionState | "idle" | "error"
38
41
  >("idle");
42
+ const [workspaceInteractionEvent, setWorkspaceInteractionEvent] =
43
+ useState<WorkspaceInteractionRevisionEvent | null>(null);
44
+ const [workspaceInteractionConnectionState, setWorkspaceInteractionConnectionState] = useState<
45
+ StreamConnectionState | "idle" | "error"
46
+ >("idle");
39
47
  const [contractMismatch, setContractMismatch] = useState<OpenGeniApiContractMismatchError | null>(
40
48
  null,
41
49
  );
42
50
  const callbackRef = useRef(onWorkspaceControlEvent);
51
+ const interactionCallbackRef = useRef(onWorkspaceInteractionEvent);
43
52
  const reconcilersRef = useRef(new Map<string, Map<string, () => Promise<void>>>());
44
53
  const reconcileInFlightRef = useRef(new Map<string, Promise<void>>());
45
54
  const workspaceControlSequencesRef = useRef(new Map<string, number>());
55
+ const workspaceInteractionSequencesRef = useRef(new Map<string, number>());
46
56
  const pageLive = usePageLiveActivity();
57
+ const supportsWorkspaceLiveStream =
58
+ "streamWorkspaceLiveEvents" in client && typeof client.streamWorkspaceLiveEvents === "function";
47
59
  callbackRef.current = onWorkspaceControlEvent;
60
+ interactionCallbackRef.current = onWorkspaceInteractionEvent;
48
61
 
49
62
  const verifyApiContract = useCallback(async (): Promise<void> => {
50
63
  try {
@@ -105,6 +118,78 @@ export function OpenGeniProvider({
105
118
  );
106
119
 
107
120
  useEffect(() => {
121
+ if (!supportsWorkspaceLiveStream) return;
122
+ const openLiveStream = client.streamWorkspaceLiveEvents!;
123
+ setWorkspaceControlEvent(null);
124
+ setWorkspaceInteractionEvent(null);
125
+ if (!pageLive) {
126
+ setWorkspaceControlConnectionState("idle");
127
+ setWorkspaceInteractionConnectionState("idle");
128
+ return;
129
+ }
130
+ const controller = new AbortController();
131
+ const setConnectionState = (state: StreamConnectionState) => {
132
+ setWorkspaceControlConnectionState(state);
133
+ setWorkspaceInteractionConnectionState(state);
134
+ };
135
+ setConnectionState("connecting");
136
+ void (async () => {
137
+ try {
138
+ await verifyApiContract();
139
+ const workspace = await client.getWorkspace(workspaceId);
140
+ const controlAfter = Math.max(
141
+ workspaceControlSequencesRef.current.get(workspaceId) ?? 0,
142
+ workspace.inferenceControl.revision,
143
+ );
144
+ const interactionAfter = workspaceInteractionSequencesRef.current.get(workspaceId) ?? 0;
145
+ workspaceControlSequencesRef.current.set(workspaceId, controlAfter);
146
+ const stream = openLiveStream.call(client, workspaceId, {
147
+ controlAfter,
148
+ interactionAfter,
149
+ signal: controller.signal,
150
+ onStateChange: setConnectionState,
151
+ });
152
+ for await (const event of stream) {
153
+ if (controller.signal.aborted) return;
154
+ if (event.type === "workspace.control.changed") {
155
+ workspaceControlSequencesRef.current.set(
156
+ workspaceId,
157
+ Math.max(workspaceControlSequencesRef.current.get(workspaceId) ?? 0, event.sequence),
158
+ );
159
+ setWorkspaceControlEvent((current) =>
160
+ !current || event.sequence > current.sequence ? event : current,
161
+ );
162
+ callbackRef.current?.(event);
163
+ } else {
164
+ workspaceInteractionSequencesRef.current.set(
165
+ workspaceId,
166
+ Math.max(
167
+ workspaceInteractionSequencesRef.current.get(workspaceId) ?? 0,
168
+ event.sequence,
169
+ ),
170
+ );
171
+ setWorkspaceInteractionEvent((current) =>
172
+ !current || event.sequence > current.sequence ? event : current,
173
+ );
174
+ interactionCallbackRef.current?.(event);
175
+ }
176
+ }
177
+ } catch (error) {
178
+ if (error instanceof OpenGeniApiContractMismatchError) {
179
+ setContractMismatch(error);
180
+ reloadForContractMismatchOnce(error);
181
+ }
182
+ if (!controller.signal.aborted) {
183
+ setWorkspaceControlConnectionState("error");
184
+ setWorkspaceInteractionConnectionState("error");
185
+ }
186
+ }
187
+ })();
188
+ return () => controller.abort();
189
+ }, [client, pageLive, supportsWorkspaceLiveStream, verifyApiContract, workspaceId]);
190
+
191
+ useEffect(() => {
192
+ if (supportsWorkspaceLiveStream) return;
108
193
  if (!pageLive) {
109
194
  setWorkspaceControlConnectionState("idle");
110
195
  return;
@@ -145,7 +230,50 @@ export function OpenGeniProvider({
145
230
  }
146
231
  })();
147
232
  return () => controller.abort();
148
- }, [client, pageLive, verifyApiContract, workspaceId]);
233
+ }, [client, pageLive, supportsWorkspaceLiveStream, verifyApiContract, workspaceId]);
234
+
235
+ useEffect(() => {
236
+ if (supportsWorkspaceLiveStream) return;
237
+ setWorkspaceInteractionEvent(null);
238
+ if (!pageLive) {
239
+ setWorkspaceInteractionConnectionState("idle");
240
+ return;
241
+ }
242
+ const controller = new AbortController();
243
+ setWorkspaceInteractionConnectionState("connecting");
244
+ void (async () => {
245
+ try {
246
+ await verifyApiContract();
247
+ const resumeAfter = workspaceInteractionSequencesRef.current.get(workspaceId) ?? 0;
248
+ const stream = client.streamWorkspaceInteractionRevisions(workspaceId, {
249
+ after: resumeAfter,
250
+ signal: controller.signal,
251
+ onStateChange: setWorkspaceInteractionConnectionState,
252
+ });
253
+ for await (const event of stream) {
254
+ if (controller.signal.aborted) return;
255
+ workspaceInteractionSequencesRef.current.set(
256
+ workspaceId,
257
+ Math.max(
258
+ workspaceInteractionSequencesRef.current.get(workspaceId) ?? 0,
259
+ event.sequence,
260
+ ),
261
+ );
262
+ setWorkspaceInteractionEvent((current) =>
263
+ !current || event.sequence > current.sequence ? event : current,
264
+ );
265
+ interactionCallbackRef.current?.(event);
266
+ }
267
+ } catch (error) {
268
+ if (error instanceof OpenGeniApiContractMismatchError) {
269
+ setContractMismatch(error);
270
+ reloadForContractMismatchOnce(error);
271
+ }
272
+ if (!controller.signal.aborted) setWorkspaceInteractionConnectionState("error");
273
+ }
274
+ })();
275
+ return () => controller.abort();
276
+ }, [client, pageLive, supportsWorkspaceLiveStream, verifyApiContract, workspaceId]);
149
277
 
150
278
  const value = useMemo(
151
279
  () => ({
@@ -153,6 +281,8 @@ export function OpenGeniProvider({
153
281
  workspaceId,
154
282
  workspaceControlEvent,
155
283
  workspaceControlConnectionState,
284
+ workspaceInteractionEvent,
285
+ workspaceInteractionConnectionState,
156
286
  registerSessionReconciler,
157
287
  reconcileSession,
158
288
  }),
@@ -161,6 +291,8 @@ export function OpenGeniProvider({
161
291
  workspaceId,
162
292
  workspaceControlEvent,
163
293
  workspaceControlConnectionState,
294
+ workspaceInteractionEvent,
295
+ workspaceInteractionConnectionState,
164
296
  registerSessionReconciler,
165
297
  reconcileSession,
166
298
  ],
@@ -57,7 +57,7 @@ import {
57
57
  export type RealtimeModelOption = {
58
58
  id: SessionRealtimeModel;
59
59
  label: string;
60
- provider: "OpenGeni" | "Connected Codex" | "Your Gateway";
60
+ provider: "OpenGeni" | "Connected Codex" | "Connected SuperGrok" | "Your Gateway";
61
61
  description: string;
62
62
  available: boolean;
63
63
  unavailableReason: string | null;
@@ -74,7 +74,12 @@ const CODEX_LIVE_MODEL: RealtimeModelOption = {
74
74
  recommended: false,
75
75
  };
76
76
 
77
- const REALTIME_MODEL_PROVIDERS = ["OpenGeni", "Connected Codex", "Your Gateway"] as const;
77
+ const REALTIME_MODEL_PROVIDERS = [
78
+ "OpenGeni",
79
+ "Connected Codex",
80
+ "Connected SuperGrok",
81
+ "Your Gateway",
82
+ ] as const;
78
83
  type RealtimeModelProvider = (typeof REALTIME_MODEL_PROVIDERS)[number];
79
84
 
80
85
  const REALTIME_PROVIDER_META: Record<
@@ -86,6 +91,10 @@ const REALTIME_PROVIDER_META: Record<
86
91
  billingClass: "codex_subscription",
87
92
  hint: "ChatGPT / Codex plan",
88
93
  },
94
+ "Connected SuperGrok": {
95
+ billingClass: "supergrok_subscription",
96
+ hint: "SuperGrok / xAI plan",
97
+ },
89
98
  "Your Gateway": { billingClass: "byok", hint: "Billed to your AI Gateway" },
90
99
  };
91
100
  const REALTIME_MODEL_STORAGE_PREFIX = "opengeni:realtime-model";
@@ -141,7 +150,11 @@ export function useSessionRealtime(options: {
141
150
  const controllerRef = useRef<SessionRealtimeController | null>(null);
142
151
  const controllerModelRef = useRef<SessionRealtimeModel | null>(null);
143
152
  const [snapshot, setSnapshot] = useState<SessionRealtimeControllerSnapshot>(() => ({
144
- status: hasStoredSessionRealtimeOwnerProof({ workspaceId, sessionId: options.sessionId, model })
153
+ status: hasStoredSessionRealtimeOwnerProof({
154
+ workspaceId,
155
+ sessionId: options.sessionId,
156
+ model,
157
+ })
145
158
  ? "recovering"
146
159
  : "idle",
147
160
  realtimeId: null,
@@ -684,7 +697,13 @@ export function RealtimeVoiceControl(props: {
684
697
  opacity: 1,
685
698
  transition: reduceMotion
686
699
  ? { duration: 0 }
687
- : { delay: 0.32, type: "spring", stiffness: 320, damping: 30, mass: 0.8 },
700
+ : {
701
+ delay: 0.32,
702
+ type: "spring",
703
+ stiffness: 320,
704
+ damping: 30,
705
+ mass: 0.8,
706
+ },
688
707
  }}
689
708
  {...(reduceMotion
690
709
  ? {}
@@ -1160,7 +1179,11 @@ function statusContent(
1160
1179
  };
1161
1180
  }
1162
1181
  if (!canStart && admissionBlocker) {
1163
- return { phase: "unavailable", label: "Voice unavailable", detail: admissionBlocker };
1182
+ return {
1183
+ phase: "unavailable",
1184
+ label: "Voice unavailable",
1185
+ detail: admissionBlocker,
1186
+ };
1164
1187
  }
1165
1188
  return {
1166
1189
  phase: "idle",
@@ -1268,7 +1291,11 @@ function RealtimeStatusDot(props: { phase: RealtimeVisualPhase; reduceMotion: bo
1268
1291
  <motion.span
1269
1292
  className="absolute inset-0 rounded-full bg-og-status-running"
1270
1293
  animate={{ opacity: [0.45, 0], scale: [1, 2.2] }}
1271
- transition={{ duration: 1.4, ease: "easeOut", repeat: Number.POSITIVE_INFINITY }}
1294
+ transition={{
1295
+ duration: 1.4,
1296
+ ease: "easeOut",
1297
+ repeat: Number.POSITIVE_INFINITY,
1298
+ }}
1272
1299
  />
1273
1300
  ) : null}
1274
1301
  <span
@@ -1343,6 +1370,7 @@ function isRealtimeModel(value: string | null): value is SessionRealtimeModel {
1343
1370
  value === "opengeni-gateway/openai/gpt-realtime-2.1" ||
1344
1371
  value === "opengeni-gateway/openai/gpt-realtime-mini" ||
1345
1372
  value === "opengeni-gateway/xai/grok-voice-think-fast-2.0" ||
1373
+ value === "supergrok/grok-voice-think-fast-2.0" ||
1346
1374
  value === "workspace-gateway/openai/gpt-realtime-2.1" ||
1347
1375
  value === "workspace-gateway/openai/gpt-realtime-mini" ||
1348
1376
  value === "workspace-gateway/xai/grok-voice-think-fast-2.0"