@opengeni/react 0.57.0 → 1.0.2-canary.37191796234001
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 +654 -22
- package/dist/accounts.d.ts +64 -0
- package/dist/accounts.js +822 -0
- package/dist/accounts.js.map +1 -0
- package/dist/approvals.d.ts +2 -1
- package/dist/artifacts-document.js +3 -2
- package/dist/artifacts-presentation.js +3 -2
- package/dist/artifacts-spreadsheet.js +2 -2
- package/dist/artifacts.d.ts +4 -1
- package/dist/artifacts.js +518 -42
- package/dist/artifacts.js.map +1 -1
- package/dist/browser-viewer-GTR5XQ7X.js +16 -0
- package/dist/capability-catalog-row.d.ts +20 -0
- package/dist/capability-logo-fallback.d.ts +3 -0
- package/dist/chat-interactive-block-UGBTNB3L.js +11 -0
- package/dist/chat-interactive-block-UGBTNB3L.js.map +1 -0
- package/dist/{chunk-5UQPNLIO.js → chunk-23J2ZNXT.js} +4117 -3896
- package/dist/chunk-23J2ZNXT.js.map +1 -0
- package/dist/chunk-447JLCBU.js +209 -0
- package/dist/chunk-447JLCBU.js.map +1 -0
- package/dist/chunk-4RVYOY4O.js +379 -0
- package/dist/chunk-4RVYOY4O.js.map +1 -0
- package/dist/chunk-5CVXZA3Y.js +292 -0
- package/dist/chunk-5CVXZA3Y.js.map +1 -0
- package/dist/chunk-5J4FOW6Q.js +108 -0
- package/dist/chunk-5J4FOW6Q.js.map +1 -0
- package/dist/chunk-A2PI6UMY.js +41 -0
- package/dist/chunk-A2PI6UMY.js.map +1 -0
- package/dist/{chunk-7WCLAEFV.js → chunk-A4UJB2MM.js} +37 -27
- package/dist/chunk-A4UJB2MM.js.map +1 -0
- package/dist/chunk-B3V6TG77.js +41 -0
- package/dist/chunk-B3V6TG77.js.map +1 -0
- package/dist/chunk-BRM6FVZA.js +302 -0
- package/dist/chunk-BRM6FVZA.js.map +1 -0
- package/dist/chunk-C5X5AJXK.js +182 -0
- package/dist/chunk-C5X5AJXK.js.map +1 -0
- package/dist/chunk-CR7U7HAR.js +453 -0
- package/dist/chunk-CR7U7HAR.js.map +1 -0
- package/dist/{chunk-R3AZOAB5.js → chunk-DYWBUX5Q.js} +29 -123
- package/dist/chunk-DYWBUX5Q.js.map +1 -0
- package/dist/chunk-E3G7SAYZ.js +3124 -0
- package/dist/chunk-E3G7SAYZ.js.map +1 -0
- package/dist/chunk-ELCE5SXV.js +359 -0
- package/dist/chunk-ELCE5SXV.js.map +1 -0
- package/dist/chunk-ERGYJIBB.js +21 -0
- package/dist/chunk-ERGYJIBB.js.map +1 -0
- package/dist/chunk-FFA2OVOV.js +319 -0
- package/dist/chunk-FFA2OVOV.js.map +1 -0
- package/dist/chunk-FZCP527Y.js +116 -0
- package/dist/chunk-FZCP527Y.js.map +1 -0
- package/dist/chunk-GIMRELBW.js +14 -0
- package/dist/chunk-GIMRELBW.js.map +1 -0
- package/dist/{chunk-6KLX2RH5.js → chunk-H2NJQORO.js} +1069 -79
- package/dist/chunk-H2NJQORO.js.map +1 -0
- package/dist/chunk-I7IWRQLN.js +1608 -0
- package/dist/chunk-I7IWRQLN.js.map +1 -0
- package/dist/{chunk-HA46CYQK.js → chunk-IQUCRAT7.js} +792 -537
- package/dist/chunk-IQUCRAT7.js.map +1 -0
- package/dist/chunk-IWIDV7SB.js +1 -0
- package/dist/chunk-IWIDV7SB.js.map +1 -0
- package/dist/chunk-J2QWVSQY.js +312 -0
- package/dist/chunk-J2QWVSQY.js.map +1 -0
- package/dist/chunk-JFNEV4LU.js +2733 -0
- package/dist/chunk-JFNEV4LU.js.map +1 -0
- package/dist/chunk-JT4JW7BC.js +54 -0
- package/dist/chunk-JT4JW7BC.js.map +1 -0
- package/dist/chunk-K3HQAKQX.js +24 -0
- package/dist/chunk-K3HQAKQX.js.map +1 -0
- package/dist/{chunk-C5ZPSSS5.js → chunk-NEXLLTP4.js} +2 -1
- package/dist/{chunk-C5ZPSSS5.js.map → chunk-NEXLLTP4.js.map} +1 -1
- package/dist/chunk-NZUI76EM.js +371 -0
- package/dist/chunk-NZUI76EM.js.map +1 -0
- package/dist/{chunk-PEI6RANI.js → chunk-PNY3JKBJ.js} +309 -74
- package/dist/chunk-PNY3JKBJ.js.map +1 -0
- package/dist/{chunk-IGC6A2ZI.js → chunk-Q5QBEZIQ.js} +777 -246
- package/dist/chunk-Q5QBEZIQ.js.map +1 -0
- package/dist/chunk-RHREZ7BO.js +11 -0
- package/dist/chunk-RHREZ7BO.js.map +1 -0
- package/dist/chunk-SCOTPE2I.js +589 -0
- package/dist/chunk-SCOTPE2I.js.map +1 -0
- package/dist/{chunk-B6WPZSTT.js → chunk-SJZDKVW2.js} +1331 -1163
- package/dist/chunk-SJZDKVW2.js.map +1 -0
- package/dist/chunk-TMJRG4YC.js +12803 -0
- package/dist/chunk-TMJRG4YC.js.map +1 -0
- package/dist/chunk-TMYGL6X5.js +742 -0
- package/dist/chunk-TMYGL6X5.js.map +1 -0
- package/dist/chunk-UGLEYEMP.js +33 -0
- package/dist/chunk-UGLEYEMP.js.map +1 -0
- package/dist/chunk-UK4TINKT.js +27 -0
- package/dist/chunk-UK4TINKT.js.map +1 -0
- package/dist/chunk-UTRTG6LH.js +220 -0
- package/dist/chunk-UTRTG6LH.js.map +1 -0
- package/dist/chunk-WEHMPOXK.js +39 -0
- package/dist/chunk-WEHMPOXK.js.map +1 -0
- package/dist/chunk-WRHIZYZF.js +988 -0
- package/dist/chunk-WRHIZYZF.js.map +1 -0
- package/dist/{chunk-HUIKIDM5.js → chunk-WUISZ3WU.js} +223 -115
- package/dist/chunk-WUISZ3WU.js.map +1 -0
- package/dist/chunk-XCHWDJ22.js +107 -0
- package/dist/chunk-XCHWDJ22.js.map +1 -0
- package/dist/chunk-XOAMRDDK.js +481 -0
- package/dist/chunk-XOAMRDDK.js.map +1 -0
- package/dist/chunk-XUW2UWQM.js +299 -0
- package/dist/chunk-XUW2UWQM.js.map +1 -0
- package/dist/{chunk-KCGXPP5V.js → chunk-Y2PRMYLC.js} +11 -6
- package/dist/chunk-Y2PRMYLC.js.map +1 -0
- package/dist/chunk-YBXQDQFX.js +1772 -0
- package/dist/chunk-YBXQDQFX.js.map +1 -0
- package/dist/{chunk-KZ73RL76.js → chunk-YQEAA6LT.js} +7 -3
- package/dist/chunk-YQEAA6LT.js.map +1 -0
- package/dist/chunk-YV4L3ILF.js +9 -0
- package/dist/chunk-YV4L3ILF.js.map +1 -0
- package/dist/{chunk-LLOLUHVG.js → chunk-YWFG7ZX7.js} +1358 -2746
- package/dist/chunk-YWFG7ZX7.js.map +1 -0
- package/dist/chunk-ZYRGEKWS.js +216 -0
- package/dist/chunk-ZYRGEKWS.js.map +1 -0
- package/dist/client.d.ts +7 -4
- package/dist/clipboard.js +1 -0
- package/dist/commands/types.d.ts +2 -0
- package/dist/components/anthropic-mark.d.ts +3 -0
- package/dist/components/approval-surface.d.ts +15 -0
- package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
- package/dist/components/artifacts/artifact-sandbox.d.ts +27 -0
- package/dist/components/artifacts/artifact-surface.d.ts +3 -1
- package/dist/components/artifacts/chat-interactive-block.d.ts +29 -0
- package/dist/components/artifacts/deferred-chat-media.d.ts +15 -0
- package/dist/components/artifacts/document-editor.d.ts +4 -2
- package/dist/components/artifacts/editable-artifact-ui.d.ts +2 -1
- package/dist/components/artifacts/editable-artifact-view.d.ts +46 -0
- package/dist/components/artifacts/editable-document.d.ts +1 -1
- package/dist/components/artifacts/editable-presentation.d.ts +2 -2
- package/dist/components/artifacts/editable-spreadsheet.d.ts +2 -1
- package/dist/components/artifacts/index.d.ts +8 -1
- package/dist/components/artifacts/inline-html-document.d.ts +2 -0
- package/dist/components/artifacts/latest-task-runner.d.ts +15 -0
- package/dist/components/artifacts/presentation-editor.d.ts +6 -2
- package/dist/components/artifacts/published-html-artifact-frame.d.ts +48 -3
- package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
- package/dist/components/artifacts/site-view.d.ts +23 -0
- package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
- package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
- package/dist/components/browser-select-control.d.ts +16 -0
- package/dist/components/browser-viewer.d.ts +10 -1
- package/dist/components/chat-composer.d.ts +21 -3
- package/dist/components/child-session-link.d.ts +5 -0
- package/dist/components/claude-mark.d.ts +3 -0
- package/dist/components/code-editor.d.ts +1 -4
- package/dist/components/composer.d.ts +45 -4
- package/dist/components/computer-viewer.d.ts +4 -1
- package/dist/components/copy-button.d.ts +3 -1
- package/dist/components/desktop-viewer.d.ts +1 -1
- package/dist/components/enrollment-consent.d.ts +6 -3
- package/dist/components/file-browser.d.ts +10 -1
- package/dist/components/fleet-tile.d.ts +2 -2
- package/dist/components/grok-mark.d.ts +26 -0
- package/dist/components/human-input-form.d.ts +21 -2
- package/dist/components/human-input-surface.d.ts +6 -3
- package/dist/components/machine-card.d.ts +4 -1
- package/dist/components/machines/machine-detail.d.ts +4 -1
- package/dist/components/machines/machine-operation-policy.d.ts +11 -0
- package/dist/components/machines-dashboard.d.ts +3 -1
- package/dist/components/markdown-table-layout.d.ts +12 -0
- package/dist/components/markdown.d.ts +47 -3
- package/dist/components/message-timeline.d.ts +72 -9
- package/dist/components/model-mark.d.ts +29 -0
- package/dist/components/model-policy-picker-menu.d.ts +9 -0
- package/dist/components/model-policy-picker.d.ts +62 -13
- package/dist/components/open-geni-chat.d.ts +55 -0
- package/dist/components/open-geni-links.d.ts +68 -0
- package/dist/components/openrouter-mark.d.ts +6 -0
- package/dist/components/pierre-file.d.ts +1 -1
- package/dist/components/preview-loading.d.ts +2 -0
- package/dist/components/queue-item-content.d.ts +9 -0
- package/dist/components/sandbox-files.d.ts +13 -2
- package/dist/components/sandbox-workspace.d.ts +43 -3
- package/dist/components/session-capability-frame.d.ts +35 -0
- package/dist/components/session-chrome.d.ts +66 -8
- package/dist/components/session-commands-panel.d.ts +6 -0
- package/dist/components/session-commands.d.ts +6 -0
- package/dist/components/session-connection-request.d.ts +8 -0
- package/dist/components/session-conversation.d.ts +86 -0
- package/dist/components/session-list.d.ts +36 -0
- package/dist/components/session-mcp-capability-card.d.ts +41 -0
- package/dist/components/timeline-anchor.d.ts +24 -0
- package/dist/components/timeline-annotation-chrome.d.ts +25 -0
- package/dist/components/timeline-annotation-layout.d.ts +42 -0
- package/dist/components/timeline-annotation-markers.d.ts +8 -0
- package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
- package/dist/components/timeline-annotation-shared.d.ts +31 -0
- package/dist/components/timeline-annotations-dialog.d.ts +3 -2
- package/dist/components/timeline-annotations.d.ts +13 -3
- package/dist/components/timeline-reading-progress.d.ts +11 -0
- package/dist/components/timeline-search.d.ts +34 -0
- package/dist/components/timeline-settlement.d.ts +16 -0
- package/dist/components/tip-follow.d.ts +16 -0
- package/dist/components/usage-limit-notice.d.ts +49 -0
- package/dist/components/usage-member-list.d.ts +91 -0
- package/dist/components/usage-meter.d.ts +73 -0
- package/dist/components/use-viewer-menu-dismiss.d.ts +2 -0
- package/dist/components/user-message-body.d.ts +10 -1
- package/dist/components/workspace-dock.d.ts +6 -2
- package/dist/composer.d.ts +5 -4
- package/dist/composer.js +15 -9
- package/dist/computer-viewer-ENHVAZ2Q.js +19 -0
- package/dist/computer-viewer-ENHVAZ2Q.js.map +1 -0
- package/dist/connect-account-identity.d.ts +8 -0
- package/dist/connect-accounts.d.ts +15 -0
- package/dist/connect-chooser.d.ts +18 -0
- package/dist/connect-panel.d.ts +18 -0
- package/dist/connect-setup.d.ts +16 -0
- package/dist/connect.d.ts +21 -0
- package/dist/connect.js +2129 -0
- package/dist/connect.js.map +1 -0
- package/dist/connection-catalog.d.ts +38 -0
- package/dist/connection-discovery.d.ts +12 -0
- package/dist/connection-installed.d.ts +17 -0
- package/dist/connection-logo.d.ts +9 -0
- package/dist/connection-service-logo.d.ts +8 -0
- package/dist/connection-service-presentation.d.ts +13 -0
- package/dist/connection-skeleton.d.ts +5 -0
- package/dist/connection-type-picker.d.ts +6 -0
- package/dist/conversation-timeline.d.ts +5 -0
- package/dist/desktop.d.ts +7 -0
- package/dist/desktop.js +26 -0
- package/dist/desktop.js.map +1 -0
- package/dist/device-authorization.d.ts +23 -0
- package/dist/diffs.d.ts +8 -0
- package/dist/diffs.js +14 -0
- package/dist/diffs.js.map +1 -0
- package/dist/discovery-cache.d.ts +5 -0
- package/dist/editor.d.ts +7 -0
- package/dist/editor.js +21 -0
- package/dist/editor.js.map +1 -0
- package/dist/embedded-session-client.d.ts +23 -0
- package/dist/file-node-visibility.d.ts +15 -0
- package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-YZ3ZKWMM.js} +2 -1
- package/dist/fleet-decision-row-YZ3ZKWMM.js.map +1 -0
- package/dist/hooks/channel-cache.d.ts +23 -0
- package/dist/hooks/latest-question.d.ts +25 -0
- package/dist/hooks/shared-machines-list.d.ts +14 -0
- package/dist/hooks/use-attached-browsers.d.ts +2 -1
- package/dist/hooks/use-browser-frame-stream.d.ts +1 -1
- package/dist/hooks/use-browser-session.d.ts +12 -1
- package/dist/hooks/use-channels.d.ts +1 -0
- package/dist/hooks/use-codex-accounts.d.ts +25 -7
- package/dist/hooks/use-composer.d.ts +45 -9
- package/dist/hooks/use-computer-frame-stream.d.ts +1 -1
- package/dist/hooks/use-computer-input-posture.d.ts +13 -0
- package/dist/hooks/use-computer-session.d.ts +2 -0
- package/dist/hooks/use-connect.d.ts +22 -0
- package/dist/hooks/use-desktop-stream.d.ts +1 -1
- package/dist/hooks/use-file-attachments.d.ts +21 -2
- package/dist/hooks/use-machine-chip.d.ts +3 -3
- package/dist/hooks/use-machines.d.ts +19 -1
- package/dist/hooks/use-sandbox-files.d.ts +5 -1
- package/dist/hooks/use-session-background-commands.d.ts +14 -0
- package/dist/hooks/use-session-events.d.ts +30 -8
- package/dist/hooks/use-session-lineage.d.ts +4 -0
- package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
- package/dist/hooks/use-session.d.ts +6 -0
- package/dist/hooks/use-turn-queue.d.ts +12 -0
- package/dist/hooks/use-usage.d.ts +40 -0
- package/dist/hooks/use-workspace-edit.d.ts +4 -0
- package/dist/hooks/use-workspace-sessions.d.ts +27 -5
- package/dist/human-input.d.ts +3 -1
- package/dist/identity-link-accounts.d.ts +11 -0
- package/dist/identity-link-consent.d.ts +18 -0
- package/dist/index.d.ts +60 -17
- package/dist/index.js +2237 -6200
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +1 -1
- package/dist/interaction.js +35 -184
- package/dist/interaction.js.map +1 -1
- package/dist/latest-question-755OW5DS.js +117 -0
- package/dist/latest-question-755OW5DS.js.map +1 -0
- package/dist/lib/error-message.d.ts +7 -0
- package/dist/lib/format.d.ts +36 -2
- package/dist/lib/host-theme.d.ts +70 -0
- package/dist/lib/interaction-errors.d.ts +6 -0
- package/dist/lib/menu-styles.d.ts +22 -0
- package/dist/lib/pierre-diffs-loader.d.ts +20 -0
- package/dist/lib/workbench-peers.d.ts +36 -0
- package/dist/lib/xterm-theme.d.ts +7 -5
- package/dist/machines.d.ts +4 -2
- package/dist/machines.js +14 -4
- package/dist/markdown-table-layout-QXSLK4BY.js +106 -0
- package/dist/markdown-table-layout-QXSLK4BY.js.map +1 -0
- package/dist/mcp-connection-status.d.ts +14 -0
- package/dist/model-policy-picker-menu-PWRI7R2X.js +14 -0
- package/dist/model-policy-picker-menu-PWRI7R2X.js.map +1 -0
- package/dist/model-policy.d.ts +19 -3
- package/dist/model-policy.js +9 -1
- package/dist/older-history.d.ts +30 -0
- package/dist/platform-activity-row-627BFZ46.js +182 -0
- package/dist/platform-activity-row-627BFZ46.js.map +1 -0
- package/dist/plugin-details.d.ts +14 -0
- package/dist/plugin-discovery.d.ts +25 -0
- package/dist/provider.d.ts +13 -1
- package/dist/{queue-surface-implementation-2KVJTYXH.js → queue-surface-implementation-ZHFI5JBP.js} +131 -44
- package/dist/queue-surface-implementation-ZHFI5JBP.js.map +1 -0
- package/dist/realtime/realtime-control.d.ts +10 -3
- package/dist/realtime.js +229 -83
- package/dist/realtime.js.map +1 -1
- package/dist/sandbox-files-BBC47SLD.js +20 -0
- package/dist/sandbox-files-BBC47SLD.js.map +1 -0
- package/dist/session-auth-recommendation.d.ts +5 -0
- package/dist/session-capability-policy.d.ts +12 -0
- package/dist/session-ui.d.ts +30 -2
- package/dist/session-ui.js +85 -7
- package/dist/session-ui.js.map +1 -1
- package/dist/session.d.ts +8 -2
- package/dist/session.js +30 -19
- package/dist/sites-ui.d.ts +34 -0
- package/dist/sites.d.ts +3 -0
- package/dist/sites.js +11 -0
- package/dist/sites.js.map +1 -0
- package/dist/skill-discovery.d.ts +47 -0
- package/dist/terminal.d.ts +8 -0
- package/dist/terminal.js +31 -0
- package/dist/terminal.js.map +1 -0
- package/dist/timeline/activity-rail.d.ts +11 -2
- package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
- package/dist/timeline/compaction-copy.d.ts +10 -0
- package/dist/timeline/entrance.d.ts +13 -1
- package/dist/timeline/genie-loading.d.ts +34 -0
- package/dist/timeline/index.d.ts +6 -2
- package/dist/timeline/knowledge-receipt.d.ts +17 -0
- package/dist/timeline/platform-activity-row.d.ts +14 -0
- package/dist/timeline/presented-image.d.ts +6 -0
- package/dist/timeline/projection.d.ts +31 -2
- package/dist/timeline/registry.d.ts +2 -0
- package/dist/timeline/retained-image.d.ts +18 -0
- package/dist/timeline/rolling-activity.d.ts +11 -0
- package/dist/timeline/screenshot-lightbox.d.ts +16 -1
- package/dist/timeline/shared.d.ts +8 -3
- package/dist/timeline/startup-preference.d.ts +3 -0
- package/dist/timeline/startup-timings.d.ts +4 -0
- package/dist/timeline/tool-display-name.d.ts +2 -1
- package/dist/timeline/turn-summary.d.ts +32 -3
- package/dist/timeline/types.d.ts +141 -7
- package/dist/timeline-annotation-markers-GNDHTGBD.js +165 -0
- package/dist/timeline-annotation-markers-GNDHTGBD.js.map +1 -0
- package/dist/timeline-annotation-selection-DMLMM2TX.js +241 -0
- package/dist/timeline-annotation-selection-DMLMM2TX.js.map +1 -0
- package/dist/timeline-annotations-dialog-ELRDBHTS.js +273 -0
- package/dist/timeline-annotations-dialog-ELRDBHTS.js.map +1 -0
- package/dist/types/machines.d.ts +2 -2
- package/dist/usage/allowance-copy.d.ts +25 -0
- package/dist/usage/summary.d.ts +35 -0
- package/dist/usage.d.ts +13 -0
- package/dist/usage.js +1074 -0
- package/dist/usage.js.map +1 -0
- package/package.json +44 -4
- package/src/accounts.tsx +1072 -0
- package/src/approvals.ts +8 -1
- package/src/artifacts.ts +42 -0
- package/src/assets/README.md +8 -0
- package/src/assets/gmail.ico +0 -0
- package/src/assets/outlook.ico +0 -0
- package/src/capability-catalog-row.tsx +94 -0
- package/src/capability-logo-fallback.ts +22 -0
- package/src/client.ts +22 -13
- package/src/commands/registry.ts +18 -15
- package/src/commands/types.ts +2 -0
- package/src/components/anthropic-mark.tsx +10 -0
- package/src/components/approval-surface.tsx +171 -37
- package/src/components/artifacts/artifact-chrome.tsx +413 -0
- package/src/components/artifacts/artifact-sandbox.tsx +185 -0
- package/src/components/artifacts/artifact-surface.tsx +39 -19
- package/src/components/artifacts/chat-interactive-block.tsx +260 -0
- package/src/components/artifacts/deferred-chat-media.tsx +67 -0
- package/src/components/artifacts/document-editor.tsx +141 -16
- package/src/components/artifacts/editable-artifact-ui.tsx +4 -2
- package/src/components/artifacts/editable-artifact-view.tsx +187 -0
- package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
- package/src/components/artifacts/editable-document.tsx +37 -36
- package/src/components/artifacts/editable-presentation.tsx +36 -18
- package/src/components/artifacts/editable-spreadsheet.tsx +5 -2
- package/src/components/artifacts/index.ts +44 -0
- package/src/components/artifacts/inline-html-document.ts +24 -0
- package/src/components/artifacts/latest-task-runner.ts +49 -0
- package/src/components/artifacts/presentation-editor.tsx +323 -67
- package/src/components/artifacts/published-html-artifact-frame.tsx +338 -5
- package/src/components/artifacts/session-artifact-viewer.tsx +376 -0
- package/src/components/artifacts/site-view.tsx +116 -0
- package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
- package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
- package/src/components/artifacts/spreadsheet-grid.tsx +12 -13
- package/src/components/artifacts/visualization-assets/base.css +1015 -0
- package/src/components/artifacts/visualization-assets/helpers.html +349 -0
- package/src/components/artifacts/visualization-assets.gen.ts +3 -0
- package/src/components/browser-select-control.tsx +312 -0
- package/src/components/browser-viewer.tsx +1054 -314
- package/src/components/chat-composer.tsx +131 -85
- package/src/components/child-session-link.tsx +27 -0
- package/src/components/claude-mark.tsx +10 -0
- package/src/components/code-editor.tsx +13 -16
- package/src/components/composer-transcription-control.tsx +7 -5
- package/src/components/composer.tsx +376 -49
- package/src/components/computer-viewer.tsx +1041 -329
- package/src/components/copy-button.tsx +13 -5
- package/src/components/desktop-viewer.tsx +1 -1
- package/src/components/enrollment-consent.tsx +65 -7
- package/src/components/enrollment-device-flow.tsx +1 -1
- package/src/components/file-browser.tsx +158 -34
- package/src/components/fleet-tile.tsx +8 -16
- package/src/components/generated-video-player.tsx +4 -2
- package/src/components/grok-mark.tsx +33 -0
- package/src/components/human-input-form.tsx +455 -114
- package/src/components/human-input-surface.tsx +18 -7
- package/src/components/interaction-intervention-banner.tsx +2 -2
- package/src/components/machine-card.tsx +119 -4
- package/src/components/machine-dock-bar.tsx +1 -1
- package/src/components/machine-input-display.ts +23 -2
- package/src/components/machines/machine-detail.tsx +52 -2
- package/src/components/machines/machine-operation-policy.tsx +179 -0
- package/src/components/machines-dashboard.tsx +8 -17
- package/src/components/markdown-table-layout.ts +132 -0
- package/src/components/markdown.tsx +473 -44
- package/src/components/message-timeline.tsx +2498 -663
- package/src/components/model-mark.tsx +90 -0
- package/src/components/model-picker.tsx +15 -4
- package/src/components/model-policy-picker-menu.tsx +424 -0
- package/src/components/model-policy-picker.tsx +337 -381
- package/src/components/open-geni-chat.tsx +319 -0
- package/src/components/open-geni-links.tsx +179 -0
- package/src/components/openrouter-mark.tsx +13 -0
- package/src/components/pierre-diff.tsx +41 -16
- package/src/components/pierre-file.tsx +36 -11
- package/src/components/preview-loading.tsx +154 -0
- package/src/components/queue-item-content.ts +14 -0
- package/src/components/queue-surface-implementation.tsx +132 -42
- package/src/components/queue-surface-state.tsx +3 -1
- package/src/components/sandbox-files.tsx +267 -35
- package/src/components/sandbox-terminal.tsx +48 -11
- package/src/components/sandbox-workspace.tsx +337 -135
- package/src/components/session-capability-frame.tsx +192 -0
- package/src/components/session-chrome.tsx +1027 -328
- package/src/components/session-commands-panel.tsx +126 -0
- package/src/components/session-commands.tsx +18 -0
- package/src/components/session-connection-request.tsx +97 -0
- package/src/components/session-conversation.tsx +512 -0
- package/src/components/session-list.tsx +250 -0
- package/src/components/session-mcp-capability-card.tsx +680 -0
- package/src/components/session-status.tsx +1 -1
- package/src/components/timeline-anchor.tsx +119 -0
- package/src/components/timeline-annotation-chrome.tsx +196 -0
- package/src/components/timeline-annotation-layout.ts +268 -0
- package/src/components/timeline-annotation-markers.tsx +185 -0
- package/src/components/timeline-annotation-reveal-context.ts +9 -0
- package/src/components/timeline-annotation-selection.tsx +106 -54
- package/src/components/timeline-annotation-shared.ts +245 -0
- package/src/components/timeline-annotations-dialog.tsx +185 -128
- package/src/components/timeline-annotations.tsx +189 -45
- package/src/components/timeline-reading-progress.ts +80 -0
- package/src/components/timeline-search.tsx +168 -0
- package/src/components/timeline-settlement.ts +60 -0
- package/src/components/tip-follow.ts +70 -7
- package/src/components/tooltip.tsx +38 -5
- package/src/components/usage-limit-notice.tsx +179 -0
- package/src/components/usage-member-list.tsx +792 -0
- package/src/components/usage-meter.tsx +382 -0
- package/src/components/use-viewer-menu-dismiss.ts +33 -0
- package/src/components/user-message-body.tsx +194 -49
- package/src/components/workspace-dock.tsx +141 -175
- package/src/composer.ts +6 -1
- package/src/connect-account-identity.tsx +34 -0
- package/src/connect-accounts.tsx +233 -0
- package/src/connect-chooser.tsx +336 -0
- package/src/connect-panel.tsx +99 -0
- package/src/connect-setup.tsx +307 -0
- package/src/connect.ts +60 -0
- package/src/connection-assets.d.ts +4 -0
- package/src/connection-catalog.tsx +162 -0
- package/src/connection-discovery.tsx +235 -0
- package/src/connection-installed.tsx +51 -0
- package/src/connection-logo.tsx +37 -0
- package/src/connection-service-logo.tsx +55 -0
- package/src/connection-service-presentation.ts +46 -0
- package/src/connection-skeleton.tsx +16 -0
- package/src/connection-type-picker.tsx +36 -0
- package/src/conversation-timeline.ts +92 -0
- package/src/desktop.ts +24 -0
- package/src/device-authorization.tsx +98 -0
- package/src/diffs.ts +16 -0
- package/src/discovery-cache.ts +42 -0
- package/src/editor.ts +13 -0
- package/src/embedded-session-client.ts +104 -0
- package/src/file-node-visibility.ts +66 -0
- package/src/hooks/channel-cache.ts +104 -0
- package/src/hooks/internal.ts +3 -2
- package/src/hooks/latest-question.ts +164 -0
- package/src/hooks/shared-machines-list.ts +239 -0
- package/src/hooks/use-attached-browsers.ts +5 -1
- package/src/hooks/use-available-models.ts +20 -14
- package/src/hooks/use-browser-frame-stream.ts +25 -3
- package/src/hooks/use-browser-session.ts +271 -71
- package/src/hooks/use-browser-sessions.ts +7 -1
- package/src/hooks/use-channels.ts +32 -10
- package/src/hooks/use-codex-accounts.ts +78 -21
- package/src/hooks/use-composer.ts +1034 -320
- package/src/hooks/use-computer-frame-stream.ts +39 -16
- package/src/hooks/use-computer-input-posture.ts +94 -0
- package/src/hooks/use-computer-session.ts +110 -32
- package/src/hooks/use-computer-sessions.ts +8 -1
- package/src/hooks/use-connect.ts +23 -0
- package/src/hooks/use-desktop-stream.ts +19 -28
- package/src/hooks/use-file-attachments.ts +118 -10
- package/src/hooks/use-goal.ts +36 -9
- package/src/hooks/use-human-input.ts +31 -4
- package/src/hooks/use-last-started-turn-policy.ts +15 -13
- package/src/hooks/use-machine-chip.ts +23 -6
- package/src/hooks/use-machines.ts +104 -6
- package/src/hooks/use-sandbox-files.ts +253 -150
- package/src/hooks/use-sandbox-git.ts +58 -29
- package/src/hooks/use-session-background-commands.ts +67 -0
- package/src/hooks/use-session-capabilities.ts +21 -2
- package/src/hooks/use-session-events.ts +759 -433
- package/src/hooks/use-session-lineage.ts +28 -6
- package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
- package/src/hooks/use-session.ts +75 -16
- package/src/hooks/use-slash-commands.ts +6 -11
- package/src/hooks/use-turn-queue.ts +113 -13
- package/src/hooks/use-usage.ts +100 -0
- package/src/hooks/use-voice-input.ts +12 -1
- package/src/hooks/use-workspace-capture.ts +3 -2
- package/src/hooks/use-workspace-edit.ts +23 -5
- package/src/hooks/use-workspace-sessions.ts +99 -11
- package/src/human-input.ts +12 -1
- package/src/identity-link-accounts.tsx +148 -0
- package/src/identity-link-consent.tsx +192 -0
- package/src/index.ts +157 -12
- package/src/interaction.ts +1 -0
- package/src/lib/error-message.ts +37 -0
- package/src/lib/format.ts +150 -14
- package/src/lib/host-theme.ts +511 -0
- package/src/lib/interaction-errors.ts +33 -0
- package/src/lib/menu-styles.ts +44 -0
- package/src/lib/pierre-diffs-loader.ts +53 -0
- package/src/lib/workbench-peers.ts +62 -0
- package/src/lib/xterm-theme.ts +23 -21
- package/src/machines.ts +9 -1
- package/src/mcp-connection-status.ts +35 -0
- package/src/model-policy.ts +223 -69
- package/src/older-history.ts +87 -0
- package/src/plugin-details.tsx +185 -0
- package/src/plugin-discovery.tsx +196 -0
- package/src/provider.tsx +55 -14
- package/src/realtime/dropdown-menu.tsx +19 -12
- package/src/realtime/realtime-control.tsx +274 -60
- package/src/session-auth-recommendation.ts +48 -0
- package/src/session-capability-policy.ts +83 -0
- package/src/session-context.ts +1 -0
- package/src/session-ui.ts +66 -2
- package/src/session.ts +18 -1
- package/src/sites-ui.tsx +402 -0
- package/src/sites.ts +3 -0
- package/src/skill-discovery.tsx +208 -0
- package/src/terminal.ts +26 -0
- package/src/timeline/activity-rail.tsx +171 -80
- package/src/timeline/allowance-exhausted-row.tsx +86 -0
- package/src/timeline/compaction-copy.ts +42 -0
- package/src/timeline/entrance.tsx +28 -3
- package/src/timeline/fleet-decision-projection.ts +2 -1
- package/src/timeline/fleet-decision-row.tsx +1 -0
- package/src/timeline/genie-loading.tsx +136 -0
- package/src/timeline/index.ts +11 -0
- package/src/timeline/knowledge-receipt.tsx +100 -0
- package/src/timeline/parsers.ts +2 -2
- package/src/timeline/platform-activity-row.tsx +216 -0
- package/src/timeline/presented-image.ts +49 -0
- package/src/timeline/projection.ts +1600 -84
- package/src/timeline/registry.ts +15 -3
- package/src/timeline/retained-image.ts +97 -0
- package/src/timeline/rolling-activity.tsx +92 -0
- package/src/timeline/screenshot-lightbox.tsx +115 -17
- package/src/timeline/shared.tsx +47 -15
- package/src/timeline/startup-preference.ts +33 -0
- package/src/timeline/startup-timings.tsx +145 -0
- package/src/timeline/tool-display-name.ts +8 -6
- package/src/timeline/tool-renderers.tsx +497 -128
- package/src/timeline/turn-summary.tsx +208 -44
- package/src/timeline/types.ts +186 -7
- package/src/types/machines.ts +10 -0
- package/src/usage/allowance-copy.ts +64 -0
- package/src/usage/summary.ts +93 -0
- package/src/usage.ts +50 -0
- package/styles/compiled.css +2098 -757
- package/styles/connect.css +284 -0
- package/styles/connect.d.ts +1 -0
- package/styles/effective-tokens.css +1 -0
- package/styles/index.css +201 -9
- package/styles/responsive.css +27 -1
- package/styles/session-capability.css +44 -0
- package/styles/tokens.css +135 -65
- package/dist/chunk-5UQPNLIO.js.map +0 -1
- package/dist/chunk-6KLX2RH5.js.map +0 -1
- package/dist/chunk-7WCLAEFV.js.map +0 -1
- package/dist/chunk-B6WPZSTT.js.map +0 -1
- package/dist/chunk-FK6VG4LL.js +0 -90
- package/dist/chunk-FK6VG4LL.js.map +0 -1
- package/dist/chunk-HA46CYQK.js.map +0 -1
- package/dist/chunk-HUIKIDM5.js.map +0 -1
- package/dist/chunk-IGC6A2ZI.js.map +0 -1
- package/dist/chunk-KCGXPP5V.js.map +0 -1
- package/dist/chunk-KZ73RL76.js.map +0 -1
- package/dist/chunk-LAKLF4PA.js +0 -141
- package/dist/chunk-LAKLF4PA.js.map +0 -1
- package/dist/chunk-LLOLUHVG.js.map +0 -1
- package/dist/chunk-MKPIAGVL.js +0 -465
- package/dist/chunk-MKPIAGVL.js.map +0 -1
- package/dist/chunk-PEI6RANI.js.map +0 -1
- package/dist/chunk-R3AZOAB5.js.map +0 -1
- package/dist/chunk-WSK7G5LE.js +0 -170
- package/dist/chunk-WSK7G5LE.js.map +0 -1
- package/dist/chunk-XBZWOM2K.js +0 -218
- package/dist/chunk-XBZWOM2K.js.map +0 -1
- package/dist/chunk-Y7OEDUJ5.js +0 -8810
- package/dist/chunk-Y7OEDUJ5.js.map +0 -1
- package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
- package/dist/hooks/use-packs.d.ts +0 -32
- package/dist/interactive-workbench-viewers-TOHBXJEE.js +0 -15
- package/dist/queue-surface-implementation-2KVJTYXH.js.map +0 -1
- package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
- package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
- package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
- package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
- package/src/hooks/use-packs.ts +0 -157
- /package/dist/{interactive-workbench-viewers-TOHBXJEE.js.map → browser-viewer-GTR5XQ7X.js.map} +0 -0
|
@@ -4,6 +4,15 @@ import { ChevronRightIcon } from "lucide-react";
|
|
|
4
4
|
import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
|
|
5
5
|
import { createContext, useContext, type ComponentProps, type Ref } from "react";
|
|
6
6
|
import { cn } from "../lib/cn";
|
|
7
|
+
import {
|
|
8
|
+
MENU_CHEVRON_CLASS,
|
|
9
|
+
MENU_ITEM_CLASS,
|
|
10
|
+
MENU_SEPARATOR_CLASS,
|
|
11
|
+
MENU_SURFACE_CLASS,
|
|
12
|
+
} from "../lib/menu-styles";
|
|
13
|
+
|
|
14
|
+
const MENU_MOTION_CLASS =
|
|
15
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95";
|
|
7
16
|
import { usePortalTokenSource, usePortalTokenStyle } from "../lib/use-portal-token-style";
|
|
8
17
|
|
|
9
18
|
type DropdownMenuSourceContextValue = {
|
|
@@ -58,7 +67,9 @@ function DropdownMenuContent({
|
|
|
58
67
|
data-slot="dropdown-menu-content"
|
|
59
68
|
sideOffset={sideOffset}
|
|
60
69
|
className={cn(
|
|
61
|
-
"og-root z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto
|
|
70
|
+
"og-root z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto",
|
|
71
|
+
MENU_SURFACE_CLASS,
|
|
72
|
+
MENU_MOTION_CLASS,
|
|
62
73
|
className,
|
|
63
74
|
)}
|
|
64
75
|
style={{ ...portalStyle, ...style }}
|
|
@@ -82,10 +93,7 @@ function DropdownMenuItem({
|
|
|
82
93
|
data-slot="dropdown-menu-item"
|
|
83
94
|
data-inset={inset}
|
|
84
95
|
data-variant={variant}
|
|
85
|
-
className={cn(
|
|
86
|
-
"relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-og-menu outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:text-destructive!",
|
|
87
|
-
className,
|
|
88
|
-
)}
|
|
96
|
+
className={cn(MENU_ITEM_CLASS, "data-[inset]:pl-9", className)}
|
|
89
97
|
{...props}
|
|
90
98
|
/>
|
|
91
99
|
);
|
|
@@ -98,7 +106,7 @@ function DropdownMenuSeparator({
|
|
|
98
106
|
return (
|
|
99
107
|
<DropdownMenuPrimitive.Separator
|
|
100
108
|
data-slot="dropdown-menu-separator"
|
|
101
|
-
className={cn(
|
|
109
|
+
className={cn(MENU_SEPARATOR_CLASS, className)}
|
|
102
110
|
{...props}
|
|
103
111
|
/>
|
|
104
112
|
);
|
|
@@ -118,14 +126,11 @@ function DropdownMenuSubTrigger({
|
|
|
118
126
|
<DropdownMenuPrimitive.SubTrigger
|
|
119
127
|
data-slot="dropdown-menu-sub-trigger"
|
|
120
128
|
data-inset={inset}
|
|
121
|
-
className={cn(
|
|
122
|
-
"flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-og-menu outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[inset]:pl-8 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",
|
|
123
|
-
className,
|
|
124
|
-
)}
|
|
129
|
+
className={cn(MENU_ITEM_CLASS, "data-[inset]:pl-9", className)}
|
|
125
130
|
{...props}
|
|
126
131
|
>
|
|
127
132
|
{children}
|
|
128
|
-
<ChevronRightIcon className="ml-auto
|
|
133
|
+
<ChevronRightIcon aria-hidden="true" className={cn(MENU_CHEVRON_CLASS, "ml-auto")} />
|
|
129
134
|
</DropdownMenuPrimitive.SubTrigger>
|
|
130
135
|
);
|
|
131
136
|
}
|
|
@@ -141,7 +146,9 @@ function DropdownMenuSubContent({
|
|
|
141
146
|
<DropdownMenuPrimitive.SubContent
|
|
142
147
|
data-slot="dropdown-menu-sub-content"
|
|
143
148
|
className={cn(
|
|
144
|
-
"og-root z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden
|
|
149
|
+
"og-root z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden",
|
|
150
|
+
MENU_SURFACE_CLASS,
|
|
151
|
+
MENU_MOTION_CLASS,
|
|
145
152
|
className,
|
|
146
153
|
)}
|
|
147
154
|
style={{ ...portalStyle, ...style }}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type SessionRealtimeController,
|
|
7
7
|
type SessionRealtimeControllerSnapshot,
|
|
8
8
|
type CreateSessionRealtimeControllerOptions,
|
|
9
|
+
type SessionRealtimeLifecycleProjection,
|
|
9
10
|
type SessionRealtimeModel,
|
|
10
11
|
type WorkspaceRealtimeModelCatalogItem,
|
|
11
12
|
} from "@opengeni/sdk/realtime";
|
|
@@ -53,6 +54,7 @@ import {
|
|
|
53
54
|
DropdownMenuSubTrigger,
|
|
54
55
|
DropdownMenuTrigger,
|
|
55
56
|
} from "./dropdown-menu";
|
|
57
|
+
import { MENU_CHECK_CLASS } from "../lib/menu-styles";
|
|
56
58
|
|
|
57
59
|
export type RealtimeModelOption = {
|
|
58
60
|
id: SessionRealtimeModel;
|
|
@@ -98,9 +100,155 @@ const REALTIME_PROVIDER_META: Record<
|
|
|
98
100
|
"Your Gateway": { billingClass: "byok", hint: "Billed to your AI Gateway" },
|
|
99
101
|
};
|
|
100
102
|
const REALTIME_MODEL_STORAGE_PREFIX = "opengeni:realtime-model";
|
|
103
|
+
const REALTIME_MODEL_CATALOG_CACHE_TTL_MS = 60_000;
|
|
104
|
+
const REALTIME_MODEL_CATALOG_CACHE_MAX_WORKSPACES = 64;
|
|
101
105
|
|
|
102
106
|
type RealtimeControllerClient = EmbeddedRealtimeSessionClientLike & SessionRealtimeClientLike;
|
|
103
107
|
|
|
108
|
+
type RealtimeModelCatalogCacheEntry =
|
|
109
|
+
| {
|
|
110
|
+
state: "loading";
|
|
111
|
+
promise: Promise<RealtimeModelOption[]>;
|
|
112
|
+
controller: AbortController;
|
|
113
|
+
consumers: number;
|
|
114
|
+
}
|
|
115
|
+
| { state: "ready"; models: RealtimeModelOption[]; expiresAt: number };
|
|
116
|
+
|
|
117
|
+
// Scope advisory availability to the exact client object and workspace. The
|
|
118
|
+
// server still authorizes every realtime operation; changing principals should
|
|
119
|
+
// replace the client just as it does for the rest of the SDK state.
|
|
120
|
+
const realtimeModelCatalogCache = new WeakMap<
|
|
121
|
+
RealtimeControllerClient,
|
|
122
|
+
Map<string, RealtimeModelCatalogCacheEntry>
|
|
123
|
+
>();
|
|
124
|
+
|
|
125
|
+
function realtimeModelFallback(codexConnected: boolean): RealtimeModelOption[] {
|
|
126
|
+
return [
|
|
127
|
+
{
|
|
128
|
+
...CODEX_LIVE_MODEL,
|
|
129
|
+
available: codexConnected,
|
|
130
|
+
unavailableReason: codexConnected ? null : CODEX_LIVE_MODEL.unavailableReason,
|
|
131
|
+
},
|
|
132
|
+
];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function realtimeModelCatalogCacheFor(
|
|
136
|
+
client: RealtimeControllerClient,
|
|
137
|
+
): Map<string, RealtimeModelCatalogCacheEntry> {
|
|
138
|
+
const existing = realtimeModelCatalogCache.get(client);
|
|
139
|
+
if (existing) return existing;
|
|
140
|
+
const created = new Map<string, RealtimeModelCatalogCacheEntry>();
|
|
141
|
+
realtimeModelCatalogCache.set(client, created);
|
|
142
|
+
return created;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function readCachedRealtimeModelCatalog(
|
|
146
|
+
client: RealtimeControllerClient,
|
|
147
|
+
workspaceId: string,
|
|
148
|
+
now = Date.now(),
|
|
149
|
+
): RealtimeModelOption[] | null {
|
|
150
|
+
const cache = realtimeModelCatalogCache.get(client);
|
|
151
|
+
const entry = cache?.get(workspaceId);
|
|
152
|
+
if (!entry || entry.state === "loading") return null;
|
|
153
|
+
if (entry.expiresAt > now) return entry.models;
|
|
154
|
+
cache?.delete(workspaceId);
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function pruneRealtimeModelCatalogCache(
|
|
159
|
+
cache: Map<string, RealtimeModelCatalogCacheEntry>,
|
|
160
|
+
now: number,
|
|
161
|
+
): void {
|
|
162
|
+
for (const [workspaceId, entry] of cache) {
|
|
163
|
+
if (entry.state === "ready" && entry.expiresAt <= now) cache.delete(workspaceId);
|
|
164
|
+
}
|
|
165
|
+
while (cache.size >= REALTIME_MODEL_CATALOG_CACHE_MAX_WORKSPACES) {
|
|
166
|
+
const oldestWorkspaceId = cache.keys().next().value;
|
|
167
|
+
if (oldestWorkspaceId === undefined) return;
|
|
168
|
+
cache.delete(oldestWorkspaceId);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function loadRealtimeModelCatalog(
|
|
173
|
+
client: RealtimeControllerClient,
|
|
174
|
+
workspaceId: string,
|
|
175
|
+
signal?: AbortSignal,
|
|
176
|
+
): Promise<RealtimeModelOption[]> | null {
|
|
177
|
+
const load = client.getWorkspaceRealtimeModelCatalog;
|
|
178
|
+
if (!load) return null;
|
|
179
|
+
if (signal?.aborted) {
|
|
180
|
+
return Promise.reject(signal.reason ?? new DOMException("Request aborted", "AbortError"));
|
|
181
|
+
}
|
|
182
|
+
const now = Date.now();
|
|
183
|
+
const cache = realtimeModelCatalogCacheFor(client);
|
|
184
|
+
const entry = cache.get(workspaceId);
|
|
185
|
+
if (entry?.state === "loading" && !entry.controller.signal.aborted) {
|
|
186
|
+
return consumeRealtimeModelCatalog(entry, signal);
|
|
187
|
+
}
|
|
188
|
+
if (entry?.state === "ready" && entry.expiresAt > now) return Promise.resolve(entry.models);
|
|
189
|
+
if (entry) cache.delete(workspaceId);
|
|
190
|
+
pruneRealtimeModelCatalogCache(cache, now);
|
|
191
|
+
|
|
192
|
+
const controller = new AbortController();
|
|
193
|
+
const promise = load
|
|
194
|
+
.call(client, workspaceId, { signal: controller.signal })
|
|
195
|
+
.then((response) => response.models.map(toRealtimeModelOption))
|
|
196
|
+
.then((models) => {
|
|
197
|
+
const current = cache.get(workspaceId);
|
|
198
|
+
if (current?.state === "loading" && current.promise === promise) {
|
|
199
|
+
cache.delete(workspaceId);
|
|
200
|
+
cache.set(workspaceId, {
|
|
201
|
+
state: "ready",
|
|
202
|
+
models,
|
|
203
|
+
expiresAt: Date.now() + REALTIME_MODEL_CATALOG_CACHE_TTL_MS,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
return models;
|
|
207
|
+
})
|
|
208
|
+
.catch((error: unknown) => {
|
|
209
|
+
const current = cache.get(workspaceId);
|
|
210
|
+
if (current?.state === "loading" && current.promise === promise) cache.delete(workspaceId);
|
|
211
|
+
throw error;
|
|
212
|
+
});
|
|
213
|
+
const loading: RealtimeModelCatalogCacheEntry & { state: "loading" } = {
|
|
214
|
+
state: "loading",
|
|
215
|
+
promise,
|
|
216
|
+
controller,
|
|
217
|
+
consumers: 0,
|
|
218
|
+
};
|
|
219
|
+
cache.set(workspaceId, loading);
|
|
220
|
+
return consumeRealtimeModelCatalog(loading, signal);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function consumeRealtimeModelCatalog(
|
|
224
|
+
entry: RealtimeModelCatalogCacheEntry & { state: "loading" },
|
|
225
|
+
signal?: AbortSignal,
|
|
226
|
+
): Promise<RealtimeModelOption[]> {
|
|
227
|
+
entry.consumers += 1;
|
|
228
|
+
return new Promise((resolve, reject) => {
|
|
229
|
+
let released = false;
|
|
230
|
+
const release = (abandoned: boolean) => {
|
|
231
|
+
if (released) return;
|
|
232
|
+
released = true;
|
|
233
|
+
entry.consumers = Math.max(0, entry.consumers - 1);
|
|
234
|
+
if (abandoned && entry.consumers === 0) {
|
|
235
|
+
entry.controller.abort(
|
|
236
|
+
signal?.reason ?? new DOMException("Request abandoned", "AbortError"),
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
const onAbort = () => {
|
|
241
|
+
release(true);
|
|
242
|
+
reject(signal?.reason ?? new DOMException("Request aborted", "AbortError"));
|
|
243
|
+
};
|
|
244
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
245
|
+
void entry.promise.then(resolve, reject).finally(() => {
|
|
246
|
+
signal?.removeEventListener("abort", onAbort);
|
|
247
|
+
release(false);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
104
252
|
export type SessionRealtimeControllerFactory = (
|
|
105
253
|
options: CreateSessionRealtimeControllerOptions,
|
|
106
254
|
) => SessionRealtimeController;
|
|
@@ -138,6 +286,8 @@ export function useSessionRealtime(options: {
|
|
|
138
286
|
model?: SessionRealtimeModel | undefined;
|
|
139
287
|
modelAvailable?: boolean | undefined;
|
|
140
288
|
modelUnavailableReason?: string | null | undefined;
|
|
289
|
+
/** Model-visible application context captured with each durable realtime message. */
|
|
290
|
+
getModelContext?: (() => string | undefined) | undefined;
|
|
141
291
|
/** Deterministic browser-test/demo seam. Production hosts should use the SDK default. */
|
|
142
292
|
controllerFactory?: SessionRealtimeControllerFactory | undefined;
|
|
143
293
|
}) {
|
|
@@ -149,6 +299,8 @@ export function useSessionRealtime(options: {
|
|
|
149
299
|
const audioRef = useRef<HTMLAudioElement>(null);
|
|
150
300
|
const controllerRef = useRef<SessionRealtimeController | null>(null);
|
|
151
301
|
const controllerModelRef = useRef<SessionRealtimeModel | null>(null);
|
|
302
|
+
const modelContextProviderRef = useRef(options.getModelContext);
|
|
303
|
+
modelContextProviderRef.current = options.getModelContext;
|
|
152
304
|
const [snapshot, setSnapshot] = useState<SessionRealtimeControllerSnapshot>(() => ({
|
|
153
305
|
status: hasStoredSessionRealtimeOwnerProof({
|
|
154
306
|
workspaceId,
|
|
@@ -177,7 +329,7 @@ export function useSessionRealtime(options: {
|
|
|
177
329
|
const eventsReadyRef = useRef(options.eventsReady);
|
|
178
330
|
lifecycleRef.current = lifecycle;
|
|
179
331
|
eventsReadyRef.current = options.eventsReady;
|
|
180
|
-
const lifecycleActive = lifecycle
|
|
332
|
+
const lifecycleActive = sessionRealtimeLifecycleIsActive(lifecycle);
|
|
181
333
|
|
|
182
334
|
useEffect(() => {
|
|
183
335
|
let disposed = false;
|
|
@@ -193,6 +345,7 @@ export function useSessionRealtime(options: {
|
|
|
193
345
|
sessionId: options.sessionId,
|
|
194
346
|
...(audioRef.current ? { remoteAudio: audioRef.current } : {}),
|
|
195
347
|
model,
|
|
348
|
+
getModelContext: () => modelContextProviderRef.current?.(),
|
|
196
349
|
});
|
|
197
350
|
controllerRef.current = controller;
|
|
198
351
|
controllerModelRef.current = model;
|
|
@@ -297,6 +450,14 @@ export function useSessionRealtime(options: {
|
|
|
297
450
|
};
|
|
298
451
|
}
|
|
299
452
|
|
|
453
|
+
function sessionRealtimeLifecycleIsActive(
|
|
454
|
+
lifecycle: SessionRealtimeLifecycleProjection | null,
|
|
455
|
+
): boolean {
|
|
456
|
+
if (lifecycle?.state !== "active") return false;
|
|
457
|
+
const leaseExpiresAt = Date.parse(lifecycle.leaseExpiresAt);
|
|
458
|
+
return !Number.isFinite(leaseExpiresAt) || leaseExpiresAt > Date.now();
|
|
459
|
+
}
|
|
460
|
+
|
|
300
461
|
export function SessionRealtimeControl(props: {
|
|
301
462
|
client?: RealtimeControllerClient | undefined;
|
|
302
463
|
workspaceId?: string | undefined;
|
|
@@ -306,6 +467,8 @@ export function SessionRealtimeControl(props: {
|
|
|
306
467
|
events: SessionEvent[];
|
|
307
468
|
eventsReady: boolean;
|
|
308
469
|
codexConnected: boolean;
|
|
470
|
+
/** Model-visible application context captured with each durable realtime message. */
|
|
471
|
+
getModelContext?: (() => string | undefined) | undefined;
|
|
309
472
|
realtimeAutostartModel?: SessionRealtimeModel | undefined;
|
|
310
473
|
onRealtimeAutostartConsumed?: (() => void) | undefined;
|
|
311
474
|
/** Host hides dictate (and can choreograph layout) while realtime voice is live. */
|
|
@@ -317,15 +480,18 @@ export function SessionRealtimeControl(props: {
|
|
|
317
480
|
* `none` never attaches a model menu to the bar button.
|
|
318
481
|
*/
|
|
319
482
|
modelMenu?: "split" | "split-desktop" | "none" | undefined;
|
|
483
|
+
/** Explicitly expose low-level controller diagnostics; disabled by default. */
|
|
484
|
+
showDiagnostics?: boolean | undefined;
|
|
320
485
|
/** Deterministic browser-test/demo seam. Production hosts should use the SDK default. */
|
|
321
486
|
controllerFactory?: SessionRealtimeControllerFactory | undefined;
|
|
322
487
|
}) {
|
|
323
488
|
const lifecycle = useMemo(() => projectSessionRealtimeLifecycle(props.events), [props.events]);
|
|
489
|
+
const lifecycleActive = sessionRealtimeLifecycleIsActive(lifecycle);
|
|
324
490
|
const selection = useRealtimeModelSelection({
|
|
325
491
|
client: props.client,
|
|
326
492
|
workspaceId: props.workspaceId,
|
|
327
493
|
codexConnected: props.codexConnected,
|
|
328
|
-
activeModel: lifecycle?.state === "active" ? lifecycle.model : null,
|
|
494
|
+
activeModel: lifecycleActive && lifecycle?.state === "active" ? lifecycle.model : null,
|
|
329
495
|
});
|
|
330
496
|
const selectedModel = selection.selectedModel;
|
|
331
497
|
const realtime = useSessionRealtime({
|
|
@@ -349,7 +515,7 @@ export function SessionRealtimeControl(props: {
|
|
|
349
515
|
|
|
350
516
|
useEffect(() => {
|
|
351
517
|
const pending = autostartModelRef.current;
|
|
352
|
-
if (!pending || autostartStartedRef.current ||
|
|
518
|
+
if (!pending || autostartStartedRef.current || lifecycleActive) return;
|
|
353
519
|
const available = models.some((model) => model.id === pending && model.available);
|
|
354
520
|
if (!available) return;
|
|
355
521
|
if (selectedRealtimeModel.id !== pending) {
|
|
@@ -368,7 +534,7 @@ export function SessionRealtimeControl(props: {
|
|
|
368
534
|
});
|
|
369
535
|
}, [
|
|
370
536
|
canStart,
|
|
371
|
-
|
|
537
|
+
lifecycleActive,
|
|
372
538
|
models,
|
|
373
539
|
props.sessionId,
|
|
374
540
|
props.workspaceId,
|
|
@@ -386,6 +552,7 @@ export function SessionRealtimeControl(props: {
|
|
|
386
552
|
modelAvailable={selectedModel.available}
|
|
387
553
|
menuSide="top"
|
|
388
554
|
modelMenu={props.modelMenu ?? "split"}
|
|
555
|
+
showDiagnostics={props.showDiagnostics}
|
|
389
556
|
audioRef={realtime.audioRef}
|
|
390
557
|
selectedModel={selectedModel}
|
|
391
558
|
models={selection.models}
|
|
@@ -411,35 +578,58 @@ export function useRealtimeModelSelection(options: {
|
|
|
411
578
|
workspaceId: options.workspaceId,
|
|
412
579
|
});
|
|
413
580
|
const activeModel = options.activeModel;
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
available: options.codexConnected,
|
|
418
|
-
unavailableReason: options.codexConnected ? null : CODEX_LIVE_MODEL.unavailableReason,
|
|
419
|
-
},
|
|
420
|
-
]);
|
|
421
|
-
const [selectedModelId, setSelectedModelId] = useState<SessionRealtimeModel>(
|
|
422
|
-
() => readRealtimeModelPreference(workspaceId) ?? CODEX_LIVE_MODEL.id,
|
|
581
|
+
const initialCachedCatalog = readCachedRealtimeModelCatalog(client, workspaceId);
|
|
582
|
+
const [catalog, setCatalog] = useState<RealtimeModelOption[]>(
|
|
583
|
+
() => initialCachedCatalog ?? realtimeModelFallback(options.codexConnected),
|
|
423
584
|
);
|
|
585
|
+
const catalogScopeRef = useRef({
|
|
586
|
+
client,
|
|
587
|
+
workspaceId,
|
|
588
|
+
source: initialCachedCatalog ? ("cache" as const) : ("fallback" as const),
|
|
589
|
+
});
|
|
590
|
+
const [selectedModelId, setSelectedModelId] = useState<SessionRealtimeModel>(() => {
|
|
591
|
+
const preferred = readRealtimeModelPreference(workspaceId) ?? CODEX_LIVE_MODEL.id;
|
|
592
|
+
if (!initialCachedCatalog) return preferred;
|
|
593
|
+
if (initialCachedCatalog.some((model) => model.id === preferred && model.available)) {
|
|
594
|
+
return preferred;
|
|
595
|
+
}
|
|
596
|
+
return initialCachedCatalog.find((model) => model.available)?.id ?? CODEX_LIVE_MODEL.id;
|
|
597
|
+
});
|
|
424
598
|
|
|
425
599
|
useEffect(() => {
|
|
426
600
|
let disposed = false;
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
601
|
+
const requestAbort = new AbortController();
|
|
602
|
+
const applyCatalog = (models: RealtimeModelOption[]) => {
|
|
603
|
+
catalogScopeRef.current = { client, workspaceId, source: "cache" };
|
|
604
|
+
setCatalog(models);
|
|
605
|
+
setSelectedModelId((current) => {
|
|
606
|
+
if (models.some((model) => model.id === current && model.available)) return current;
|
|
607
|
+
return models.find((model) => model.available)?.id ?? CODEX_LIVE_MODEL.id;
|
|
608
|
+
});
|
|
609
|
+
};
|
|
610
|
+
const cached = readCachedRealtimeModelCatalog(client, workspaceId);
|
|
611
|
+
if (cached) {
|
|
612
|
+
const scope = catalogScopeRef.current;
|
|
613
|
+
if (
|
|
614
|
+
scope.client !== client ||
|
|
615
|
+
scope.workspaceId !== workspaceId ||
|
|
616
|
+
scope.source !== "cache"
|
|
617
|
+
) {
|
|
618
|
+
applyCatalog(cached);
|
|
619
|
+
}
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
const loading = loadRealtimeModelCatalog(client, workspaceId, requestAbort.signal);
|
|
623
|
+
if (!loading) return;
|
|
624
|
+
void loading
|
|
625
|
+
.then((models) => {
|
|
432
626
|
if (disposed) return;
|
|
433
|
-
|
|
434
|
-
setCatalog(models);
|
|
435
|
-
setSelectedModelId((current) => {
|
|
436
|
-
if (models.some((model) => model.id === current && model.available)) return current;
|
|
437
|
-
return models.find((model) => model.available)?.id ?? CODEX_LIVE_MODEL.id;
|
|
438
|
-
});
|
|
627
|
+
applyCatalog(models);
|
|
439
628
|
})
|
|
440
629
|
.catch(() => undefined);
|
|
441
630
|
return () => {
|
|
442
631
|
disposed = true;
|
|
632
|
+
requestAbort.abort();
|
|
443
633
|
};
|
|
444
634
|
}, [client, workspaceId]);
|
|
445
635
|
|
|
@@ -482,7 +672,7 @@ const IDLE_REALTIME_SNAPSHOT: SessionRealtimeControllerSnapshot = {
|
|
|
482
672
|
error: null,
|
|
483
673
|
};
|
|
484
674
|
|
|
485
|
-
|
|
675
|
+
type NewSessionRealtimeControlProps = {
|
|
486
676
|
client?: RealtimeControllerClient | undefined;
|
|
487
677
|
workspaceId?: string | undefined;
|
|
488
678
|
codexConnected: boolean;
|
|
@@ -500,20 +690,43 @@ export function NewSessionRealtimeControl(props: {
|
|
|
500
690
|
* `none` never attaches a model menu to the bar button.
|
|
501
691
|
*/
|
|
502
692
|
modelMenu?: "split" | "split-desktop" | "none" | undefined;
|
|
503
|
-
}
|
|
504
|
-
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
type NewSessionRealtimeSelection = {
|
|
696
|
+
models: readonly RealtimeModelOption[];
|
|
697
|
+
selectedModel: RealtimeModelOption;
|
|
698
|
+
selectModel: (modelId: string) => void;
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
export function NewSessionRealtimeControl(props: NewSessionRealtimeControlProps) {
|
|
702
|
+
if (props.models && props.selectedModel && props.onSelectModel) {
|
|
703
|
+
return (
|
|
704
|
+
<NewSessionRealtimeControlView
|
|
705
|
+
{...props}
|
|
706
|
+
selection={{
|
|
707
|
+
models: props.models,
|
|
708
|
+
selectedModel: props.selectedModel,
|
|
709
|
+
selectModel: props.onSelectModel,
|
|
710
|
+
}}
|
|
711
|
+
/>
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
return <NewSessionRealtimeControlWithInternalSelection {...props} />;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
function NewSessionRealtimeControlWithInternalSelection(props: NewSessionRealtimeControlProps) {
|
|
718
|
+
const selection = useRealtimeModelSelection({
|
|
505
719
|
client: props.client,
|
|
506
720
|
workspaceId: props.workspaceId,
|
|
507
721
|
codexConnected: props.codexConnected,
|
|
508
722
|
});
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
: internalSelection;
|
|
723
|
+
return <NewSessionRealtimeControlView {...props} selection={selection} />;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
function NewSessionRealtimeControlView(
|
|
727
|
+
props: NewSessionRealtimeControlProps & { selection: NewSessionRealtimeSelection },
|
|
728
|
+
) {
|
|
729
|
+
const selection = props.selection;
|
|
517
730
|
const audioRef = useRef<HTMLAudioElement>(null);
|
|
518
731
|
const [starting, setStarting] = useState(false);
|
|
519
732
|
const [error, setError] = useState<string | null>(null);
|
|
@@ -582,7 +795,7 @@ export function RealtimeVoiceControl(props: {
|
|
|
582
795
|
* `none` = start button only.
|
|
583
796
|
*/
|
|
584
797
|
modelMenu?: "split" | "split-desktop" | "none" | undefined;
|
|
585
|
-
showDiagnostics?: boolean;
|
|
798
|
+
showDiagnostics?: boolean | undefined;
|
|
586
799
|
/** Extra classes on the in-bar mute cluster (e.g. `max-sm:hidden` when mutes live in “+”). */
|
|
587
800
|
muteControlsClassName?: string | undefined;
|
|
588
801
|
audioRef: RefObject<HTMLAudioElement | null>;
|
|
@@ -636,7 +849,7 @@ export function RealtimeVoiceControl(props: {
|
|
|
636
849
|
: modeOwned
|
|
637
850
|
? props.onStop
|
|
638
851
|
: props.onStart;
|
|
639
|
-
const diagnosticsVisible = props.showDiagnostics ??
|
|
852
|
+
const diagnosticsVisible = props.showDiagnostics ?? false;
|
|
640
853
|
const modelMenu = props.modelMenu ?? "split";
|
|
641
854
|
const showAttachedModelMenu = modelMenu === "split" || modelMenu === "split-desktop";
|
|
642
855
|
const desktopOnlyModelMenu = modelMenu === "split-desktop";
|
|
@@ -793,7 +1006,7 @@ export function RealtimeVoiceControl(props: {
|
|
|
793
1006
|
align="end"
|
|
794
1007
|
sideOffset={8}
|
|
795
1008
|
collisionPadding={12}
|
|
796
|
-
className="og-realtime-menu flex w-72 max-h-[min(20rem,var(--radix-dropdown-menu-content-available-height))] flex-col overflow-hidden
|
|
1009
|
+
className="og-realtime-menu flex w-72 max-h-[min(20rem,var(--radix-dropdown-menu-content-available-height))] flex-col overflow-hidden"
|
|
797
1010
|
onCloseAutoFocus={(event) => event.preventDefault()}
|
|
798
1011
|
>
|
|
799
1012
|
<div className="min-h-0 flex-1 overflow-y-auto overscroll-contain">
|
|
@@ -816,9 +1029,15 @@ export function RealtimeVoiceControl(props: {
|
|
|
816
1029
|
/>
|
|
817
1030
|
</div>
|
|
818
1031
|
|
|
819
|
-
{status.phase !== "idle"
|
|
1032
|
+
{status.phase !== "idle" &&
|
|
1033
|
+
// Say it once: the selected model's row already carries its reason.
|
|
1034
|
+
!(
|
|
1035
|
+
status.phase === "unavailable" &&
|
|
1036
|
+
pickerProvider === selectedModel.provider &&
|
|
1037
|
+
selectedModel.unavailableReason === status.detail
|
|
1038
|
+
) ? (
|
|
820
1039
|
<>
|
|
821
|
-
<DropdownMenuSeparator
|
|
1040
|
+
<DropdownMenuSeparator />
|
|
822
1041
|
<div className="px-2.5 py-2" role="status" aria-live="polite">
|
|
823
1042
|
<div className="flex items-center gap-2 text-og-sm font-medium text-og-fg">
|
|
824
1043
|
<RealtimeStatusDot
|
|
@@ -834,7 +1053,6 @@ export function RealtimeVoiceControl(props: {
|
|
|
834
1053
|
|
|
835
1054
|
{audioBlocked ? (
|
|
836
1055
|
<DropdownMenuItem
|
|
837
|
-
className="rounded-og-md"
|
|
838
1056
|
onSelect={() => void props.onRetryAudibleOutput().catch(() => undefined)}
|
|
839
1057
|
>
|
|
840
1058
|
<Volume2Icon />
|
|
@@ -842,10 +1060,7 @@ export function RealtimeVoiceControl(props: {
|
|
|
842
1060
|
</DropdownMenuItem>
|
|
843
1061
|
) : null}
|
|
844
1062
|
{retryConnection ? (
|
|
845
|
-
<DropdownMenuItem
|
|
846
|
-
className="rounded-og-md"
|
|
847
|
-
onSelect={() => void props.onRetry().catch(() => undefined)}
|
|
848
|
-
>
|
|
1063
|
+
<DropdownMenuItem onSelect={() => void props.onRetry().catch(() => undefined)}>
|
|
849
1064
|
<RotateCcwIcon />
|
|
850
1065
|
Retry connection
|
|
851
1066
|
</DropdownMenuItem>
|
|
@@ -853,7 +1068,6 @@ export function RealtimeVoiceControl(props: {
|
|
|
853
1068
|
{modeOwned && props.snapshot.status !== "lost_owner" ? (
|
|
854
1069
|
<DropdownMenuItem
|
|
855
1070
|
variant="destructive"
|
|
856
|
-
className="rounded-og-md"
|
|
857
1071
|
disabled={props.snapshot.status === "stopping"}
|
|
858
1072
|
onSelect={() => void props.onStop().catch(() => undefined)}
|
|
859
1073
|
>
|
|
@@ -893,16 +1107,14 @@ export function RealtimeVoiceModelPanel(props: {
|
|
|
893
1107
|
|
|
894
1108
|
return (
|
|
895
1109
|
<div className="flex min-h-0 flex-1 flex-col" data-testid="realtime-voice-model-panel">
|
|
896
|
-
<div className="flex shrink-0 items-
|
|
1110
|
+
<div className="flex min-h-10 shrink-0 items-center gap-2 border-b border-og-border px-2 pb-2">
|
|
897
1111
|
{props.leading}
|
|
898
|
-
<div className="min-w-0">
|
|
899
|
-
<div className="text-og-menu font-medium text-og-fg">Voice model</div>
|
|
900
|
-
<p className="mt-0.5 text-og-control text-og-fg-subtle">
|
|
901
|
-
Used when you start a voice conversation.
|
|
902
|
-
</p>
|
|
903
|
-
</div>
|
|
1112
|
+
<div className="min-w-0 flex-1 text-og-menu font-medium text-og-fg">Voice model</div>
|
|
904
1113
|
</div>
|
|
905
|
-
<div className="min-h-0 flex-1 overflow-y-auto overscroll-contain
|
|
1114
|
+
<div className="min-h-0 flex-1 overflow-y-auto overscroll-contain p-2">
|
|
1115
|
+
<p className="mb-3 text-og-control text-og-fg-muted">
|
|
1116
|
+
Used when you start a voice conversation.
|
|
1117
|
+
</p>
|
|
906
1118
|
<RealtimeModelPickerMenu
|
|
907
1119
|
models={props.models}
|
|
908
1120
|
selectedModel={props.selectedModel}
|
|
@@ -1016,7 +1228,9 @@ export function RealtimeModelPickerMenu(props: {
|
|
|
1016
1228
|
title={model.unavailableReason ?? model.description}
|
|
1017
1229
|
active={selected}
|
|
1018
1230
|
showChevron={false}
|
|
1019
|
-
trailing={
|
|
1231
|
+
trailing={
|
|
1232
|
+
selected ? <CheckIcon className={MENU_CHECK_CLASS} aria-hidden /> : undefined
|
|
1233
|
+
}
|
|
1020
1234
|
testId={`realtime-model-choice-${model.id}`}
|
|
1021
1235
|
onClick={() => props.onSelect(model.id)}
|
|
1022
1236
|
/>
|
|
@@ -1079,12 +1293,12 @@ function RealtimeDiagnosticsMenu({ snapshot }: { snapshot: SessionRealtimeContro
|
|
|
1079
1293
|
|
|
1080
1294
|
return (
|
|
1081
1295
|
<>
|
|
1082
|
-
<DropdownMenuSeparator
|
|
1296
|
+
<DropdownMenuSeparator />
|
|
1083
1297
|
<DropdownMenuSub>
|
|
1084
|
-
<DropdownMenuSubTrigger className="
|
|
1298
|
+
<DropdownMenuSubTrigger className="text-og-fg-muted">
|
|
1085
1299
|
Realtime diagnostics
|
|
1086
1300
|
</DropdownMenuSubTrigger>
|
|
1087
|
-
<DropdownMenuSubContent className="max-h-80 w-72 overflow-y-auto
|
|
1301
|
+
<DropdownMenuSubContent className="max-h-80 w-72 overflow-y-auto">
|
|
1088
1302
|
{rows.map(([label, value]) => (
|
|
1089
1303
|
<DropdownMenuItem
|
|
1090
1304
|
key={label}
|
|
@@ -1316,7 +1530,7 @@ function RealtimeStatusDot(props: { phase: RealtimeVisualPhase; reduceMotion: bo
|
|
|
1316
1530
|
|
|
1317
1531
|
function voiceButtonTone(phase: RealtimeVisualPhase): string {
|
|
1318
1532
|
if (phase === "listening" || phase === "speaking") {
|
|
1319
|
-
return "border border-og-
|
|
1533
|
+
return "border border-og-primary-border bg-og-primary text-og-primary-fg hover:bg-og-primary-hover";
|
|
1320
1534
|
}
|
|
1321
1535
|
if (phase === "blocked" || phase === "error") {
|
|
1322
1536
|
return "border border-og-status-waiting/35 bg-og-status-waiting/10 text-og-status-waiting hover:bg-og-status-waiting/15";
|
|
@@ -1330,7 +1544,7 @@ function voiceButtonTone(phase: RealtimeVisualPhase): string {
|
|
|
1330
1544
|
|
|
1331
1545
|
function voiceChevronTone(phase: RealtimeVisualPhase): string {
|
|
1332
1546
|
if (phase === "listening" || phase === "speaking") {
|
|
1333
|
-
return "border border-l-0 border-og-
|
|
1547
|
+
return "border border-l-0 border-og-primary-border bg-og-primary text-og-primary-fg hover:bg-og-primary-hover";
|
|
1334
1548
|
}
|
|
1335
1549
|
if (phase === "blocked" || phase === "error") {
|
|
1336
1550
|
return "border border-l-0 border-og-status-waiting/35 bg-og-status-waiting/10 text-og-status-waiting hover:bg-og-status-waiting/15";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { AuthNeededItem } from "./timeline/types";
|
|
2
|
+
import type { CapabilityCatalogItem } from "@opengeni/sdk";
|
|
3
|
+
|
|
4
|
+
/** Recovery events identify runtime servers/connections, while recommendation
|
|
5
|
+
* events already carry a catalog id. Never guess among same-domain accounts. */
|
|
6
|
+
export function sessionAuthRecommendation(
|
|
7
|
+
item: AuthNeededItem,
|
|
8
|
+
catalog: CapabilityCatalogItem[],
|
|
9
|
+
): AuthNeededItem | undefined {
|
|
10
|
+
if (
|
|
11
|
+
item.authoritySource === "host" ||
|
|
12
|
+
item.reason === "unsupported_auth" ||
|
|
13
|
+
item.reason === "resource_scope_unavailable"
|
|
14
|
+
)
|
|
15
|
+
return undefined;
|
|
16
|
+
if (item.capability) return item;
|
|
17
|
+
const recoveryServerId = item.canonicalServerId ?? item.serverId;
|
|
18
|
+
const matches = catalog.filter(
|
|
19
|
+
(candidate) =>
|
|
20
|
+
(recoveryServerId !== null &&
|
|
21
|
+
candidate.runtime.mcpServerId === recoveryServerId &&
|
|
22
|
+
recoveryServerId !== "opengeni") ||
|
|
23
|
+
(item.connectionId !== null && candidate.connectionRef?.connectionId === item.connectionId),
|
|
24
|
+
);
|
|
25
|
+
if (matches.length !== 1) return undefined;
|
|
26
|
+
const entry = matches[0]!;
|
|
27
|
+
const personalAccess = item.reason === "personal_authority_unavailable";
|
|
28
|
+
if (
|
|
29
|
+
personalAccess &&
|
|
30
|
+
((item.connectionSubjectScope ?? entry.connectionRef?.subjectScope) !== "subject" ||
|
|
31
|
+
entry.connectionRef?.authoritySource === "host")
|
|
32
|
+
)
|
|
33
|
+
return undefined;
|
|
34
|
+
return {
|
|
35
|
+
...item,
|
|
36
|
+
capability: {
|
|
37
|
+
id: entry.id,
|
|
38
|
+
name: entry.name,
|
|
39
|
+
kind: entry.kind,
|
|
40
|
+
source: entry.source,
|
|
41
|
+
action: "connect",
|
|
42
|
+
rationale: personalAccess
|
|
43
|
+
? "Review permission to use your personal account in this conversation."
|
|
44
|
+
: "Reconnect this integration to use its tools in this conversation.",
|
|
45
|
+
requiredVariables: [],
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|