@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
@@ -26,15 +26,17 @@ import {
26
26
  Share2Icon,
27
27
  TargetIcon,
28
28
  TerminalIcon,
29
+ VideoIcon,
29
30
  WrenchIcon,
30
31
  } from "lucide-react";
31
- import { useEffect, useState, type ReactNode } from "react";
32
+ import { useEffect, useRef, useState, type ReactNode } from "react";
32
33
  import { stringifyPayload, tryParseJson } from "../lib/format";
33
34
  import { useTimelineComputeLabel } from "./compute-label";
34
35
  import {
35
36
  applyPatchOpsFromToolItem,
36
37
  controlCaret,
37
38
  execTruncated,
39
+ generatedImageReceipt,
38
40
  isExecSessionLostBanner,
39
41
  looksBinary,
40
42
  mediaPreviewFact,
@@ -664,11 +666,14 @@ function ComputerCallRenderer({ item, loadRetainedScreenshot }: ToolRendererProp
664
666
  );
665
667
  }
666
668
  return (
667
- <RetainedScreenshotDisclosure
669
+ <RetainedSessionImageDisclosure
668
670
  artifact={retained}
669
671
  load={loadRetainedScreenshot}
670
- verb={verb}
671
- countSuffix={countSuffix}
672
+ title={`${verb}${countSuffix}`}
673
+ caption={`${verb}${countSuffix}`}
674
+ noun="screenshot"
675
+ icon={<CameraIcon className={ICON_SIZE} />}
676
+ lightboxLabel="Screenshot"
672
677
  batched={batched}
673
678
  failed={isFailed}
674
679
  cancelled={isCancelled}
@@ -756,30 +761,26 @@ function ComputerCallRenderer({ item, loadRetainedScreenshot }: ToolRendererProp
756
761
  );
757
762
  }
758
763
 
