@opengeni/react 1.0.1 → 1.0.2-canary.37202341988001
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 +660 -21
- 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-SHYKQRNX.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-26ZNDDLZ.js +453 -0
- package/dist/chunk-26ZNDDLZ.js.map +1 -0
- package/dist/chunk-3CTRFMAK.js +359 -0
- package/dist/chunk-3CTRFMAK.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-742CZ3L3.js +481 -0
- package/dist/chunk-742CZ3L3.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-6KLX2RH5.js → chunk-DO544OSV.js} +1075 -79
- package/dist/chunk-DO544OSV.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-HA46CYQK.js → chunk-EESD3PY3.js} +792 -537
- package/dist/chunk-EESD3PY3.js.map +1 -0
- package/dist/{chunk-5UQPNLIO.js → chunk-EN3YTHKR.js} +4117 -3896
- package/dist/chunk-EN3YTHKR.js.map +1 -0
- package/dist/chunk-ERGYJIBB.js +21 -0
- package/dist/chunk-ERGYJIBB.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-GYVRFZDY.js +2733 -0
- package/dist/chunk-GYVRFZDY.js.map +1 -0
- package/dist/{chunk-LLOLUHVG.js → chunk-HDJWDK7W.js} +1358 -2746
- package/dist/chunk-HDJWDK7W.js.map +1 -0
- package/dist/chunk-I7IWRQLN.js +1608 -0
- package/dist/chunk-I7IWRQLN.js.map +1 -0
- package/dist/chunk-IT4BJUGF.js +13055 -0
- package/dist/chunk-IT4BJUGF.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-J6DBS4T3.js +371 -0
- package/dist/chunk-J6DBS4T3.js.map +1 -0
- package/dist/{chunk-B6WPZSTT.js → chunk-JIQYUGVL.js} +1331 -1163
- package/dist/chunk-JIQYUGVL.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-PEI6RANI.js → chunk-PNY3JKBJ.js} +309 -74
- package/dist/chunk-PNY3JKBJ.js.map +1 -0
- package/dist/chunk-RHREZ7BO.js +11 -0
- package/dist/chunk-RHREZ7BO.js.map +1 -0
- package/dist/chunk-RLUSC2WA.js +299 -0
- package/dist/chunk-RLUSC2WA.js.map +1 -0
- package/dist/{chunk-IGC6A2ZI.js → chunk-RSI7XYXL.js} +777 -246
- package/dist/chunk-RSI7XYXL.js.map +1 -0
- package/dist/chunk-SCOTPE2I.js +589 -0
- package/dist/chunk-SCOTPE2I.js.map +1 -0
- package/dist/{chunk-C5ZPSSS5.js → chunk-TKOTKRWY.js} +5 -4
- package/dist/{chunk-C5ZPSSS5.js.map → chunk-TKOTKRWY.js.map} +1 -1
- 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-WGXVEJO5.js +319 -0
- package/dist/chunk-WGXVEJO5.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-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-YM2DE7BQ.js +3124 -0
- package/dist/chunk-YM2DE7BQ.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-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 +58 -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 +89 -0
- package/dist/components/session-list.d.ts +36 -0
- package/dist/components/session-mcp-capability-card.d.ts +41 -0
- package/dist/components/session-proxy-scope.d.ts +21 -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-6SRGWRUX.js +19 -0
- package/dist/computer-viewer-6SRGWRUX.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 +2238 -6201
- 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-HTRIS4KJ.js +117 -0
- package/dist/latest-question-HTRIS4KJ.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-M54ISBMN.js +14 -0
- package/dist/model-policy-picker-menu-M54ISBMN.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 +6 -3
- package/dist/realtime.js +133 -74
- package/dist/realtime.js.map +1 -1
- package/dist/sandbox-files-GORZOUUJ.js +20 -0
- package/dist/sandbox-files-GORZOUUJ.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 +34 -3
- package/dist/timeline/types.d.ts +147 -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 +2754 -665
- 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 +338 -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 +526 -0
- package/src/components/session-list.tsx +250 -0
- package/src/components/session-mcp-capability-card.tsx +680 -0
- package/src/components/session-proxy-scope.tsx +92 -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-video-artifact-playback.ts +1 -1
- 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 +133 -46
- package/src/session-auth-recommendation.ts +48 -0
- package/src/session-capability-policy.ts +83 -0
- package/src/session-context.ts +4 -3
- 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 +1609 -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 +218 -44
- package/src/timeline/types.ts +192 -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-SHYKQRNX.js.map} +0 -0
|
@@ -1,56 +1,82 @@
|
|
|
1
|
+
import { ClaudeMark } from "./claude-mark";
|
|
2
|
+
import { GrokMark } from "./grok-mark";
|
|
3
|
+
import { ChatGptMark, ModelMark, modelHasMark } from "./model-mark";
|
|
4
|
+
import { modelDisplayName } from "@opengeni/sdk/model-display";
|
|
1
5
|
import type { ClientModel, LatencyMode, ReasoningEffort } from "@opengeni/sdk";
|
|
2
6
|
import {
|
|
3
|
-
CheckIcon,
|
|
4
7
|
ChevronDownIcon,
|
|
5
8
|
ChevronLeftIcon,
|
|
6
9
|
ChevronRightIcon,
|
|
10
|
+
Globe2Icon,
|
|
7
11
|
KeyRoundIcon,
|
|
12
|
+
SparklesIcon,
|
|
8
13
|
ZapIcon,
|
|
9
14
|
} from "lucide-react";
|
|
10
15
|
import { motion, useReducedMotion } from "motion/react";
|
|
11
|
-
import { DropdownMenu } from "radix-ui";
|
|
12
16
|
import {
|
|
13
|
-
|
|
17
|
+
Suspense,
|
|
18
|
+
lazy,
|
|
14
19
|
useMemo,
|
|
20
|
+
useId,
|
|
15
21
|
useState,
|
|
16
22
|
type CSSProperties,
|
|
17
23
|
type ReactNode,
|
|
18
|
-
type SVGProps,
|
|
19
24
|
} from "react";
|
|
20
25
|
import { cn } from "../lib/cn";
|
|
26
|
+
import { MENU_CHEVRON_CLASS } from "../lib/menu-styles";
|
|
21
27
|
import { usePortalTokenSource, usePortalTokenStyle } from "../lib/use-portal-token-style";
|
|
22
28
|
import {
|
|
23
|
-
coerceReasoningEffortForModel,
|
|
24
29
|
effortOptionsForModel,
|
|
25
30
|
findPickerRow,
|
|
26
|
-
groupPickerRowsByBillingClass,
|
|
27
31
|
labelReasoningEffort,
|
|
28
32
|
projectClientModelRows,
|
|
29
|
-
|
|
33
|
+
scopedBillingClassLabel,
|
|
30
34
|
type PickerBillingClass,
|
|
31
35
|
type PickerModelRow,
|
|
32
36
|
} from "../model-policy";
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
const LazyModelPolicyPickerMenu = lazy(() =>
|
|
39
|
+
import("./model-policy-picker-menu").then(({ ModelPolicyPickerPopover }) => ({
|
|
40
|
+
default: ModelPolicyPickerPopover,
|
|
41
|
+
})),
|
|
42
|
+
);
|
|
37
43
|
|
|
38
|
-
type
|
|
39
|
-
level: NavLevel;
|
|
40
|
-
rail: PickerBillingClass | null;
|
|
41
|
-
modelId: string | null;
|
|
42
|
-
};
|
|
44
|
+
type ClientPickerModelRow = PickerModelRow<ClientModel>;
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
/** Presentation only; never changes model identity, billing or availability. */
|
|
47
|
+
export type ModelPolicyPickerGroupPresentation = Partial<
|
|
48
|
+
Record<
|
|
49
|
+
PickerBillingClass,
|
|
50
|
+
{
|
|
51
|
+
label?: string | undefined;
|
|
52
|
+
/** Omit to preserve the default; null hides the supporting text. */
|
|
53
|
+
description?: string | null | undefined;
|
|
54
|
+
/** Decorative, non-interactive content. Omit for the default; null hides it. */
|
|
55
|
+
icon?: ReactNode | undefined;
|
|
56
|
+
}
|
|
57
|
+
>
|
|
58
|
+
>;
|
|
45
59
|
|
|
46
60
|
export type ModelPolicyPickerMessages = {
|
|
47
61
|
label: string;
|
|
48
62
|
loading: string;
|
|
49
63
|
noModels: string;
|
|
64
|
+
connectTitle: string;
|
|
65
|
+
connectBody: string;
|
|
66
|
+
connectAction: string;
|
|
50
67
|
thinking: string;
|
|
51
68
|
fast: string;
|
|
52
69
|
fastRateHint: string;
|
|
53
70
|
codexOnly: string;
|
|
71
|
+
searchLabel?: string;
|
|
72
|
+
searchPlaceholder?: string;
|
|
73
|
+
currentModel?: string;
|
|
74
|
+
noMatches?: string;
|
|
75
|
+
unsupportedAttachments?: string;
|
|
76
|
+
thinkingEffort?: string;
|
|
77
|
+
selected?: string;
|
|
78
|
+
free?: string;
|
|
79
|
+
|
|
54
80
|
billingHints: Record<PickerBillingClass, string>;
|
|
55
81
|
};
|
|
56
82
|
|
|
@@ -58,21 +84,40 @@ export const defaultModelPolicyPickerMessages: ModelPolicyPickerMessages = {
|
|
|
58
84
|
label: "Model and effort",
|
|
59
85
|
loading: "Loading model catalog…",
|
|
60
86
|
noModels: "No models available.",
|
|
87
|
+
connectTitle: "Connect a model",
|
|
88
|
+
connectBody: "Use a subscription or a provider key you already have.",
|
|
89
|
+
connectAction: "Open Models",
|
|
61
90
|
thinking: "Thinking",
|
|
62
91
|
fast: "Fast",
|
|
63
92
|
fastRateHint: "2× rate",
|
|
64
93
|
codexOnly: "Codex-only session",
|
|
94
|
+
searchLabel: "Search models or providers",
|
|
95
|
+
searchPlaceholder: "Search models or providers…",
|
|
96
|
+
currentModel: "Current model",
|
|
97
|
+
noMatches: "No matching models. Try a model or provider name.",
|
|
98
|
+
unsupportedAttachments: "This model cannot view the attached images.",
|
|
99
|
+
thinkingEffort: "Thinking effort",
|
|
100
|
+
selected: "Selected",
|
|
101
|
+
free: "Free",
|
|
102
|
+
|
|
65
103
|
billingHints: {
|
|
66
|
-
opengeni_credits: "
|
|
104
|
+
opengeni_credits: "Provided by Opengeni",
|
|
105
|
+
external: "Provider terms and limits apply",
|
|
67
106
|
codex_subscription: "ChatGPT / Codex plan",
|
|
68
107
|
supergrok_subscription: "SuperGrok / xAI plan",
|
|
69
|
-
|
|
108
|
+
claude_subscription: "Claude plan",
|
|
109
|
+
byok: "Billed to the connected provider account",
|
|
110
|
+
organization_byok: "Billed to the connected provider account",
|
|
70
111
|
},
|
|
71
112
|
};
|
|
72
113
|
|
|
73
114
|
export type ModelPolicyPickerProps = {
|
|
115
|
+
/** Host branding for payment-source groups, shared by menu and trigger. */
|
|
116
|
+
groupPresentation?: ModelPolicyPickerGroupPresentation | undefined;
|
|
74
117
|
/** Lightweight deployment models. Catalog rows take precedence when supplied. */
|
|
75
118
|
models?: ClientModel[] | undefined;
|
|
119
|
+
/** Warn only when the draft actually contains images this model cannot view. */
|
|
120
|
+
hasImageAttachments?: boolean | undefined;
|
|
76
121
|
/** Catalog-backed rows with availability and billing-class truth. */
|
|
77
122
|
rows?: PickerModelRow[] | undefined;
|
|
78
123
|
model: string;
|
|
@@ -88,15 +133,35 @@ export type ModelPolicyPickerProps = {
|
|
|
88
133
|
onOpenChange?: ((open: boolean) => void) | undefined;
|
|
89
134
|
/** Non-Codex models stay visible but cannot be selected. */
|
|
90
135
|
codexOnly?: boolean | undefined;
|
|
91
|
-
/**
|
|
136
|
+
/** Identity of the current session scope. */
|
|
92
137
|
sessionKey?: string | undefined;
|
|
93
138
|
/** Prefer bottom on new-chat surfaces and top for bottom-docked composers. */
|
|
94
139
|
menuSide?: "top" | "bottom" | undefined;
|
|
140
|
+
/**
|
|
141
|
+
* Default true: show models the way people choose them, with clean names,
|
|
142
|
+
* maker marks, one "API keys" group for organization- and workspace-connected
|
|
143
|
+
* keys, and one row for identical copies. Models settings passes false to
|
|
144
|
+
* keep its scope-aware presentation (raw catalog labels, scoped groups).
|
|
145
|
+
*/
|
|
146
|
+
collapseScopes?: boolean | undefined;
|
|
147
|
+
/** Hide latency controls on surfaces whose saved policy does not include latency. */
|
|
148
|
+
allowLatencyMode?: boolean | undefined;
|
|
149
|
+
/** Settings → Models. Shown when the catalog has no model that can run. */
|
|
150
|
+
connectModelsHref?: string | undefined;
|
|
95
151
|
/** Classes for the portalled menu surface. Prefer --og-* tokens for theming. */
|
|
96
152
|
contentClassName?: string | undefined;
|
|
97
153
|
/** Inline styles for the portalled menu, applied after inherited --og-* tokens. */
|
|
98
154
|
contentStyle?: CSSProperties | undefined;
|
|
99
155
|
className?: string | undefined;
|
|
156
|
+
/**
|
|
157
|
+
* "pill" (default) is the composer's quiet rounded trigger with the effort.
|
|
158
|
+
* "field" is a settings control: a bordered rectangle with the model name
|
|
159
|
+
* and `triggerMeta` (for example the payer) in muted text. The effort stays
|
|
160
|
+
* in the menu.
|
|
161
|
+
*/
|
|
162
|
+
triggerStyle?: "pill" | "field" | undefined;
|
|
163
|
+
/** Muted text after the model name in the "field" trigger. */
|
|
164
|
+
triggerMeta?: ReactNode;
|
|
100
165
|
messages?: Partial<ModelPolicyPickerMessages> | undefined;
|
|
101
166
|
onModelChange: (modelId: string) => void;
|
|
102
167
|
onEffortChange: (effort: ReasoningEffort) => void;
|
|
@@ -105,63 +170,29 @@ export type ModelPolicyPickerProps = {
|
|
|
105
170
|
|
|
106
171
|
const SLIDE_EASE = [0.22, 1, 0.36, 1] as const;
|
|
107
172
|
|
|
108
|
-
function OpenGeniMark(props: SVGProps<SVGSVGElement>) {
|
|
109
|
-
return (
|
|
110
|
-
<svg
|
|
111
|
-
viewBox="0 0 140 133"
|
|
112
|
-
fill="none"
|
|
113
|
-
stroke="currentColor"
|
|
114
|
-
strokeWidth={1.2}
|
|
115
|
-
strokeLinejoin="round"
|
|
116
|
-
aria-hidden="true"
|
|
117
|
-
{...props}
|
|
118
|
-
>
|
|
119
|
-
<g transform="translate(-17.5,-20.999893188476562) scale(1.75)">
|
|
120
|
-
<g transform="translate(0,-952.36218)">
|
|
121
|
-
<path d="m 60.7828,964.36215 27.1809,0.8834 -27.1809,25.9958 z m -1.9745,1.4513 0,26.7845 -25.2681,0 c 8.6166,-8.7334 16.8796,-17.8103 25.2681,-26.7845 z m 27.7053,3.628 3.4864,1.1989 -12.5877,7.4768 z m -68.1835,2.9656 5.5226,0 12.8654,14.0705 -5.9854,6.1204 -12.4026,0 c 9e-4,-6.7347 0,-13.4597 0,-20.1909 z m -1.9746,1.2304 0,5.8364 -6.3555,0 z m 3.363,20.9796 38.627,0 -10.7675,29.43465 z m 39.0898,4.54286 0,41.20229 -12.5878,-6.8775 c 4.1972,-11.443 8.3886,-22.879 12.5878,-34.32479 z" />
|
|
122
|
-
</g>
|
|
123
|
-
</g>
|
|
124
|
-
</svg>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function ChatGptMark(props: SVGProps<SVGSVGElement>) {
|
|
129
|
-
return (
|
|
130
|
-
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" {...props}>
|
|
131
|
-
<path d="M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3653-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8414 3.3698-2.02 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.783-2.7622a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z" />
|
|
132
|
-
</svg>
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function XaiMark(props: SVGProps<SVGSVGElement>) {
|
|
137
|
-
return (
|
|
138
|
-
<svg viewBox="0 0 466.04 516.93" fill="currentColor" aria-hidden="true" {...props}>
|
|
139
|
-
<polygon points="0.12 182.71 234.14 516.92 338.15 516.92 104.13 182.71 0.12 182.71" />
|
|
140
|
-
<polygon points="0 516.92 104.08 516.92 156.08 442.67 104.04 368.34 0 516.92" />
|
|
141
|
-
<polygon points="466.04 0 361.96 0 182.1 256.86 234.15 331.18 466.04 0" />
|
|
142
|
-
<polygon points="380.78 516.92 466.04 516.92 466.04 37.16 380.78 158.92 380.78 516.92" />
|
|
143
|
-
</svg>
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
173
|
export function BillingClassMark(props: {
|
|
148
174
|
billingClass: PickerBillingClass;
|
|
175
|
+
presentation?: ModelPolicyPickerGroupPresentation[PickerBillingClass] | undefined;
|
|
149
176
|
className?: string | undefined;
|
|
150
177
|
"aria-label"?: string | undefined;
|
|
151
178
|
}) {
|
|
152
179
|
const labels: Record<PickerBillingClass, string> = {
|
|
153
|
-
opengeni_credits: "
|
|
180
|
+
opengeni_credits: "Models",
|
|
181
|
+
external: "External provider",
|
|
154
182
|
codex_subscription: "Codex",
|
|
155
183
|
supergrok_subscription: "SuperGrok",
|
|
156
|
-
|
|
184
|
+
claude_subscription: "Claude",
|
|
185
|
+
byok: "API key",
|
|
186
|
+
organization_byok: "API key",
|
|
157
187
|
};
|
|
158
|
-
|
|
188
|
+
if (props.presentation?.icon === null) return null;
|
|
189
|
+
const label = props["aria-label"] ?? props.presentation?.label ?? labels[props.billingClass];
|
|
159
190
|
const accessibility =
|
|
160
191
|
label.length === 0
|
|
161
192
|
? { "aria-hidden": true as const }
|
|
162
193
|
: { role: "img" as const, "aria-label": label };
|
|
163
194
|
const shell = cn(
|
|
164
|
-
"inline-flex size-3.5 shrink-0 items-center justify-center overflow-hidden text-og-fg-subtle",
|
|
195
|
+
"inline-flex size-3.5 shrink-0 items-center justify-center overflow-hidden text-og-fg-subtle [&>svg]:size-full [&>img]:size-full",
|
|
165
196
|
props.className,
|
|
166
197
|
);
|
|
167
198
|
const mark = "size-3.5";
|
|
@@ -171,12 +202,18 @@ export function BillingClassMark(props: {
|
|
|
171
202
|
data-testid={`billing-class-icon-${props.billingClass}`}
|
|
172
203
|
{...accessibility}
|
|
173
204
|
>
|
|
174
|
-
{props.
|
|
175
|
-
|
|
205
|
+
{props.presentation?.icon !== undefined ? (
|
|
206
|
+
props.presentation.icon
|
|
207
|
+
) : props.billingClass === "opengeni_credits" ? (
|
|
208
|
+
<SparklesIcon className={mark} aria-hidden />
|
|
209
|
+
) : props.billingClass === "external" ? (
|
|
210
|
+
<Globe2Icon className={mark} aria-hidden />
|
|
176
211
|
) : props.billingClass === "codex_subscription" ? (
|
|
177
212
|
<ChatGptMark className={mark} />
|
|
213
|
+
) : props.billingClass === "claude_subscription" ? (
|
|
214
|
+
<ClaudeMark className={mark} />
|
|
178
215
|
) : props.billingClass === "supergrok_subscription" ? (
|
|
179
|
-
<
|
|
216
|
+
<GrokMark className={mark} />
|
|
180
217
|
) : (
|
|
181
218
|
<KeyRoundIcon className={mark} aria-hidden />
|
|
182
219
|
)}
|
|
@@ -188,6 +225,22 @@ function isCodexModel(model: ClientModel): boolean {
|
|
|
188
225
|
return model.id.startsWith("codex/") || model.source === "codex";
|
|
189
226
|
}
|
|
190
227
|
|
|
228
|
+
function billingClassForMissingSelection(modelId: string): PickerBillingClass {
|
|
229
|
+
if (modelId.startsWith("workspace-claude-subscription/")) return "claude_subscription";
|
|
230
|
+
if (modelId.startsWith("workspace-anthropic/")) return "byok";
|
|
231
|
+
if (modelId.startsWith("organization-claude-subscription/")) return "claude_subscription";
|
|
232
|
+
if (modelId.startsWith("organization-anthropic/")) return "organization_byok";
|
|
233
|
+
if (modelId.startsWith("workspace-gateway/")) return "byok";
|
|
234
|
+
if (modelId.startsWith("workspace-openrouter/")) return "byok";
|
|
235
|
+
// A deployment OpenRouter ID does not encode its workspace-facing cost.
|
|
236
|
+
// Missing rows therefore use the credits-safe rail instead of falsely
|
|
237
|
+
// claiming that an unknown former selection was externally funded.
|
|
238
|
+
if (modelId.startsWith("openrouter/")) return "opengeni_credits";
|
|
239
|
+
if (modelId.startsWith("codex/")) return "codex_subscription";
|
|
240
|
+
if (modelId.startsWith("supergrok/")) return "supergrok_subscription";
|
|
241
|
+
return "opengeni_credits";
|
|
242
|
+
}
|
|
243
|
+
|
|
191
244
|
function applyCodexOnly(
|
|
192
245
|
rows: ClientPickerModelRow[],
|
|
193
246
|
codexOnly: boolean,
|
|
@@ -205,36 +258,102 @@ function applyCodexOnly(
|
|
|
205
258
|
);
|
|
206
259
|
}
|
|
207
260
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
261
|
+
/**
|
|
262
|
+
* The trigger shows who makes the chosen model. Subscription rails already
|
|
263
|
+
* carry their maker's mark (ChatGPT, Claude, Grok), and explicit host branding
|
|
264
|
+
* for a payment group always wins; otherwise API-key and deployment models show
|
|
265
|
+
* the maker's logo instead of a generic key, falling back to the group mark.
|
|
266
|
+
*/
|
|
267
|
+
function SelectedModelMark(input: {
|
|
268
|
+
props: ModelPolicyPickerProps;
|
|
269
|
+
selected: ClientPickerModelRow | null;
|
|
270
|
+
}) {
|
|
271
|
+
const billingClass =
|
|
272
|
+
input.selected?.billingClass ?? billingClassForMissingSelection(input.props.model);
|
|
273
|
+
const presentation = groupPresentationFor(input.props, billingClass);
|
|
274
|
+
const model = input.selected?.catalog ?? input.props.model;
|
|
275
|
+
if (input.props.collapseScopes === false) {
|
|
276
|
+
return (
|
|
277
|
+
<BillingClassMark
|
|
278
|
+
billingClass={billingClass}
|
|
279
|
+
presentation={presentation}
|
|
280
|
+
aria-label={presentation?.label ?? SCOPED_MARK_LABELS[billingClass]}
|
|
281
|
+
className="text-og-fg"
|
|
282
|
+
/>
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
if (
|
|
286
|
+
presentation?.icon !== undefined ||
|
|
287
|
+
BRANDED_BILLING_CLASSES.has(billingClass) ||
|
|
288
|
+
!modelHasMark(model)
|
|
289
|
+
) {
|
|
290
|
+
return (
|
|
291
|
+
<BillingClassMark
|
|
292
|
+
billingClass={billingClass}
|
|
293
|
+
presentation={presentation}
|
|
294
|
+
className="text-og-fg"
|
|
295
|
+
/>
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
return <ModelMark model={model} className="text-og-fg" />;
|
|
212
299
|
}
|
|
213
300
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
301
|
+
const SCOPED_MARK_LABELS: Partial<Record<PickerBillingClass, string>> = {
|
|
302
|
+
byok: "Workspace provider account",
|
|
303
|
+
organization_byok: "Organization provider account",
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/** Models settings keeps naming who is billed for a key. */
|
|
307
|
+
export const SCOPED_BILLING_HINTS: Partial<Record<PickerBillingClass, string>> = {
|
|
308
|
+
byok: "Billed to the workspace provider account",
|
|
309
|
+
organization_byok: "Billed to the organization provider account",
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Host branding for a payment group. While scopes are collapsed, API keys are
|
|
314
|
+
* one group, so either API-key presentation serves both.
|
|
315
|
+
*/
|
|
316
|
+
export function groupPresentationFor(
|
|
317
|
+
props: Pick<ModelPolicyPickerProps, "groupPresentation" | "collapseScopes">,
|
|
318
|
+
billingClass: PickerBillingClass,
|
|
319
|
+
): ModelPolicyPickerGroupPresentation[PickerBillingClass] {
|
|
320
|
+
const own = props.groupPresentation?.[billingClass];
|
|
321
|
+
if (own !== undefined || props.collapseScopes === false) return own;
|
|
322
|
+
if (billingClass === "byok") return props.groupPresentation?.organization_byok;
|
|
323
|
+
if (billingClass === "organization_byok") return props.groupPresentation?.byok;
|
|
324
|
+
return undefined;
|
|
224
325
|
}
|
|
225
326
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
327
|
+
/** A selection the catalog no longer lists: its clean name (settings keep the id). */
|
|
328
|
+
function fallbackName(props: ModelPolicyPickerProps): string {
|
|
329
|
+
return props.collapseScopes === false ? props.model : modelDisplayName(props.model);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const BRANDED_BILLING_CLASSES: ReadonlySet<PickerBillingClass> = new Set([
|
|
333
|
+
"codex_subscription",
|
|
334
|
+
"claude_subscription",
|
|
335
|
+
"supergrok_subscription",
|
|
336
|
+
]);
|
|
337
|
+
|
|
338
|
+
export function effectiveRows(props: ModelPolicyPickerProps): ClientPickerModelRow[] {
|
|
339
|
+
const rows = props.rows !== undefined ? props.rows : projectClientModelRows(props.models ?? []);
|
|
340
|
+
const messages = { ...defaultModelPolicyPickerMessages, ...props.messages };
|
|
341
|
+
return applyCodexOnly(rows, props.codexOnly === true, messages.codexOnly).map((row) => {
|
|
342
|
+
const scoped =
|
|
343
|
+
props.collapseScopes === false
|
|
344
|
+
? {
|
|
345
|
+
...row,
|
|
346
|
+
label: row.catalog.label,
|
|
347
|
+
billingClassLabel: scopedBillingClassLabel(row.billingClass),
|
|
348
|
+
}
|
|
349
|
+
: row;
|
|
350
|
+
if (props.collapseScopes === false) {
|
|
351
|
+
if (row.catalog.shortLabel) scoped.shortLabel = row.catalog.shortLabel;
|
|
352
|
+
else delete scoped.shortLabel;
|
|
353
|
+
}
|
|
354
|
+
const label = groupPresentationFor(props, row.billingClass)?.label;
|
|
355
|
+
return label === undefined ? scoped : { ...scoped, billingClassLabel: label };
|
|
356
|
+
});
|
|
238
357
|
}
|
|
239
358
|
|
|
240
359
|
export function PickerNavRow(props: {
|
|
@@ -245,6 +364,7 @@ export function PickerNavRow(props: {
|
|
|
245
364
|
showChevron?: boolean | undefined;
|
|
246
365
|
disabled?: boolean | undefined;
|
|
247
366
|
title?: string | undefined;
|
|
367
|
+
description?: string | undefined;
|
|
248
368
|
active?: boolean | undefined;
|
|
249
369
|
testId?: string | undefined;
|
|
250
370
|
onClick: () => void;
|
|
@@ -254,28 +374,24 @@ export function PickerNavRow(props: {
|
|
|
254
374
|
type="button"
|
|
255
375
|
disabled={props.disabled}
|
|
256
376
|
title={props.title}
|
|
377
|
+
aria-description={props.description}
|
|
257
378
|
onClick={props.onClick}
|
|
258
379
|
data-testid={props.testId}
|
|
259
380
|
className={cn(
|
|
260
|
-
|
|
381
|
+
// The one menu row (lib/menu-styles.ts), with density tokens for embedders.
|
|
382
|
+
"flex min-h-8 w-full cursor-pointer items-center gap-2.5 rounded-og-md px-[var(--og-model-picker-row-padding-x)] py-[var(--og-model-picker-row-padding-y)] text-left text-og-fg outline-hidden transition-colors duration-[120ms] hover:bg-og-hover focus-visible:bg-og-hover focus-visible:outline-2 focus-visible:-outline-offset-2! focus-visible:outline-og-accent/55 pointer-coarse:min-h-11",
|
|
261
383
|
props.disabled && "cursor-not-allowed opacity-50",
|
|
262
384
|
)}
|
|
263
385
|
>
|
|
264
386
|
{props.icon}
|
|
265
387
|
<span className="min-w-0 flex-1">
|
|
266
|
-
<span className=
|
|
267
|
-
{props.label}
|
|
268
|
-
</span>
|
|
388
|
+
<span className="block truncate text-og-menu">{props.label}</span>
|
|
269
389
|
{props.hint ? (
|
|
270
|
-
<span className="mt-0.5 block truncate text-og-
|
|
271
|
-
{props.hint}
|
|
272
|
-
</span>
|
|
390
|
+
<span className="mt-0.5 block truncate text-og-sm text-og-fg-muted">{props.hint}</span>
|
|
273
391
|
) : null}
|
|
274
392
|
</span>
|
|
275
393
|
{props.trailing ? <span className="ml-auto shrink-0">{props.trailing}</span> : null}
|
|
276
|
-
{props.showChevron === false ? null :
|
|
277
|
-
<ChevronRightIcon className="size-3.5 shrink-0 text-og-fg-subtle" />
|
|
278
|
-
)}
|
|
394
|
+
{props.showChevron === false ? null : <ChevronRightIcon className={MENU_CHEVRON_CLASS} />}
|
|
279
395
|
</button>
|
|
280
396
|
);
|
|
281
397
|
}
|
|
@@ -287,14 +403,16 @@ export function PickerBackHeader(props: {
|
|
|
287
403
|
trailing?: ReactNode;
|
|
288
404
|
}) {
|
|
289
405
|
return (
|
|
290
|
-
<div className="mb-1 flex items-center gap-
|
|
406
|
+
<div className="mb-1.5 flex min-h-9 items-center gap-1 border-b border-og-border pb-1.5">
|
|
291
407
|
<button
|
|
292
408
|
type="button"
|
|
293
409
|
onClick={props.onBack}
|
|
294
410
|
data-testid="model-picker-back"
|
|
295
|
-
className="flex min-w-0 flex-1 cursor-pointer items-center gap-1
|
|
411
|
+
className="flex min-h-8 min-w-0 flex-1 cursor-pointer items-center gap-1 rounded-og-md pr-2.5 text-left text-og-fg outline-hidden transition-colors duration-[120ms] hover:bg-og-hover focus-visible:outline-2 focus-visible:-outline-offset-2! focus-visible:outline-og-accent/55 pointer-coarse:min-h-11"
|
|
296
412
|
>
|
|
297
|
-
<
|
|
413
|
+
<span className="flex size-8 shrink-0 items-center justify-center text-og-fg-muted">
|
|
414
|
+
<ChevronLeftIcon className="size-4" />
|
|
415
|
+
</span>
|
|
298
416
|
{props.icon}
|
|
299
417
|
<span className="min-w-0 flex-1 truncate text-og-menu font-medium">{props.label}</span>
|
|
300
418
|
</button>
|
|
@@ -322,255 +440,36 @@ export function PickerAnimatedPage(props: {
|
|
|
322
440
|
);
|
|
323
441
|
}
|
|
324
442
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
nav?: PickerNavState | undefined;
|
|
328
|
-
onNavChange?: ((next: NavUpdater) => void) | undefined;
|
|
329
|
-
},
|
|
330
|
-
) {
|
|
331
|
-
const messages = useMemo(
|
|
332
|
-
() => ({ ...defaultModelPolicyPickerMessages, ...props.messages }),
|
|
333
|
-
[props.messages],
|
|
334
|
-
);
|
|
335
|
-
const rows = effectiveRows(props);
|
|
336
|
-
const groups = useMemo(() => groupPickerRowsByBillingClass(rows), [rows]);
|
|
337
|
-
const [localNav, setLocalNav] = usePickerNavState(
|
|
338
|
-
props.nav === undefined ? props.sessionKey : undefined,
|
|
339
|
-
rows,
|
|
340
|
-
props.model,
|
|
341
|
-
);
|
|
342
|
-
const nav = props.nav ?? localNav;
|
|
343
|
-
const setNav = props.onNavChange ?? setLocalNav;
|
|
344
|
-
const [direction, setDirection] = useState<1 | -1>(1);
|
|
345
|
-
|
|
346
|
-
const effectiveNav =
|
|
347
|
-
nav.level === "providers" && groups.length === 1
|
|
348
|
-
? { level: "models" as const, rail: groups[0]!.billingClass, modelId: null }
|
|
349
|
-
: nav;
|
|
350
|
-
const activeGroup =
|
|
351
|
-
effectiveNav.rail === null
|
|
352
|
-
? undefined
|
|
353
|
-
: groups.find((group) => group.billingClass === effectiveNav.rail);
|
|
354
|
-
const focusModel =
|
|
355
|
-
effectiveNav.modelId === null ? undefined : findPickerRow(rows, effectiveNav.modelId);
|
|
356
|
-
const selectedRow = findPickerRow(rows, props.model);
|
|
357
|
-
const { latencyMode, loading, onLatencyModeChange } = props;
|
|
358
|
-
|
|
359
|
-
useEffect(() => {
|
|
360
|
-
if (loading || !selectedRow?.selectable) return;
|
|
361
|
-
const supportsCurrentMode = runnableLatencyModesForModel(selectedRow.catalog).includes(
|
|
362
|
-
latencyMode,
|
|
363
|
-
);
|
|
364
|
-
if (!supportsCurrentMode && latencyMode !== "standard") {
|
|
365
|
-
onLatencyModeChange("standard");
|
|
366
|
-
}
|
|
367
|
-
}, [latencyMode, loading, onLatencyModeChange, selectedRow]);
|
|
368
|
-
|
|
369
|
-
const go = (next: PickerNavState, nextDirection: 1 | -1) => {
|
|
370
|
-
setDirection(nextDirection);
|
|
371
|
-
setNav(next);
|
|
372
|
-
};
|
|
373
|
-
|
|
374
|
-
const selectEffort = (row: ClientPickerModelRow, effort: ReasoningEffort) => {
|
|
375
|
-
if (!row.selectable) return;
|
|
376
|
-
if (row.id !== props.model) props.onModelChange(row.id);
|
|
377
|
-
props.onEffortChange(coerceReasoningEffortForModel(row.catalog, effort));
|
|
378
|
-
};
|
|
379
|
-
|
|
380
|
-
const pageKey =
|
|
381
|
-
effectiveNav.level === "providers"
|
|
382
|
-
? "providers"
|
|
383
|
-
: effectiveNav.level === "models"
|
|
384
|
-
? `models:${effectiveNav.rail ?? ""}`
|
|
385
|
-
: `thinking:${effectiveNav.modelId ?? ""}`;
|
|
386
|
-
|
|
387
|
-
let body: ReactNode;
|
|
388
|
-
if (props.loading) {
|
|
389
|
-
body = <p className="px-2 py-3 text-og-control text-og-fg-subtle">{messages.loading}</p>;
|
|
390
|
-
} else if (groups.length === 0) {
|
|
391
|
-
body = <p className="px-2 py-3 text-og-control text-og-fg-subtle">{messages.noModels}</p>;
|
|
392
|
-
} else if (effectiveNav.level === "providers") {
|
|
393
|
-
body = (
|
|
394
|
-
<div className="flex flex-col gap-0.5" data-testid="model-picker-providers">
|
|
395
|
-
{groups.map((group) => (
|
|
396
|
-
<PickerNavRow
|
|
397
|
-
key={group.billingClass}
|
|
398
|
-
label={group.label}
|
|
399
|
-
hint={messages.billingHints[group.billingClass]}
|
|
400
|
-
icon={<BillingClassMark billingClass={group.billingClass} />}
|
|
401
|
-
active={selectedRow?.billingClass === group.billingClass}
|
|
402
|
-
testId={`model-picker-rail-${group.billingClass}`}
|
|
403
|
-
onClick={() => go({ level: "models", rail: group.billingClass, modelId: null }, 1)}
|
|
404
|
-
/>
|
|
405
|
-
))}
|
|
406
|
-
</div>
|
|
407
|
-
);
|
|
408
|
-
} else if (effectiveNav.level === "models" && activeGroup) {
|
|
409
|
-
body = (
|
|
410
|
-
<div data-testid="model-picker-models">
|
|
411
|
-
{groups.length > 1 ? (
|
|
412
|
-
<PickerBackHeader
|
|
413
|
-
label={activeGroup.label}
|
|
414
|
-
icon={<BillingClassMark billingClass={activeGroup.billingClass} />}
|
|
415
|
-
onBack={() => go({ level: "providers", rail: null, modelId: null }, -1)}
|
|
416
|
-
/>
|
|
417
|
-
) : null}
|
|
418
|
-
<div className="flex flex-col gap-0.5">
|
|
419
|
-
{activeGroup.rows.map((row) => (
|
|
420
|
-
<PickerNavRow
|
|
421
|
-
key={`${row.billingClass}:${row.id}`}
|
|
422
|
-
label={row.label}
|
|
423
|
-
hint={row.unavailableReason ?? undefined}
|
|
424
|
-
disabled={!row.selectable}
|
|
425
|
-
title={row.unavailableReason ?? undefined}
|
|
426
|
-
active={row.id === props.model}
|
|
427
|
-
testId={`model-picker-choice-${row.id}`}
|
|
428
|
-
onClick={() => {
|
|
429
|
-
if (row.selectable) {
|
|
430
|
-
go({ level: "thinking", rail: row.billingClass, modelId: row.id }, 1);
|
|
431
|
-
}
|
|
432
|
-
}}
|
|
433
|
-
/>
|
|
434
|
-
))}
|
|
435
|
-
</div>
|
|
436
|
-
</div>
|
|
437
|
-
);
|
|
438
|
-
} else if (effectiveNav.level === "thinking" && focusModel) {
|
|
439
|
-
const activeModel = focusModel.id === props.model;
|
|
440
|
-
const supportsFast = runnableLatencyModesForModel(focusModel.catalog).includes("fast");
|
|
441
|
-
body = (
|
|
442
|
-
<div data-testid="model-picker-reasoning">
|
|
443
|
-
<PickerBackHeader
|
|
444
|
-
label={focusModel.label}
|
|
445
|
-
icon={<BillingClassMark billingClass={focusModel.billingClass} />}
|
|
446
|
-
onBack={() => go({ level: "models", rail: focusModel.billingClass, modelId: null }, -1)}
|
|
447
|
-
trailing={
|
|
448
|
-
supportsFast ? (
|
|
449
|
-
<button
|
|
450
|
-
type="button"
|
|
451
|
-
disabled={!focusModel.selectable}
|
|
452
|
-
aria-pressed={activeModel && props.latencyMode === "fast"}
|
|
453
|
-
aria-label={
|
|
454
|
-
activeModel && props.latencyMode === "fast"
|
|
455
|
-
? `Disable ${messages.fast}`
|
|
456
|
-
: `Enable ${messages.fast}`
|
|
457
|
-
}
|
|
458
|
-
title={`${messages.fast} · ${messages.fastRateHint}`}
|
|
459
|
-
data-testid="model-picker-fast"
|
|
460
|
-
onClick={() => {
|
|
461
|
-
if (!activeModel) {
|
|
462
|
-
props.onModelChange(focusModel.id);
|
|
463
|
-
props.onEffortChange(
|
|
464
|
-
coerceReasoningEffortForModel(focusModel.catalog, props.effort),
|
|
465
|
-
);
|
|
466
|
-
}
|
|
467
|
-
props.onLatencyModeChange(
|
|
468
|
-
activeModel && props.latencyMode === "fast" ? "standard" : "fast",
|
|
469
|
-
);
|
|
470
|
-
}}
|
|
471
|
-
className={cn(
|
|
472
|
-
"flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-og-sm text-og-fg-subtle outline-hidden transition-colors hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:cursor-not-allowed disabled:opacity-50",
|
|
473
|
-
activeModel && props.latencyMode === "fast" && "text-og-fg",
|
|
474
|
-
)}
|
|
475
|
-
>
|
|
476
|
-
<ZapIcon
|
|
477
|
-
className={cn(
|
|
478
|
-
"size-3.5",
|
|
479
|
-
activeModel && props.latencyMode === "fast" && "fill-current",
|
|
480
|
-
)}
|
|
481
|
-
/>
|
|
482
|
-
</button>
|
|
483
|
-
) : null
|
|
484
|
-
}
|
|
485
|
-
/>
|
|
486
|
-
<p className="px-2.5 pt-1 pb-1 text-og-control font-medium tracking-wide text-og-fg-subtle uppercase">
|
|
487
|
-
{messages.thinking}
|
|
488
|
-
</p>
|
|
489
|
-
{focusModel.catalog.capabilities?.inputModalities.includes("image") === false ? (
|
|
490
|
-
<p className="px-2.5 pb-1.5 text-og-control leading-relaxed text-og-fg-subtle">
|
|
491
|
-
Unsupported attachments stay in the session but are hidden from this model.
|
|
492
|
-
</p>
|
|
493
|
-
) : null}
|
|
494
|
-
<div className="flex flex-col gap-0.5">
|
|
495
|
-
{effortOptionsForModel(focusModel.catalog).map((effort) => {
|
|
496
|
-
const selected = activeModel && effort === props.effort;
|
|
497
|
-
return (
|
|
498
|
-
<button
|
|
499
|
-
key={effort}
|
|
500
|
-
type="button"
|
|
501
|
-
disabled={!focusModel.selectable}
|
|
502
|
-
onClick={() => selectEffort(focusModel, effort)}
|
|
503
|
-
className={cn(
|
|
504
|
-
"flex h-[var(--og-model-picker-effort-height)] w-full cursor-pointer items-center rounded-og-sm px-[var(--og-model-picker-row-padding-x)] text-left text-og-menu text-og-fg outline-hidden transition-colors hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:cursor-not-allowed disabled:opacity-50",
|
|
505
|
-
selected && "bg-og-surface-2",
|
|
506
|
-
)}
|
|
507
|
-
>
|
|
508
|
-
<span className="min-w-0 flex-1 truncate">{labelReasoningEffort(effort)}</span>
|
|
509
|
-
{selected ? (
|
|
510
|
-
<CheckIcon
|
|
511
|
-
className="ml-auto size-3.5 shrink-0"
|
|
512
|
-
data-testid="model-picker-effort-check"
|
|
513
|
-
/>
|
|
514
|
-
) : null}
|
|
515
|
-
</button>
|
|
516
|
-
);
|
|
517
|
-
})}
|
|
518
|
-
</div>
|
|
519
|
-
</div>
|
|
520
|
-
);
|
|
521
|
-
} else {
|
|
522
|
-
body = (
|
|
523
|
-
<div className="flex flex-col gap-0.5" data-testid="model-picker-providers">
|
|
524
|
-
{groups.map((group) => (
|
|
525
|
-
<PickerNavRow
|
|
526
|
-
key={group.billingClass}
|
|
527
|
-
label={group.label}
|
|
528
|
-
hint={messages.billingHints[group.billingClass]}
|
|
529
|
-
icon={<BillingClassMark billingClass={group.billingClass} />}
|
|
530
|
-
testId={`model-picker-rail-${group.billingClass}`}
|
|
531
|
-
onClick={() => go({ level: "models", rail: group.billingClass, modelId: null }, 1)}
|
|
532
|
-
/>
|
|
533
|
-
))}
|
|
534
|
-
</div>
|
|
535
|
-
);
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
return (
|
|
539
|
-
<div data-testid="model-picker-menu" className="relative overflow-hidden">
|
|
540
|
-
{props.error ? (
|
|
541
|
-
<p className="px-2 py-1 text-og-control text-og-status-failed" role="alert">
|
|
542
|
-
{props.error}
|
|
543
|
-
</p>
|
|
544
|
-
) : null}
|
|
545
|
-
<PickerAnimatedPage pageKey={pageKey} direction={direction}>
|
|
546
|
-
{body}
|
|
547
|
-
</PickerAnimatedPage>
|
|
548
|
-
</div>
|
|
549
|
-
);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
export function ModelPolicyPicker(props: ModelPolicyPickerProps) {
|
|
443
|
+
/** @internal Shared controlled/uncontrolled state seam. */
|
|
444
|
+
export function useModelPolicyPickerState(props: ModelPolicyPickerProps) {
|
|
553
445
|
const [uncontrolledOpen, setUncontrolledOpen] = useState(props.defaultOpen ?? false);
|
|
554
446
|
const open = props.open ?? uncontrolledOpen;
|
|
555
447
|
const setOpen = (next: boolean) => {
|
|
556
448
|
if (props.open === undefined) setUncontrolledOpen(next);
|
|
557
449
|
props.onOpenChange?.(next);
|
|
558
450
|
};
|
|
451
|
+
return { open, setOpen, rows: effectiveRows(props) };
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export function ModelPolicyPicker(props: ModelPolicyPickerProps) {
|
|
455
|
+
const contentId = useId();
|
|
559
456
|
const trigger = usePortalTokenSource<HTMLButtonElement>();
|
|
560
457
|
const portalStyle = usePortalTokenStyle(trigger.source);
|
|
561
458
|
const messages = useMemo(
|
|
562
459
|
() => ({ ...defaultModelPolicyPickerMessages, ...props.messages }),
|
|
563
460
|
[props.messages],
|
|
564
461
|
);
|
|
565
|
-
const rows =
|
|
566
|
-
const [nav, setNav] = usePickerNavState(props.sessionKey, rows, props.model);
|
|
462
|
+
const { open, setOpen, rows } = useModelPolicyPickerState(props);
|
|
567
463
|
const selected = findPickerRow(rows, props.model);
|
|
464
|
+
const needsModel =
|
|
465
|
+
!rows.some((row) => row.selectable) && (rows.length > 0 || Boolean(props.connectModelsHref));
|
|
568
466
|
|
|
569
467
|
if (props.loading) {
|
|
570
468
|
return (
|
|
571
469
|
<span
|
|
572
470
|
className={cn(
|
|
573
471
|
"og-root inline-flex h-8 w-40 shrink-0 animate-pulse rounded-full bg-og-surface-2",
|
|
472
|
+
props.triggerStyle === "field" && "w-[180px] rounded-og-md",
|
|
574
473
|
props.className,
|
|
575
474
|
)}
|
|
576
475
|
aria-label={messages.loading}
|
|
@@ -578,64 +477,121 @@ export function ModelPolicyPicker(props: ModelPolicyPickerProps) {
|
|
|
578
477
|
/>
|
|
579
478
|
);
|
|
580
479
|
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
480
|
+
if (props.triggerStyle === "field") {
|
|
481
|
+
return (
|
|
482
|
+
<>
|
|
584
483
|
<button
|
|
585
484
|
ref={trigger.ref}
|
|
586
485
|
type="button"
|
|
486
|
+
aria-haspopup="dialog"
|
|
487
|
+
aria-expanded={open}
|
|
488
|
+
aria-controls={open ? contentId : undefined}
|
|
489
|
+
data-state={open ? "open" : "closed"}
|
|
490
|
+
data-trigger-style="field"
|
|
491
|
+
onClick={() => setOpen(!open)}
|
|
587
492
|
disabled={props.disabled}
|
|
588
493
|
aria-label={messages.label}
|
|
589
494
|
className={cn(
|
|
590
|
-
"og-root
|
|
495
|
+
"og-root inline-flex h-8 min-w-[180px] max-w-full items-center gap-2 rounded-og-md border border-og-border bg-og-surface px-2.5 text-sm text-og-fg outline-hidden transition-colors hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:cursor-not-allowed disabled:opacity-50",
|
|
591
496
|
props.className,
|
|
592
497
|
)}
|
|
593
498
|
>
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
<span className="og-model-policy-label-full min-w-0 truncate font-medium text-og-fg max-sm:hidden">
|
|
602
|
-
{selected?.label ?? props.model}
|
|
603
|
-
</span>
|
|
604
|
-
<span className="og-model-policy-label-short min-w-0 truncate font-medium text-og-fg sm:hidden">
|
|
605
|
-
{selected?.shortLabel ?? selected?.label ?? props.model}
|
|
606
|
-
</span>
|
|
607
|
-
<span className="og-model-policy-effort max-sm:hidden">
|
|
608
|
-
{labelReasoningEffort(props.effort)}
|
|
499
|
+
{needsModel ? (
|
|
500
|
+
<SparklesIcon className="size-3.5 shrink-0" aria-hidden />
|
|
501
|
+
) : (
|
|
502
|
+
<SelectedModelMark props={props} selected={selected} />
|
|
503
|
+
)}
|
|
504
|
+
<span className="min-w-0 truncate font-medium">
|
|
505
|
+
{needsModel ? messages.connectTitle : (selected?.label ?? fallbackName(props))}
|
|
609
506
|
</span>
|
|
610
|
-
{props.
|
|
611
|
-
<
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
data-testid="model-picker-fast-icon"
|
|
615
|
-
/>
|
|
507
|
+
{props.triggerMeta && !needsModel ? (
|
|
508
|
+
<span className="min-w-0 shrink-[9999] truncate text-og-fg-muted">
|
|
509
|
+
{props.triggerMeta}
|
|
510
|
+
</span>
|
|
616
511
|
) : null}
|
|
617
|
-
<ChevronDownIcon className="size-3 shrink-0" />
|
|
512
|
+
<ChevronDownIcon className="ml-auto size-3.5 shrink-0 text-og-fg-muted" />
|
|
618
513
|
</button>
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
514
|
+
{open ? (
|
|
515
|
+
<Suspense fallback={null}>
|
|
516
|
+
<LazyModelPolicyPickerMenu
|
|
517
|
+
{...props}
|
|
518
|
+
anchor={trigger.currentRef}
|
|
519
|
+
contentId={contentId}
|
|
520
|
+
portalStyle={portalStyle}
|
|
521
|
+
onOpenChange={setOpen}
|
|
522
|
+
/>
|
|
523
|
+
</Suspense>
|
|
524
|
+
) : null}
|
|
525
|
+
</>
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
return (
|
|
529
|
+
<>
|
|
530
|
+
<button
|
|
531
|
+
ref={trigger.ref}
|
|
532
|
+
type="button"
|
|
533
|
+
aria-haspopup="dialog"
|
|
534
|
+
aria-expanded={open}
|
|
535
|
+
aria-controls={open ? contentId : undefined}
|
|
536
|
+
data-state={open ? "open" : "closed"}
|
|
537
|
+
onClick={() => setOpen(!open)}
|
|
538
|
+
disabled={props.disabled}
|
|
539
|
+
aria-label={messages.label}
|
|
540
|
+
className={cn(
|
|
541
|
+
"og-root og-model-policy-trigger inline-flex h-[var(--og-model-picker-trigger-height)] min-w-0 max-w-64 items-center gap-1 rounded-full border px-2.5 text-og-control outline-hidden transition-colors focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:cursor-not-allowed disabled:opacity-50 max-sm:h-11 max-sm:max-w-[7.5rem] max-sm:px-2",
|
|
542
|
+
// With no usable model the pill is the one thing that unblocks the
|
|
543
|
+
// composer, so it takes the primary wash.
|
|
544
|
+
needsModel
|
|
545
|
+
? "border-og-primary-border bg-og-primary text-og-primary-fg hover:bg-og-primary-hover"
|
|
546
|
+
: "border-transparent text-og-fg-muted hover:border-og-border hover:bg-og-surface-2 hover:text-og-fg",
|
|
547
|
+
props.className,
|
|
548
|
+
)}
|
|
549
|
+
>
|
|
550
|
+
{needsModel ? (
|
|
551
|
+
<SparklesIcon className="size-3.5 shrink-0" aria-hidden />
|
|
552
|
+
) : (
|
|
553
|
+
<SelectedModelMark props={props} selected={selected} />
|
|
554
|
+
)}
|
|
555
|
+
<span className="og-model-policy-label-full min-w-0 truncate font-medium text-og-fg max-sm:hidden @max-[20rem]/model-controls:hidden">
|
|
556
|
+
{needsModel ? messages.connectTitle : (selected?.label ?? fallbackName(props))}
|
|
557
|
+
</span>
|
|
558
|
+
<span className="og-model-policy-label-short min-w-0 truncate font-medium text-og-fg sm:hidden @max-[20rem]/model-controls:block">
|
|
559
|
+
{needsModel
|
|
560
|
+
? messages.connectTitle
|
|
561
|
+
: (selected?.shortLabel ?? selected?.label ?? fallbackName(props))}
|
|
562
|
+
</span>
|
|
563
|
+
{selected &&
|
|
564
|
+
!needsModel &&
|
|
565
|
+
effortOptionsForModel(selected.catalog).length > 1 &&
|
|
566
|
+
selected.catalog.capabilities?.reasoning.runnable !== false ? (
|
|
567
|
+
<span
|
|
568
|
+
className="og-model-policy-effort min-w-0 shrink-[9999] truncate"
|
|
569
|
+
title={labelReasoningEffort(props.effort)}
|
|
570
|
+
>
|
|
571
|
+
{labelReasoningEffort(props.effort)}
|
|
572
|
+
</span>
|
|
573
|
+
) : null}
|
|
574
|
+
{props.latencyMode === "fast" && !needsModel ? (
|
|
575
|
+
<ZapIcon
|
|
576
|
+
className="size-3.5 shrink-0 fill-current stroke-current text-og-fg"
|
|
577
|
+
aria-label={messages.fast}
|
|
578
|
+
data-testid="model-picker-fast-icon"
|
|
579
|
+
/>
|
|
580
|
+
) : null}
|
|
581
|
+
<ChevronDownIcon className="size-3 shrink-0" />
|
|
582
|
+
</button>
|
|
583
|
+
|
|
584
|
+
{open ? (
|
|
585
|
+
<Suspense fallback={null}>
|
|
586
|
+
<LazyModelPolicyPickerMenu
|
|
587
|
+
{...props}
|
|
588
|
+
anchor={trigger.currentRef}
|
|
589
|
+
contentId={contentId}
|
|
590
|
+
portalStyle={portalStyle}
|
|
591
|
+
onOpenChange={setOpen}
|
|
592
|
+
/>
|
|
593
|
+
</Suspense>
|
|
594
|
+
) : null}
|
|
595
|
+
</>
|
|
640
596
|
);
|
|
641
597
|
}
|