@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.
- package/README.md +138 -2
- package/dist/artifacts-document.d.ts +3 -0
- package/dist/artifacts-document.js +17 -0
- package/dist/artifacts-document.js.map +1 -0
- package/dist/artifacts-presentation.d.ts +3 -0
- package/dist/artifacts-presentation.js +17 -0
- package/dist/artifacts-presentation.js.map +1 -0
- package/dist/artifacts-spreadsheet.d.ts +3 -0
- package/dist/artifacts-spreadsheet.js +17 -0
- package/dist/artifacts-spreadsheet.js.map +1 -0
- package/dist/artifacts.d.ts +2 -0
- package/dist/artifacts.js +199 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/{chunk-NJ7M2B6Z.js → chunk-5UQPNLIO.js} +16 -8
- package/dist/{chunk-NJ7M2B6Z.js.map → chunk-5UQPNLIO.js.map} +1 -1
- package/dist/{chunk-LHLYWG5R.js → chunk-6KLX2RH5.js} +461 -38
- package/dist/chunk-6KLX2RH5.js.map +1 -0
- package/dist/chunk-7WCLAEFV.js +2828 -0
- package/dist/chunk-7WCLAEFV.js.map +1 -0
- package/dist/{chunk-I4MPFDRP.js → chunk-B6WPZSTT.js} +104 -104
- package/dist/{chunk-I4MPFDRP.js.map → chunk-B6WPZSTT.js.map} +1 -1
- package/dist/{chunk-EKZH6IDG.js → chunk-C5ZPSSS5.js} +111 -1
- package/dist/chunk-C5ZPSSS5.js.map +1 -0
- package/dist/{chunk-OL6QVXGF.js → chunk-HA46CYQK.js} +152 -8
- package/dist/chunk-HA46CYQK.js.map +1 -0
- package/dist/chunk-HUIKIDM5.js +2148 -0
- package/dist/chunk-HUIKIDM5.js.map +1 -0
- package/dist/{chunk-FWXGSNXT.js → chunk-IGC6A2ZI.js} +585 -34
- package/dist/chunk-IGC6A2ZI.js.map +1 -0
- package/dist/chunk-JVYQRRC4.js +53 -0
- package/dist/chunk-JVYQRRC4.js.map +1 -0
- package/dist/chunk-KCGXPP5V.js +157 -0
- package/dist/chunk-KCGXPP5V.js.map +1 -0
- package/dist/chunk-LLOLUHVG.js +5937 -0
- package/dist/chunk-LLOLUHVG.js.map +1 -0
- package/dist/{chunk-WYA65Y3F.js → chunk-MKPIAGVL.js} +13 -3
- package/dist/chunk-MKPIAGVL.js.map +1 -0
- package/dist/chunk-PEI6RANI.js +3234 -0
- package/dist/chunk-PEI6RANI.js.map +1 -0
- package/dist/chunk-R3AZOAB5.js +933 -0
- package/dist/chunk-R3AZOAB5.js.map +1 -0
- package/dist/{chunk-O4VXOBGF.js → chunk-WSK7G5LE.js} +70 -2
- package/dist/chunk-WSK7G5LE.js.map +1 -0
- package/dist/{chunk-23EJ676W.js → chunk-XBZWOM2K.js} +9 -4
- package/dist/chunk-XBZWOM2K.js.map +1 -0
- package/dist/{chunk-XCNTXWBB.js → chunk-Y7OEDUJ5.js} +856 -338
- package/dist/chunk-Y7OEDUJ5.js.map +1 -0
- package/dist/client.d.ts +10 -2
- package/dist/clipboard.d.ts +1 -0
- package/dist/clipboard.js +7 -0
- package/dist/clipboard.js.map +1 -0
- package/dist/commands/index.d.ts +3 -3
- package/dist/commands/registry.d.ts +1 -1
- package/dist/commands/types.d.ts +1 -1
- package/dist/components/approval-surface.d.ts +2 -2
- package/dist/components/artifacts/artifact-surface.d.ts +18 -0
- package/dist/components/artifacts/document-editor.d.ts +172 -0
- package/dist/components/artifacts/editable-artifact-ui.d.ts +13 -0
- package/dist/components/artifacts/editable-artifact-workbench.d.ts +49 -0
- package/dist/components/artifacts/editable-document.d.ts +24 -0
- package/dist/components/artifacts/editable-presentation.d.ts +24 -0
- package/dist/components/artifacts/editable-spreadsheet.d.ts +32 -0
- package/dist/components/artifacts/index.d.ts +9 -0
- package/dist/components/artifacts/presentation-editor.d.ts +297 -0
- package/dist/components/artifacts/published-html-artifact-frame.d.ts +14 -0
- package/dist/components/artifacts/spreadsheet-canvas.d.ts +120 -0
- package/dist/components/artifacts/spreadsheet-grid.d.ts +113 -0
- package/dist/components/browser-input.d.ts +7 -0
- package/dist/components/browser-viewer.d.ts +30 -0
- package/dist/components/chat-composer.d.ts +8 -8
- package/dist/components/code-editor.d.ts +25 -3
- package/dist/components/command-palette.d.ts +2 -2
- package/dist/components/composer-transcription-control.d.ts +2 -2
- package/dist/components/composer.d.ts +17 -17
- package/dist/components/computer-viewer.d.ts +24 -0
- package/dist/components/copy-button.d.ts +2 -2
- package/dist/components/desktop-viewer.d.ts +50 -22
- package/dist/components/diff-view.d.ts +1 -1
- package/dist/components/enrollment-consent.d.ts +1 -1
- package/dist/components/enrollment-device-flow.d.ts +1 -1
- package/dist/components/file-browser.d.ts +2 -2
- package/dist/components/fleet-tile.d.ts +1 -1
- package/dist/components/generated-video-player.d.ts +10 -0
- package/dist/components/human-input-form.d.ts +1 -1
- package/dist/components/human-input-surface.d.ts +2 -2
- package/dist/components/interaction-intervention-banner.d.ts +11 -0
- package/dist/components/interactive-workbench-viewers.d.ts +2 -0
- package/dist/components/machine-card.d.ts +2 -2
- package/dist/components/machine-dock-bar.d.ts +3 -3
- package/dist/components/machine-health-pill.d.ts +2 -2
- package/dist/components/machine-input-display.d.ts +1 -1
- package/dist/components/machine-metrics.d.ts +2 -2
- package/dist/components/machine-status-pill.d.ts +4 -4
- package/dist/components/machines/health.d.ts +1 -1
- package/dist/components/machines/machine-detail.d.ts +3 -3
- package/dist/components/machines/metric-history-chart.d.ts +1 -1
- package/dist/components/machines/metric-sparkline.d.ts +2 -2
- package/dist/components/machines/series.d.ts +2 -2
- package/dist/components/machines-dashboard.d.ts +2 -2
- package/dist/components/markdown.d.ts +1 -1
- package/dist/components/message-timeline.d.ts +12 -5
- package/dist/components/model-picker.d.ts +2 -2
- package/dist/components/model-policy-picker.d.ts +7 -7
- package/dist/components/pierre-diff.d.ts +1 -1
- package/dist/components/pierre-file.d.ts +1 -1
- package/dist/components/queue-draft-policy.d.ts +1 -1
- package/dist/components/queue-surface-implementation.d.ts +3 -3
- package/dist/components/queue-surface-state.d.ts +4 -4
- package/dist/components/queue-surface.d.ts +5 -5
- package/dist/components/sandbox-files.d.ts +3 -3
- package/dist/components/sandbox-terminal.d.ts +24 -4
- package/dist/components/sandbox-workspace.d.ts +28 -9
- package/dist/components/session-chrome.d.ts +4 -4
- package/dist/components/session-status.d.ts +2 -2
- package/dist/components/timeline-annotation-selection.d.ts +9 -0
- package/dist/components/timeline-annotations-dialog.d.ts +16 -0
- package/dist/components/timeline-annotations.d.ts +13 -0
- package/dist/components/tooltip.d.ts +4 -4
- package/dist/components/user-message-body.d.ts +2 -2
- package/dist/components/workbench-changes.d.ts +2 -2
- package/dist/components/workspace-dock.d.ts +1 -1
- package/dist/composer.d.ts +11 -11
- package/dist/composer.js +7 -7
- package/dist/hooks/internal.d.ts +1 -1
- package/dist/hooks/use-attached-browsers.d.ts +21 -0
- package/dist/hooks/use-auth-runs.d.ts +32 -0
- package/dist/hooks/use-available-models.d.ts +2 -2
- package/dist/hooks/use-billing-usage.d.ts +1 -1
- package/dist/hooks/use-browser-downloads.d.ts +25 -0
- package/dist/hooks/use-browser-frame-stream.d.ts +28 -0
- package/dist/hooks/use-browser-identities.d.ts +30 -0
- package/dist/hooks/use-browser-session.d.ts +29 -0
- package/dist/hooks/use-browser-sessions.d.ts +32 -0
- package/dist/hooks/use-channels.d.ts +26 -0
- package/dist/hooks/use-codex-accounts.d.ts +2 -2
- package/dist/hooks/use-composer.d.ts +36 -9
- package/dist/hooks/use-computer-frame-stream.d.ts +24 -0
- package/dist/hooks/use-computer-session.d.ts +29 -0
- package/dist/hooks/use-computer-sessions.d.ts +28 -0
- package/dist/hooks/use-desktop-stream.d.ts +5 -1
- package/dist/hooks/use-environments.d.ts +1 -1
- package/dist/hooks/use-file-attachments.d.ts +1 -1
- package/dist/hooks/use-goal.d.ts +2 -2
- package/dist/hooks/use-human-input.d.ts +2 -2
- package/dist/hooks/use-interaction-interventions.d.ts +27 -0
- package/dist/hooks/use-interaction-invalidation.d.ts +19 -0
- package/dist/hooks/use-last-started-turn-policy.d.ts +2 -2
- package/dist/hooks/use-machine-chip.d.ts +2 -2
- package/dist/hooks/use-machines.d.ts +4 -4
- package/dist/hooks/use-network-routes.d.ts +25 -0
- package/dist/hooks/use-packs.d.ts +7 -2
- package/dist/hooks/use-rigs.d.ts +1 -1
- package/dist/hooks/use-sandbox-files.d.ts +6 -4
- package/dist/hooks/use-sandbox-git.d.ts +6 -5
- package/dist/hooks/use-sandbox-terminal.d.ts +1 -1
- package/dist/hooks/use-scheduled-tasks.d.ts +1 -1
- package/dist/hooks/use-session-capabilities.d.ts +5 -4
- package/dist/hooks/use-session-control.d.ts +1 -1
- package/dist/hooks/use-session-events.d.ts +2 -2
- package/dist/hooks/use-session-lineage.d.ts +1 -1
- package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
- package/dist/hooks/use-session.d.ts +2 -2
- package/dist/hooks/use-site-auth-connections.d.ts +25 -0
- package/dist/hooks/use-slash-commands.d.ts +1 -1
- package/dist/hooks/use-supergrok-accounts.d.ts +26 -0
- package/dist/hooks/use-terminal-stream.d.ts +11 -2
- package/dist/hooks/use-turn-queue.d.ts +2 -2
- package/dist/hooks/use-video-artifact-playback.d.ts +9 -0
- package/dist/hooks/use-voice-input.d.ts +1 -1
- package/dist/hooks/use-workspace-capture.d.ts +1 -1
- package/dist/hooks/use-workspace-edit.d.ts +1 -1
- package/dist/hooks/use-workspace-sessions.d.ts +1 -1
- package/dist/hooks/use-workspaces.d.ts +1 -1
- package/dist/index.d.ts +162 -155
- package/dist/index.js +1822 -1703
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +33 -0
- package/dist/interaction.js +550 -0
- package/dist/interaction.js.map +1 -0
- package/dist/interactive-workbench-viewers-TOHBXJEE.js +15 -0
- package/dist/interactive-workbench-viewers-TOHBXJEE.js.map +1 -0
- package/dist/lib/host-platform.d.ts +5 -0
- package/dist/lib/relay-wire.d.ts +24 -1
- package/dist/lib/sandbox-liveness.d.ts +9 -0
- package/dist/lib/terminal-capability.d.ts +5 -0
- package/dist/lib/xterm-theme.d.ts +1 -1
- package/dist/machines.d.ts +30 -30
- package/dist/machines.js +2 -2
- package/dist/model-policy.d.ts +1 -1
- package/dist/model-policy.js +1 -1
- package/dist/provider.d.ts +6 -5
- package/dist/{queue-surface-implementation-U5JFG7HT.js → queue-surface-implementation-2KVJTYXH.js} +100 -48
- package/dist/queue-surface-implementation-2KVJTYXH.js.map +1 -0
- package/dist/realtime/dropdown-menu.d.ts +8 -8
- package/dist/realtime/realtime-control.d.ts +8 -8
- package/dist/realtime.d.ts +4 -4
- package/dist/realtime.js +38 -11
- package/dist/realtime.js.map +1 -1
- package/dist/session-context.d.ts +28 -2
- package/dist/session-ui.d.ts +14 -14
- package/dist/session-ui.js +5 -4
- package/dist/session.d.ts +28 -28
- package/dist/session.js +10 -10
- package/dist/timeline/activity-rail.d.ts +5 -3
- package/dist/timeline/disclosure-context.d.ts +1 -1
- package/dist/timeline/fleet-decision-projection.d.ts +1 -1
- package/dist/timeline/fleet-decision-row.d.ts +3 -3
- package/dist/timeline/index.d.ts +19 -19
- package/dist/timeline/parsers.d.ts +4 -1
- package/dist/timeline/projection.d.ts +3 -3
- package/dist/timeline/registry.d.ts +8 -2
- package/dist/timeline/screenshot-lightbox.d.ts +2 -2
- package/dist/timeline/shared.d.ts +21 -10
- package/dist/timeline/tool-diff.d.ts +2 -2
- package/dist/timeline/tool-renderers.d.ts +1 -1
- package/dist/timeline/turn-summary.d.ts +3 -3
- package/dist/timeline/types.d.ts +44 -3
- package/dist/timeline-annotation-selection-3L7LHGG2.js +187 -0
- package/dist/timeline-annotation-selection-3L7LHGG2.js.map +1 -0
- package/dist/timeline-annotations-dialog-U7EVLR75.js +196 -0
- package/dist/timeline-annotations-dialog-U7EVLR75.js.map +1 -0
- package/package.json +36 -7
- package/src/artifacts-document.ts +31 -0
- package/src/artifacts-presentation.ts +36 -0
- package/src/artifacts-spreadsheet.ts +21 -0
- package/src/artifacts.ts +89 -0
- package/src/client.ts +157 -1
- package/src/clipboard.ts +2 -0
- package/src/components/artifacts/artifact-surface.tsx +93 -0
- package/src/components/artifacts/document-editor.tsx +2255 -0
- package/src/components/artifacts/editable-artifact-ui.tsx +89 -0
- package/src/components/artifacts/editable-artifact-workbench.tsx +203 -0
- package/src/components/artifacts/editable-document.tsx +657 -0
- package/src/components/artifacts/editable-presentation.tsx +1020 -0
- package/src/components/artifacts/editable-spreadsheet.tsx +733 -0
- package/src/components/artifacts/index.ts +104 -0
- package/src/components/artifacts/presentation-editor.tsx +3148 -0
- package/src/components/artifacts/published-html-artifact-frame.tsx +38 -0
- package/src/components/artifacts/spreadsheet-canvas.ts +799 -0
- package/src/components/artifacts/spreadsheet-grid.tsx +2129 -0
- package/src/components/browser-input.ts +65 -0
- package/src/components/browser-viewer.tsx +2702 -0
- package/src/components/chat-composer.tsx +13 -0
- package/src/components/code-editor.tsx +89 -30
- package/src/components/composer-transcription-control.tsx +10 -6
- package/src/components/computer-viewer.tsx +1636 -0
- package/src/components/desktop-viewer.tsx +215 -74
- package/src/components/generated-video-player.tsx +89 -0
- package/src/components/interaction-intervention-banner.tsx +99 -0
- package/src/components/interactive-workbench-viewers.ts +2 -0
- package/src/components/machine-input-display.ts +3 -0
- package/src/components/machines/machine-detail.tsx +1 -1
- package/src/components/message-timeline.tsx +289 -32
- package/src/components/model-policy-picker.tsx +15 -0
- package/src/components/queue-surface-implementation.tsx +116 -60
- package/src/components/sandbox-files.tsx +2 -2
- package/src/components/sandbox-terminal.tsx +128 -46
- package/src/components/sandbox-workspace.tsx +256 -90
- package/src/components/session-chrome.tsx +53 -13
- package/src/components/timeline-annotation-selection.tsx +221 -0
- package/src/components/timeline-annotations-dialog.tsx +213 -0
- package/src/components/timeline-annotations.tsx +84 -0
- package/src/components/workbench-changes.tsx +188 -31
- package/src/components/workspace-dock.tsx +59 -5
- package/src/hooks/use-attached-browsers.ts +154 -0
- package/src/hooks/use-auth-runs.ts +278 -0
- package/src/hooks/use-browser-downloads.ts +218 -0
- package/src/hooks/use-browser-frame-stream.ts +425 -0
- package/src/hooks/use-browser-identities.ts +266 -0
- package/src/hooks/use-browser-session.ts +543 -0
- package/src/hooks/use-browser-sessions.ts +286 -0
- package/src/hooks/use-channels.ts +99 -0
- package/src/hooks/use-composer.ts +769 -24
- package/src/hooks/use-computer-frame-stream.ts +434 -0
- package/src/hooks/use-computer-session.ts +462 -0
- package/src/hooks/use-computer-sessions.ts +251 -0
- package/src/hooks/use-desktop-stream.ts +39 -7
- package/src/hooks/use-interaction-interventions.ts +242 -0
- package/src/hooks/use-interaction-invalidation.ts +66 -0
- package/src/hooks/use-machine-chip.ts +15 -3
- package/src/hooks/use-machines.ts +33 -3
- package/src/hooks/use-network-routes.ts +214 -0
- package/src/hooks/use-packs.ts +51 -0
- package/src/hooks/use-sandbox-files.ts +98 -55
- package/src/hooks/use-sandbox-git.ts +93 -38
- package/src/hooks/use-sandbox-terminal.ts +3 -2
- package/src/hooks/use-session-capabilities.ts +59 -46
- package/src/hooks/use-site-auth-connections.ts +226 -0
- package/src/hooks/use-supergrok-accounts.ts +81 -0
- package/src/hooks/use-terminal-stream.ts +359 -47
- package/src/hooks/use-video-artifact-playback.ts +28 -0
- package/src/hooks/use-workspace-edit.ts +2 -1
- package/src/index.ts +18 -0
- package/src/interaction.ts +101 -0
- package/src/lib/host-platform.ts +10 -0
- package/src/lib/relay-wire.ts +47 -4
- package/src/lib/sandbox-liveness.ts +11 -0
- package/src/lib/terminal-capability.ts +10 -0
- package/src/model-policy.ts +19 -4
- package/src/provider.tsx +133 -1
- package/src/realtime/realtime-control.tsx +34 -6
- package/src/session-context.ts +156 -1
- package/src/timeline/activity-rail.tsx +25 -3
- package/src/timeline/index.ts +3 -0
- package/src/timeline/parsers.ts +14 -1
- package/src/timeline/projection.ts +269 -14
- package/src/timeline/registry.ts +13 -1
- package/src/timeline/screenshot-lightbox.tsx +19 -9
- package/src/timeline/shared.tsx +56 -8
- package/src/timeline/tool-renderers.tsx +303 -50
- package/src/timeline/types.ts +57 -3
- package/styles/compiled.css +312 -21
- package/styles/index.css +15 -0
- package/styles/responsive.css +13 -1
- package/dist/chunk-23EJ676W.js.map +0 -1
- package/dist/chunk-EKZH6IDG.js.map +0 -1
- package/dist/chunk-FWXGSNXT.js.map +0 -1
- package/dist/chunk-LHLYWG5R.js.map +0 -1
- package/dist/chunk-O4VXOBGF.js.map +0 -1
- package/dist/chunk-OL6QVXGF.js.map +0 -1
- package/dist/chunk-WYA65Y3F.js.map +0 -1
- package/dist/chunk-XCNTXWBB.js.map +0 -1
- package/dist/fleet-decision-projection-SLNZMS42.js +0 -241
- package/dist/fleet-decision-projection-SLNZMS42.js.map +0 -1
- package/dist/queue-surface-implementation-U5JFG7HT.js.map +0 -1
|
@@ -6,6 +6,7 @@ export const MACHINE_INPUT_META: Record<MachineInputMember["kind"], string> = {
|
|
|
6
6
|
agent_message: "Agent update",
|
|
7
7
|
agent_steer_instruction: "Agent direction",
|
|
8
8
|
child_terminal_result: "Agent finished",
|
|
9
|
+
media_generation_result: "Video update",
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -32,6 +33,8 @@ export function machineInputBatchLabel(members: readonly MachineInputMember[]):
|
|
|
32
33
|
return n === 1 ? "Agent update" : `${n} agent updates`;
|
|
33
34
|
case "agent_steer_instruction":
|
|
34
35
|
return n === 1 ? "Agent direction" : `${n} agent directions`;
|
|
36
|
+
case "media_generation_result":
|
|
37
|
+
return n === 1 ? "Video ready" : `${n} video updates`;
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
40
|
const parts = [...counts.entries()].map(([kind, count]) => {
|
|
@@ -95,7 +95,7 @@ export function MachineDetail({
|
|
|
95
95
|
data-remove-machine
|
|
96
96
|
aria-label={`Remove machine ${machine.name}`}
|
|
97
97
|
onClick={() => onRemove(machine)}
|
|
98
|
-
className="inline-flex min-h-9 items-center gap-1.5 rounded-og-sm border border-og-status-failed/40 px-2.5 py-1 font-medium text-og-xs text-og-status-failed transition-colors hover:bg-og-status-failed/10 focus-visible:outline-
|
|
98
|
+
className="inline-flex min-h-9 items-center gap-1.5 rounded-og-sm border border-og-status-failed/40 px-2.5 py-1 font-medium text-og-xs text-og-status-failed transition-colors hover:bg-og-status-failed/10 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-status-failed/50 pointer-coarse:min-h-11"
|
|
99
99
|
>
|
|
100
100
|
<Trash2Icon className="size-3.5" aria-hidden />
|
|
101
101
|
<span className="hidden sm:inline">Remove machine</span>
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
DraftTimelineAnnotation,
|
|
3
|
+
MediaGenerationResult,
|
|
4
|
+
SessionEvent,
|
|
5
|
+
SessionStatus,
|
|
6
|
+
} from "@opengeni/sdk";
|
|
2
7
|
import {
|
|
3
8
|
ArrowDownIcon,
|
|
4
9
|
ArrowRightIcon,
|
|
@@ -23,6 +28,8 @@ import { AnimatePresence, motion } from "motion/react";
|
|
|
23
28
|
import { Collapsible } from "radix-ui";
|
|
24
29
|
import {
|
|
25
30
|
Component,
|
|
31
|
+
Suspense,
|
|
32
|
+
lazy,
|
|
26
33
|
memo,
|
|
27
34
|
useCallback,
|
|
28
35
|
useEffect,
|
|
@@ -68,7 +75,10 @@ import {
|
|
|
68
75
|
type NoticeItem,
|
|
69
76
|
type TimelineGroup,
|
|
70
77
|
type TimelineItem,
|
|
78
|
+
type TimelineAnnotationSourceDescriptor,
|
|
79
|
+
type RetainedArtifactLoader,
|
|
71
80
|
type RetainedScreenshotLoader,
|
|
81
|
+
type VideoArtifactPlaybackLoader,
|
|
72
82
|
type ToolRegistry,
|
|
73
83
|
type TurnSummaryOptions,
|
|
74
84
|
type UserMessageItem,
|
|
@@ -81,6 +91,7 @@ import {
|
|
|
81
91
|
useTurnSettleOpen,
|
|
82
92
|
} from "../timeline";
|
|
83
93
|
import { CopyHoverFrame } from "./copy-button";
|
|
94
|
+
import { GeneratedVideoPlayer } from "./generated-video-player";
|
|
84
95
|
import {
|
|
85
96
|
MACHINE_INPUT_META,
|
|
86
97
|
cleanMachineInputSummary,
|
|
@@ -92,8 +103,11 @@ import { SESSION_STATUS_META, StatusDot } from "./session-status";
|
|
|
92
103
|
import { TimelineComputeLabelProvider } from "../timeline/compute-label";
|
|
93
104
|
import { EntranceAnimationProvider, useEntranceAnimation } from "../timeline/entrance";
|
|
94
105
|
import { SeenActivityIdsProvider } from "../timeline/seen-activity-ids";
|
|
106
|
+
import { TimelineAnnotationsChip } from "./timeline-annotations";
|
|
95
107
|
import { TooltipProvider } from "./tooltip";
|
|
96
108
|
|
|
109
|
+
const TimelineAnnotationSelection = lazy(() => import("./timeline-annotation-selection"));
|
|
110
|
+
|
|
97
111
|
export type MessageTimelineProps = {
|
|
98
112
|
/** Raw session events (projected internally) … */
|
|
99
113
|
events?: SessionEvent[] | undefined;
|
|
@@ -146,6 +160,10 @@ export type MessageTimelineProps = {
|
|
|
146
160
|
toolRegistry?: ToolRegistry | undefined;
|
|
147
161
|
/** Resolve opaque retained screenshot receipts through the authenticated host SDK. */
|
|
148
162
|
loadRetainedScreenshot?: RetainedScreenshotLoader | undefined;
|
|
163
|
+
/** Resolve permanent generated-image receipts through the authenticated host SDK. */
|
|
164
|
+
loadRetainedArtifact?: RetainedArtifactLoader | undefined;
|
|
165
|
+
/** Mint short-lived native playback sources for retained generated videos. */
|
|
166
|
+
loadVideoArtifactPlayback?: VideoArtifactPlaybackLoader | undefined;
|
|
149
167
|
/**
|
|
150
168
|
* Display name of the session's active compute target (Connected Machine or
|
|
151
169
|
* cloud sandbox). When set, exec_command collapsed previews prefix `on {label}`.
|
|
@@ -155,6 +173,8 @@ export type MessageTimelineProps = {
|
|
|
155
173
|
turnSummary?: TurnSummaryOptions | undefined;
|
|
156
174
|
/** Follow new events when pinned to the bottom. Defaults to true. */
|
|
157
175
|
autoFollow?: boolean | undefined;
|
|
176
|
+
/** Capture a same-row text selection into the host's canonical composer draft. */
|
|
177
|
+
onAnnotate?: ((annotation: DraftTimelineAnnotation) => void) | undefined;
|
|
158
178
|
/** Older durable history exists above the current window (see useSessionEvents). */
|
|
159
179
|
hasOlder?: boolean | undefined;
|
|
160
180
|
/** An older window is being fetched; shows the quiet top shimmer. */
|
|
@@ -292,9 +312,12 @@ export function MessageTimeline({
|
|
|
292
312
|
resolveProviderLogo,
|
|
293
313
|
toolRegistry = defaultToolRegistry,
|
|
294
314
|
loadRetainedScreenshot,
|
|
315
|
+
loadRetainedArtifact,
|
|
316
|
+
loadVideoArtifactPlayback,
|
|
295
317
|
computeLabel = null,
|
|
296
318
|
turnSummary,
|
|
297
319
|
autoFollow = true,
|
|
320
|
+
onAnnotate,
|
|
298
321
|
hasOlder = false,
|
|
299
322
|
loadingOlder = false,
|
|
300
323
|
onLoadOlder,
|
|
@@ -316,6 +339,20 @@ export function MessageTimeline({
|
|
|
316
339
|
return projected.filter((item) => item.kind !== "auth-needed" || shouldRenderAuthNeeded(item));
|
|
317
340
|
}, [items, events, shouldRenderAuthNeeded]);
|
|
318
341
|
const allGroups = useMemo(() => groupTimeline(resolvedItems), [resolvedItems]);
|
|
342
|
+
const annotationSources = useMemo(() => {
|
|
343
|
+
const sources = new Map<string, TimelineAnnotationSourceDescriptor>();
|
|
344
|
+
for (const item of resolvedItems) {
|
|
345
|
+
if (
|
|
346
|
+
(item.kind === "user-message" ||
|
|
347
|
+
item.kind === "agent-message" ||
|
|
348
|
+
item.kind === "tool-call") &&
|
|
349
|
+
item.annotationSource
|
|
350
|
+
) {
|
|
351
|
+
sources.set(item.annotationSource.eventId, item.annotationSource);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return sources;
|
|
355
|
+
}, [resolvedItems]);
|
|
319
356
|
const groups = useStableTimelineGroupKeys(allGroups);
|
|
320
357
|
const scrollRef = useRef<HTMLDivElement | null>(null);
|
|
321
358
|
const topSentinelRef = useRef<HTMLDivElement | null>(null);
|
|
@@ -1282,6 +1319,15 @@ export function MessageTimeline({
|
|
|
1282
1319
|
<EntranceAnimationProvider value={!bulkRender}>
|
|
1283
1320
|
<TooltipProvider delayDuration={400}>
|
|
1284
1321
|
<div className={cn("og-root relative flex min-h-0 flex-col", className)}>
|
|
1322
|
+
{onAnnotate ? (
|
|
1323
|
+
<Suspense fallback={null}>
|
|
1324
|
+
<TimelineAnnotationSelection
|
|
1325
|
+
rootRef={scrollRef}
|
|
1326
|
+
sources={annotationSources}
|
|
1327
|
+
onAnnotate={onAnnotate}
|
|
1328
|
+
/>
|
|
1329
|
+
</Suspense>
|
|
1330
|
+
) : null}
|
|
1285
1331
|
{/* Pinned: anchoring off so the tip-follow camera owns the motion.
|
|
1286
1332
|
Unpinned: native scroll anchoring holds the reader's place. */}
|
|
1287
1333
|
<div
|
|
@@ -1346,6 +1392,8 @@ export function MessageTimeline({
|
|
|
1346
1392
|
resolveProviderLogo,
|
|
1347
1393
|
toolRegistry,
|
|
1348
1394
|
loadRetainedScreenshot,
|
|
1395
|
+
loadRetainedArtifact,
|
|
1396
|
+
loadVideoArtifactPlayback,
|
|
1349
1397
|
turnSummary,
|
|
1350
1398
|
]}
|
|
1351
1399
|
>
|
|
@@ -1359,6 +1407,8 @@ export function MessageTimeline({
|
|
|
1359
1407
|
resolveProviderLogo={resolveProviderLogo}
|
|
1360
1408
|
toolRegistry={toolRegistry}
|
|
1361
1409
|
loadRetainedScreenshot={loadRetainedScreenshot}
|
|
1410
|
+
loadRetainedArtifact={loadRetainedArtifact}
|
|
1411
|
+
loadVideoArtifactPlayback={loadVideoArtifactPlayback}
|
|
1362
1412
|
turnSummary={turnSummary}
|
|
1363
1413
|
foldLiveCluster={isAgentProgress(next)}
|
|
1364
1414
|
trailingAgentText={trailingAgentTextAfterTurn(group, next)}
|
|
@@ -1703,6 +1753,8 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1703
1753
|
resolveProviderLogo,
|
|
1704
1754
|
toolRegistry,
|
|
1705
1755
|
loadRetainedScreenshot,
|
|
1756
|
+
loadRetainedArtifact,
|
|
1757
|
+
loadVideoArtifactPlayback,
|
|
1706
1758
|
turnSummary,
|
|
1707
1759
|
insideTurn = false,
|
|
1708
1760
|
nestClusterChips = false,
|
|
@@ -1720,6 +1772,8 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1720
1772
|
resolveProviderLogo?: ((providerDomain: string) => string | null | undefined) | undefined;
|
|
1721
1773
|
toolRegistry: ToolRegistry;
|
|
1722
1774
|
loadRetainedScreenshot?: RetainedScreenshotLoader | undefined;
|
|
1775
|
+
loadRetainedArtifact?: RetainedArtifactLoader | undefined;
|
|
1776
|
+
loadVideoArtifactPlayback?: VideoArtifactPlaybackLoader | undefined;
|
|
1723
1777
|
turnSummary?: TurnSummaryOptions | undefined;
|
|
1724
1778
|
/** A completed cluster of a still-RUNNING turn (not the live tail) folds
|
|
1725
1779
|
behind a neutral chip — the one place activity without an outcome still
|
|
@@ -1754,13 +1808,16 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1754
1808
|
const activityShouldFold =
|
|
1755
1809
|
group.kind === "activity" &&
|
|
1756
1810
|
Boolean(group.outcome || (foldLiveCluster && clusterIsSettled(group)));
|
|
1811
|
+
const containsGeneratedImage = timelineGroupContainsGeneratedImage(group);
|
|
1757
1812
|
// Latch live→folded so a top-level shell that was already mounted open can
|
|
1758
1813
|
// start the settle beat without remounting bare rail → wrapper.
|
|
1759
1814
|
const liveActivitySettle = useLiveSettleFold(activityShouldFold && !insideTurn);
|
|
1760
1815
|
const turnDefaultOpen =
|
|
1761
1816
|
!insideTurn &&
|
|
1762
1817
|
group.kind === "turn" &&
|
|
1763
|
-
(group.outcome === "failed" ||
|
|
1818
|
+
(group.outcome === "failed" ||
|
|
1819
|
+
timelineGroupContainsAuthNeeded(group) ||
|
|
1820
|
+
containsGeneratedImage);
|
|
1764
1821
|
// activity-* → turn-* remount: carry resting state so settleFold does not
|
|
1765
1822
|
// re-open a chip the reader already watched collapse.
|
|
1766
1823
|
if (group.kind === "turn" && foldMemory && !insideTurn) {
|
|
@@ -1785,7 +1842,7 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1785
1842
|
// settled closed pre-wrap was showing as a CHIP, so mounting it closed
|
|
1786
1843
|
// is both the stable height and the honest state — force-opening it
|
|
1787
1844
|
// was the "already-collapsed cluster auto-expands at the end" reopen.
|
|
1788
|
-
const useNestedChip = nestClusterChips && activityShouldFold;
|
|
1845
|
+
const useNestedChip = nestClusterChips && activityShouldFold && !containsGeneratedImage;
|
|
1789
1846
|
if (!useNestedChip) {
|
|
1790
1847
|
return (
|
|
1791
1848
|
<ActivityRail
|
|
@@ -1794,6 +1851,7 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1794
1851
|
onMemoryClick={onMemoryClick}
|
|
1795
1852
|
toolRegistry={toolRegistry}
|
|
1796
1853
|
loadRetainedScreenshot={loadRetainedScreenshot}
|
|
1854
|
+
loadRetainedArtifact={loadRetainedArtifact}
|
|
1797
1855
|
bare
|
|
1798
1856
|
/>
|
|
1799
1857
|
);
|
|
@@ -1816,6 +1874,7 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1816
1874
|
onMemoryClick={onMemoryClick}
|
|
1817
1875
|
toolRegistry={toolRegistry}
|
|
1818
1876
|
loadRetainedScreenshot={loadRetainedScreenshot}
|
|
1877
|
+
loadRetainedArtifact={loadRetainedArtifact}
|
|
1819
1878
|
bare
|
|
1820
1879
|
/>
|
|
1821
1880
|
</TurnSummary>
|
|
@@ -1842,6 +1901,7 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1842
1901
|
onMemoryClick={onMemoryClick}
|
|
1843
1902
|
toolRegistry={toolRegistry}
|
|
1844
1903
|
loadRetainedScreenshot={loadRetainedScreenshot}
|
|
1904
|
+
loadRetainedArtifact={loadRetainedArtifact}
|
|
1845
1905
|
bare
|
|
1846
1906
|
/>
|
|
1847
1907
|
</TurnRailFrame>
|
|
@@ -1869,6 +1929,8 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1869
1929
|
resolveProviderLogo,
|
|
1870
1930
|
toolRegistry,
|
|
1871
1931
|
loadRetainedScreenshot,
|
|
1932
|
+
loadRetainedArtifact,
|
|
1933
|
+
loadVideoArtifactPlayback,
|
|
1872
1934
|
turnSummary,
|
|
1873
1935
|
]}
|
|
1874
1936
|
>
|
|
@@ -1881,6 +1943,8 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1881
1943
|
resolveProviderLogo={resolveProviderLogo}
|
|
1882
1944
|
toolRegistry={toolRegistry}
|
|
1883
1945
|
loadRetainedScreenshot={loadRetainedScreenshot}
|
|
1946
|
+
loadRetainedArtifact={loadRetainedArtifact}
|
|
1947
|
+
loadVideoArtifactPlayback={loadVideoArtifactPlayback}
|
|
1884
1948
|
turnSummary={turnSummary}
|
|
1885
1949
|
insideTurn
|
|
1886
1950
|
nestClusterChips={nestClusters}
|
|
@@ -1922,6 +1986,7 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1922
1986
|
onReconnect={onReconnect}
|
|
1923
1987
|
resolveProviderLogo={resolveProviderLogo}
|
|
1924
1988
|
onOpenSession={onOpenSession}
|
|
1989
|
+
loadVideoArtifactPlayback={loadVideoArtifactPlayback}
|
|
1925
1990
|
/>
|
|
1926
1991
|
);
|
|
1927
1992
|
}
|
|
@@ -1985,6 +2050,20 @@ function timelineGroupContainsAuthNeeded(group: TimelineGroup): boolean {
|
|
|
1985
2050
|
}
|
|
1986
2051
|
}
|
|
1987
2052
|
|
|
2053
|
+
/** Generated images are primary user-visible output, not incidental activity. */
|
|
2054
|
+
function timelineGroupContainsGeneratedImage(group: TimelineGroup): boolean {
|
|
2055
|
+
switch (group.kind) {
|
|
2056
|
+
case "item":
|
|
2057
|
+
return false;
|
|
2058
|
+
case "activity":
|
|
2059
|
+
return group.items.some(
|
|
2060
|
+
(item) => item.kind === "tool-call" && item.name === "generate_image",
|
|
2061
|
+
);
|
|
2062
|
+
case "turn":
|
|
2063
|
+
return group.groups.some(timelineGroupContainsGeneratedImage);
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
|
|
1988
2067
|
function timelineGroupItemIds(group: TimelineGroup): string[] {
|
|
1989
2068
|
switch (group.kind) {
|
|
1990
2069
|
case "item":
|
|
@@ -2156,6 +2235,7 @@ export function TimelineRow({
|
|
|
2156
2235
|
onReconnect,
|
|
2157
2236
|
resolveProviderLogo,
|
|
2158
2237
|
onOpenSession,
|
|
2238
|
+
loadVideoArtifactPlayback,
|
|
2159
2239
|
}: {
|
|
2160
2240
|
item: TimelineItem;
|
|
2161
2241
|
renderMessageText?:
|
|
@@ -2164,6 +2244,7 @@ export function TimelineRow({
|
|
|
2164
2244
|
onReconnect?: ((item: AuthNeededItem) => void | Promise<void>) | undefined;
|
|
2165
2245
|
resolveProviderLogo?: ((providerDomain: string) => string | null | undefined) | undefined;
|
|
2166
2246
|
onOpenSession?: ((sessionId: string) => void) | undefined;
|
|
2247
|
+
loadVideoArtifactPlayback?: VideoArtifactPlaybackLoader | undefined;
|
|
2167
2248
|
}) {
|
|
2168
2249
|
switch (item.kind) {
|
|
2169
2250
|
case "user-message":
|
|
@@ -2177,7 +2258,9 @@ export function TimelineRow({
|
|
|
2177
2258
|
case "goal":
|
|
2178
2259
|
return <GoalRow item={item} />;
|
|
2179
2260
|
case "machine-input-batch":
|
|
2180
|
-
return
|
|
2261
|
+
return (
|
|
2262
|
+
<MachineInputBatchRow item={item} loadVideoArtifactPlayback={loadVideoArtifactPlayback} />
|
|
2263
|
+
);
|
|
2181
2264
|
case "notice":
|
|
2182
2265
|
return <NoticeRow item={item} />;
|
|
2183
2266
|
case "context-compaction":
|
|
@@ -2297,25 +2380,71 @@ function UserMessageRow({
|
|
|
2297
2380
|
| undefined;
|
|
2298
2381
|
}) {
|
|
2299
2382
|
const enter = useEntranceAnimation();
|
|
2383
|
+
const deliveryLabel =
|
|
2384
|
+
item.delivery?.state === "sending"
|
|
2385
|
+
? "Sending…"
|
|
2386
|
+
: item.delivery?.state === "queued"
|
|
2387
|
+
? "Queued"
|
|
2388
|
+
: item.delivery?.state === "failed"
|
|
2389
|
+
? "Not sent"
|
|
2390
|
+
: null;
|
|
2300
2391
|
return (
|
|
2301
2392
|
<div className={cn(enter && "animate-og-enter", "flex justify-end")}>
|
|
2302
2393
|
<div className="flex max-w-[85%] min-w-0 flex-col items-end gap-1">
|
|
2303
2394
|
<CopyHoverFrame
|
|
2304
|
-
copyText={
|
|
2395
|
+
copyText={
|
|
2396
|
+
item.text ||
|
|
2397
|
+
(item.annotations ?? [])
|
|
2398
|
+
.map((annotation) => `${annotation.quote}\n${annotation.note}`)
|
|
2399
|
+
.join("\n\n")
|
|
2400
|
+
}
|
|
2305
2401
|
label="Copy message"
|
|
2306
2402
|
className="w-fit max-w-full min-w-0"
|
|
2307
2403
|
trailing={<MessageFooterTime occurredAt={item.occurredAt} />}
|
|
2308
2404
|
>
|
|
2309
2405
|
<div className="w-fit max-w-full min-w-0 rounded-og-lg rounded-br-og-xs border border-og-border bg-og-surface-2 px-4 py-2.5 text-og-md leading-6 text-og-fg">
|
|
2310
|
-
{
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2406
|
+
{item.text ? (
|
|
2407
|
+
<div data-og-annotation-source-key={item.annotationSource?.eventId}>
|
|
2408
|
+
{renderMessageText ? (
|
|
2409
|
+
renderMessageText(item.text, item)
|
|
2410
|
+
) : (
|
|
2411
|
+
<UserMessageBody messageId={item.id} text={item.text}>
|
|
2412
|
+
<Markdown>{item.text}</Markdown>
|
|
2413
|
+
</UserMessageBody>
|
|
2414
|
+
)}
|
|
2415
|
+
</div>
|
|
2416
|
+
) : null}
|
|
2417
|
+
{(item.annotations?.length ?? 0) > 0 ? (
|
|
2418
|
+
<TimelineAnnotationsChip
|
|
2419
|
+
annotations={item.annotations ?? []}
|
|
2420
|
+
className={item.text ? "mt-2" : undefined}
|
|
2421
|
+
/>
|
|
2422
|
+
) : null}
|
|
2317
2423
|
</div>
|
|
2318
2424
|
</CopyHoverFrame>
|
|
2425
|
+
{deliveryLabel ? (
|
|
2426
|
+
<div className="flex max-w-full items-center gap-2 px-1 text-og-xs text-og-fg-subtle">
|
|
2427
|
+
<span title={item.delivery?.error}>{deliveryLabel}</span>
|
|
2428
|
+
{item.delivery?.state === "failed" && item.delivery.onRetry ? (
|
|
2429
|
+
<button
|
|
2430
|
+
type="button"
|
|
2431
|
+
className="font-medium text-og-fg underline decoration-og-border underline-offset-2 hover:text-og-fg-strong"
|
|
2432
|
+
onClick={item.delivery.onRetry}
|
|
2433
|
+
>
|
|
2434
|
+
Retry
|
|
2435
|
+
</button>
|
|
2436
|
+
) : null}
|
|
2437
|
+
{item.delivery?.state === "failed" && item.delivery.onRemove ? (
|
|
2438
|
+
<button
|
|
2439
|
+
type="button"
|
|
2440
|
+
className="font-medium text-og-fg-subtle underline decoration-og-border underline-offset-2 hover:text-og-fg"
|
|
2441
|
+
onClick={item.delivery.onRemove}
|
|
2442
|
+
>
|
|
2443
|
+
Remove
|
|
2444
|
+
</button>
|
|
2445
|
+
) : null}
|
|
2446
|
+
</div>
|
|
2447
|
+
) : null}
|
|
2319
2448
|
</div>
|
|
2320
2449
|
</div>
|
|
2321
2450
|
);
|
|
@@ -2341,15 +2470,17 @@ function AgentMessageRow({
|
|
|
2341
2470
|
// While streaming, copy is still useful (current text) but keep chrome calm —
|
|
2342
2471
|
// stamp only after the message finishes (occurredAt tracks completion).
|
|
2343
2472
|
return (
|
|
2344
|
-
<
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2473
|
+
<div data-og-annotation-source-key={item.annotationSource?.eventId}>
|
|
2474
|
+
<CopyHoverFrame
|
|
2475
|
+
copyText={item.text}
|
|
2476
|
+
label="Copy message"
|
|
2477
|
+
align="start"
|
|
2478
|
+
className={cn(enter && "animate-og-enter", "min-w-0 text-og-md leading-7 text-og-fg")}
|
|
2479
|
+
trailing={item.streaming ? null : <MessageFooterTime occurredAt={item.occurredAt} />}
|
|
2480
|
+
>
|
|
2481
|
+
{body}
|
|
2482
|
+
</CopyHoverFrame>
|
|
2483
|
+
</div>
|
|
2353
2484
|
);
|
|
2354
2485
|
}
|
|
2355
2486
|
|
|
@@ -2599,10 +2730,24 @@ function GoalRow({ item }: { item: GoalItem }) {
|
|
|
2599
2730
|
);
|
|
2600
2731
|
}
|
|
2601
2732
|
|
|
2602
|
-
function MachineInputBatchRow({
|
|
2733
|
+
function MachineInputBatchRow({
|
|
2734
|
+
item,
|
|
2735
|
+
loadVideoArtifactPlayback,
|
|
2736
|
+
}: {
|
|
2737
|
+
item: MachineInputBatchItem;
|
|
2738
|
+
loadVideoArtifactPlayback?: VideoArtifactPlaybackLoader | undefined;
|
|
2739
|
+
}) {
|
|
2603
2740
|
const enter = useEntranceAnimation();
|
|
2604
2741
|
const label = machineInputBatchLabel(item.members);
|
|
2605
2742
|
const single = item.members.length === 1 ? item.members[0]! : null;
|
|
2743
|
+
if (single?.kind === "media_generation_result" && single.result) {
|
|
2744
|
+
return (
|
|
2745
|
+
<VideoGenerationResultRow
|
|
2746
|
+
result={single.result}
|
|
2747
|
+
loadVideoArtifactPlayback={loadVideoArtifactPlayback}
|
|
2748
|
+
/>
|
|
2749
|
+
);
|
|
2750
|
+
}
|
|
2606
2751
|
const singleSummary = single ? cleanMachineInputSummary(single.summary) : "";
|
|
2607
2752
|
const showCollapsedSummary =
|
|
2608
2753
|
single != null && machineInputSummaryIsUseful(single.kind, singleSummary);
|
|
@@ -2626,7 +2771,11 @@ function MachineInputBatchRow({ item }: { item: MachineInputBatchItem }) {
|
|
|
2626
2771
|
</summary>
|
|
2627
2772
|
<div className="mx-auto mt-2 w-full max-w-lg space-y-2 border-t border-og-border/50 pt-2">
|
|
2628
2773
|
{item.members.map((member) => (
|
|
2629
|
-
<MachineInputRow
|
|
2774
|
+
<MachineInputRow
|
|
2775
|
+
key={member.id}
|
|
2776
|
+
member={member}
|
|
2777
|
+
loadVideoArtifactPlayback={loadVideoArtifactPlayback}
|
|
2778
|
+
/>
|
|
2630
2779
|
))}
|
|
2631
2780
|
</div>
|
|
2632
2781
|
</details>
|
|
@@ -2639,7 +2788,22 @@ function MachineInputBatchRow({ item }: { item: MachineInputBatchItem }) {
|
|
|
2639
2788
|
);
|
|
2640
2789
|
}
|
|
2641
2790
|
|
|
2642
|
-
function MachineInputRow({
|
|
2791
|
+
function MachineInputRow({
|
|
2792
|
+
member,
|
|
2793
|
+
loadVideoArtifactPlayback,
|
|
2794
|
+
}: {
|
|
2795
|
+
member: MachineInputBatchItem["members"][number];
|
|
2796
|
+
loadVideoArtifactPlayback?: VideoArtifactPlaybackLoader | undefined;
|
|
2797
|
+
}) {
|
|
2798
|
+
if (member.kind === "media_generation_result" && member.result) {
|
|
2799
|
+
return (
|
|
2800
|
+
<VideoGenerationResultRow
|
|
2801
|
+
result={member.result}
|
|
2802
|
+
loadVideoArtifactPlayback={loadVideoArtifactPlayback}
|
|
2803
|
+
compact
|
|
2804
|
+
/>
|
|
2805
|
+
);
|
|
2806
|
+
}
|
|
2643
2807
|
const source = readableMachineInputSource(member.sourceId);
|
|
2644
2808
|
const summary = cleanMachineInputSummary(member.summary);
|
|
2645
2809
|
return (
|
|
@@ -2660,6 +2824,72 @@ function MachineInputRow({ member }: { member: MachineInputBatchItem["members"][
|
|
|
2660
2824
|
);
|
|
2661
2825
|
}
|
|
2662
2826
|
|
|
2827
|
+
function VideoGenerationResultRow({
|
|
2828
|
+
result,
|
|
2829
|
+
loadVideoArtifactPlayback,
|
|
2830
|
+
compact = false,
|
|
2831
|
+
}: {
|
|
2832
|
+
result: MediaGenerationResult;
|
|
2833
|
+
loadVideoArtifactPlayback?: VideoArtifactPlaybackLoader | undefined;
|
|
2834
|
+
compact?: boolean | undefined;
|
|
2835
|
+
}) {
|
|
2836
|
+
const enter = useEntranceAnimation();
|
|
2837
|
+
if (result.status !== "ready") {
|
|
2838
|
+
return (
|
|
2839
|
+
<div
|
|
2840
|
+
className={cn(
|
|
2841
|
+
enter && "animate-og-enter",
|
|
2842
|
+
"mx-auto w-full max-w-lg rounded-og-md border border-og-status-failed/30 bg-og-status-failed/5 px-3.5 py-3",
|
|
2843
|
+
)}
|
|
2844
|
+
>
|
|
2845
|
+
<div className="flex items-center gap-2 text-og-sm font-medium text-og-status-failed">
|
|
2846
|
+
<XCircleIcon aria-hidden className="size-4" />
|
|
2847
|
+
Video generation failed
|
|
2848
|
+
</div>
|
|
2849
|
+
<p className="mt-1 text-og-sm leading-5 text-og-fg-muted">{result.boundedPublicReason}</p>
|
|
2850
|
+
</div>
|
|
2851
|
+
);
|
|
2852
|
+
}
|
|
2853
|
+
const { receipt } = result;
|
|
2854
|
+
const facts = receipt.video;
|
|
2855
|
+
return (
|
|
2856
|
+
<section
|
|
2857
|
+
aria-label="Generated video"
|
|
2858
|
+
className={cn(
|
|
2859
|
+
enter && "animate-og-enter",
|
|
2860
|
+
"mx-auto w-full max-w-2xl overflow-hidden rounded-og-lg border border-og-border bg-og-surface-1 shadow-sm",
|
|
2861
|
+
compact && "max-w-lg",
|
|
2862
|
+
)}
|
|
2863
|
+
>
|
|
2864
|
+
{loadVideoArtifactPlayback ? (
|
|
2865
|
+
<GeneratedVideoPlayer
|
|
2866
|
+
receipt={receipt}
|
|
2867
|
+
loadPlaybackSource={loadVideoArtifactPlayback}
|
|
2868
|
+
className="rounded-none border-0 shadow-none"
|
|
2869
|
+
/>
|
|
2870
|
+
) : (
|
|
2871
|
+
<div className="flex aspect-video items-center justify-center bg-og-surface-2 text-og-fg-subtle">
|
|
2872
|
+
<PlayIcon aria-hidden className="size-6" />
|
|
2873
|
+
</div>
|
|
2874
|
+
)}
|
|
2875
|
+
<div className="flex items-center justify-between gap-4 px-3.5 py-2.5">
|
|
2876
|
+
<div className="min-w-0">
|
|
2877
|
+
<p className="text-og-sm font-medium text-og-fg">Generated video</p>
|
|
2878
|
+
<p className="truncate text-og-xs text-og-fg-subtle">
|
|
2879
|
+
{facts.width}×{facts.height} · {formatVideoDuration(facts.durationSeconds)}
|
|
2880
|
+
{facts.hasAudio ? " · Audio" : ""}
|
|
2881
|
+
</p>
|
|
2882
|
+
</div>
|
|
2883
|
+
<CheckCircle2Icon aria-label="Ready" className="size-4 shrink-0 text-og-status-success" />
|
|
2884
|
+
</div>
|
|
2885
|
+
</section>
|
|
2886
|
+
);
|
|
2887
|
+
}
|
|
2888
|
+
|
|
2889
|
+
function formatVideoDuration(seconds: number): string {
|
|
2890
|
+
return `${Math.round(seconds * 10) / 10}s`;
|
|
2891
|
+
}
|
|
2892
|
+
|
|
2663
2893
|
function NoticeRow({ item }: { item: NoticeItem }) {
|
|
2664
2894
|
const enter = useEntranceAnimation();
|
|
2665
2895
|
const tone =
|
|
@@ -2725,14 +2955,32 @@ function AuthNeededRow({
|
|
|
2725
2955
|
const enter = useEntranceAnimation();
|
|
2726
2956
|
const [busy, setBusy] = useState(false);
|
|
2727
2957
|
const [failed, setFailed] = useState(false);
|
|
2958
|
+
const recommendation = item.capability ?? null;
|
|
2728
2959
|
const provider =
|
|
2729
|
-
|
|
2960
|
+
recommendation?.name ??
|
|
2961
|
+
(item.serverId === "codex_apps" ? "Codex Apps" : providerLabel(item.providerDomain));
|
|
2730
2962
|
const unavailable =
|
|
2731
2963
|
item.reason === "personal_authority_unavailable" ||
|
|
2732
2964
|
item.reason === "unsupported_auth" ||
|
|
2733
2965
|
item.reason === "resource_scope_unavailable";
|
|
2734
2966
|
const missing = item.reason === "missing_connection";
|
|
2735
|
-
const actionLabel =
|
|
2967
|
+
const actionLabel = recommendation
|
|
2968
|
+
? recommendation.action === "connect"
|
|
2969
|
+
? "Connect"
|
|
2970
|
+
: "Review"
|
|
2971
|
+
: missing
|
|
2972
|
+
? "Connect"
|
|
2973
|
+
: "Reconnect";
|
|
2974
|
+
const title = recommendation
|
|
2975
|
+
? recommendation.action === "connect"
|
|
2976
|
+
? `Connect ${provider}`
|
|
2977
|
+
: recommendation.action === "add_credentials"
|
|
2978
|
+
? `Set up ${provider}`
|
|
2979
|
+
: `Enable ${provider}`
|
|
2980
|
+
: unavailable
|
|
2981
|
+
? `${provider} tools unavailable`
|
|
2982
|
+
: `${actionLabel} ${provider}`;
|
|
2983
|
+
const reasonLine = recommendation?.rationale ?? authReasonLine(item.reason);
|
|
2736
2984
|
|
|
2737
2985
|
const start = async () => {
|
|
2738
2986
|
if (!onReconnect || busy) {
|
|
@@ -2761,10 +3009,18 @@ function AuthNeededRow({
|
|
|
2761
3009
|
label={provider}
|
|
2762
3010
|
/>
|
|
2763
3011
|
<div className="min-w-0">
|
|
2764
|
-
<p className="truncate text-og-md font-medium text-og-fg">
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
3012
|
+
<p className="truncate text-og-md font-medium text-og-fg">{title}</p>
|
|
3013
|
+
<p className="line-clamp-2 text-og-sm text-og-fg-subtle">{reasonLine}</p>
|
|
3014
|
+
{recommendation ? (
|
|
3015
|
+
<p className="mt-1 truncate text-og-xs text-og-fg-muted">
|
|
3016
|
+
Provider: {item.providerDomain}
|
|
3017
|
+
</p>
|
|
3018
|
+
) : null}
|
|
3019
|
+
{recommendation && recommendation.requiredVariables.length > 0 ? (
|
|
3020
|
+
<p className="mt-1 truncate text-og-xs text-og-fg-muted">
|
|
3021
|
+
Needs variables: {recommendation.requiredVariables.join(", ")}
|
|
3022
|
+
</p>
|
|
3023
|
+
) : null}
|
|
2768
3024
|
</div>
|
|
2769
3025
|
</div>
|
|
2770
3026
|
{!unavailable && onReconnect ? (
|
|
@@ -2797,8 +3053,9 @@ function AuthNeededRow({
|
|
|
2797
3053
|
</div>
|
|
2798
3054
|
{!unavailable ? (
|
|
2799
3055
|
<p className="px-1 text-og-xs text-og-fg-subtle">
|
|
2800
|
-
|
|
2801
|
-
|
|
3056
|
+
{recommendation
|
|
3057
|
+
? "No access has been granted. Review and confirm the provider before continuing."
|
|
3058
|
+
: `This tool call wasn't replayed. After ${missing ? "connecting" : "reconnecting"}, send a new message to try again.`}
|
|
2802
3059
|
</p>
|
|
2803
3060
|
) : null}
|
|
2804
3061
|
{failed ? (
|
|
@@ -65,6 +65,7 @@ export const defaultModelPolicyPickerMessages: ModelPolicyPickerMessages = {
|
|
|
65
65
|
billingHints: {
|
|
66
66
|
opengeni_credits: "Will use credits",
|
|
67
67
|
codex_subscription: "ChatGPT / Codex plan",
|
|
68
|
+
supergrok_subscription: "SuperGrok / xAI plan",
|
|
68
69
|
byok: "Billed to your AI Gateway",
|
|
69
70
|
},
|
|
70
71
|
};
|
|
@@ -132,6 +133,17 @@ function ChatGptMark(props: SVGProps<SVGSVGElement>) {
|
|
|
132
133
|
);
|
|
133
134
|
}
|
|
134
135
|
|
|
136
|
+
function XaiMark(props: SVGProps<SVGSVGElement>) {
|
|
137
|
+
return (
|
|
138
|
+
<svg viewBox="0 0 466.04 516.93" fill="currentColor" aria-hidden="true" {...props}>
|
|
139
|
+
<polygon points="0.12 182.71 234.14 516.92 338.15 516.92 104.13 182.71 0.12 182.71" />
|
|
140
|
+
<polygon points="0 516.92 104.08 516.92 156.08 442.67 104.04 368.34 0 516.92" />
|
|
141
|
+
<polygon points="466.04 0 361.96 0 182.1 256.86 234.15 331.18 466.04 0" />
|
|
142
|
+
<polygon points="380.78 516.92 466.04 516.92 466.04 37.16 380.78 158.92 380.78 516.92" />
|
|
143
|
+
</svg>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
135
147
|
export function BillingClassMark(props: {
|
|
136
148
|
billingClass: PickerBillingClass;
|
|
137
149
|
className?: string | undefined;
|
|
@@ -140,6 +152,7 @@ export function BillingClassMark(props: {
|
|
|
140
152
|
const labels: Record<PickerBillingClass, string> = {
|
|
141
153
|
opengeni_credits: "OpenGeni",
|
|
142
154
|
codex_subscription: "Codex",
|
|
155
|
+
supergrok_subscription: "SuperGrok",
|
|
143
156
|
byok: "Bring your own key",
|
|
144
157
|
};
|
|
145
158
|
const label = props["aria-label"] ?? labels[props.billingClass];
|
|
@@ -162,6 +175,8 @@ export function BillingClassMark(props: {
|
|
|
162
175
|
<OpenGeniMark className={mark} />
|
|
163
176
|
) : props.billingClass === "codex_subscription" ? (
|
|
164
177
|
<ChatGptMark className={mark} />
|
|
178
|
+
) : props.billingClass === "supergrok_subscription" ? (
|
|
179
|
+
<XaiMark className={mark} />
|
|
165
180
|
) : (
|
|
166
181
|
<KeyRoundIcon className={mark} aria-hidden />
|
|
167
182
|
)}
|