@opengeni/react 0.46.1 → 0.52.1
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 +158 -14
- 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 +170 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/chunk-6BBWWOOU.js +82 -0
- package/dist/chunk-6BBWWOOU.js.map +1 -0
- package/dist/{chunk-HFO4ERGQ.js → chunk-724BW4TW.js} +586 -35
- package/dist/chunk-724BW4TW.js.map +1 -0
- package/dist/chunk-7I2KB3OK.js +3895 -0
- package/dist/chunk-7I2KB3OK.js.map +1 -0
- package/dist/chunk-7WCLAEFV.js +2828 -0
- package/dist/chunk-7WCLAEFV.js.map +1 -0
- package/dist/{chunk-U3CSCMWA.js → chunk-FK6VG4LL.js} +9 -13
- package/dist/chunk-FK6VG4LL.js.map +1 -0
- package/dist/{chunk-SRFUT2ZU.js → chunk-FWS3KC3Z.js} +120 -64
- package/dist/chunk-FWS3KC3Z.js.map +1 -0
- package/dist/{chunk-EKZH6IDG.js → chunk-HDBG7XGO.js} +62 -1
- package/dist/chunk-HDBG7XGO.js.map +1 -0
- package/dist/chunk-HUIKIDM5.js +2148 -0
- package/dist/chunk-HUIKIDM5.js.map +1 -0
- package/dist/{chunk-LGVMUIRV.js → chunk-JAGDUCZQ.js} +1053 -390
- package/dist/chunk-JAGDUCZQ.js.map +1 -0
- package/dist/{chunk-LWR4MXSS.js → chunk-JR3QFY6B.js} +420 -35
- package/dist/chunk-JR3QFY6B.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-EB67J347.js → chunk-KZ73RL76.js} +111 -31
- package/dist/chunk-KZ73RL76.js.map +1 -0
- package/dist/chunk-PEI6RANI.js +3234 -0
- package/dist/chunk-PEI6RANI.js.map +1 -0
- package/dist/{chunk-3PB7MIT6.js → chunk-ROIRTM37.js} +220 -72
- package/dist/chunk-ROIRTM37.js.map +1 -0
- package/dist/chunk-VZTQ73XT.js +86 -0
- package/dist/chunk-VZTQ73XT.js.map +1 -0
- package/dist/{chunk-VCBFUSUZ.js → chunk-WSK7G5LE.js} +72 -4
- package/dist/chunk-WSK7G5LE.js.map +1 -0
- package/dist/{chunk-FGZUCXZF.js → chunk-WYA65Y3F.js} +16 -16
- package/dist/chunk-WYA65Y3F.js.map +1 -0
- package/dist/{chunk-6EDV6YFE.js → chunk-X4S56Y2H.js} +147 -35
- package/dist/chunk-X4S56Y2H.js.map +1 -0
- package/dist/client.d.ts +7 -1
- 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 +8 -0
- package/dist/components/artifacts/presentation-editor.d.ts +297 -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-viewer.d.ts +29 -0
- package/dist/components/chat-composer.d.ts +13 -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 +4 -2
- package/dist/components/composer.d.ts +29 -15
- package/dist/components/computer-viewer.d.ts +23 -0
- package/dist/components/copy-button.d.ts +2 -2
- package/dist/components/desktop-viewer.d.ts +25 -21
- 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/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 +5 -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 +5 -5
- package/dist/components/markdown.d.ts +1 -1
- package/dist/components/message-timeline.d.ts +22 -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 +5 -5
- package/dist/components/sandbox-terminal.d.ts +50 -4
- package/dist/components/sandbox-workspace.d.ts +30 -10
- 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 +3 -1
- package/dist/composer.d.ts +11 -11
- package/dist/composer.js +7 -7
- package/dist/hooks/internal.d.ts +7 -1
- package/dist/hooks/use-attached-browsers.d.ts +21 -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-frame-stream.d.ts +28 -0
- package/dist/hooks/use-browser-identities.d.ts +26 -0
- package/dist/hooks/use-browser-session.d.ts +28 -0
- package/dist/hooks/use-browser-sessions.d.ts +32 -0
- package/dist/hooks/use-codex-accounts.d.ts +3 -3
- 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 +28 -0
- package/dist/hooks/use-computer-sessions.d.ts +28 -0
- package/dist/hooks/use-desktop-stream.d.ts +1 -1
- package/dist/hooks/use-environments.d.ts +11 -5
- 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-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 +10 -3
- 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 +25 -4
- package/dist/hooks/use-sandbox-git.d.ts +13 -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-slash-commands.d.ts +1 -1
- package/dist/hooks/use-terminal-stream.d.ts +8 -2
- package/dist/hooks/use-transcription.d.ts +2 -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 +6 -4
- 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 +158 -154
- package/dist/index.js +1718 -908
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +23 -0
- package/dist/interaction.js +36 -0
- package/dist/interaction.js.map +1 -0
- package/dist/interactive-workbench-viewers-KHNOHWQE.js +13 -0
- package/dist/interactive-workbench-viewers-KHNOHWQE.js.map +1 -0
- package/dist/lib/composer-responsive-context.d.ts +9 -0
- package/dist/lib/relay-wire.d.ts +4 -0
- package/dist/lib/sandbox-liveness.d.ts +9 -0
- package/dist/lib/terminal-capability.d.ts +5 -0
- package/dist/lib/use-portal-token-style.d.ts +14 -3
- package/dist/lib/xterm-theme.d.ts +1 -1
- package/dist/machines.d.ts +30 -30
- package/dist/machines.js +3 -3
- package/dist/provider.d.ts +4 -4
- package/dist/{queue-surface-implementation-J4XJFKRW.js → queue-surface-implementation-2KVJTYXH.js} +117 -64
- 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 +15 -6
- package/dist/realtime.d.ts +4 -4
- package/dist/realtime.js +30 -33
- package/dist/realtime.js.map +1 -1
- package/dist/session-context.d.ts +19 -1
- package/dist/session-ui.d.ts +14 -14
- package/dist/session-ui.js +6 -5
- package/dist/session.d.ts +28 -28
- package/dist/session.js +5 -5
- package/dist/timeline/activity-rail.d.ts +6 -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 +6 -3
- package/dist/timeline/projection.d.ts +3 -3
- package/dist/timeline/registry.d.ts +10 -1
- 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 +42 -2
- 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/dist/voice-recording-store.d.ts +8 -2
- package/package.json +52 -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 +86 -0
- package/src/client.ts +90 -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 +99 -0
- package/src/components/artifacts/presentation-editor.tsx +3148 -0
- package/src/components/artifacts/spreadsheet-canvas.ts +799 -0
- package/src/components/artifacts/spreadsheet-grid.tsx +2129 -0
- package/src/components/browser-viewer.tsx +1592 -0
- package/src/components/chat-composer.tsx +25 -2
- package/src/components/code-editor.tsx +90 -31
- package/src/components/command-palette.tsx +1 -1
- package/src/components/composer-transcription-control.tsx +51 -22
- package/src/components/composer.tsx +49 -23
- package/src/components/computer-viewer.tsx +1139 -0
- package/src/components/copy-button.tsx +1 -1
- package/src/components/desktop-viewer.tsx +103 -75
- package/src/components/file-browser.tsx +39 -17
- package/src/components/generated-video-player.tsx +89 -0
- package/src/components/human-input-form.tsx +2 -2
- package/src/components/interactive-workbench-viewers.ts +2 -0
- package/src/components/machine-card.tsx +1 -1
- package/src/components/machine-input-display.ts +3 -0
- package/src/components/machines/machine-detail.tsx +39 -15
- package/src/components/machines-dashboard.tsx +7 -6
- package/src/components/message-timeline.tsx +327 -37
- package/src/components/model-picker.tsx +2 -2
- package/src/components/model-policy-picker.tsx +16 -15
- package/src/components/queue-surface-implementation.tsx +135 -75
- package/src/components/queue-surface-state.tsx +2 -2
- package/src/components/sandbox-files.tsx +142 -62
- package/src/components/sandbox-terminal.tsx +119 -35
- package/src/components/sandbox-workspace.tsx +394 -228
- package/src/components/session-chrome.tsx +67 -27
- 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/tooltip.tsx +13 -16
- package/src/components/user-message-body.tsx +1 -1
- package/src/components/workbench-changes.tsx +192 -35
- package/src/components/workspace-dock.tsx +13 -5
- package/src/composer.ts +3 -0
- package/src/hooks/internal.ts +132 -38
- package/src/hooks/use-attached-browsers.ts +152 -0
- package/src/hooks/use-browser-frame-stream.ts +316 -0
- package/src/hooks/use-browser-identities.ts +225 -0
- package/src/hooks/use-browser-session.ts +476 -0
- package/src/hooks/use-browser-sessions.ts +281 -0
- package/src/hooks/use-codex-accounts.ts +4 -4
- package/src/hooks/use-composer.ts +769 -24
- package/src/hooks/use-computer-frame-stream.ts +311 -0
- package/src/hooks/use-computer-session.ts +442 -0
- package/src/hooks/use-computer-sessions.ts +245 -0
- package/src/hooks/use-environments.ts +24 -5
- package/src/hooks/use-file-attachments.ts +70 -32
- package/src/hooks/use-goal.ts +17 -5
- package/src/hooks/use-machine-chip.ts +5 -3
- package/src/hooks/use-machines.ts +79 -3
- package/src/hooks/use-packs.ts +51 -0
- package/src/hooks/use-sandbox-files.ts +382 -88
- package/src/hooks/use-sandbox-git.ts +208 -46
- package/src/hooks/use-sandbox-terminal.ts +3 -2
- package/src/hooks/use-session-capabilities.ts +94 -70
- package/src/hooks/use-session-events.ts +18 -4
- package/src/hooks/use-terminal-stream.ts +102 -23
- package/src/hooks/use-transcription.ts +4 -14
- package/src/hooks/use-turn-queue.ts +17 -5
- package/src/hooks/use-video-artifact-playback.ts +28 -0
- package/src/hooks/use-voice-input.ts +163 -19
- package/src/hooks/use-windowed-sections.ts +9 -7
- package/src/hooks/use-workspace-edit.ts +2 -1
- package/src/index.ts +21 -6
- package/src/interaction.ts +71 -0
- package/src/lib/composer-responsive-context.ts +15 -0
- package/src/lib/relay-wire.ts +4 -0
- package/src/lib/sandbox-liveness.ts +11 -0
- package/src/lib/terminal-capability.ts +10 -0
- package/src/lib/use-portal-token-style.ts +60 -15
- package/src/provider.tsx +52 -7
- package/src/realtime/dropdown-menu.tsx +15 -19
- package/src/realtime/realtime-control.tsx +16 -5
- package/src/session-context.ts +90 -0
- package/src/timeline/activity-rail.tsx +31 -6
- package/src/timeline/index.ts +4 -1
- package/src/timeline/parsers.ts +46 -20
- package/src/timeline/projection.ts +233 -13
- package/src/timeline/registry.ts +19 -0
- package/src/timeline/screenshot-lightbox.tsx +30 -9
- package/src/timeline/shared.tsx +59 -11
- package/src/timeline/tool-renderers.tsx +421 -24
- package/src/timeline/turn-summary.tsx +2 -2
- package/src/timeline/types.ts +58 -2
- package/src/voice-recording-store.ts +15 -0
- package/styles/compiled.css +5298 -0
- package/styles/compiled.d.ts +2 -0
- package/styles/effective-tokens.css +27 -0
- package/styles/index.css +18 -0
- package/styles/responsive.css +208 -0
- package/styles/responsive.d.ts +2 -0
- package/styles/tokens.css +50 -17
- package/dist/chunk-3PB7MIT6.js.map +0 -1
- package/dist/chunk-6EDV6YFE.js.map +0 -1
- package/dist/chunk-EB67J347.js.map +0 -1
- package/dist/chunk-EKZH6IDG.js.map +0 -1
- package/dist/chunk-FGZUCXZF.js.map +0 -1
- package/dist/chunk-HFO4ERGQ.js.map +0 -1
- package/dist/chunk-JB5725BI.js +0 -48
- package/dist/chunk-JB5725BI.js.map +0 -1
- package/dist/chunk-LGVMUIRV.js.map +0 -1
- package/dist/chunk-LWR4MXSS.js.map +0 -1
- package/dist/chunk-SRFUT2ZU.js.map +0 -1
- package/dist/chunk-U3CSCMWA.js.map +0 -1
- package/dist/chunk-VCBFUSUZ.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-J4XJFKRW.js.map +0 -1
|
@@ -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,6 +75,10 @@ import {
|
|
|
68
75
|
type NoticeItem,
|
|
69
76
|
type TimelineGroup,
|
|
70
77
|
type TimelineItem,
|
|
78
|
+
type TimelineAnnotationSourceDescriptor,
|
|
79
|
+
type RetainedArtifactLoader,
|
|
80
|
+
type RetainedScreenshotLoader,
|
|
81
|
+
type VideoArtifactPlaybackLoader,
|
|
71
82
|
type ToolRegistry,
|
|
72
83
|
type TurnSummaryOptions,
|
|
73
84
|
type UserMessageItem,
|
|
@@ -80,6 +91,7 @@ import {
|
|
|
80
91
|
useTurnSettleOpen,
|
|
81
92
|
} from "../timeline";
|
|
82
93
|
import { CopyHoverFrame } from "./copy-button";
|
|
94
|
+
import { GeneratedVideoPlayer } from "./generated-video-player";
|
|
83
95
|
import {
|
|
84
96
|
MACHINE_INPUT_META,
|
|
85
97
|
cleanMachineInputSummary,
|
|
@@ -91,8 +103,11 @@ import { SESSION_STATUS_META, StatusDot } from "./session-status";
|
|
|
91
103
|
import { TimelineComputeLabelProvider } from "../timeline/compute-label";
|
|
92
104
|
import { EntranceAnimationProvider, useEntranceAnimation } from "../timeline/entrance";
|
|
93
105
|
import { SeenActivityIdsProvider } from "../timeline/seen-activity-ids";
|
|
106
|
+
import { TimelineAnnotationsChip } from "./timeline-annotations";
|
|
94
107
|
import { TooltipProvider } from "./tooltip";
|
|
95
108
|
|
|
109
|
+
const TimelineAnnotationSelection = lazy(() => import("./timeline-annotation-selection"));
|
|
110
|
+
|
|
96
111
|
export type MessageTimelineProps = {
|
|
97
112
|
/** Raw session events (projected internally) … */
|
|
98
113
|
events?: SessionEvent[] | undefined;
|
|
@@ -123,6 +138,12 @@ export type MessageTimelineProps = {
|
|
|
123
138
|
* a Reconnect button without a handler to run it.
|
|
124
139
|
*/
|
|
125
140
|
onReconnect?: ((item: AuthNeededItem) => void | Promise<void>) | undefined;
|
|
141
|
+
/**
|
|
142
|
+
* Decide which durable authentication notices this timeline presents.
|
|
143
|
+
* Defaults to showing every notice. Embedded hosts can suppress notices for
|
|
144
|
+
* credentials they manage elsewhere without discarding the underlying event.
|
|
145
|
+
*/
|
|
146
|
+
shouldRenderAuthNeeded?: ((item: AuthNeededItem) => boolean) | undefined;
|
|
126
147
|
/**
|
|
127
148
|
* Resolve a provider domain (from a reconnect card) to a logo URL the host
|
|
128
149
|
* serves itself — the app maps it through its catalog + `catalogAssetUrl`.
|
|
@@ -137,6 +158,12 @@ export type MessageTimelineProps = {
|
|
|
137
158
|
* `createDefaultToolRegistry({ entries })` to add custom tool renderers.
|
|
138
159
|
*/
|
|
139
160
|
toolRegistry?: ToolRegistry | undefined;
|
|
161
|
+
/** Resolve opaque retained screenshot receipts through the authenticated host SDK. */
|
|
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;
|
|
140
167
|
/**
|
|
141
168
|
* Display name of the session's active compute target (Connected Machine or
|
|
142
169
|
* cloud sandbox). When set, exec_command collapsed previews prefix `on {label}`.
|
|
@@ -146,6 +173,8 @@ export type MessageTimelineProps = {
|
|
|
146
173
|
turnSummary?: TurnSummaryOptions | undefined;
|
|
147
174
|
/** Follow new events when pinned to the bottom. Defaults to true. */
|
|
148
175
|
autoFollow?: boolean | undefined;
|
|
176
|
+
/** Capture a same-row text selection into the host's canonical composer draft. */
|
|
177
|
+
onAnnotate?: ((annotation: DraftTimelineAnnotation) => void) | undefined;
|
|
149
178
|
/** Older durable history exists above the current window (see useSessionEvents). */
|
|
150
179
|
hasOlder?: boolean | undefined;
|
|
151
180
|
/** An older window is being fetched; shows the quiet top shimmer. */
|
|
@@ -167,6 +196,8 @@ export type MessageTimelineProps = {
|
|
|
167
196
|
* scrolls the in-memory window.
|
|
168
197
|
*/
|
|
169
198
|
onJumpToLatest?: (() => void | Promise<void>) | undefined;
|
|
199
|
+
/** Host-owned content appended after timeline groups, such as startup progress. */
|
|
200
|
+
trailingState?: ReactNode | undefined;
|
|
170
201
|
emptyState?: ReactNode | undefined;
|
|
171
202
|
className?: string | undefined;
|
|
172
203
|
};
|
|
@@ -277,11 +308,16 @@ export function MessageTimeline({
|
|
|
277
308
|
onOpenSession,
|
|
278
309
|
onMemoryClick,
|
|
279
310
|
onReconnect,
|
|
311
|
+
shouldRenderAuthNeeded,
|
|
280
312
|
resolveProviderLogo,
|
|
281
313
|
toolRegistry = defaultToolRegistry,
|
|
314
|
+
loadRetainedScreenshot,
|
|
315
|
+
loadRetainedArtifact,
|
|
316
|
+
loadVideoArtifactPlayback,
|
|
282
317
|
computeLabel = null,
|
|
283
318
|
turnSummary,
|
|
284
319
|
autoFollow = true,
|
|
320
|
+
onAnnotate,
|
|
285
321
|
hasOlder = false,
|
|
286
322
|
loadingOlder = false,
|
|
287
323
|
onLoadOlder,
|
|
@@ -291,11 +327,32 @@ export function MessageTimeline({
|
|
|
291
327
|
loadingNewer = false,
|
|
292
328
|
onLoadNewer,
|
|
293
329
|
onJumpToLatest,
|
|
330
|
+
trailingState,
|
|
294
331
|
emptyState,
|
|
295
332
|
className,
|
|
296
333
|
}: MessageTimelineProps) {
|
|
297
|
-
const resolvedItems = useMemo(() =>
|
|
334
|
+
const resolvedItems = useMemo(() => {
|
|
335
|
+
const projected = items ?? buildTimeline(events ?? []);
|
|
336
|
+
if (!shouldRenderAuthNeeded) {
|
|
337
|
+
return projected;
|
|
338
|
+
}
|
|
339
|
+
return projected.filter((item) => item.kind !== "auth-needed" || shouldRenderAuthNeeded(item));
|
|
340
|
+
}, [items, events, shouldRenderAuthNeeded]);
|
|
298
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]);
|
|
299
356
|
const groups = useStableTimelineGroupKeys(allGroups);
|
|
300
357
|
const scrollRef = useRef<HTMLDivElement | null>(null);
|
|
301
358
|
const topSentinelRef = useRef<HTMLDivElement | null>(null);
|
|
@@ -1262,6 +1319,15 @@ export function MessageTimeline({
|
|
|
1262
1319
|
<EntranceAnimationProvider value={!bulkRender}>
|
|
1263
1320
|
<TooltipProvider delayDuration={400}>
|
|
1264
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}
|
|
1265
1331
|
{/* Pinned: anchoring off so the tip-follow camera owns the motion.
|
|
1266
1332
|
Unpinned: native scroll anchoring holds the reader's place. */}
|
|
1267
1333
|
<div
|
|
@@ -1278,7 +1344,7 @@ export function MessageTimeline({
|
|
|
1278
1344
|
className={cn(
|
|
1279
1345
|
// tabIndex=-1 is programmatic only — never paint a focus ring on
|
|
1280
1346
|
// the whole scroller (click + Shift used to flash a blue outline).
|
|
1281
|
-
"min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-6 sm:px-6 outline-
|
|
1347
|
+
"min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-6 sm:px-6 outline-hidden",
|
|
1282
1348
|
autoFollow && pinned && !hasNewer
|
|
1283
1349
|
? "[overflow-anchor:none]"
|
|
1284
1350
|
: "[overflow-anchor:auto]",
|
|
@@ -1325,6 +1391,9 @@ export function MessageTimeline({
|
|
|
1325
1391
|
onReconnect,
|
|
1326
1392
|
resolveProviderLogo,
|
|
1327
1393
|
toolRegistry,
|
|
1394
|
+
loadRetainedScreenshot,
|
|
1395
|
+
loadRetainedArtifact,
|
|
1396
|
+
loadVideoArtifactPlayback,
|
|
1328
1397
|
turnSummary,
|
|
1329
1398
|
]}
|
|
1330
1399
|
>
|
|
@@ -1337,6 +1406,9 @@ export function MessageTimeline({
|
|
|
1337
1406
|
onReconnect={onReconnect}
|
|
1338
1407
|
resolveProviderLogo={resolveProviderLogo}
|
|
1339
1408
|
toolRegistry={toolRegistry}
|
|
1409
|
+
loadRetainedScreenshot={loadRetainedScreenshot}
|
|
1410
|
+
loadRetainedArtifact={loadRetainedArtifact}
|
|
1411
|
+
loadVideoArtifactPlayback={loadVideoArtifactPlayback}
|
|
1340
1412
|
turnSummary={turnSummary}
|
|
1341
1413
|
foldLiveCluster={isAgentProgress(next)}
|
|
1342
1414
|
trailingAgentText={trailingAgentTextAfterTurn(group, next)}
|
|
@@ -1349,6 +1421,9 @@ export function MessageTimeline({
|
|
|
1349
1421
|
</div>
|
|
1350
1422
|
);
|
|
1351
1423
|
})}
|
|
1424
|
+
{groups.length > 0 && trailingState ? (
|
|
1425
|
+
<div data-og-timeline-trailing-state="">{trailingState}</div>
|
|
1426
|
+
) : null}
|
|
1352
1427
|
{hasNewer ? (
|
|
1353
1428
|
<div
|
|
1354
1429
|
ref={bottomSentinelRef}
|
|
@@ -1502,7 +1577,7 @@ export function MessageTimeline({
|
|
|
1502
1577
|
}
|
|
1503
1578
|
}}
|
|
1504
1579
|
className={cn(
|
|
1505
|
-
"absolute bottom-4
|
|
1580
|
+
"absolute inset-x-0 bottom-4 mx-auto w-fit",
|
|
1506
1581
|
"inline-flex items-center gap-1.5 rounded-full border border-og-border bg-og-surface-3/90 px-3 py-1.5",
|
|
1507
1582
|
"text-og-control font-medium text-og-fg shadow-og-md backdrop-blur",
|
|
1508
1583
|
"hover:border-og-border-strong",
|
|
@@ -1677,6 +1752,9 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1677
1752
|
onReconnect,
|
|
1678
1753
|
resolveProviderLogo,
|
|
1679
1754
|
toolRegistry,
|
|
1755
|
+
loadRetainedScreenshot,
|
|
1756
|
+
loadRetainedArtifact,
|
|
1757
|
+
loadVideoArtifactPlayback,
|
|
1680
1758
|
turnSummary,
|
|
1681
1759
|
insideTurn = false,
|
|
1682
1760
|
nestClusterChips = false,
|
|
@@ -1693,6 +1771,9 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1693
1771
|
onReconnect?: ((item: AuthNeededItem) => void | Promise<void>) | undefined;
|
|
1694
1772
|
resolveProviderLogo?: ((providerDomain: string) => string | null | undefined) | undefined;
|
|
1695
1773
|
toolRegistry: ToolRegistry;
|
|
1774
|
+
loadRetainedScreenshot?: RetainedScreenshotLoader | undefined;
|
|
1775
|
+
loadRetainedArtifact?: RetainedArtifactLoader | undefined;
|
|
1776
|
+
loadVideoArtifactPlayback?: VideoArtifactPlaybackLoader | undefined;
|
|
1696
1777
|
turnSummary?: TurnSummaryOptions | undefined;
|
|
1697
1778
|
/** A completed cluster of a still-RUNNING turn (not the live tail) folds
|
|
1698
1779
|
behind a neutral chip — the one place activity without an outcome still
|
|
@@ -1727,13 +1808,16 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1727
1808
|
const activityShouldFold =
|
|
1728
1809
|
group.kind === "activity" &&
|
|
1729
1810
|
Boolean(group.outcome || (foldLiveCluster && clusterIsSettled(group)));
|
|
1811
|
+
const containsGeneratedImage = timelineGroupContainsGeneratedImage(group);
|
|
1730
1812
|
// Latch live→folded so a top-level shell that was already mounted open can
|
|
1731
1813
|
// start the settle beat without remounting bare rail → wrapper.
|
|
1732
1814
|
const liveActivitySettle = useLiveSettleFold(activityShouldFold && !insideTurn);
|
|
1733
1815
|
const turnDefaultOpen =
|
|
1734
1816
|
!insideTurn &&
|
|
1735
1817
|
group.kind === "turn" &&
|
|
1736
|
-
(group.outcome === "failed" ||
|
|
1818
|
+
(group.outcome === "failed" ||
|
|
1819
|
+
timelineGroupContainsAuthNeeded(group) ||
|
|
1820
|
+
containsGeneratedImage);
|
|
1737
1821
|
// activity-* → turn-* remount: carry resting state so settleFold does not
|
|
1738
1822
|
// re-open a chip the reader already watched collapse.
|
|
1739
1823
|
if (group.kind === "turn" && foldMemory && !insideTurn) {
|
|
@@ -1758,7 +1842,7 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1758
1842
|
// settled closed pre-wrap was showing as a CHIP, so mounting it closed
|
|
1759
1843
|
// is both the stable height and the honest state — force-opening it
|
|
1760
1844
|
// was the "already-collapsed cluster auto-expands at the end" reopen.
|
|
1761
|
-
const useNestedChip = nestClusterChips && activityShouldFold;
|
|
1845
|
+
const useNestedChip = nestClusterChips && activityShouldFold && !containsGeneratedImage;
|
|
1762
1846
|
if (!useNestedChip) {
|
|
1763
1847
|
return (
|
|
1764
1848
|
<ActivityRail
|
|
@@ -1766,6 +1850,8 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1766
1850
|
onOpenSession={onOpenSession}
|
|
1767
1851
|
onMemoryClick={onMemoryClick}
|
|
1768
1852
|
toolRegistry={toolRegistry}
|
|
1853
|
+
loadRetainedScreenshot={loadRetainedScreenshot}
|
|
1854
|
+
loadRetainedArtifact={loadRetainedArtifact}
|
|
1769
1855
|
bare
|
|
1770
1856
|
/>
|
|
1771
1857
|
);
|
|
@@ -1787,6 +1873,8 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1787
1873
|
onOpenSession={onOpenSession}
|
|
1788
1874
|
onMemoryClick={onMemoryClick}
|
|
1789
1875
|
toolRegistry={toolRegistry}
|
|
1876
|
+
loadRetainedScreenshot={loadRetainedScreenshot}
|
|
1877
|
+
loadRetainedArtifact={loadRetainedArtifact}
|
|
1790
1878
|
bare
|
|
1791
1879
|
/>
|
|
1792
1880
|
</TurnSummary>
|
|
@@ -1812,6 +1900,8 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1812
1900
|
onOpenSession={onOpenSession}
|
|
1813
1901
|
onMemoryClick={onMemoryClick}
|
|
1814
1902
|
toolRegistry={toolRegistry}
|
|
1903
|
+
loadRetainedScreenshot={loadRetainedScreenshot}
|
|
1904
|
+
loadRetainedArtifact={loadRetainedArtifact}
|
|
1815
1905
|
bare
|
|
1816
1906
|
/>
|
|
1817
1907
|
</TurnRailFrame>
|
|
@@ -1838,6 +1928,9 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1838
1928
|
onReconnect,
|
|
1839
1929
|
resolveProviderLogo,
|
|
1840
1930
|
toolRegistry,
|
|
1931
|
+
loadRetainedScreenshot,
|
|
1932
|
+
loadRetainedArtifact,
|
|
1933
|
+
loadVideoArtifactPlayback,
|
|
1841
1934
|
turnSummary,
|
|
1842
1935
|
]}
|
|
1843
1936
|
>
|
|
@@ -1849,6 +1942,9 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1849
1942
|
onReconnect={onReconnect}
|
|
1850
1943
|
resolveProviderLogo={resolveProviderLogo}
|
|
1851
1944
|
toolRegistry={toolRegistry}
|
|
1945
|
+
loadRetainedScreenshot={loadRetainedScreenshot}
|
|
1946
|
+
loadRetainedArtifact={loadRetainedArtifact}
|
|
1947
|
+
loadVideoArtifactPlayback={loadVideoArtifactPlayback}
|
|
1852
1948
|
turnSummary={turnSummary}
|
|
1853
1949
|
insideTurn
|
|
1854
1950
|
nestClusterChips={nestClusters}
|
|
@@ -1890,6 +1986,7 @@ const TimelineGroupView = memo(function TimelineGroupView({
|
|
|
1890
1986
|
onReconnect={onReconnect}
|
|
1891
1987
|
resolveProviderLogo={resolveProviderLogo}
|
|
1892
1988
|
onOpenSession={onOpenSession}
|
|
1989
|
+
loadVideoArtifactPlayback={loadVideoArtifactPlayback}
|
|
1893
1990
|
/>
|
|
1894
1991
|
);
|
|
1895
1992
|
}
|
|
@@ -1953,6 +2050,20 @@ function timelineGroupContainsAuthNeeded(group: TimelineGroup): boolean {
|
|
|
1953
2050
|
}
|
|
1954
2051
|
}
|
|
1955
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
|
+
|
|
1956
2067
|
function timelineGroupItemIds(group: TimelineGroup): string[] {
|
|
1957
2068
|
switch (group.kind) {
|
|
1958
2069
|
case "item":
|
|
@@ -2124,6 +2235,7 @@ export function TimelineRow({
|
|
|
2124
2235
|
onReconnect,
|
|
2125
2236
|
resolveProviderLogo,
|
|
2126
2237
|
onOpenSession,
|
|
2238
|
+
loadVideoArtifactPlayback,
|
|
2127
2239
|
}: {
|
|
2128
2240
|
item: TimelineItem;
|
|
2129
2241
|
renderMessageText?:
|
|
@@ -2132,6 +2244,7 @@ export function TimelineRow({
|
|
|
2132
2244
|
onReconnect?: ((item: AuthNeededItem) => void | Promise<void>) | undefined;
|
|
2133
2245
|
resolveProviderLogo?: ((providerDomain: string) => string | null | undefined) | undefined;
|
|
2134
2246
|
onOpenSession?: ((sessionId: string) => void) | undefined;
|
|
2247
|
+
loadVideoArtifactPlayback?: VideoArtifactPlaybackLoader | undefined;
|
|
2135
2248
|
}) {
|
|
2136
2249
|
switch (item.kind) {
|
|
2137
2250
|
case "user-message":
|
|
@@ -2145,7 +2258,9 @@ export function TimelineRow({
|
|
|
2145
2258
|
case "goal":
|
|
2146
2259
|
return <GoalRow item={item} />;
|
|
2147
2260
|
case "machine-input-batch":
|
|
2148
|
-
return
|
|
2261
|
+
return (
|
|
2262
|
+
<MachineInputBatchRow item={item} loadVideoArtifactPlayback={loadVideoArtifactPlayback} />
|
|
2263
|
+
);
|
|
2149
2264
|
case "notice":
|
|
2150
2265
|
return <NoticeRow item={item} />;
|
|
2151
2266
|
case "context-compaction":
|
|
@@ -2265,25 +2380,71 @@ function UserMessageRow({
|
|
|
2265
2380
|
| undefined;
|
|
2266
2381
|
}) {
|
|
2267
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;
|
|
2268
2391
|
return (
|
|
2269
2392
|
<div className={cn(enter && "animate-og-enter", "flex justify-end")}>
|
|
2270
2393
|
<div className="flex max-w-[85%] min-w-0 flex-col items-end gap-1">
|
|
2271
2394
|
<CopyHoverFrame
|
|
2272
|
-
copyText={
|
|
2395
|
+
copyText={
|
|
2396
|
+
item.text ||
|
|
2397
|
+
(item.annotations ?? [])
|
|
2398
|
+
.map((annotation) => `${annotation.quote}\n${annotation.note}`)
|
|
2399
|
+
.join("\n\n")
|
|
2400
|
+
}
|
|
2273
2401
|
label="Copy message"
|
|
2274
2402
|
className="w-fit max-w-full min-w-0"
|
|
2275
2403
|
trailing={<MessageFooterTime occurredAt={item.occurredAt} />}
|
|
2276
2404
|
>
|
|
2277
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">
|
|
2278
|
-
{
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
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}
|
|
2285
2423
|
</div>
|
|
2286
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}
|
|
2287
2448
|
</div>
|
|
2288
2449
|
</div>
|
|
2289
2450
|
);
|
|
@@ -2309,15 +2470,17 @@ function AgentMessageRow({
|
|
|
2309
2470
|
// While streaming, copy is still useful (current text) but keep chrome calm —
|
|
2310
2471
|
// stamp only after the message finishes (occurredAt tracks completion).
|
|
2311
2472
|
return (
|
|
2312
|
-
<
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
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>
|
|
2321
2484
|
);
|
|
2322
2485
|
}
|
|
2323
2486
|
|
|
@@ -2428,7 +2591,7 @@ function WorkerCompletionRow({
|
|
|
2428
2591
|
onClick={() => onOpenSession(item.childSessionId)}
|
|
2429
2592
|
className={cn(
|
|
2430
2593
|
"-my-0.5 -mr-1 inline-flex shrink-0 items-center gap-1 rounded-og-sm px-2 py-1 text-og-sm font-medium text-og-fg-muted pointer-coarse:py-2",
|
|
2431
|
-
"outline-
|
|
2594
|
+
"outline-hidden transition-colors duration-150 hover:bg-og-surface-2 hover:text-og-fg",
|
|
2432
2595
|
"focus-visible:ring-2 focus-visible:ring-og-accent",
|
|
2433
2596
|
)}
|
|
2434
2597
|
>
|
|
@@ -2444,7 +2607,7 @@ function WorkerCompletionRow({
|
|
|
2444
2607
|
type="button"
|
|
2445
2608
|
className={cn(
|
|
2446
2609
|
"group/wc -mx-1 inline-flex w-fit items-center gap-1 rounded-og-sm px-1 py-0.5 text-og-xs font-medium text-og-fg-subtle",
|
|
2447
|
-
"outline-
|
|
2610
|
+
"outline-hidden transition-colors duration-150 hover:text-og-fg-muted focus-visible:ring-2 focus-visible:ring-og-accent",
|
|
2448
2611
|
)}
|
|
2449
2612
|
>
|
|
2450
2613
|
<ChevronRightIcon className="size-3 transition-transform duration-150 ease-og-in-out group-data-[state=open]/wc:rotate-90" />
|
|
@@ -2567,10 +2730,24 @@ function GoalRow({ item }: { item: GoalItem }) {
|
|
|
2567
2730
|
);
|
|
2568
2731
|
}
|
|
2569
2732
|
|
|
2570
|
-
function MachineInputBatchRow({
|
|
2733
|
+
function MachineInputBatchRow({
|
|
2734
|
+
item,
|
|
2735
|
+
loadVideoArtifactPlayback,
|
|
2736
|
+
}: {
|
|
2737
|
+
item: MachineInputBatchItem;
|
|
2738
|
+
loadVideoArtifactPlayback?: VideoArtifactPlaybackLoader | undefined;
|
|
2739
|
+
}) {
|
|
2571
2740
|
const enter = useEntranceAnimation();
|
|
2572
2741
|
const label = machineInputBatchLabel(item.members);
|
|
2573
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
|
+
}
|
|
2574
2751
|
const singleSummary = single ? cleanMachineInputSummary(single.summary) : "";
|
|
2575
2752
|
const showCollapsedSummary =
|
|
2576
2753
|
single != null && machineInputSummaryIsUseful(single.kind, singleSummary);
|
|
@@ -2594,7 +2771,11 @@ function MachineInputBatchRow({ item }: { item: MachineInputBatchItem }) {
|
|
|
2594
2771
|
</summary>
|
|
2595
2772
|
<div className="mx-auto mt-2 w-full max-w-lg space-y-2 border-t border-og-border/50 pt-2">
|
|
2596
2773
|
{item.members.map((member) => (
|
|
2597
|
-
<MachineInputRow
|
|
2774
|
+
<MachineInputRow
|
|
2775
|
+
key={member.id}
|
|
2776
|
+
member={member}
|
|
2777
|
+
loadVideoArtifactPlayback={loadVideoArtifactPlayback}
|
|
2778
|
+
/>
|
|
2598
2779
|
))}
|
|
2599
2780
|
</div>
|
|
2600
2781
|
</details>
|
|
@@ -2607,7 +2788,22 @@ function MachineInputBatchRow({ item }: { item: MachineInputBatchItem }) {
|
|
|
2607
2788
|
);
|
|
2608
2789
|
}
|
|
2609
2790
|
|
|
2610
|
-
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
|
+
}
|
|
2611
2807
|
const source = readableMachineInputSource(member.sourceId);
|
|
2612
2808
|
const summary = cleanMachineInputSummary(member.summary);
|
|
2613
2809
|
return (
|
|
@@ -2628,6 +2824,72 @@ function MachineInputRow({ member }: { member: MachineInputBatchItem["members"][
|
|
|
2628
2824
|
);
|
|
2629
2825
|
}
|
|
2630
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
|
+
|
|
2631
2893
|
function NoticeRow({ item }: { item: NoticeItem }) {
|
|
2632
2894
|
const enter = useEntranceAnimation();
|
|
2633
2895
|
const tone =
|
|
@@ -2693,13 +2955,32 @@ function AuthNeededRow({
|
|
|
2693
2955
|
const enter = useEntranceAnimation();
|
|
2694
2956
|
const [busy, setBusy] = useState(false);
|
|
2695
2957
|
const [failed, setFailed] = useState(false);
|
|
2696
|
-
const
|
|
2958
|
+
const recommendation = item.capability ?? null;
|
|
2959
|
+
const provider =
|
|
2960
|
+
recommendation?.name ??
|
|
2961
|
+
(item.serverId === "codex_apps" ? "Codex Apps" : providerLabel(item.providerDomain));
|
|
2697
2962
|
const unavailable =
|
|
2698
2963
|
item.reason === "personal_authority_unavailable" ||
|
|
2699
2964
|
item.reason === "unsupported_auth" ||
|
|
2700
2965
|
item.reason === "resource_scope_unavailable";
|
|
2701
2966
|
const missing = item.reason === "missing_connection";
|
|
2702
|
-
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);
|
|
2703
2984
|
|
|
2704
2985
|
const start = async () => {
|
|
2705
2986
|
if (!onReconnect || busy) {
|
|
@@ -2728,10 +3009,18 @@ function AuthNeededRow({
|
|
|
2728
3009
|
label={provider}
|
|
2729
3010
|
/>
|
|
2730
3011
|
<div className="min-w-0">
|
|
2731
|
-
<p className="truncate text-og-md font-medium text-og-fg">
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
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}
|
|
2735
3024
|
</div>
|
|
2736
3025
|
</div>
|
|
2737
3026
|
{!unavailable && onReconnect ? (
|
|
@@ -2764,8 +3053,9 @@ function AuthNeededRow({
|
|
|
2764
3053
|
</div>
|
|
2765
3054
|
{!unavailable ? (
|
|
2766
3055
|
<p className="px-1 text-og-xs text-og-fg-subtle">
|
|
2767
|
-
|
|
2768
|
-
|
|
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.`}
|
|
2769
3059
|
</p>
|
|
2770
3060
|
) : null}
|
|
2771
3061
|
{failed ? (
|