@opengeni/react 0.48.0 → 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 +90 -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 +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-FWXGSNXT.js → chunk-724BW4TW.js} +585 -34
- 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-I4MPFDRP.js → chunk-FWS3KC3Z.js} +3 -3
- 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-XCNTXWBB.js → chunk-JAGDUCZQ.js} +854 -340
- package/dist/chunk-JAGDUCZQ.js.map +1 -0
- package/dist/{chunk-LHLYWG5R.js → chunk-JR3QFY6B.js} +413 -37
- 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-PEI6RANI.js +3234 -0
- package/dist/chunk-PEI6RANI.js.map +1 -0
- package/dist/{chunk-NJ7M2B6Z.js → chunk-ROIRTM37.js} +18 -10
- package/dist/{chunk-NJ7M2B6Z.js.map → chunk-ROIRTM37.js.map} +1 -1
- package/dist/{chunk-O4VXOBGF.js → chunk-WSK7G5LE.js} +70 -2
- package/dist/chunk-WSK7G5LE.js.map +1 -0
- package/dist/{chunk-OL6QVXGF.js → chunk-X4S56Y2H.js} +27 -7
- package/dist/{chunk-OL6QVXGF.js.map → chunk-X4S56Y2H.js.map} +1 -1
- 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 +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 +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 +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 +21 -4
- package/dist/components/sandbox-workspace.d.ts +25 -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 +5 -5
- package/dist/hooks/internal.d.ts +1 -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 +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 +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 +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-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-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-slash-commands.d.ts +1 -1
- package/dist/hooks/use-terminal-stream.d.ts +8 -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 +158 -155
- package/dist/index.js +906 -462
- 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/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/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-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 +6 -6
- package/dist/realtime.d.ts +4 -4
- package/dist/realtime.js +3 -3
- package/dist/session-context.d.ts +19 -1
- 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 +5 -5
- 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 +39 -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 +86 -0
- package/src/client.ts +87 -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 +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 +1139 -0
- package/src/components/desktop-viewer.tsx +101 -73
- package/src/components/generated-video-player.tsx +89 -0
- package/src/components/interactive-workbench-viewers.ts +2 -0
- package/src/components/machine-input-display.ts +3 -0
- package/src/components/message-timeline.tsx +289 -32
- package/src/components/queue-surface-implementation.tsx +116 -60
- package/src/components/sandbox-files.tsx +2 -2
- package/src/components/sandbox-terminal.tsx +106 -41
- package/src/components/sandbox-workspace.tsx +215 -87
- 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/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-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-machine-chip.ts +5 -3
- package/src/hooks/use-machines.ts +33 -3
- 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-terminal-stream.ts +102 -23
- package/src/hooks/use-video-artifact-playback.ts +28 -0
- package/src/hooks/use-workspace-edit.ts +2 -1
- package/src/index.ts +10 -0
- package/src/interaction.ts +71 -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/session-context.ts +90 -0
- package/src/timeline/activity-rail.tsx +19 -3
- package/src/timeline/index.ts +3 -0
- package/src/timeline/parsers.ts +14 -1
- package/src/timeline/projection.ts +211 -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 +55 -3
- package/styles/compiled.css +248 -15
- package/styles/index.css +15 -0
- package/styles/responsive.css +13 -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-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
- /package/dist/{chunk-I4MPFDRP.js.map → chunk-FWS3KC3Z.js.map} +0 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TerminalCapability } from "@opengeni/sdk";
|
|
2
|
+
|
|
3
|
+
/** Whether an explicit viewer grant can upgrade this cell to a real PTY.
|
|
4
|
+
* Keep acquisition feasibility separate from the current transport: a cold
|
|
5
|
+
* real-PTY backend reports sse-events until the just-in-time grant warms it. */
|
|
6
|
+
export function terminalCanAcquirePty(cell: TerminalCapability | null | undefined): boolean {
|
|
7
|
+
if (!cell?.ptyCapable) return false;
|
|
8
|
+
if (cell.transport === "pty-ws") return true;
|
|
9
|
+
return cell.reason === "lease_cold" || cell.reason === "not_provisioned";
|
|
10
|
+
}
|
package/src/session-context.ts
CHANGED
|
@@ -4,6 +4,9 @@ import type {
|
|
|
4
4
|
EmbeddedFileAttachmentClientLike,
|
|
5
5
|
EmbeddedGoalClientLike,
|
|
6
6
|
EmbeddedHumanInputSessionClientLike,
|
|
7
|
+
EmbeddedBrowserInteractionClientLike,
|
|
8
|
+
EmbeddedComputerInteractionClientLike,
|
|
9
|
+
EmbeddedInteractionClientLike,
|
|
7
10
|
EmbeddedRealtimeSessionClientLike,
|
|
8
11
|
EmbeddedSessionClientLike,
|
|
9
12
|
EmbeddedSessionLineageClientLike,
|
|
@@ -76,6 +79,21 @@ export type EmbeddedFileAttachmentClientOverride = {
|
|
|
76
79
|
workspaceId?: string | undefined;
|
|
77
80
|
};
|
|
78
81
|
|
|
82
|
+
export type EmbeddedInteractionClientOverride = {
|
|
83
|
+
client?: EmbeddedInteractionClientLike | undefined;
|
|
84
|
+
workspaceId?: string | undefined;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export type EmbeddedBrowserInteractionClientOverride = {
|
|
88
|
+
client?: EmbeddedBrowserInteractionClientLike | undefined;
|
|
89
|
+
workspaceId?: string | undefined;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export type EmbeddedComputerInteractionClientOverride = {
|
|
93
|
+
client?: EmbeddedComputerInteractionClientLike | undefined;
|
|
94
|
+
workspaceId?: string | undefined;
|
|
95
|
+
};
|
|
96
|
+
|
|
79
97
|
export type EmbeddedSessionContextValue = Omit<OpenGeniContextValue, "client"> & {
|
|
80
98
|
client: EmbeddedSessionClientLike;
|
|
81
99
|
};
|
|
@@ -145,6 +163,78 @@ export function useOpenGeni(override: ClientOverride = {}): OpenGeniContextValue
|
|
|
145
163
|
};
|
|
146
164
|
}
|
|
147
165
|
|
|
166
|
+
const BROWSER_INTERACTION_METHODS = [
|
|
167
|
+
"listAttachedBrowsers",
|
|
168
|
+
"getAttachedBrowser",
|
|
169
|
+
"listBrowserIdentities",
|
|
170
|
+
"getBrowserIdentity",
|
|
171
|
+
"createBrowserIdentity",
|
|
172
|
+
"listBrowserRevisions",
|
|
173
|
+
"listBrowserSessions",
|
|
174
|
+
"getBrowserSession",
|
|
175
|
+
"createBrowserSession",
|
|
176
|
+
"listBrowserTargets",
|
|
177
|
+
"openBrowserTarget",
|
|
178
|
+
"selectBrowserTarget",
|
|
179
|
+
"closeBrowserTarget",
|
|
180
|
+
"observeBrowserTarget",
|
|
181
|
+
"actInBrowser",
|
|
182
|
+
"getBrowserActionReceipt",
|
|
183
|
+
"listBrowserDiagnostics",
|
|
184
|
+
"attachBrowserSession",
|
|
185
|
+
"heartbeatBrowserSession",
|
|
186
|
+
"publishBrowserRevision",
|
|
187
|
+
"suspendBrowserSession",
|
|
188
|
+
"resumeBrowserSession",
|
|
189
|
+
"endBrowserSession",
|
|
190
|
+
] as const;
|
|
191
|
+
|
|
192
|
+
const COMPUTER_INTERACTION_METHODS = [
|
|
193
|
+
"listComputerSessions",
|
|
194
|
+
"getComputerSession",
|
|
195
|
+
"createComputerSession",
|
|
196
|
+
"listComputerTargets",
|
|
197
|
+
"observeComputerTarget",
|
|
198
|
+
"actInComputer",
|
|
199
|
+
"getComputerActionReceipt",
|
|
200
|
+
"attachComputerSession",
|
|
201
|
+
"heartbeatComputerSession",
|
|
202
|
+
"endComputerSession",
|
|
203
|
+
] as const;
|
|
204
|
+
|
|
205
|
+
/** Resolve only BrowserSession methods for a standalone Browser embed. */
|
|
206
|
+
export function useEmbeddedBrowserInteraction(
|
|
207
|
+
override: EmbeddedBrowserInteractionClientOverride = {},
|
|
208
|
+
): EmbeddedClientContextValue<EmbeddedBrowserInteractionClientLike> {
|
|
209
|
+
return useEmbeddedClientRefinement(
|
|
210
|
+
override,
|
|
211
|
+
BROWSER_INTERACTION_METHODS,
|
|
212
|
+
"browser interaction hooks",
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Resolve only ComputerSession methods for a standalone Computer embed. */
|
|
217
|
+
export function useEmbeddedComputerInteraction(
|
|
218
|
+
override: EmbeddedComputerInteractionClientOverride = {},
|
|
219
|
+
): EmbeddedClientContextValue<EmbeddedComputerInteractionClientLike> {
|
|
220
|
+
return useEmbeddedClientRefinement(
|
|
221
|
+
override,
|
|
222
|
+
COMPUTER_INTERACTION_METHODS,
|
|
223
|
+
"computer interaction hooks",
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Resolve the complete Browser + Computer client surface. */
|
|
228
|
+
export function useEmbeddedInteraction(
|
|
229
|
+
override: EmbeddedInteractionClientOverride = {},
|
|
230
|
+
): EmbeddedClientContextValue<EmbeddedInteractionClientLike> {
|
|
231
|
+
return useEmbeddedClientRefinement(
|
|
232
|
+
override,
|
|
233
|
+
[...BROWSER_INTERACTION_METHODS, ...COMPUTER_INTERACTION_METHODS],
|
|
234
|
+
"interaction hooks",
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
148
238
|
/**
|
|
149
239
|
* Resolve the narrow client required by the session-only hooks. The full
|
|
150
240
|
* provider client is structurally compatible, while an explicit host proxy
|
|
@@ -12,9 +12,9 @@ import { cn } from "../lib/cn";
|
|
|
12
12
|
import { truncate } from "../lib/format";
|
|
13
13
|
import { defaultToolRegistry } from "./tool-renderers";
|
|
14
14
|
import { useEntranceAnimation, useEntranceAnimationLive } from "./entrance";
|
|
15
|
-
import type { RetainedScreenshotLoader, ToolRegistry } from "./registry";
|
|
15
|
+
import type { RetainedArtifactLoader, RetainedScreenshotLoader, ToolRegistry } from "./registry";
|
|
16
16
|
import { useSeenActivityIds } from "./seen-activity-ids";
|
|
17
|
-
import { BodyNote, PayloadBlock, ActivityDisclosure } from "./shared";
|
|
17
|
+
import { BodyNote, PayloadBlock, ActivityDisclosure, ToolCallTruncationProvider } from "./shared";
|
|
18
18
|
import { toolDisplayName } from "./tool-display-name";
|
|
19
19
|
import type { ActivityItem, MemoryItem, ReasoningItem, SandboxItem, WorkerItem } from "./types";
|
|
20
20
|
|
|
@@ -44,6 +44,8 @@ export type ActivityRailProps = {
|
|
|
44
44
|
*/
|
|
45
45
|
onMemoryClick?: ((memoryId: string) => void) | undefined;
|
|
46
46
|
loadRetainedScreenshot?: RetainedScreenshotLoader | undefined;
|
|
47
|
+
/** Resolve permanent generated-image receipts through the authenticated host SDK. */
|
|
48
|
+
loadRetainedArtifact?: RetainedArtifactLoader | undefined;
|
|
47
49
|
/** Drop the left rule + indent (used inside a folded turn summary). */
|
|
48
50
|
bare?: boolean | undefined;
|
|
49
51
|
className?: string | undefined;
|
|
@@ -67,6 +69,7 @@ export function ActivityRail({
|
|
|
67
69
|
onOpenSession,
|
|
68
70
|
onMemoryClick,
|
|
69
71
|
loadRetainedScreenshot,
|
|
72
|
+
loadRetainedArtifact,
|
|
70
73
|
bare,
|
|
71
74
|
className,
|
|
72
75
|
}: ActivityRailProps) {
|
|
@@ -120,11 +123,15 @@ export function ActivityRail({
|
|
|
120
123
|
onOpenSession,
|
|
121
124
|
onMemoryClick,
|
|
122
125
|
loadRetainedScreenshot,
|
|
126
|
+
loadRetainedArtifact,
|
|
123
127
|
);
|
|
124
128
|
return (
|
|
125
129
|
<div
|
|
126
130
|
key={item.id}
|
|
127
131
|
data-og-timeline-row-anchor=""
|
|
132
|
+
data-og-annotation-source-key={
|
|
133
|
+
item.kind === "tool-call" ? item.annotationSource?.eventId : undefined
|
|
134
|
+
}
|
|
128
135
|
className={cn(newFamily && "mt-3", enteringIds.has(item.id) && "animate-og-row-enter")}
|
|
129
136
|
>
|
|
130
137
|
{row}
|
|
@@ -146,13 +153,22 @@ function renderActivity(
|
|
|
146
153
|
onOpenSession: ((sessionId: string) => void) | undefined,
|
|
147
154
|
onMemoryClick: ((memoryId: string) => void) | undefined,
|
|
148
155
|
loadRetainedScreenshot: RetainedScreenshotLoader | undefined,
|
|
156
|
+
loadRetainedArtifact: RetainedArtifactLoader | undefined,
|
|
149
157
|
) {
|
|
150
158
|
switch (item.kind) {
|
|
151
159
|
case "reasoning":
|
|
152
160
|
return <ReasoningRow item={item} />;
|
|
153
161
|
case "tool-call": {
|
|
154
162
|
const Renderer = toolRegistry.resolve(item);
|
|
155
|
-
return
|
|
163
|
+
return (
|
|
164
|
+
<ToolCallTruncationProvider value={item.truncation ?? null}>
|
|
165
|
+
<Renderer
|
|
166
|
+
item={item}
|
|
167
|
+
loadRetainedScreenshot={loadRetainedScreenshot}
|
|
168
|
+
loadRetainedArtifact={loadRetainedArtifact}
|
|
169
|
+
/>
|
|
170
|
+
</ToolCallTruncationProvider>
|
|
171
|
+
);
|
|
156
172
|
}
|
|
157
173
|
case "worker":
|
|
158
174
|
return <WorkerRow item={item} onOpenSession={onOpenSession} />;
|
package/src/timeline/index.ts
CHANGED
|
@@ -45,6 +45,7 @@ export type {
|
|
|
45
45
|
SessionStatusItem,
|
|
46
46
|
TimelineGroup,
|
|
47
47
|
TimelineItem,
|
|
48
|
+
TimelineAnnotationSourceDescriptor,
|
|
48
49
|
TurnEndItem,
|
|
49
50
|
ToolCallItem,
|
|
50
51
|
UserMessageItem,
|
|
@@ -56,7 +57,9 @@ export type {
|
|
|
56
57
|
export { createToolRegistry, rawTypeOf } from "./registry";
|
|
57
58
|
export type {
|
|
58
59
|
CreateToolRegistryOptions,
|
|
60
|
+
RetainedArtifactLoader,
|
|
59
61
|
RetainedScreenshotLoader,
|
|
62
|
+
VideoArtifactPlaybackLoader,
|
|
60
63
|
ToolRegistry,
|
|
61
64
|
ToolRegistryEntry,
|
|
62
65
|
ToolRenderer,
|
package/src/timeline/parsers.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
normalizeMcpOutput,
|
|
3
|
+
parseGeneratedImageReceipt,
|
|
4
|
+
type GeneratedImageReceipt,
|
|
5
|
+
type GitFileDiff,
|
|
6
|
+
type RetainedArtifactMetadata,
|
|
7
|
+
} from "@opengeni/sdk";
|
|
2
8
|
import { tryParseJson } from "../lib/format";
|
|
3
9
|
|
|
10
|
+
export type { GeneratedImageReceipt };
|
|
11
|
+
|
|
4
12
|
/* ----------------------------------------------------------------------------
|
|
5
13
|
Pure parsers for the provider-native tool shapes that the timeline renders.
|
|
6
14
|
|
|
@@ -571,6 +579,11 @@ export function retainedScreenshotMetadata(out: unknown): RetainedArtifactMetada
|
|
|
571
579
|
: null;
|
|
572
580
|
}
|
|
573
581
|
|
|
582
|
+
/** Parse the closed permanent generated-image receipt from native/function tools. */
|
|
583
|
+
export function generatedImageReceipt(out: unknown): GeneratedImageReceipt | null {
|
|
584
|
+
return parseGeneratedImageReceipt(out);
|
|
585
|
+
}
|
|
586
|
+
|
|
574
587
|
export type TimelineMediaPreview = {
|
|
575
588
|
type: "media_preview";
|
|
576
589
|
mediaType: string;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
parseMediaGenerationResult,
|
|
3
|
+
type SessionEvent,
|
|
4
|
+
type SessionStatus,
|
|
5
|
+
type TimelineAnnotation,
|
|
6
|
+
} from "@opengeni/sdk";
|
|
7
|
+
import fleetDecisionItem from "./fleet-decision-projection";
|
|
3
8
|
import {
|
|
4
9
|
CREDIT_EXHAUSTION_MESSAGE,
|
|
5
10
|
humanizeFailureReason,
|
|
@@ -21,6 +26,7 @@ import type {
|
|
|
21
26
|
TimelineItem,
|
|
22
27
|
TurnEndItem,
|
|
23
28
|
ToolCallItem,
|
|
29
|
+
ToolCallTruncation,
|
|
24
30
|
WorkerItem,
|
|
25
31
|
} from "./types";
|
|
26
32
|
|
|
@@ -61,6 +67,56 @@ const WORKER_MESSAGE_TOOL = "session_send_message";
|
|
|
61
67
|
* render as machine-input rows.
|
|
62
68
|
*/
|
|
63
69
|
const LANDMARK_ONLY_TOOL_LEAVES = new Set(["memory_save", "memory_correct"]);
|
|
70
|
+
const TIMELINE_ANNOTATION_ANSI_SEQUENCE = new RegExp("\\u001B\\[[0-?]*[ -/]*[@-~]", "g");
|
|
71
|
+
|
|
72
|
+
function safeTimelineAnnotationJson(value: unknown): string {
|
|
73
|
+
try {
|
|
74
|
+
return JSON.stringify(value) ?? "";
|
|
75
|
+
} catch {
|
|
76
|
+
return String(value ?? "");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function timelineAnnotationToolOutputValue(value: unknown, depth = 0): string {
|
|
81
|
+
if (depth > 8 || value === null || value === undefined) {
|
|
82
|
+
return value == null ? "" : safeTimelineAnnotationJson(value);
|
|
83
|
+
}
|
|
84
|
+
if (typeof value === "string") return value;
|
|
85
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
86
|
+
return safeTimelineAnnotationJson(value);
|
|
87
|
+
}
|
|
88
|
+
const record = value as Record<string, unknown>;
|
|
89
|
+
if (record.type === "text" && typeof record.text === "string") return record.text;
|
|
90
|
+
if (Array.isArray(record.content)) {
|
|
91
|
+
const text = record.content.find(
|
|
92
|
+
(part) =>
|
|
93
|
+
part !== null &&
|
|
94
|
+
typeof part === "object" &&
|
|
95
|
+
(part as { type?: unknown }).type === "text" &&
|
|
96
|
+
typeof (part as { text?: unknown }).text === "string",
|
|
97
|
+
) as { text: string } | undefined;
|
|
98
|
+
if (text) return text.text;
|
|
99
|
+
}
|
|
100
|
+
if ("structuredContent" in record) {
|
|
101
|
+
return timelineAnnotationToolOutputValue(record.structuredContent, depth + 1);
|
|
102
|
+
}
|
|
103
|
+
if ("result" in record) return timelineAnnotationToolOutputValue(record.result, depth + 1);
|
|
104
|
+
return safeTimelineAnnotationJson(value);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Browser mirror of the server's canonical annotation source projection. */
|
|
108
|
+
function timelineAnnotationToolOutputText(output: unknown): string | null {
|
|
109
|
+
const raw = timelineAnnotationToolOutputValue(output);
|
|
110
|
+
const marker = raw.indexOf("\nOutput:\n");
|
|
111
|
+
const text = (
|
|
112
|
+
marker >= 0
|
|
113
|
+
? raw.slice(marker + "\nOutput:\n".length)
|
|
114
|
+
: raw.startsWith("Output:\n")
|
|
115
|
+
? raw.slice("Output:\n".length)
|
|
116
|
+
: raw
|
|
117
|
+
).replace(TIMELINE_ANNOTATION_ANSI_SEQUENCE, "");
|
|
118
|
+
return text.length > 0 ? text : null;
|
|
119
|
+
}
|
|
64
120
|
|
|
65
121
|
export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
|
|
66
122
|
const items: TimelineItem[] = [];
|
|
@@ -134,6 +190,15 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
|
|
|
134
190
|
kind: "user-message",
|
|
135
191
|
id: event.id,
|
|
136
192
|
text: voiceMessage?.text ?? stringValue(payload.text),
|
|
193
|
+
annotations: timelineAnnotations(payload.annotations),
|
|
194
|
+
annotationSource: {
|
|
195
|
+
kind: "user_message",
|
|
196
|
+
eventId: event.id,
|
|
197
|
+
eventType: "user.message",
|
|
198
|
+
sequence: event.sequence,
|
|
199
|
+
turnId,
|
|
200
|
+
text: voiceMessage?.text ?? stringValue(payload.text),
|
|
201
|
+
},
|
|
137
202
|
...(voiceMessage ? { presentation: voiceMessage.presentation } : {}),
|
|
138
203
|
resources: resourceRefs(payload.resources),
|
|
139
204
|
tools: toolRefs(payload.tools),
|
|
@@ -212,6 +277,17 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
|
|
|
212
277
|
// Completion time is what the footer shows ("finished at"); keep the
|
|
213
278
|
// first-delta stamp only until this event arrives.
|
|
214
279
|
open.occurredAt = event.occurredAt;
|
|
280
|
+
open.annotationSource =
|
|
281
|
+
text && open.text === text
|
|
282
|
+
? {
|
|
283
|
+
kind: "assistant_message",
|
|
284
|
+
eventId: event.id,
|
|
285
|
+
eventType: "agent.message.completed",
|
|
286
|
+
sequence: event.sequence,
|
|
287
|
+
turnId,
|
|
288
|
+
text,
|
|
289
|
+
}
|
|
290
|
+
: undefined;
|
|
215
291
|
// The SDK can emit a hosted-tool item only after its provider-native
|
|
216
292
|
// operation has completed, even though answer deltas were already
|
|
217
293
|
// streamed. The completed message event is the durable ordering
|
|
@@ -231,6 +307,14 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
|
|
|
231
307
|
text,
|
|
232
308
|
streaming: false,
|
|
233
309
|
occurredAt: event.occurredAt,
|
|
310
|
+
annotationSource: {
|
|
311
|
+
kind: "assistant_message",
|
|
312
|
+
eventId: event.id,
|
|
313
|
+
eventType: "agent.message.completed",
|
|
314
|
+
sequence: event.sequence,
|
|
315
|
+
turnId,
|
|
316
|
+
text,
|
|
317
|
+
},
|
|
234
318
|
});
|
|
235
319
|
}
|
|
236
320
|
break;
|
|
@@ -312,6 +396,7 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
|
|
|
312
396
|
name,
|
|
313
397
|
arguments: args,
|
|
314
398
|
output: undefined,
|
|
399
|
+
truncation: null,
|
|
315
400
|
// The provider-native item drives the per-tool renderers (apply_patch
|
|
316
401
|
// operation, computer_call action, web_search providerData, …).
|
|
317
402
|
raw: payload.raw,
|
|
@@ -336,8 +421,30 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
|
|
|
336
421
|
}
|
|
337
422
|
// An output carrying an explicit error flag (or an MCP isError result)
|
|
338
423
|
// settles the tool to "failed" so the renderer can surface it loudly.
|
|
424
|
+
const truncation = toolCallTruncation(payload);
|
|
339
425
|
target.status = isErrorOutput(payload) ? "failed" : "complete";
|
|
340
|
-
target.output = payload
|
|
426
|
+
target.output = Object.prototype.hasOwnProperty.call(payload, "output")
|
|
427
|
+
? payload.output
|
|
428
|
+
: truncation && typeof payload.preview === "string"
|
|
429
|
+
? payload.preview
|
|
430
|
+
: payload.output;
|
|
431
|
+
target.truncation = truncation;
|
|
432
|
+
const sourceText = timelineAnnotationToolOutputText(
|
|
433
|
+
Object.prototype.hasOwnProperty.call(payload, "output")
|
|
434
|
+
? payload.output
|
|
435
|
+
: payload.preview,
|
|
436
|
+
);
|
|
437
|
+
if (sourceText !== null) {
|
|
438
|
+
target.annotationSource = {
|
|
439
|
+
kind: "tool_output",
|
|
440
|
+
eventId: event.id,
|
|
441
|
+
eventType: "agent.toolCall.output",
|
|
442
|
+
sequence: event.sequence,
|
|
443
|
+
turnId,
|
|
444
|
+
text: sourceText,
|
|
445
|
+
label: target.name,
|
|
446
|
+
};
|
|
447
|
+
}
|
|
341
448
|
break;
|
|
342
449
|
}
|
|
343
450
|
|
|
@@ -540,6 +647,7 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
|
|
|
540
647
|
|
|
541
648
|
case "tool.auth_needed":
|
|
542
649
|
case "credential.auth_needed": {
|
|
650
|
+
const capability = capabilityAuthorizationRequest(payload.capability);
|
|
543
651
|
if (
|
|
544
652
|
event.type === "tool.auth_needed" &&
|
|
545
653
|
!stringValue(payload.toolName) &&
|
|
@@ -562,7 +670,11 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
|
|
|
562
670
|
id: event.id,
|
|
563
671
|
turnId,
|
|
564
672
|
serverId: typeof payload.serverId === "string" ? payload.serverId : null,
|
|
565
|
-
source:
|
|
673
|
+
source: capability
|
|
674
|
+
? "capability"
|
|
675
|
+
: event.type === "tool.auth_needed"
|
|
676
|
+
? "tool"
|
|
677
|
+
: "credential",
|
|
566
678
|
providerDomain: stringValue(payload.providerDomain),
|
|
567
679
|
connectionId: typeof payload.connectionId === "string" ? payload.connectionId : null,
|
|
568
680
|
reason: authNeededReason(payload.reason),
|
|
@@ -571,6 +683,7 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
|
|
|
571
683
|
toolName: typeof payload.toolName === "string" ? payload.toolName : null,
|
|
572
684
|
authorizationUrl:
|
|
573
685
|
typeof payload.authorizationUrl === "string" ? payload.authorizationUrl : null,
|
|
686
|
+
capability,
|
|
574
687
|
occurredAt: event.occurredAt,
|
|
575
688
|
});
|
|
576
689
|
break;
|
|
@@ -1315,6 +1428,7 @@ function machineInputMembers(value: unknown): MachineInputBatchItem["members"] {
|
|
|
1315
1428
|
"agent_message",
|
|
1316
1429
|
"agent_steer_instruction",
|
|
1317
1430
|
"child_terminal_result",
|
|
1431
|
+
"media_generation_result",
|
|
1318
1432
|
]);
|
|
1319
1433
|
const classifications = new Set<MachineInputBatchItem["members"][number]["classification"]>([
|
|
1320
1434
|
"success",
|
|
@@ -1333,16 +1447,24 @@ function machineInputMembers(value: unknown): MachineInputBatchItem["members"] {
|
|
|
1333
1447
|
member.classification as MachineInputBatchItem["members"][number]["classification"],
|
|
1334
1448
|
) &&
|
|
1335
1449
|
typeof member.sourceId === "string"
|
|
1336
|
-
?
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
kind
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1450
|
+
? (() => {
|
|
1451
|
+
const kind = member.kind as MachineInputBatchItem["members"][number]["kind"];
|
|
1452
|
+
const result =
|
|
1453
|
+
kind === "media_generation_result"
|
|
1454
|
+
? parseMediaGenerationResult(member.result)
|
|
1455
|
+
: null;
|
|
1456
|
+
return [
|
|
1457
|
+
{
|
|
1458
|
+
id: member.id,
|
|
1459
|
+
kind,
|
|
1460
|
+
classification:
|
|
1461
|
+
member.classification as MachineInputBatchItem["members"][number]["classification"],
|
|
1462
|
+
sourceId: member.sourceId,
|
|
1463
|
+
summary: stringValue(member.summary),
|
|
1464
|
+
...(result ? { result } : {}),
|
|
1465
|
+
},
|
|
1466
|
+
];
|
|
1467
|
+
})()
|
|
1346
1468
|
: [];
|
|
1347
1469
|
})
|
|
1348
1470
|
: [];
|
|
@@ -1378,6 +1500,25 @@ function resourceRefs(value: unknown): import("@opengeni/sdk").ResourceRef[] {
|
|
|
1378
1500
|
});
|
|
1379
1501
|
}
|
|
1380
1502
|
|
|
1503
|
+
function timelineAnnotations(value: unknown): TimelineAnnotation[] {
|
|
1504
|
+
if (!Array.isArray(value)) return [];
|
|
1505
|
+
return value.filter((candidate): candidate is TimelineAnnotation => {
|
|
1506
|
+
const annotation = asRecord(candidate);
|
|
1507
|
+
const source = asRecord(annotation.source);
|
|
1508
|
+
return (
|
|
1509
|
+
typeof annotation.id === "string" &&
|
|
1510
|
+
typeof annotation.ordinal === "number" &&
|
|
1511
|
+
typeof annotation.quote === "string" &&
|
|
1512
|
+
typeof annotation.note === "string" &&
|
|
1513
|
+
typeof source.eventId === "string" &&
|
|
1514
|
+
typeof source.eventType === "string" &&
|
|
1515
|
+
typeof source.sequence === "number" &&
|
|
1516
|
+
typeof source.startOffset === "number" &&
|
|
1517
|
+
typeof source.endOffset === "number"
|
|
1518
|
+
);
|
|
1519
|
+
});
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1381
1522
|
function toolRefs(value: unknown): import("@opengeni/sdk").ToolRef[] {
|
|
1382
1523
|
if (!Array.isArray(value)) {
|
|
1383
1524
|
return [];
|
|
@@ -1440,6 +1581,31 @@ function isErrorOutput(payload: Record<string, unknown>): boolean {
|
|
|
1440
1581
|
);
|
|
1441
1582
|
}
|
|
1442
1583
|
|
|
1584
|
+
function toolCallTruncation(payload: Record<string, unknown>): ToolCallTruncation | null {
|
|
1585
|
+
const truncation = asRecord(payload.truncation);
|
|
1586
|
+
const fullEvidence = asRecord(truncation.fullEvidence);
|
|
1587
|
+
const surface = stringValue(truncation.surface);
|
|
1588
|
+
const reason = stringValue(truncation.reason);
|
|
1589
|
+
if (
|
|
1590
|
+
truncation.truncated !== true ||
|
|
1591
|
+
!surface ||
|
|
1592
|
+
!reason ||
|
|
1593
|
+
typeof fullEvidence.available !== "boolean"
|
|
1594
|
+
) {
|
|
1595
|
+
return null;
|
|
1596
|
+
}
|
|
1597
|
+
return {
|
|
1598
|
+
truncated: true,
|
|
1599
|
+
surface,
|
|
1600
|
+
reason,
|
|
1601
|
+
omittedBytes: numberOrNull(truncation.omittedBytes),
|
|
1602
|
+
fullEvidence: {
|
|
1603
|
+
available: fullEvidence.available,
|
|
1604
|
+
reason: stringValue(fullEvidence.reason) || null,
|
|
1605
|
+
},
|
|
1606
|
+
};
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1443
1609
|
function findOpenCall(
|
|
1444
1610
|
items: TimelineItem[],
|
|
1445
1611
|
callId: string | null,
|
|
@@ -1563,6 +1729,37 @@ function authNeededReason(value: unknown): AuthNeededItem["reason"] {
|
|
|
1563
1729
|
: null;
|
|
1564
1730
|
}
|
|
1565
1731
|
|
|
1732
|
+
function capabilityAuthorizationRequest(
|
|
1733
|
+
value: unknown,
|
|
1734
|
+
): NonNullable<AuthNeededItem["capability"]> | null {
|
|
1735
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
1736
|
+
const record = value as Record<string, unknown>;
|
|
1737
|
+
const kind = record.kind;
|
|
1738
|
+
const source = record.source;
|
|
1739
|
+
const action = record.action;
|
|
1740
|
+
if (
|
|
1741
|
+
typeof record.id !== "string" ||
|
|
1742
|
+
typeof record.name !== "string" ||
|
|
1743
|
+
!["pack", "mcp", "api", "skill", "plugin"].includes(String(kind)) ||
|
|
1744
|
+
!["built_in", "library", "configured", "public_registry", "registry", "manual"].includes(
|
|
1745
|
+
String(source),
|
|
1746
|
+
) ||
|
|
1747
|
+
!["connect", "add_credentials", "enable"].includes(String(action)) ||
|
|
1748
|
+
typeof record.rationale !== "string"
|
|
1749
|
+
) {
|
|
1750
|
+
return null;
|
|
1751
|
+
}
|
|
1752
|
+
return {
|
|
1753
|
+
id: record.id,
|
|
1754
|
+
name: record.name,
|
|
1755
|
+
kind: kind as NonNullable<AuthNeededItem["capability"]>["kind"],
|
|
1756
|
+
source: source as NonNullable<AuthNeededItem["capability"]>["source"],
|
|
1757
|
+
action: action as NonNullable<AuthNeededItem["capability"]>["action"],
|
|
1758
|
+
rationale: record.rationale,
|
|
1759
|
+
requiredVariables: stringList(record.requiredVariables),
|
|
1760
|
+
};
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1566
1763
|
function stringList(value: unknown): string[] {
|
|
1567
1764
|
return Array.isArray(value)
|
|
1568
1765
|
? value.filter((entry): entry is string => typeof entry === "string" && entry.trim().length > 0)
|
package/src/timeline/registry.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RetainedArtifactReference } from "@opengeni/sdk";
|
|
1
|
+
import type { RetainedArtifactReference, VideoArtifactPlaybackSource } from "@opengeni/sdk";
|
|
2
2
|
import type { ComponentType } from "react";
|
|
3
3
|
import { mcpToolLeaf } from "./tool-display-name";
|
|
4
4
|
import type { ToolCallItem } from "./types";
|
|
@@ -24,6 +24,7 @@ import type { ToolCallItem } from "./types";
|
|
|
24
24
|
export type ToolRendererProps = {
|
|
25
25
|
item: ToolCallItem;
|
|
26
26
|
loadRetainedScreenshot?: RetainedScreenshotLoader | undefined;
|
|
27
|
+
loadRetainedArtifact?: RetainedArtifactLoader | undefined;
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
export type RetainedScreenshotLoader = (
|
|
@@ -31,6 +32,17 @@ export type RetainedScreenshotLoader = (
|
|
|
31
32
|
signal: AbortSignal,
|
|
32
33
|
) => Promise<Uint8Array | null>;
|
|
33
34
|
|
|
35
|
+
export type RetainedArtifactLoader = (
|
|
36
|
+
artifact: RetainedArtifactReference,
|
|
37
|
+
signal: AbortSignal,
|
|
38
|
+
) => Promise<Uint8Array | { url: string } | null>;
|
|
39
|
+
|
|
40
|
+
/** Mint an expiring source for native browser playback without loading video bytes in JS. */
|
|
41
|
+
export type VideoArtifactPlaybackLoader = (
|
|
42
|
+
artifactId: string,
|
|
43
|
+
signal: AbortSignal,
|
|
44
|
+
) => Promise<VideoArtifactPlaybackSource>;
|
|
45
|
+
|
|
34
46
|
export type ToolRenderer = ComponentType<ToolRendererProps>;
|
|
35
47
|
|
|
36
48
|
/** A registry entry: which key it matches and the component that renders it. */
|
|
@@ -19,7 +19,7 @@ import { usePortalTokenStyle } from "../lib/use-portal-token-style";
|
|
|
19
19
|
-------------------------------------------------------------------------- */
|
|
20
20
|
|
|
21
21
|
type LightboxController = {
|
|
22
|
-
open: (src: string, caption?: string, source?: HTMLElement | null) => void;
|
|
22
|
+
open: (src: string, caption?: string, source?: HTMLElement | null, label?: string) => void;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
const LightboxContext = createContext<LightboxController | null>(null);
|
|
@@ -59,14 +59,21 @@ export function LightboxProvider({ children }: { children: ReactNode }) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function LightboxRoot({ children }: { children: ReactNode }) {
|
|
62
|
-
const [state, setState] = useState<{
|
|
62
|
+
const [state, setState] = useState<{
|
|
63
|
+
src: string;
|
|
64
|
+
caption?: string;
|
|
65
|
+
label: string;
|
|
66
|
+
} | null>(null);
|
|
63
67
|
const [tokenSource, setTokenSource] = useState<HTMLElement | null>(null);
|
|
64
68
|
const portalStyle = usePortalTokenStyle(tokenSource);
|
|
65
69
|
|
|
66
|
-
const open = useCallback(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
const open = useCallback(
|
|
71
|
+
(src: string, caption?: string, source?: HTMLElement | null, label = "Screenshot") => {
|
|
72
|
+
setTokenSource(source ?? null);
|
|
73
|
+
setState(caption ? { src, caption, label } : { src, label });
|
|
74
|
+
},
|
|
75
|
+
[],
|
|
76
|
+
);
|
|
70
77
|
|
|
71
78
|
const close = useCallback(() => {
|
|
72
79
|
setState(null);
|
|
@@ -95,7 +102,7 @@ function LightboxRoot({ children }: { children: ReactNode }) {
|
|
|
95
102
|
<Dialog.Content
|
|
96
103
|
asChild
|
|
97
104
|
forceMount
|
|
98
|
-
aria-label=
|
|
105
|
+
aria-label={state.label}
|
|
99
106
|
onOpenAutoFocus={(event) => event.preventDefault()}
|
|
100
107
|
>
|
|
101
108
|
<motion.div
|
|
@@ -117,7 +124,10 @@ function LightboxRoot({ children }: { children: ReactNode }) {
|
|
|
117
124
|
className="og-root fixed inset-0 z-50 flex items-center justify-center p-6 sm:p-12"
|
|
118
125
|
style={portalStyle}
|
|
119
126
|
>
|
|
120
|
-
<Dialog.Title className="sr-only">
|
|
127
|
+
<Dialog.Title className="sr-only">{state.label}</Dialog.Title>
|
|
128
|
+
<Dialog.Description className="sr-only">
|
|
129
|
+
{state.caption ?? `Expanded ${state.label.toLowerCase()}`}
|
|
130
|
+
</Dialog.Description>
|
|
121
131
|
{/* The figure is one self-contained object: image, caption, and
|
|
122
132
|
its own close control. The close button anchors to a wrapper
|
|
123
133
|
sized to the IMAGE (w-fit), so it hugs the real top-right
|
|
@@ -128,7 +138,7 @@ function LightboxRoot({ children }: { children: ReactNode }) {
|
|
|
128
138
|
{/* A plain <img>: this SDK is framework-agnostic, with no host Image component. */}
|
|
129
139
|
<img
|
|
130
140
|
src={state.src}
|
|
131
|
-
alt={state.caption ??
|
|
141
|
+
alt={state.caption ?? state.label}
|
|
132
142
|
className="min-h-0 max-h-[82vh] w-auto max-w-full rounded-og-md border border-white/10 object-contain shadow-og-lg"
|
|
133
143
|
/>
|
|
134
144
|
<Dialog.Close
|