759
- function RetainedScreenshotDisclosure({
760
- artifact,
761
- load,
762
- verb,
763
- countSuffix,
764
- batched,
765
- failed,
766
- cancelled,
767
- }: {
768
- artifact: RetainedArtifactReference;
769
- load: ToolRendererProps["loadRetainedScreenshot"];
770
- verb: string;
771
- countSuffix: string;
772
- batched: string | null;
773
- failed: boolean;
774
- cancelled: boolean;
775
- }) {
776
- const [state, setState] = useState<
777
- | { kind: "loading" }
778
- | { kind: "ready"; url: string }
779
- | { kind: "unavailable"; label: string }
780
- | { kind: "error"; message: string }
781
- >({ kind: "loading" });
782
-
764
+ type RetainedImageState =
765
+ | { kind: "loading" }
766
+ | { kind: "ready"; url: string }
767
+ | { kind: "unavailable"; label: string }
768
+ | { kind: "error"; message: string };
769
+
770
+ function useRetainedImageObjectUrl(
771
+ artifact: RetainedArtifactReference,
772
+ load: ToolRendererProps["loadRetainedArtifact"],
773
+ ): RetainedImageState {
774
+ const [state, setState] = useState<RetainedImageState>({ kind: "loading" });
775
+ // Function outputs are commonly serialized JSON. Parsing them creates a new
776
+ // object on every render, so depend on the immutable wire value rather than
777
+ // object identity; otherwise the loader can refetch after its own setState.
778
+ const artifactValue = retainedArtifactValue(artifact);
779
+ const stableArtifactRef = useRef({ value: artifactValue, artifact });
780
+ if (stableArtifactRef.current.value !== artifactValue) {
781
+ stableArtifactRef.current = { value: artifactValue, artifact };
782
+ }
783
+ const stableArtifact = stableArtifactRef.current.artifact;
783
784
  useEffect(() => {
784
785
  if (!load) {
785
786
  setState({ kind: "unavailable", label: "retrieval is not configured" });
@@ -788,14 +789,24 @@ function RetainedScreenshotDisclosure({
788
789
  const controller = new AbortController();
789
790
  let objectUrl: string | null = null;
790
791
  setState({ kind: "loading" });
791
- void load(artifact, controller.signal)
792
- .then((bytes) => {
792
+ void load(stableArtifact, controller.signal)
793
+ .then((source) => {
793
794
  if (controller.signal.aborted) return;
794
- if (!bytes) {
795
+ if (!source) {
795
796
  setState({ kind: "unavailable", label: "bytes are unavailable" });
796
797
  return;
797
798
  }
798
- objectUrl = URL.createObjectURL(new Blob([Uint8Array.from(bytes)], { type: "image/png" }));
799
+ if (!(source instanceof Uint8Array)) {
800
+ if (!source.url.trim()) {
801
+ setState({ kind: "unavailable", label: "URL is unavailable" });
802
+ return;
803
+ }
804
+ setState({ kind: "ready", url: source.url });
805
+ return;
806
+ }
807
+ objectUrl = URL.createObjectURL(
808
+ new Blob([source as unknown as BlobPart], { type: stableArtifact.contentType }),
809
+ );
799
810
  setState({ kind: "ready", url: objectUrl });
800
811
  })
801
812
  .catch((error: unknown) => {
@@ -809,38 +820,86 @@ function RetainedScreenshotDisclosure({
809
820
  ? { kind: "unavailable", label: "deleted" }
810
821
  : status === 410
811
822
  ? { kind: "unavailable", label: "expired or unavailable" }
812
- : {
813
- kind: "error",
814
- message: "retrieval failed",
815
- },
823
+ : { kind: "error", message: "retrieval failed" },
816
824
  );
817
825
  });
818
826
  return () => {
819
827
  controller.abort();
820
828
  if (objectUrl) URL.revokeObjectURL(objectUrl);
821
829
  };
822
- }, [artifact, load]);
830
+ }, [stableArtifact, load]);
831
+ return state;
832
+ }
833
+
834
+ function retainedArtifactValue(artifact: RetainedArtifactReference): string {
835
+ return [
836
+ artifact.artifactId,
837
+ artifact.kind,
838
+ artifact.contentType,
839
+ artifact.originalBytes,
840
+ artifact.sha256,
841
+ artifact.retainedAt,
842
+ artifact.dimensions?.width ?? "",
843
+ artifact.dimensions?.height ?? "",
844
+ artifact.retention.policy,
845
+ artifact.retention.expiresAt ?? "",
846
+ artifact.retrieval.method,
847
+ artifact.retrieval.path,
848
+ artifact.retrieval.acceptRanges,
849
+ artifact.retrieval.maxRangeBytes,
850
+ ].join("\0");
851
+ }
852
+
853
+ function RetainedSessionImageDisclosure({
854
+ artifact,
855
+ load,
856
+ title,
857
+ caption,
858
+ noun,
859
+ icon,
860
+ lightboxLabel,
861
+ batched,
862
+ failed,
863
+ cancelled,
864
+ }: {
865
+ artifact: RetainedArtifactReference;
866
+ load: ToolRendererProps["loadRetainedScreenshot"];
867
+ title: string;
868
+ caption: string;
869
+ noun: "image" | "screenshot";
870
+ icon: ReactNode;
871
+ lightboxLabel: string;
872
+ batched: string | null;
873
+ failed: boolean;
874
+ cancelled: boolean;
875
+ }) {
876
+ const state = useRetainedImageObjectUrl(artifact, load);
823
877
 
824
- const caption = `${verb}${countSuffix}`;
825
878
  return (
826
879
  <ActivityDisclosure
827
- icon={<CameraIcon className={ICON_SIZE} />}
880
+ icon={icon}
828
881
  iconTone={failed ? "failed" : state.kind === "ready" ? "accent" : "muted"}
829
- title={caption}
882
+ title={title}
830
883
  failed={failed}
831
884
  cancelled={cancelled}
832
885
  preview={
833
886
  state.kind === "loading"
834
- ? "loading retained screenshot…"
887
+ ? `loading retained ${noun}…`
835
888
  : state.kind === "error"
836
- ? "screenshot retrieval failed"
889
+ ? `${noun} retrieval failed`
837
890
  : state.kind === "unavailable"
838
- ? `screenshot ${state.label}`
891
+ ? `${noun} ${state.label}`
839
892
  : undefined
840
893
  }
841
894
  media={
842
895
  state.kind === "ready" ? (
843
- <Thumbnail src={state.url} caption={caption} />
896
+ <Thumbnail
897
+ src={state.url}
898
+ caption={caption}
899
+ alt={caption}
900
+ expandLabel={`Expand ${noun}`}
901
+ lightboxLabel={lightboxLabel}
902
+ />
844
903
  ) : state.kind === "loading" ? (
845
904
  <MediaSkeleton />
846
905
  ) : (
@@ -849,19 +908,171 @@ function RetainedScreenshotDisclosure({
849
908
  }
850
909
  >
851
910
  {state.kind === "ready" ? (
852
- <ScreenshotFigure src={state.url} caption={caption} />
911
+ <ScreenshotFigure
912
+ src={state.url}
913
+ caption={caption}
914
+ alt={caption}
915
+ expandLabel={`Expand ${noun}`}
916
+ lightboxLabel={lightboxLabel}
917
+ />
853
918
  ) : state.kind === "loading" ? (
854
- <BodyNote>Loading the retained screenshot…</BodyNote>
919
+ <BodyNote>Loading the retained {noun}…</BodyNote>
855
920
  ) : state.kind === "unavailable" ? (
856
- <BodyNote>Screenshot {state.label}.</BodyNote>
921
+ <BodyNote>
922
+ {noun === "screenshot" ? "Screenshot" : "Image"} {state.label}.
923
+ </BodyNote>
857
924
  ) : (
858
- <BodyNote tone="error">Screenshot retrieval failed: {state.message}</BodyNote>
925
+ <BodyNote tone="error">
926
+ {noun === "screenshot" ? "Screenshot" : "Image"} retrieval failed: {state.message}
927
+ </BodyNote>
859
928
  )}
860
929
  {batched ? <BodyNote>batched: {batched}</BodyNote> : null}
861
930
  </ActivityDisclosure>
862
931
  );
863
932
  }
864
933
 
934
+ function GeneratedImageRenderer({ item, loadRetainedArtifact }: ToolRendererProps) {
935
+ const args = parseToolArgs(item.arguments);
936
+ const prompt = typeof args.prompt === "string" ? args.prompt : "";
937
+ const raw =
938
+ item.raw && typeof item.raw === "object" && !Array.isArray(item.raw)
939
+ ? (item.raw as Record<string, unknown>)
940
+ : null;
941
+ // Function tools settle through agent.toolCall.output; OpenAI's hosted image
942
+ // call is already complete on agent.toolCall.created and carries the compact
943
+ // receipt in raw.output. Both paths deliberately converge on one renderer.
944
+ const receipt = generatedImageReceipt(item.output) ?? generatedImageReceipt(raw?.output);
945
+ if (item.status === "running") {
946
+ return (
947
+ <ActivityDisclosure
948
+ icon={<ImageIcon className={ICON_SIZE} />}
949
+ iconTone="running"
950
+ title="Generating image"
951
+ running
952
+ preview={<RunningPreview>{truncatePreview(prompt, 72) || "creating…"}</RunningPreview>}
953
+ media={<MediaSkeleton />}
954
+ >
955
+ {prompt ? <BodyNote>{prompt}</BodyNote> : null}
956
+ </ActivityDisclosure>
957
+ );
958
+ }
959
+ if (!receipt) return <GenericRenderer item={item} />;
960
+ return (
961
+ <GeneratedImageDisclosure
962
+ receipt={receipt}
963
+ load={loadRetainedArtifact}
964
+ prompt={prompt}
965
+ failed={item.status === "failed"}
966
+ cancelled={item.status === "cancelled"}
967
+ />
968
+ );
969
+ }
970
+
971
+ function GeneratedVideoRenderer({ item }: ToolRendererProps) {
972
+ const args = parseToolArgs(item.arguments);
973
+ const prompt = typeof args.prompt === "string" ? args.prompt : "";
974
+ const parsedOutput = typeof item.output === "string" ? tryParseJson(item.output) : item.output;
975
+ const accepted =
976
+ parsedOutput &&
977
+ typeof parsedOutput === "object" &&
978
+ !Array.isArray(parsedOutput) &&
979
+ (parsedOutput as Record<string, unknown>).status === "accepted";
980
+ const failed = item.status === "failed";
981
+ const cancelled = item.status === "cancelled";
982
+ const running = item.status === "running";
983
+ return (
984
+ <ActivityDisclosure
985
+ icon={<VideoIcon className={ICON_SIZE} />}
986
+ iconTone={failed ? "failed" : running ? "running" : accepted ? "accent" : "muted"}
987
+ title={
988
+ running ? "Starting video generation" : accepted ? "Generating video" : "Generate video"
989
+ }
990
+ running={running}
991
+ failed={failed}
992
+ cancelled={cancelled}
993
+ preview={truncatePreview(prompt, 88) || (accepted ? "request accepted" : undefined)}
994
+ >
995
+ {prompt ? <BodyNote>{prompt}</BodyNote> : null}
996
+ {accepted ? (
997
+ <BodyNote>The video will appear here when it is ready.</BodyNote>
998
+ ) : item.output !== undefined ? (
999
+ <PayloadBlock label="Output" value={item.output} />
1000
+ ) : null}
1001
+ </ActivityDisclosure>
1002
+ );
1003
+ }
1004
+ function GeneratedImageDisclosure({
1005
+ receipt,
1006
+ load,
1007
+ prompt,
1008
+ failed,
1009
+ cancelled,
1010
+ }: {
1011
+ receipt: NonNullable<ReturnType<typeof generatedImageReceipt>>;
1012
+ load: ToolRendererProps["loadRetainedArtifact"];
1013
+ prompt: string;
1014
+ failed: boolean;
1015
+ cancelled: boolean;
1016
+ }) {
1017
+ const state = useRetainedImageObjectUrl(receipt.artifact, load);
1018
+ const dimensions = receipt.artifact.dimensions!;
1019
+ const title = failed ? "Image generation failed" : "Generated image";
1020
+ const caption = prompt || `Generated image · ${dimensions.width}×${dimensions.height}`;
1021
+ return (
1022
+ <ActivityDisclosure
1023
+ icon={<ImageIcon className={ICON_SIZE} />}
1024
+ iconTone={failed ? "failed" : state.kind === "ready" ? "accent" : "muted"}
1025
+ title={title}
1026
+ defaultOpen={!failed && !cancelled}
1027
+ failed={failed}
1028
+ cancelled={cancelled}
1029
+ preview={
1030
+ state.kind === "loading"
1031
+ ? "loading image…"
1032
+ : state.kind === "error"
1033
+ ? "image retrieval failed"
1034
+ : state.kind === "unavailable"
1035
+ ? `image ${state.label}`
1036
+ : truncatePreview(prompt, 88) || `${dimensions.width}×${dimensions.height}`
1037
+ }
1038
+ media={
1039
+ state.kind === "ready" ? (
1040
+ <Thumbnail
1041
+ src={state.url}
1042
+ caption={caption}
1043
+ alt={caption}
1044
+ expandLabel="Expand generated image"
1045
+ lightboxLabel="Generated image"
1046
+ />
1047
+ ) : state.kind === "loading" ? (
1048
+ <MediaSkeleton />
1049
+ ) : (
1050
+ <MediaEmpty />
1051
+ )
1052
+ }
1053
+ >
1054
+ {state.kind === "ready" ? (
1055
+ <ScreenshotFigure
1056
+ src={state.url}
1057
+ caption={caption}
1058
+ alt={caption}
1059
+ expandLabel="Expand generated image"
1060
+ lightboxLabel="Generated image"
1061
+ />
1062
+ ) : state.kind === "loading" ? (
1063
+ <BodyNote>Loading the generated image…</BodyNote>
1064
+ ) : state.kind === "unavailable" ? (
1065
+ <BodyNote>Image {state.label}.</BodyNote>
1066
+ ) : (
1067
+ <BodyNote tone="error">Image retrieval failed.</BodyNote>
1068
+ )}
1069
+ <BodyNote>
1070
+ {dimensions.width}×{dimensions.height} · {receipt.sandboxPath}
1071
+ </BodyNote>
1072
+ </ActivityDisclosure>
1073
+ );
1074
+ }
1075
+
865
1076
  /* ---- web_search ------------------------------------------------------------ */
866
1077
 
867
1078
  type WebSearchResult = { title: string; domain: string; snippet: string };
@@ -1013,11 +1224,12 @@ const VIEW_IMAGE_ERRORS = [
1013
1224
  "unable to read image",
1014
1225
  ];
1015
1226
 
1016
- function ViewImageRenderer({ item }: ToolRendererProps) {
1227
+ function ViewImageRenderer({ item, loadRetainedScreenshot }: ToolRendererProps) {
1017
1228
  const args = parseToolArgs(item.arguments);
1018
1229
  const path = typeof args.path === "string" ? args.path : "";
1019
1230
  const out = item.output;
1020
1231
  const text = typeof out === "string" ? out : "";
1232
+ const retained = retainedScreenshotMetadata(out);
1021
1233
  const omittedMedia = mediaPreviewFact(out);
1022
1234
 
1023
1235
  if (item.status === "running") {
@@ -1038,6 +1250,45 @@ function ViewImageRenderer({ item }: ToolRendererProps) {
1038
1250
  const viewFailed = item.status === "failed";
1039
1251
  const viewCancelled = item.status === "cancelled";
1040
1252
 
1253
+ if (retained) {
1254
+ const title = `Viewed ${basename(path)}`;
1255
+ if (!retained.available) {
1256
+ const state =
1257
+ retained.reason === "expired" || retained.reason === "deleted"
1258
+ ? retained.reason
1259
+ : "unavailable";
1260
+ return (
1261
+ <ActivityDisclosure
1262
+ icon={<ImageIcon className={ICON_SIZE} />}
1263
+ iconTone={viewFailed ? "failed" : "muted"}
1264
+ title={`${title} · ${state}`}
1265
+ failed={viewFailed}
1266
+ cancelled={viewCancelled}
1267
+ preview={`image ${state}`}
1268
+ media={<MediaEmpty />}
1269
+ >
1270
+ <BodyNote tone={viewFailed ? "error" : undefined}>
1271
+ Image {state}: {retained.reason.replaceAll("_", " ")}.
1272
+ </BodyNote>
1273
+ </ActivityDisclosure>
1274
+ );
1275
+ }
1276
+ return (
1277
+ <RetainedSessionImageDisclosure
1278
+ artifact={retained}
1279
+ load={loadRetainedScreenshot}
1280
+ title={title}
1281
+ caption={path || title}
1282
+ noun="image"
1283
+ icon={<ImageIcon className={ICON_SIZE} />}
1284
+ lightboxLabel="Image"
1285
+ batched={null}
1286
+ failed={viewFailed}
1287
+ cancelled={viewCancelled}
1288
+ />
1289
+ );
1290
+ }
1291
+
1041
1292
  const errMatch = VIEW_IMAGE_ERRORS.find((p) => text.includes(p));
1042
1293
  if (errMatch) {
1043
1294
  const tooBig = text.includes("exceeded the allowed size");
@@ -1935,7 +2186,6 @@ const BASE_ENTRIES: ToolRegistryEntry[] = [
1935
2186
  // truth and is consulted first by the registry.
1936
2187
  { match: "rawType", type: "apply_patch_call", render: ApplyPatchRenderer },
1937
2188
  { match: "rawType", type: "computer_call", render: ComputerCallRenderer },
1938
- { match: "rawType", type: "hosted_tool_call", render: WebSearchRenderer },
1939
2189
  { match: "rawType", type: "tool_search_call", render: ToolSearchRenderer },
1940
2190
  // First-party sandbox + MCP tools resolve by name (exact or MCP leaf).
1941
2191
  { match: "name", name: "exec_command", render: ExecRenderer },
@@ -1955,6 +2205,9 @@ const BASE_ENTRIES: ToolRegistryEntry[] = [
1955
2205
  { match: "name", name: "computer_keypress", render: ComputerCallRenderer },
1956
2206
  { match: "name", name: "computer_drag", render: ComputerCallRenderer },
1957
2207
  { match: "name", name: "web_search_call", render: WebSearchRenderer },
2208
+ { match: "name", name: "image_generation_call", render: GeneratedImageRenderer },
2209
+ { match: "name", name: "generate_image", render: GeneratedImageRenderer },
2210
+ { match: "name", name: "generate_video", render: GeneratedVideoRenderer },
1958
2211
  { match: "name", name: "tool_search", render: ToolSearchRenderer },
1959
2212
  { match: "name", name: "view_image", render: ViewImageRenderer },
1960
2213
  { match: "name", name: "environment_set_variable", render: SecretSetRenderer },
@@ -1,4 +1,12 @@
1
- import type { ResourceRef, SessionStatus, ToolAuthNeededPayload, ToolRef } from "@opengeni/sdk";
1
+ import type {
2
+ MediaGenerationResult,
3
+ ResourceRef,
4
+ SessionStatus,
5
+ TimelineAnnotation,
6
+ TimelineAnnotationSource,
7
+ ToolAuthNeededPayload,
8
+ ToolRef,
9
+ } from "@opengeni/sdk";
2
10
 
3
11
  /* ----------------------------------------------------------------------------
4
12
  Timeline item types
@@ -9,10 +17,19 @@ import type { ResourceRef, SessionStatus, ToolAuthNeededPayload, ToolRef } from
9
17
  and the component demo.
10
18
  -------------------------------------------------------------------------- */
11
19
 
20
+ export type TimelineAnnotationSourceDescriptor = Omit<
21
+ TimelineAnnotationSource,
22
+ "startOffset" | "endOffset" | "contextBefore" | "contextAfter"
23
+ > & {
24
+ text: string;
25
+ };
26
+
12
27
  export type UserMessageItem = {
13
28
  kind: "user-message";
14
29
  id: string;
15
30
  text: string;
31
+ annotations?: TimelineAnnotation[] | undefined;
32
+ annotationSource?: TimelineAnnotationSourceDescriptor | undefined;
16
33
  presentation?: {
17
34
  kind: "realtime_voice" | "realtime_voice_handoff";
18
35
  /** Full bounded execution context sent with this visible voice request. */
@@ -23,6 +40,15 @@ export type UserMessageItem = {
23
40
  /** Tools requested for the turn this message starts. */
24
41
  tools: ToolRef[];
25
42
  occurredAt: string;
43
+ /** Local-only delivery projection; absent for authoritative durable events. */
44
+ delivery?:
45
+ | {
46
+ state: "sending" | "queued" | "failed";
47
+ error?: string | undefined;
48
+ onRetry?: (() => void) | undefined;
49
+ onRemove?: (() => void) | undefined;
50
+ }
51
+ | undefined;
26
52
  };
27
53
 
28
54
  export type AgentMessageItem = {
@@ -33,6 +59,8 @@ export type AgentMessageItem = {
33
59
  /** Still receiving deltas (no completed/turn-end seen yet). */
34
60
  streaming: boolean;
35
61
  occurredAt: string;
62
+ /** Available only after the canonical completed event lands. */
63
+ annotationSource?: TimelineAnnotationSourceDescriptor | undefined;
36
64
  };
37
65
 
38
66
  export type ReasoningItem = {
@@ -44,6 +72,23 @@ export type ReasoningItem = {
44
72
  occurredAt: string;
45
73
  };
46
74
 
75
+ /**
76
+ * Bounded delivery metadata carried by a projected tool-output event. The
77
+ * canonical event remains unchanged; this fact only explains what the current
78
+ * timeline surface could render and whether separately retained full evidence
79
+ * exists.
80
+ */
81
+ export type ToolCallTruncation = {
82
+ truncated: true;
83
+ surface: string;
84
+ reason: string;
85
+ omittedBytes: number | null;
86
+ fullEvidence: {
87
+ available: boolean;
88
+ reason: string | null;
89
+ };
90
+ };
91
+
47
92
  export type ToolCallItem = {
48
93
  kind: "tool-call";
49
94
  id: string;
@@ -52,6 +97,7 @@ export type ToolCallItem = {
52
97
  name: string;
53
98
  arguments: unknown;
54
99
  output: unknown;
100
+ truncation?: ToolCallTruncation | null;
55
101
  /**
56
102
  * The provider-native tool item (`agent.toolCall.created.payload.raw`). Carries
57
103
  * `type` (e.g. `apply_patch_call`, `computer_call`, `hosted_tool_call`) and the
@@ -62,6 +108,8 @@ export type ToolCallItem = {
62
108
  raw: unknown;
63
109
  status: "running" | "complete" | "failed" | "cancelled";
64
110
  occurredAt: string;
111
+ /** Canonical textual projection of the settled tool output. */
112
+ annotationSource?: TimelineAnnotationSourceDescriptor | undefined;
65
113
  };
66
114
 
67
115
  /**
@@ -79,6 +127,8 @@ export type WorkerItem = {
79
127
  prompt: string | null;
80
128
  /** The target/spawned worker session id, when parseable from args/output. */
81
129
  workerSessionId: string | null;
130
+ /** Bounded structured failure retained from session_create/session_send_message. */
131
+ failure: { code: string; message: string } | null;
82
132
  status: "running" | "complete" | "failed" | "cancelled";
83
133
  occurredAt: string;
84
134
  };
@@ -256,10 +306,12 @@ export type MachineInputMember = {
256
306
  | "goal_continuation"
257
307
  | "agent_message"
258
308
  | "agent_steer_instruction"
259
- | "child_terminal_result";
309
+ | "child_terminal_result"
310
+ | "media_generation_result";
260
311
  classification: "success" | "failure" | "action_required" | "info";
261
312
  sourceId: string;
262
313
  summary: string;
314
+ result?: MediaGenerationResult | undefined;
263
315
  };
264
316
 
265
317
  /**
@@ -291,7 +343,7 @@ export type AuthNeededItem = {
291
343
  /** The runtime surface that requested recovery, when the event is an MCP auth signal. */
292
344
  serverId: string | null;
293
345
  /** Durable event family that produced this notice. */
294
- source?: "tool" | "credential" | undefined;
346
+ source?: "tool" | "credential" | "capability" | undefined;
295
347
  /** The connection's registrable domain, e.g. "linear.app". */
296
348
  providerDomain: string;
297
349
  /** The lapsed connection to reconnect, when the row survived. */
@@ -305,6 +357,8 @@ export type AuthNeededItem = {
305
357
  toolName: string | null;
306
358
  /** A pre-minted authorization URL, when the broker already produced one. */
307
359
  authorizationUrl: string | null;
360
+ /** Agent-selected catalog recommendation. The host still owns authorization. */
361
+ capability?: NonNullable<ToolAuthNeededPayload["capability"]> | null | undefined;
308
362
  occurredAt: string;
309
363
  };
310
364