@opengeni/react 3.1.0 → 3.1.3-canary.38890816741001
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 +769 -22
- package/dist/accounts.js +89 -11
- package/dist/accounts.js.map +1 -1
- package/dist/approvals.d.ts +2 -1
- package/dist/artifacts-document.js +5 -3
- package/dist/artifacts-presentation.js +5 -3
- package/dist/artifacts-spreadsheet.d.ts +1 -1
- package/dist/artifacts-spreadsheet.js +5 -3
- package/dist/artifacts.d.ts +5 -1
- package/dist/artifacts.js +536 -42
- package/dist/artifacts.js.map +1 -1
- package/dist/browser-viewer-ZWR6MWJ7.js +19 -0
- package/dist/capability-catalog-row.d.ts +20 -0
- package/dist/capability-logo-fallback.d.ts +3 -0
- package/dist/chat-interactive-block-BO2IWXVK.js +14 -0
- package/dist/chunk-2DDJ6YH6.js +41 -0
- package/dist/chunk-2DDJ6YH6.js.map +1 -0
- package/dist/chunk-2HVLQ26H.js +183 -0
- package/dist/chunk-2HVLQ26H.js.map +1 -0
- package/dist/{chunk-RGALCTWO.js → chunk-2I6R3GCZ.js} +4285 -3980
- package/dist/chunk-2I6R3GCZ.js.map +1 -0
- package/dist/{chunk-D3UIAJKY.js → chunk-2SFFYIH3.js} +1179 -166
- package/dist/chunk-2SFFYIH3.js.map +1 -0
- package/dist/chunk-3PVDYTTB.js +24 -0
- package/dist/chunk-3PVDYTTB.js.map +1 -0
- package/dist/chunk-3UZCWK46.js +298 -0
- package/dist/chunk-3UZCWK46.js.map +1 -0
- package/dist/chunk-47CKUXTW.js +293 -0
- package/dist/chunk-47CKUXTW.js.map +1 -0
- package/dist/chunk-4QYP6QUI.js +109 -0
- package/dist/chunk-4QYP6QUI.js.map +1 -0
- package/dist/chunk-5EY26VZ7.js +1053 -0
- package/dist/chunk-5EY26VZ7.js.map +1 -0
- package/dist/chunk-5I4VRWBB.js +56 -0
- package/dist/chunk-5I4VRWBB.js.map +1 -0
- package/dist/chunk-5WOR7UCL.js +191 -0
- package/dist/chunk-5WOR7UCL.js.map +1 -0
- package/dist/chunk-5YJLGOM5.js +51 -0
- package/dist/chunk-5YJLGOM5.js.map +1 -0
- package/dist/chunk-6JFN3OWG.js +386 -0
- package/dist/chunk-6JFN3OWG.js.map +1 -0
- package/dist/chunk-7QJT5O4S.js +35 -0
- package/dist/chunk-7QJT5O4S.js.map +1 -0
- package/dist/chunk-A55KV72M.js +402 -0
- package/dist/chunk-A55KV72M.js.map +1 -0
- package/dist/chunk-ADWCLI4G.js +2028 -0
- package/dist/chunk-ADWCLI4G.js.map +1 -0
- package/dist/chunk-B27E3V37.js +29 -0
- package/dist/chunk-B27E3V37.js.map +1 -0
- package/dist/chunk-B7TC2A33.js +83 -0
- package/dist/chunk-B7TC2A33.js.map +1 -0
- package/dist/chunk-BLL56F7R.js +385 -0
- package/dist/chunk-BLL56F7R.js.map +1 -0
- package/dist/chunk-BOFEQC6K.js +162 -0
- package/dist/chunk-BOFEQC6K.js.map +1 -0
- package/dist/chunk-CM7LVUKC.js +35 -0
- package/dist/chunk-CM7LVUKC.js.map +1 -0
- package/dist/chunk-CORUP6JB.js +122 -0
- package/dist/chunk-CORUP6JB.js.map +1 -0
- package/dist/chunk-CSX5FFKZ.js +35 -0
- package/dist/chunk-CSX5FFKZ.js.map +1 -0
- package/dist/chunk-EGVHJKGJ.js +3125 -0
- package/dist/chunk-EGVHJKGJ.js.map +1 -0
- package/dist/{chunk-NEXLLTP4.js → chunk-G76LSA76.js} +6 -5
- package/dist/chunk-G76LSA76.js.map +1 -0
- package/dist/{chunk-PEI6RANI.js → chunk-GQMRL52F.js} +311 -75
- package/dist/chunk-GQMRL52F.js.map +1 -0
- package/dist/{chunk-ELIYWBZR.js → chunk-GUUXOISA.js} +1113 -457
- package/dist/chunk-GUUXOISA.js.map +1 -0
- package/dist/{chunk-HUIKIDM5.js → chunk-I7X2P4FU.js} +225 -116
- package/dist/chunk-I7X2P4FU.js.map +1 -0
- package/dist/chunk-IGFZFLI2.js +1390 -0
- package/dist/chunk-IGFZFLI2.js.map +1 -0
- package/dist/{chunk-4MDLEHXL.js → chunk-IMSUVYQB.js} +26 -13
- package/dist/chunk-IMSUVYQB.js.map +1 -0
- package/dist/chunk-IOYHDEP3.js +38 -0
- package/dist/chunk-IOYHDEP3.js.map +1 -0
- package/dist/chunk-IZV5FTJC.js +55 -0
- package/dist/chunk-IZV5FTJC.js.map +1 -0
- package/dist/chunk-KF33GTWN.js +343 -0
- package/dist/chunk-KF33GTWN.js.map +1 -0
- package/dist/chunk-KSGQ5ODA.js +457 -0
- package/dist/chunk-KSGQ5ODA.js.map +1 -0
- package/dist/{chunk-OAM4WAAM.js → chunk-KZC6QRNR.js} +1513 -697
- package/dist/chunk-KZC6QRNR.js.map +1 -0
- package/dist/chunk-LJUMYUBO.js +218 -0
- package/dist/chunk-LJUMYUBO.js.map +1 -0
- package/dist/chunk-LSW2OJVV.js +380 -0
- package/dist/chunk-LSW2OJVV.js.map +1 -0
- package/dist/chunk-M357MHH3.js +2 -0
- package/dist/chunk-M357MHH3.js.map +1 -0
- package/dist/chunk-MK2TQO4Y.js +24 -0
- package/dist/chunk-MK2TQO4Y.js.map +1 -0
- package/dist/chunk-N7S72EXK.js +25 -0
- package/dist/chunk-N7S72EXK.js.map +1 -0
- package/dist/{chunk-XXWH2JLC.js → chunk-NKMYZFHA.js} +616 -621
- package/dist/chunk-NKMYZFHA.js.map +1 -0
- package/dist/chunk-NX4ADH73.js +14 -0
- package/dist/chunk-NX4ADH73.js.map +1 -0
- package/dist/chunk-O7F6UJO4.js +71 -0
- package/dist/chunk-O7F6UJO4.js.map +1 -0
- package/dist/chunk-OVB5WIG5.js +14064 -0
- package/dist/chunk-OVB5WIG5.js.map +1 -0
- package/dist/chunk-OYQQJL3J.js +16 -0
- package/dist/chunk-OYQQJL3J.js.map +1 -0
- package/dist/{chunk-H5YGYNXS.js → chunk-P4BNUO57.js} +60 -17
- package/dist/chunk-P4BNUO57.js.map +1 -0
- package/dist/{chunk-JVYQRRC4.js → chunk-PEHTX3V7.js} +21 -1
- package/dist/chunk-PEHTX3V7.js.map +1 -0
- package/dist/chunk-PMV53IMM.js +26 -0
- package/dist/chunk-PMV53IMM.js.map +1 -0
- package/dist/{chunk-KCGXPP5V.js → chunk-PYEOPA4M.js} +13 -7
- package/dist/chunk-PYEOPA4M.js.map +1 -0
- package/dist/{chunk-KZ73RL76.js → chunk-QHUE7E4N.js} +8 -3
- package/dist/chunk-QHUE7E4N.js.map +1 -0
- package/dist/chunk-QV3DJVRZ.js +11 -0
- package/dist/chunk-QV3DJVRZ.js.map +1 -0
- package/dist/chunk-R5SBNG7S.js +810 -0
- package/dist/chunk-R5SBNG7S.js.map +1 -0
- package/dist/chunk-RI42H5IU.js +326 -0
- package/dist/chunk-RI42H5IU.js.map +1 -0
- package/dist/chunk-S2QH6EZ5.js +211 -0
- package/dist/chunk-S2QH6EZ5.js.map +1 -0
- package/dist/chunk-SHLZMAJN.js +304 -0
- package/dist/chunk-SHLZMAJN.js.map +1 -0
- package/dist/chunk-TGXK4BAZ.js +293 -0
- package/dist/chunk-TGXK4BAZ.js.map +1 -0
- package/dist/{chunk-5YK2ZDIG.js → chunk-TNEZNMSN.js} +4 -10
- package/dist/chunk-TNEZNMSN.js.map +1 -0
- package/dist/{chunk-22KP6LR5.js → chunk-TXS65BB2.js} +3 -1
- package/dist/{chunk-22KP6LR5.js.map → chunk-TXS65BB2.js.map} +1 -1
- package/dist/chunk-UNJPZGNK.js +63 -0
- package/dist/chunk-UNJPZGNK.js.map +1 -0
- package/dist/{chunk-MZ2G2XBA.js → chunk-V5ZUJT2T.js} +205 -45
- package/dist/chunk-V5ZUJT2T.js.map +1 -0
- package/dist/chunk-VIUEOHXY.js +394 -0
- package/dist/chunk-VIUEOHXY.js.map +1 -0
- package/dist/chunk-WIUKB3LD.js +1911 -0
- package/dist/chunk-WIUKB3LD.js.map +1 -0
- package/dist/{chunk-ICA6R6TW.js → chunk-WNN7NO2N.js} +1451 -355
- package/dist/chunk-WNN7NO2N.js.map +1 -0
- package/dist/{chunk-YJFGAFBD.js → chunk-X5UVUIMF.js} +1892 -1223
- package/dist/chunk-X5UVUIMF.js.map +1 -0
- package/dist/chunk-XDA5QJE7.js +402 -0
- package/dist/chunk-XDA5QJE7.js.map +1 -0
- package/dist/{chunk-VZTQ73XT.js → chunk-XEA5BCMA.js} +3 -1
- package/dist/{chunk-VZTQ73XT.js.map → chunk-XEA5BCMA.js.map} +1 -1
- package/dist/chunk-XHF7OYAN.js +1150 -0
- package/dist/chunk-XHF7OYAN.js.map +1 -0
- package/dist/chunk-YSRBFJMQ.js +43 -0
- package/dist/chunk-YSRBFJMQ.js.map +1 -0
- package/dist/chunk-ZOZAPAUO.js +174 -0
- package/dist/chunk-ZOZAPAUO.js.map +1 -0
- package/dist/chunk-ZQV5W7YC.js +809 -0
- package/dist/chunk-ZQV5W7YC.js.map +1 -0
- package/dist/chunk-ZUWF4NF7.js +13 -0
- package/dist/chunk-ZUWF4NF7.js.map +1 -0
- package/dist/client.d.ts +16 -7
- package/dist/clipboard.js +3 -1
- package/dist/commands/types.d.ts +2 -0
- package/dist/components/anthropic-mark.d.ts +3 -0
- package/dist/components/approval-surface.d.ts +19 -6
- package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
- package/dist/components/artifacts/artifact-sandbox.d.ts +30 -0
- package/dist/components/artifacts/artifact-surface.d.ts +4 -2
- 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 +48 -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 +8 -3
- package/dist/components/artifacts/index.d.ts +9 -2
- 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 +23 -3
- package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
- package/dist/components/artifacts/site-view.d.ts +26 -0
- package/dist/components/artifacts/spreadsheet-command-queue.d.ts +20 -0
- package/dist/components/artifacts/spreadsheet-download.d.ts +7 -0
- package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
- package/dist/components/artifacts/spreadsheet-grid.d.ts +10 -3
- package/dist/components/artifacts/spreadsheet-resize.d.ts +50 -0
- package/dist/components/artifacts/spreadsheet-submissions.d.ts +9 -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 +11 -2
- package/dist/components/chat-composer.d.ts +21 -3
- package/dist/components/child-session-link.d.ts +9 -0
- package/dist/components/claude-mark.d.ts +3 -0
- package/dist/components/code-editor.d.ts +1 -4
- package/dist/components/composer-transcription-control.d.ts +7 -0
- package/dist/components/composer.d.ts +34 -67
- package/dist/components/computer-viewer.d.ts +1 -1
- package/dist/components/copy-button.d.ts +3 -1
- package/dist/components/desktop-viewer.d.ts +1 -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 +28 -32
- package/dist/components/human-input-surface.d.ts +7 -2
- package/dist/components/linkified-text.d.ts +18 -0
- package/dist/components/machine-input-display.d.ts +22 -1
- package/dist/components/machines/agent-status-icon.d.ts +6 -0
- package/dist/components/machines/machine-detail.d.ts +7 -1
- package/dist/components/machines/machine-status.d.ts +48 -0
- package/dist/components/markdown-table-layout.d.ts +18 -0
- package/dist/components/markdown.d.ts +37 -4
- package/dist/components/message-timeline.d.ts +86 -7
- 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 +41 -25
- package/dist/components/new-conversation.d.ts +32 -0
- package/dist/components/open-geni-chat.d.ts +73 -0
- package/dist/components/open-geni-links.d.ts +68 -0
- package/dist/components/openrouter-mark.d.ts +6 -0
- package/dist/components/opper-mark.d.ts +7 -0
- package/dist/components/preview-loading.d.ts +2 -0
- package/dist/components/provider-recovery-notice.d.ts +16 -0
- package/dist/components/queue-item-content.d.ts +9 -0
- package/dist/components/rehype-secret-refs.d.ts +23 -0
- package/dist/components/remark-soft-line-breaks.d.ts +38 -0
- package/dist/components/sandbox-files.d.ts +3 -1
- package/dist/components/sandbox-workspace.d.ts +18 -0
- package/dist/components/secret-question-field.d.ts +31 -0
- package/dist/components/secret-ref-chip.d.ts +35 -0
- package/dist/components/session-capability-frame.d.ts +37 -0
- package/dist/components/session-chrome.d.ts +57 -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 +157 -0
- package/dist/components/session-list.d.ts +39 -0
- package/dist/components/session-mcp-capability-card.d.ts +41 -0
- package/dist/components/session-proxy-scope.d.ts +35 -0
- package/dist/components/session-status.d.ts +4 -1
- package/dist/components/session-usage-limit-notice.d.ts +39 -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/tool-action-review.d.ts +47 -0
- package/dist/components/tool-review-history.d.ts +25 -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/composer-messages.d.ts +74 -0
- package/dist/composer-messages.js +9 -0
- package/dist/composer-messages.js.map +1 -0
- package/dist/composer-voice-events.d.ts +8 -0
- package/dist/composer.d.ts +5 -4
- package/dist/composer.js +26 -13
- package/dist/computer-viewer-GMLDXPON.js +20 -0
- package/dist/computer-viewer-GMLDXPON.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 +18 -0
- package/dist/connect.d.ts +21 -0
- package/dist/connect.js +2149 -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 +27 -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 +15 -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 +22 -0
- package/dist/editor.js.map +1 -0
- package/dist/embedded-new-voice-OCRNT6U5.js +18 -0
- package/dist/embedded-new-voice-OCRNT6U5.js.map +1 -0
- package/dist/embedded-voice-RPHPYVBT.js +18 -0
- package/dist/embedded-voice-RPHPYVBT.js.map +1 -0
- package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-SI63O5V4.js} +4 -1
- package/dist/fleet-decision-row-SI63O5V4.js.map +1 -0
- package/dist/hooks/latest-question.d.ts +25 -0
- package/dist/hooks/shared-machines-list.d.ts +4 -0
- package/dist/hooks/shared-query.d.ts +113 -0
- package/dist/hooks/use-attached-browsers.d.ts +1 -1
- package/dist/hooks/use-auth-runs.d.ts +1 -4
- package/dist/hooks/use-available-models.d.ts +1 -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-client-config-flags.d.ts +49 -0
- package/dist/hooks/use-codex-accounts.d.ts +59 -10
- package/dist/hooks/use-composer.d.ts +24 -2
- 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 +4 -0
- package/dist/hooks/use-connect.d.ts +23 -0
- package/dist/hooks/use-desktop-stream.d.ts +1 -1
- package/dist/hooks/use-file-attachments.d.ts +12 -0
- package/dist/hooks/use-goal.d.ts +2 -1
- package/dist/hooks/use-last-started-turn-policy.d.ts +5 -1
- package/dist/hooks/use-new-conversation.d.ts +56 -0
- package/dist/hooks/use-new-session-draft.d.ts +74 -0
- package/dist/hooks/use-realtime-voice-models.d.ts +7 -0
- package/dist/hooks/use-sandbox-files.d.ts +4 -1
- package/dist/hooks/use-session-conversation.d.ts +49 -0
- package/dist/hooks/use-session-events.d.ts +28 -7
- package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
- package/dist/hooks/use-session-model-account.d.ts +48 -0
- package/dist/hooks/use-supergrok-accounts.d.ts +7 -1
- package/dist/hooks/use-terminal-stream.d.ts +11 -5
- package/dist/hooks/use-usage.d.ts +40 -0
- package/dist/hooks/use-vaults.d.ts +53 -0
- package/dist/hooks/use-voice-input.d.ts +8 -1
- package/dist/hooks/use-workspace-edit.d.ts +4 -0
- package/dist/hooks/use-workspace-sessions.d.ts +22 -5
- package/dist/human-input-model.d.ts +122 -0
- package/dist/identity-link-accounts.d.ts +11 -0
- package/dist/identity-link-consent.d.ts +18 -0
- package/dist/index.d.ts +82 -20
- package/dist/index.js +2350 -6605
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +1 -1
- package/dist/interaction.js +14 -24
- package/dist/interaction.js.map +1 -1
- package/dist/latest-question-R77KWSUP.js +118 -0
- package/dist/latest-question-R77KWSUP.js.map +1 -0
- package/dist/lib/clipboard.d.ts +7 -0
- package/dist/lib/error-message.d.ts +7 -0
- package/dist/lib/format.d.ts +58 -4
- package/dist/lib/host-theme.d.ts +77 -0
- package/dist/lib/interaction-errors.d.ts +3 -0
- package/dist/lib/menu-styles.d.ts +22 -0
- package/dist/lib/notify-observer.d.ts +2 -0
- package/dist/lib/pierre-diffs-loader.d.ts +20 -0
- package/dist/lib/provider-recovery.d.ts +55 -0
- package/dist/lib/scrollbars.d.ts +11 -0
- package/dist/lib/terminal-input-readiness.d.ts +11 -0
- package/dist/lib/transient-retry.d.ts +25 -0
- package/dist/lib/workbench-peers.d.ts +36 -0
- package/dist/lib/xterm-theme.d.ts +7 -5
- package/dist/machines.js +9 -5
- package/dist/markdown-table-layout-3PV2UAAH.js +113 -0
- package/dist/markdown-table-layout-3PV2UAAH.js.map +1 -0
- package/dist/mcp-connection-status.d.ts +14 -0
- package/dist/model-mark-paths.d.ts +34 -0
- package/dist/model-mark-paths.js +16 -0
- package/dist/model-mark-paths.js.map +1 -0
- package/dist/model-picker-model.d.ts +111 -0
- package/dist/model-picker-model.js +25 -0
- package/dist/model-picker-model.js.map +1 -0
- package/dist/model-policy-picker-menu-7GJ5URPR.js +17 -0
- package/dist/model-policy-picker-menu-7GJ5URPR.js.map +1 -0
- package/dist/model-policy.d.ts +30 -3
- package/dist/model-policy.js +14 -1
- package/dist/native-previews.d.ts +28 -0
- package/dist/native-previews.js +82 -0
- package/dist/native-previews.js.map +1 -0
- package/dist/new-session-draft.d.ts +7 -0
- package/dist/new-session-draft.js +639 -0
- package/dist/new-session-draft.js.map +1 -0
- package/dist/notification-text.d.ts +27 -0
- package/dist/{noto-sans-arabic-loader-IA2T4X2A.js → noto-sans-arabic-loader-XSH2KYWJ.js} +3 -1
- package/dist/{noto-sans-arabic-loader-IA2T4X2A.js.map → noto-sans-arabic-loader-XSH2KYWJ.js.map} +1 -1
- package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js → noto-sans-jp-loader.generated-MR5L6V7K.js} +3 -1
- package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js.map → noto-sans-jp-loader.generated-MR5L6V7K.js.map} +1 -1
- package/dist/older-history.d.ts +3 -2
- package/dist/organization-model.d.ts +32 -0
- package/dist/organization-model.js +65 -0
- package/dist/organization-model.js.map +1 -0
- package/dist/{platform-activity-row-BJHUHXAT.js → platform-activity-row-5OCKOQWZ.js} +16 -78
- package/dist/platform-activity-row-5OCKOQWZ.js.map +1 -0
- package/dist/plugin-details.d.ts +14 -0
- package/dist/plugin-discovery.d.ts +25 -0
- package/dist/preview-loading-paint.d.ts +20 -0
- package/dist/provider.d.ts +25 -2
- package/dist/queue-presentation-model.d.ts +72 -0
- package/dist/queue-presentation-model.js +38 -0
- package/dist/queue-presentation-model.js.map +1 -0
- package/dist/{queue-surface-implementation-BSKUWHRI.js → queue-surface-implementation-GJBH7NKO.js} +65 -265
- package/dist/queue-surface-implementation-GJBH7NKO.js.map +1 -0
- package/dist/realtime/embedded-new-voice.d.ts +1 -0
- package/dist/realtime/embedded-voice.d.ts +1 -0
- package/dist/realtime/realtime-control.d.ts +4 -65
- package/dist/realtime/session-realtime.d.ts +78 -0
- package/dist/realtime.js +25 -1294
- package/dist/realtime.js.map +1 -1
- package/dist/sandbox-files-O27IPOZW.js +21 -0
- package/dist/sandbox-files-O27IPOZW.js.map +1 -0
- package/dist/sandbox-label-model.d.ts +30 -0
- package/dist/sandbox-label-model.js +20 -0
- package/dist/sandbox-label-model.js.map +1 -0
- package/dist/scrollbars.d.ts +1 -0
- package/dist/scrollbars.js +10 -0
- package/dist/scrollbars.js.map +1 -0
- package/dist/secret-reference-label.d.ts +14 -0
- package/dist/secrets-ui.d.ts +57 -0
- package/dist/session-agents-model.d.ts +10 -0
- package/dist/session-agents-model.js +25 -0
- package/dist/session-agents-model.js.map +1 -0
- package/dist/session-attention-model.d.ts +8 -0
- package/dist/session-attention-model.js +47 -0
- package/dist/session-attention-model.js.map +1 -0
- package/dist/session-auth-recommendation.d.ts +5 -0
- package/dist/session-capability-policy.d.ts +31 -0
- package/dist/session-feedback-model.d.ts +20 -0
- package/dist/session-feedback-model.js +56 -0
- package/dist/session-feedback-model.js.map +1 -0
- package/dist/session-list-model.d.ts +138 -0
- package/dist/session-list-model.js +274 -0
- package/dist/session-list-model.js.map +1 -0
- package/dist/session-realtime-7DJOIHQW.js +21 -0
- package/dist/session-realtime-7DJOIHQW.js.map +1 -0
- package/dist/session-realtime.d.ts +7 -0
- package/dist/session-realtime.js +19 -0
- package/dist/session-realtime.js.map +1 -0
- package/dist/session-status-model.d.ts +36 -0
- package/dist/session-ui.d.ts +39 -1
- package/dist/session-ui.js +126 -12
- package/dist/session-ui.js.map +1 -1
- package/dist/session.d.ts +8 -2
- package/dist/session.js +35 -20
- package/dist/site-snapshot.d.ts +14 -0
- package/dist/sites-ui.d.ts +24 -0
- package/dist/sites.d.ts +3 -0
- package/dist/sites.js +14 -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 +32 -0
- package/dist/terminal.js.map +1 -0
- package/dist/testing/session-scenarios.d.ts +10 -0
- package/dist/testing/session-scenarios.js +367 -0
- package/dist/testing/session-scenarios.js.map +1 -0
- package/dist/timeline/activity-rail.d.ts +11 -2
- package/dist/timeline/agent-identity.d.ts +30 -0
- package/dist/timeline/agent-row.d.ts +31 -0
- package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
- package/dist/timeline/compaction-copy.d.ts +46 -0
- package/dist/timeline/entrance.d.ts +13 -1
- package/dist/timeline/focus-sequence.d.ts +9 -0
- package/dist/timeline/genie-copy.d.ts +3 -0
- package/dist/timeline/genie-loading.d.ts +47 -0
- package/dist/timeline/index.d.ts +10 -5
- package/dist/timeline/knowledge-receipt.d.ts +17 -0
- package/dist/timeline/message-sender.d.ts +19 -0
- package/dist/timeline/notice-presentation.d.ts +13 -0
- package/dist/timeline/parsers.d.ts +11 -0
- package/dist/timeline/patch-apply-command.d.ts +18 -0
- package/dist/timeline/platform-activity-presentation.d.ts +21 -0
- package/dist/timeline/platform-activity-row.d.ts +1 -2
- package/dist/timeline/presented-image.d.ts +11 -0
- package/dist/timeline/projection.d.ts +31 -2
- package/dist/timeline/provider-logo.d.ts +15 -0
- package/dist/timeline/question-nav-model.d.ts +23 -0
- package/dist/timeline/registry.d.ts +12 -1
- package/dist/timeline/retained-image.d.ts +18 -0
- package/dist/timeline/retained-loaders.d.ts +27 -0
- package/dist/timeline/rolling-activity.d.ts +11 -0
- package/dist/timeline/screenshot-lightbox.d.ts +23 -1
- package/dist/timeline/session-usage-limit-row.d.ts +11 -0
- package/dist/timeline/shared.d.ts +4 -1
- package/dist/timeline/startup-dispatch-details.d.ts +5 -0
- 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 +5 -2
- package/dist/timeline/tool-presentation.d.ts +172 -0
- package/dist/timeline/turn-summary-model.d.ts +95 -0
- package/dist/timeline/turn-summary.d.ts +20 -54
- package/dist/timeline/types.d.ts +179 -7
- package/dist/timeline/work-presentation.d.ts +60 -0
- package/dist/timeline-annotation-markers-U3G66KUD.js +166 -0
- package/dist/timeline-annotation-markers-U3G66KUD.js.map +1 -0
- package/dist/timeline-annotation-selection-BI7QTPTZ.js +242 -0
- package/dist/timeline-annotation-selection-BI7QTPTZ.js.map +1 -0
- package/dist/timeline-annotations-dialog-FOMHSDTE.js +274 -0
- package/dist/timeline-annotations-dialog-FOMHSDTE.js.map +1 -0
- package/dist/timeline-model.d.ts +29 -0
- package/dist/timeline-model.js +254 -0
- package/dist/timeline-model.js.map +1 -0
- package/dist/usage/allowance-copy.d.ts +25 -0
- package/dist/usage/session-usage-limit.d.ts +88 -0
- package/dist/usage/summary.d.ts +35 -0
- package/dist/usage.d.ts +17 -0
- package/dist/usage.js +1187 -0
- package/dist/usage.js.map +1 -0
- package/dist/voice-recording-owner.d.ts +7 -0
- package/package.json +107 -7
- package/src/accounts.tsx +116 -14
- package/src/approvals.ts +8 -1
- package/src/artifacts-spreadsheet.ts +1 -0
- package/src/artifacts.ts +44 -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 +20 -31
- 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 +401 -138
- package/src/components/artifacts/artifact-chrome.tsx +413 -0
- package/src/components/artifacts/artifact-sandbox.tsx +189 -0
- package/src/components/artifacts/artifact-surface.tsx +40 -20
- 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 +197 -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 +543 -103
- package/src/components/artifacts/index.ts +45 -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 +122 -5
- package/src/components/artifacts/session-artifact-viewer.tsx +378 -0
- package/src/components/artifacts/site-view.tsx +121 -0
- package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
- package/src/components/artifacts/spreadsheet-command-queue.ts +184 -0
- package/src/components/artifacts/spreadsheet-download.tsx +109 -0
- package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
- package/src/components/artifacts/spreadsheet-grid.tsx +344 -144
- package/src/components/artifacts/spreadsheet-resize.tsx +421 -0
- package/src/components/artifacts/spreadsheet-submissions.tsx +46 -0
- 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 +778 -318
- package/src/components/chat-composer.tsx +47 -5
- package/src/components/child-session-link.tsx +36 -0
- package/src/components/claude-mark.tsx +11 -0
- package/src/components/code-editor.tsx +13 -16
- package/src/components/composer-transcription-control.tsx +128 -30
- package/src/components/composer.tsx +404 -195
- package/src/components/computer-viewer.tsx +880 -253
- package/src/components/copy-button.tsx +13 -5
- package/src/components/desktop-viewer.tsx +1 -1
- package/src/components/enrollment-consent.tsx +1 -1
- package/src/components/enrollment-device-flow.tsx +1 -1
- package/src/components/file-browser.tsx +10 -14
- package/src/components/fleet-tile.tsx +9 -18
- package/src/components/generated-video-player.tsx +4 -2
- package/src/components/grok-mark.tsx +34 -0
- package/src/components/human-input-form.tsx +590 -283
- package/src/components/human-input-surface.tsx +11 -0
- package/src/components/interaction-intervention-banner.tsx +2 -2
- package/src/components/linkified-text.tsx +79 -0
- package/src/components/machine-card.tsx +35 -78
- package/src/components/machine-dock-bar.tsx +1 -1
- package/src/components/machine-input-display.ts +197 -3
- package/src/components/machines/agent-status-icon.tsx +31 -0
- package/src/components/machines/machine-detail.tsx +200 -31
- package/src/components/machines/machine-operation-policy.tsx +1 -1
- package/src/components/machines/machine-status.ts +241 -0
- package/src/components/machines-dashboard.tsx +2 -17
- package/src/components/markdown-table-layout.ts +143 -0
- package/src/components/markdown.tsx +466 -129
- package/src/components/message-timeline.tsx +2567 -728
- package/src/components/model-mark.tsx +102 -0
- package/src/components/model-picker.tsx +15 -4
- package/src/components/model-policy-picker-menu.tsx +371 -0
- package/src/components/model-policy-picker.tsx +256 -412
- package/src/components/new-conversation.tsx +221 -0
- package/src/components/open-geni-chat.tsx +309 -0
- package/src/components/open-geni-links.tsx +179 -0
- package/src/components/openrouter-mark.tsx +13 -0
- package/src/components/opper-mark.tsx +18 -0
- package/src/components/pierre-diff.tsx +41 -16
- package/src/components/pierre-file.tsx +35 -10
- package/src/components/preview-loading.tsx +109 -0
- package/src/components/provider-recovery-notice.tsx +49 -0
- package/src/components/queue-item-content.ts +14 -0
- package/src/components/queue-surface-implementation.tsx +51 -356
- package/src/components/queue-surface-state.tsx +3 -1
- package/src/components/rehype-secret-refs.ts +98 -0
- package/src/components/remark-soft-line-breaks.ts +166 -0
- package/src/components/sandbox-files.tsx +91 -15
- package/src/components/sandbox-terminal.tsx +84 -13
- package/src/components/sandbox-workspace.tsx +147 -51
- package/src/components/secret-question-field.tsx +324 -0
- package/src/components/secret-ref-chip.tsx +185 -0
- package/src/components/session-capability-frame.tsx +197 -0
- package/src/components/session-chrome.tsx +842 -251
- 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 +876 -0
- package/src/components/session-list.tsx +257 -0
- package/src/components/session-mcp-capability-card.tsx +680 -0
- package/src/components/session-proxy-scope.tsx +153 -0
- package/src/components/session-status.tsx +26 -17
- package/src/components/session-usage-limit-notice.tsx +174 -0
- 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 +52 -0
- package/src/components/tool-action-review.tsx +650 -0
- package/src/components/tool-review-history.tsx +88 -0
- 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 +27 -2
- package/src/components/workspace-dock.tsx +18 -1
- package/src/composer-messages.ts +150 -0
- package/src/composer-voice-events.ts +12 -0
- 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 +355 -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 +238 -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/hooks/internal.ts +3 -2
- package/src/hooks/latest-question.ts +164 -0
- package/src/hooks/shared-machines-list.ts +34 -1
- package/src/hooks/shared-query.ts +721 -0
- package/src/hooks/use-attached-browsers.ts +1 -1
- package/src/hooks/use-auth-runs.ts +0 -27
- package/src/hooks/use-available-models.ts +21 -15
- package/src/hooks/use-browser-frame-stream.ts +19 -2
- package/src/hooks/use-browser-session.ts +680 -205
- package/src/hooks/use-browser-sessions.ts +32 -1
- package/src/hooks/use-client-config-flags.ts +118 -0
- package/src/hooks/use-codex-accounts.ts +247 -47
- package/src/hooks/use-composer.ts +276 -47
- package/src/hooks/use-computer-frame-stream.ts +25 -7
- package/src/hooks/use-computer-input-posture.ts +94 -0
- package/src/hooks/use-computer-session.ts +409 -95
- package/src/hooks/use-connect.ts +23 -0
- package/src/hooks/use-desktop-stream.ts +19 -28
- package/src/hooks/use-file-attachments.ts +80 -4
- package/src/hooks/use-goal.ts +107 -13
- package/src/hooks/use-last-started-turn-policy.ts +46 -14
- package/src/hooks/use-machines.ts +4 -0
- package/src/hooks/use-new-conversation.ts +374 -0
- package/src/hooks/use-new-session-draft.ts +813 -0
- package/src/hooks/use-realtime-voice-models.ts +46 -0
- package/src/hooks/use-sandbox-files.ts +68 -20
- package/src/hooks/use-session-background-commands.ts +22 -11
- package/src/hooks/use-session-capabilities.ts +3 -2
- package/src/hooks/use-session-conversation.ts +150 -0
- package/src/hooks/use-session-events.ts +703 -382
- package/src/hooks/use-session-lineage.ts +20 -16
- package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
- package/src/hooks/use-session-model-account.ts +174 -0
- package/src/hooks/use-session.ts +53 -21
- package/src/hooks/use-slash-commands.ts +6 -11
- package/src/hooks/use-supergrok-accounts.ts +22 -8
- package/src/hooks/use-terminal-stream.ts +153 -27
- package/src/hooks/use-transcription.ts +6 -0
- package/src/hooks/use-turn-queue.ts +2 -1
- package/src/hooks/use-usage.ts +100 -0
- package/src/hooks/use-vaults.ts +153 -0
- package/src/hooks/use-video-artifact-playback.ts +1 -1
- package/src/hooks/use-voice-input.ts +127 -19
- 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 +97 -32
- package/src/human-input-model.ts +359 -0
- package/src/identity-link-accounts.tsx +148 -0
- package/src/identity-link-consent.tsx +192 -0
- package/src/index.ts +262 -16
- package/src/interaction.ts +1 -0
- package/src/lib/clipboard.ts +29 -0
- package/src/lib/error-message.ts +37 -0
- package/src/lib/format.ts +213 -16
- package/src/lib/host-theme.ts +529 -0
- package/src/lib/interaction-errors.ts +15 -0
- package/src/lib/menu-styles.ts +44 -0
- package/src/lib/notify-observer.ts +15 -0
- package/src/lib/pierre-diffs-loader.ts +53 -0
- package/src/lib/provider-recovery.ts +243 -0
- package/src/lib/scrollbars.ts +30 -0
- package/src/lib/terminal-input-readiness.ts +51 -0
- package/src/lib/transient-retry.ts +99 -0
- package/src/lib/workbench-peers.ts +62 -0
- package/src/lib/xterm-theme.ts +23 -21
- package/src/mcp-connection-status.ts +35 -0
- package/src/model-mark-paths.ts +53 -0
- package/src/model-picker-model.ts +330 -0
- package/src/model-policy.ts +299 -74
- package/src/native-previews.ts +100 -0
- package/src/new-session-draft.ts +22 -0
- package/src/notification-text.ts +81 -0
- package/src/older-history.ts +22 -4
- package/src/organization-model.ts +118 -0
- package/src/plugin-details.tsx +185 -0
- package/src/plugin-discovery.tsx +196 -0
- package/src/preview-loading-paint.ts +68 -0
- package/src/provider.tsx +74 -15
- package/src/queue-presentation-model.ts +464 -0
- package/src/realtime/dropdown-menu.tsx +19 -12
- package/src/realtime/embedded-new-voice.tsx +1 -0
- package/src/realtime/embedded-voice.tsx +3 -0
- package/src/realtime/realtime-control.tsx +138 -501
- package/src/realtime/session-realtime.ts +566 -0
- package/src/sandbox-label-model.ts +53 -0
- package/src/scrollbars.ts +3 -0
- package/src/secret-reference-label.ts +43 -0
- package/src/secrets-ui.tsx +59 -0
- package/src/session-agents-model.ts +33 -0
- package/src/session-attention-model.ts +62 -0
- package/src/session-auth-recommendation.ts +48 -0
- package/src/session-capability-policy.ts +196 -0
- package/src/session-context.ts +3 -4
- package/src/session-feedback-model.ts +95 -0
- package/src/session-list-model.ts +434 -0
- package/src/session-realtime.ts +18 -0
- package/src/session-status-model.ts +99 -0
- package/src/session-ui.ts +98 -1
- package/src/session.ts +17 -1
- package/src/site-snapshot.ts +74 -0
- package/src/sites-ui.tsx +348 -0
- package/src/sites.ts +3 -0
- package/src/skill-discovery.tsx +208 -0
- package/src/terminal.ts +26 -0
- package/src/testing/session-scenarios.ts +404 -0
- package/src/timeline/activity-rail.tsx +242 -101
- package/src/timeline/agent-identity.tsx +84 -0
- package/src/timeline/agent-row.tsx +231 -0
- package/src/timeline/allowance-exhausted-row.tsx +86 -0
- package/src/timeline/compaction-copy.ts +115 -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/focus-sequence.ts +44 -0
- package/src/timeline/genie-copy.ts +19 -0
- package/src/timeline/genie-loading.tsx +143 -0
- package/src/timeline/index.ts +30 -2
- package/src/timeline/knowledge-receipt.tsx +100 -0
- package/src/timeline/message-sender.tsx +71 -0
- package/src/timeline/notice-presentation.ts +48 -0
- package/src/timeline/parsers.ts +42 -2
- package/src/timeline/patch-apply-command.tsx +135 -0
- package/src/timeline/platform-activity-presentation.ts +166 -0
- package/src/timeline/platform-activity-row.tsx +15 -90
- package/src/timeline/presented-image.ts +63 -0
- package/src/timeline/projection.ts +1746 -76
- package/src/timeline/provider-logo.tsx +53 -0
- package/src/timeline/question-nav-model.ts +28 -0
- package/src/timeline/registry.ts +26 -4
- package/src/timeline/retained-image.ts +97 -0
- package/src/timeline/retained-loaders.ts +91 -0
- package/src/timeline/rolling-activity.tsx +80 -0
- package/src/timeline/screenshot-lightbox.tsx +228 -5
- package/src/timeline/session-usage-limit-row.tsx +42 -0
- package/src/timeline/shared.tsx +42 -15
- package/src/timeline/startup-dispatch-details.tsx +36 -0
- package/src/timeline/startup-preference.ts +33 -0
- package/src/timeline/startup-timings.tsx +145 -0
- package/src/timeline/tool-display-name.ts +19 -7
- package/src/timeline/tool-presentation.ts +1316 -0
- package/src/timeline/tool-renderers.tsx +835 -1138
- package/src/timeline/turn-summary-model.ts +343 -0
- package/src/timeline/turn-summary.tsx +272 -365
- package/src/timeline/types.ts +189 -6
- package/src/timeline/work-presentation.ts +189 -0
- package/src/timeline-model.ts +143 -0
- package/src/usage/allowance-copy.ts +64 -0
- package/src/usage/session-usage-limit.ts +266 -0
- package/src/usage/summary.ts +93 -0
- package/src/usage.ts +70 -0
- package/src/voice-recording-owner.ts +22 -0
- package/styles/compiled.css +2319 -748
- package/styles/connect.css +290 -0
- package/styles/connect.d.ts +1 -0
- package/styles/effective-tokens.css +1 -0
- package/styles/index.css +309 -9
- package/styles/responsive.css +99 -7
- package/styles/session-capability.css +44 -0
- package/styles/tokens.css +134 -66
- package/dist/browser-viewer-AEFHUYZK.js +0 -14
- package/dist/chunk-4MDLEHXL.js.map +0 -1
- package/dist/chunk-5YK2ZDIG.js.map +0 -1
- package/dist/chunk-D3UIAJKY.js.map +0 -1
- package/dist/chunk-ELIYWBZR.js.map +0 -1
- package/dist/chunk-H5YGYNXS.js.map +0 -1
- package/dist/chunk-HQVCKCLG.js +0 -9458
- package/dist/chunk-HQVCKCLG.js.map +0 -1
- package/dist/chunk-HUIKIDM5.js.map +0 -1
- package/dist/chunk-ICA6R6TW.js.map +0 -1
- package/dist/chunk-JVYQRRC4.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-MZ2G2XBA.js.map +0 -1
- package/dist/chunk-NEXLLTP4.js.map +0 -1
- package/dist/chunk-OAM4WAAM.js.map +0 -1
- package/dist/chunk-PEI6RANI.js.map +0 -1
- package/dist/chunk-RGALCTWO.js.map +0 -1
- package/dist/chunk-W6NFJXSA.js +0 -454
- package/dist/chunk-W6NFJXSA.js.map +0 -1
- package/dist/chunk-WSK7G5LE.js +0 -170
- package/dist/chunk-WSK7G5LE.js.map +0 -1
- package/dist/chunk-X4A66EWZ.js +0 -223
- package/dist/chunk-X4A66EWZ.js.map +0 -1
- package/dist/chunk-XXWH2JLC.js.map +0 -1
- package/dist/chunk-YFKJ7VZH.js +0 -268
- package/dist/chunk-YFKJ7VZH.js.map +0 -1
- package/dist/chunk-YJFGAFBD.js.map +0 -1
- package/dist/computer-viewer-FWEZISW4.js +0 -16
- package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
- package/dist/hooks/use-environments.d.ts +0 -41
- package/dist/hooks/use-packs.d.ts +0 -32
- package/dist/platform-activity-row-BJHUHXAT.js.map +0 -1
- package/dist/queue-surface-implementation-BSKUWHRI.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-environments.ts +0 -182
- package/src/hooks/use-packs.ts +0 -157
- /package/dist/{browser-viewer-AEFHUYZK.js.map → browser-viewer-ZWR6MWJ7.js.map} +0 -0
- /package/dist/{computer-viewer-FWEZISW4.js.map → chat-interactive-block-BO2IWXVK.js.map} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ChildSessionLink } from "./child-session-link";
|
|
1
2
|
/**
|
|
2
3
|
* SessionChrome — compact merged session signals above the composer.
|
|
3
4
|
*
|
|
@@ -25,15 +26,30 @@
|
|
|
25
26
|
*
|
|
26
27
|
* Inbox and queue stay separate segments. Queue hover actions wire to
|
|
27
28
|
* `UseTurnQueueResult` (`editTurn` / `steerTurn` / `moveTurn` / `removeTurn`).
|
|
29
|
+
* The collapsed queue chip previews the latest queued message beside its Steer
|
|
30
|
+
* action; open queue rows keep Steer visible and reveal the rest on hover.
|
|
28
31
|
* Inbox has no product dismiss API; pass `onDismissIncoming` when the host
|
|
29
32
|
* wants a visible action (dev harness may use a local dummy).
|
|
30
33
|
*
|
|
34
|
+
* Queue opens by default when chrome is idle and at least one authoritative
|
|
35
|
+
* prompt is queued. Closing the queue dismisses that session's offer until
|
|
36
|
+
* occupancy drains; a different session on the same chrome instance may
|
|
37
|
+
* offer again. An in-flight optimistic Send never opens the drawer —
|
|
38
|
+
* admission stays a paint-only receipt on the chip so layout does not jump
|
|
39
|
+
* under the pointer.
|
|
40
|
+
*
|
|
31
41
|
* Segment switches keep the panel shell mounted and crossfade content. The
|
|
32
42
|
* shell uses one CSS grid-track transition for deliberate open/close actions;
|
|
33
43
|
* live queue reconciliation never feeds measurements back into layout.
|
|
34
44
|
*/
|
|
35
|
-
import type {
|
|
45
|
+
import type {
|
|
46
|
+
SessionGoal,
|
|
47
|
+
SessionPendingInputPreview,
|
|
48
|
+
SessionStatus,
|
|
49
|
+
SessionTurn,
|
|
50
|
+
} from "@opengeni/sdk";
|
|
36
51
|
import {
|
|
52
|
+
ActivityIcon,
|
|
37
53
|
AudioLinesIcon,
|
|
38
54
|
ArrowDownIcon,
|
|
39
55
|
ArrowUpIcon,
|
|
@@ -46,9 +62,11 @@ import {
|
|
|
46
62
|
PencilIcon,
|
|
47
63
|
PlayIcon,
|
|
48
64
|
Trash2Icon,
|
|
65
|
+
TerminalIcon,
|
|
49
66
|
TriangleAlertIcon,
|
|
50
67
|
XIcon,
|
|
51
|
-
|
|
68
|
+
CornerDownRightIcon,
|
|
69
|
+
TargetIcon,
|
|
52
70
|
} from "lucide-react";
|
|
53
71
|
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
|
|
54
72
|
import { useEffect, useId, useMemo, useRef, useState, type ReactNode } from "react";
|
|
@@ -57,11 +75,27 @@ import type { ComposerOptimisticMessage, ComposerState } from "../hooks/use-comp
|
|
|
57
75
|
import type { UseGoalResult } from "../hooks/use-goal";
|
|
58
76
|
import type { UseTurnQueueResult } from "../hooks/use-turn-queue";
|
|
59
77
|
import { cn } from "../lib/cn";
|
|
78
|
+
import { useErrorMessage } from "../lib/error-message";
|
|
60
79
|
import { formatClockTime } from "../lib/format";
|
|
80
|
+
import {
|
|
81
|
+
countAuthoritativeQueuedTurns,
|
|
82
|
+
isAuthoritativeQueuedTurn,
|
|
83
|
+
QUEUE_REPLACE_DRAFT_COPY,
|
|
84
|
+
queuedTurnPresentation,
|
|
85
|
+
queueNeighborAnchors,
|
|
86
|
+
} from "../queue-presentation-model";
|
|
61
87
|
import { requestQueueDraftEdit } from "./queue-draft-policy";
|
|
88
|
+
import { QUEUE_ITEM_CONTENT_UNAVAILABLE, queueItemContent } from "./queue-item-content";
|
|
89
|
+
import { TimelineAnnotationsChip, type TimelineAnnotationLike } from "./timeline-annotations";
|
|
62
90
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./tooltip";
|
|
63
91
|
|
|
64
|
-
export type SessionChromeSignalId =
|
|
92
|
+
export type SessionChromeSignalId =
|
|
93
|
+
| "incoming"
|
|
94
|
+
| "steering"
|
|
95
|
+
| "queue"
|
|
96
|
+
| "goal"
|
|
97
|
+
| "agents"
|
|
98
|
+
| "commands";
|
|
65
99
|
|
|
66
100
|
export type SessionChromeSignalTone = "neutral" | "accent" | "waiting" | "running";
|
|
67
101
|
|
|
@@ -72,12 +106,24 @@ export type SessionChromeAgentsSignal = {
|
|
|
72
106
|
};
|
|
73
107
|
|
|
74
108
|
export type SessionChromeProps = {
|
|
109
|
+
/** Authoritative execution status; omitted by older embedding hosts. */
|
|
110
|
+
sessionStatus?: SessionStatus | undefined;
|
|
75
111
|
queue: UseTurnQueueResult;
|
|
112
|
+
/** Open and focus an existing queued prompt without changing its delivery. */
|
|
113
|
+
queueFocusTarget?: { turnId: string; requestId: number } | undefined;
|
|
76
114
|
/** Needed for queue edit → composer checkout. Omit with `readOnly`. */
|
|
77
115
|
composer?: ComposerState | undefined;
|
|
116
|
+
/** Focus the composer after a successful queue checkout has applied its draft.
|
|
117
|
+
* Connect to the composer controller's `focusInput`, or a custom input ref.
|
|
118
|
+
* Never called for failed checkout or while replacement awaits confirmation.
|
|
119
|
+
*/
|
|
120
|
+
onComposerFocus?: (() => void) | undefined;
|
|
78
121
|
goal?: UseGoalResult | null | undefined;
|
|
79
122
|
/** Expanded agents body (host supplies tree / list). */
|
|
80
123
|
agentsPanel?: ReactNode;
|
|
124
|
+
/** Active commands only. The host mounts the body only when opened. */
|
|
125
|
+
commandsPanel?: ReactNode;
|
|
126
|
+
commandsCount?: number | undefined;
|
|
81
127
|
/** Chip summary; when `count > 0` the agents segment appears. */
|
|
82
128
|
agentsSignal?: SessionChromeAgentsSignal | undefined;
|
|
83
129
|
/**
|
|
@@ -85,6 +131,8 @@ export type SessionChromeProps = {
|
|
|
85
131
|
* (and the gallery) may still pass a handler so the action is visible.
|
|
86
132
|
*/
|
|
87
133
|
onDismissIncoming?: ((inputId: string) => void) | undefined;
|
|
134
|
+
/** Open a typed child update's source through the host's normal authorized route. */
|
|
135
|
+
onOpenSession?: ((sessionId: string) => void) | undefined;
|
|
88
136
|
readOnly?: boolean | undefined;
|
|
89
137
|
className?: string | undefined;
|
|
90
138
|
/** Controlled active segment; omit for uncontrolled. */
|
|
@@ -97,22 +145,19 @@ type GoalPillState =
|
|
|
97
145
|
| "pursuing"
|
|
98
146
|
| "waiting"
|
|
99
147
|
| "scheduled"
|
|
148
|
+
| "session_failed"
|
|
100
149
|
| "blocked"
|
|
101
150
|
| "held"
|
|
102
151
|
| "paused"
|
|
103
152
|
| "invariant_broken"
|
|
104
153
|
| "completed";
|
|
105
154
|
|
|
106
|
-
type QueuedTurnPresentation = {
|
|
107
|
-
kind: "prompt" | "realtime_voice" | "realtime_voice_handoff";
|
|
108
|
-
text: string;
|
|
109
|
-
};
|
|
110
|
-
|
|
111
155
|
const GOAL_LABEL: Record<GoalPillState, string> = {
|
|
112
156
|
pursuing: "Pursuing",
|
|
113
157
|
waiting: "Waiting",
|
|
114
|
-
scheduled: "
|
|
158
|
+
scheduled: "Waiting",
|
|
115
159
|
blocked: "Blocked",
|
|
160
|
+
session_failed: "Blocked by session failure",
|
|
116
161
|
held: "Held",
|
|
117
162
|
paused: "Paused",
|
|
118
163
|
invariant_broken: "Needs attention",
|
|
@@ -121,13 +166,21 @@ const GOAL_LABEL: Record<GoalPillState, string> = {
|
|
|
121
166
|
|
|
122
167
|
/**
|
|
123
168
|
* Short pill suffix per `pausedReason`. `max_auto_continuations` is pacing
|
|
124
|
-
* (new input resumes it); `limits` is
|
|
169
|
+
* (new input resumes it); `limits` is an unspecified legacy admission gate; `user_pause`/`api` is
|
|
125
170
|
* the human's own override; `agent` is the model declaring it is blocked on a
|
|
126
171
|
* human decision. Unknown or legacy reasons keep the bare "Paused".
|
|
127
172
|
*/
|
|
128
173
|
const GOAL_PAUSED_REASON_SUFFIX: Record<string, string> = {
|
|
129
174
|
max_auto_continuations: "cap",
|
|
130
|
-
limits: "
|
|
175
|
+
limits: "limits",
|
|
176
|
+
model_unavailable: "model",
|
|
177
|
+
model_policy: "policy",
|
|
178
|
+
credits: "credits",
|
|
179
|
+
budget: "budget",
|
|
180
|
+
usage_limit: "usage limit",
|
|
181
|
+
usage_policy: "limits",
|
|
182
|
+
allowance: "allowance",
|
|
183
|
+
session_usage_limit: "usage limit",
|
|
131
184
|
user_pause: "manually",
|
|
132
185
|
api: "manually",
|
|
133
186
|
agent: "agent",
|
|
@@ -136,7 +189,16 @@ const GOAL_PAUSED_REASON_SUFFIX: Record<string, string> = {
|
|
|
136
189
|
const GOAL_PAUSED_REASON_EXPLANATION: Record<string, string> = {
|
|
137
190
|
max_auto_continuations:
|
|
138
191
|
"Paused at the automatic continuation cap. New input (a child result, an agent message, or your prompt) resumes it; you can also resume it here.",
|
|
139
|
-
limits: "Paused
|
|
192
|
+
limits: "Paused by an admission limit. Resume when the blocker is resolved.",
|
|
193
|
+
model_unavailable:
|
|
194
|
+
"The selected model is unavailable. Choose an available model before resuming.",
|
|
195
|
+
model_policy: "The selected model is blocked by policy. Choose an allowed model before resuming.",
|
|
196
|
+
credits: "Insufficient Opengeni credits. Add credits before resuming.",
|
|
197
|
+
budget: "Monthly model spending limit reached. Resume when the spending limit allows.",
|
|
198
|
+
usage_limit: "Monthly agent run limit reached. Resume when the run limit allows.",
|
|
199
|
+
usage_policy: "The application's usage policy blocks another run. Resume when it allows.",
|
|
200
|
+
allowance: "Opengeni usage allowance exhausted. Resume when your allowance is available.",
|
|
201
|
+
session_usage_limit: "Paused at the task's usage limit. Raise or remove the limit, then resume.",
|
|
140
202
|
user_pause:
|
|
141
203
|
"Paused manually by a person or an API call. Resume to let the goal continue on its own.",
|
|
142
204
|
api: "Paused manually by a person or an API call. Resume to let the goal continue on its own.",
|
|
@@ -144,6 +206,7 @@ const GOAL_PAUSED_REASON_EXPLANATION: Record<string, string> = {
|
|
|
144
206
|
};
|
|
145
207
|
|
|
146
208
|
type GoalPillRecord = Pick<SessionGoal, "status" | "pausedReason"> & {
|
|
209
|
+
rationale?: SessionGoal["rationale"];
|
|
147
210
|
continuation?: SessionGoal["continuation"] | null | undefined;
|
|
148
211
|
};
|
|
149
212
|
|
|
@@ -159,7 +222,7 @@ export function sessionChromeGoalPillLabel(
|
|
|
159
222
|
|
|
160
223
|
/**
|
|
161
224
|
* One human sentence explaining WHY the goal is not pursuing right now: the
|
|
162
|
-
* pause reason, the agent's own `
|
|
225
|
+
* pause reason, the agent's own `wait_for_input` hold (reason + deadline), or the
|
|
163
226
|
* next idle-backoff check time. Null when the state needs no explanation.
|
|
164
227
|
*/
|
|
165
228
|
export function sessionChromeGoalPillExplanation(
|
|
@@ -167,55 +230,107 @@ export function sessionChromeGoalPillExplanation(
|
|
|
167
230
|
record: GoalPillRecord | null | undefined,
|
|
168
231
|
): string | null {
|
|
169
232
|
const continuation = record?.continuation ?? null;
|
|
233
|
+
if (state === "session_failed") {
|
|
234
|
+
return "Resolve the session failure, then use Continue or send a message to continue this active goal.";
|
|
235
|
+
}
|
|
170
236
|
if (state === "paused") {
|
|
237
|
+
const rationale = record?.rationale?.trim();
|
|
238
|
+
if (rationale) return rationale;
|
|
171
239
|
return record?.pausedReason
|
|
172
240
|
? (GOAL_PAUSED_REASON_EXPLANATION[record.pausedReason] ?? null)
|
|
173
241
|
: null;
|
|
174
242
|
}
|
|
175
|
-
if (state === "scheduled"
|
|
176
|
-
return continuation
|
|
177
|
-
? `
|
|
178
|
-
: "
|
|
243
|
+
if (state === "scheduled") {
|
|
244
|
+
return continuation?.nextAttemptAt
|
|
245
|
+
? `Continues at ${formatClockTime(continuation.nextAttemptAt)}.`
|
|
246
|
+
: "Waiting to continue automatically.";
|
|
247
|
+
}
|
|
248
|
+
if (state === "waiting" && continuation?.reason === "system_work_pending") {
|
|
249
|
+
return "Waiting for other session work to finish before the goal continues automatically.";
|
|
179
250
|
}
|
|
180
251
|
if (state === "held" && continuation?.reason === "held_for_input") {
|
|
181
252
|
const reason = continuation.holdReason?.trim();
|
|
182
253
|
const until = continuation.nextAttemptAt
|
|
183
254
|
? ` until ${formatClockTime(continuation.nextAttemptAt)}`
|
|
184
255
|
: "";
|
|
185
|
-
return `Waiting for input${reason ? `: ${reason}` : ""}${until}.
|
|
256
|
+
return `Waiting for input${reason ? `: ${reason}` : ""}${until}. Relevant session input—including a child result, background-command result, agent message, schedule, or your prompt—wakes it sooner.`;
|
|
186
257
|
}
|
|
187
258
|
return null;
|
|
188
259
|
}
|
|
189
260
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
261
|
+
export { countAuthoritativeQueuedTurns };
|
|
262
|
+
|
|
263
|
+
function isOptimisticQueuedMessage(
|
|
264
|
+
message: ComposerOptimisticMessage,
|
|
265
|
+
queuedTurnIds: ReadonlySet<string>,
|
|
266
|
+
snapshot: UseTurnQueueResult["snapshot"],
|
|
267
|
+
): boolean {
|
|
268
|
+
return (
|
|
269
|
+
message.delivery === "send" &&
|
|
270
|
+
message.destination === "queue" &&
|
|
271
|
+
(!message.turnId || !queuedTurnIds.has(message.turnId)) &&
|
|
272
|
+
!(
|
|
273
|
+
message.turnId &&
|
|
274
|
+
message.appliedQueueVersion !== null &&
|
|
275
|
+
message.appliedQueueVersion !== undefined &&
|
|
276
|
+
snapshot &&
|
|
277
|
+
snapshot.version >= message.appliedQueueVersion
|
|
278
|
+
)
|
|
279
|
+
);
|
|
200
280
|
}
|
|
201
281
|
|
|
202
|
-
function
|
|
203
|
-
|
|
282
|
+
export function countOptimisticQueuedMessages(
|
|
283
|
+
messages: readonly ComposerOptimisticMessage[] | undefined,
|
|
284
|
+
queuedTurnIds: ReadonlySet<string>,
|
|
285
|
+
snapshot: UseTurnQueueResult["snapshot"],
|
|
286
|
+
): number {
|
|
287
|
+
return (messages ?? []).filter((message) =>
|
|
288
|
+
isOptimisticQueuedMessage(message, queuedTurnIds, snapshot),
|
|
289
|
+
).length;
|
|
204
290
|
}
|
|
205
291
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
292
|
+
/**
|
|
293
|
+
* First uncontrolled segment. An existing authoritative queue opens itself
|
|
294
|
+
* when the host did not pick another default; optimistic-only occupancy
|
|
295
|
+
* stays collapsed so a live Send does not shove a drawer under the pointer.
|
|
296
|
+
*/
|
|
297
|
+
export function sessionChromeInitialActive(input: {
|
|
298
|
+
defaultActive: SessionChromeSignalId | null;
|
|
299
|
+
authoritativeQueuedCount: number;
|
|
300
|
+
}): SessionChromeSignalId | null {
|
|
301
|
+
if (input.defaultActive != null) return input.defaultActive;
|
|
302
|
+
return input.authoritativeQueuedCount >= 1 ? "queue" : null;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Whether idle chrome should offer the queue panel. A dismissed session
|
|
307
|
+
* stays collapsed until occupancy drains. Controlled hosts own this.
|
|
308
|
+
*/
|
|
309
|
+
export function sessionChromeShouldOfferQueue(input: {
|
|
310
|
+
controlled: boolean;
|
|
311
|
+
active: SessionChromeSignalId | null;
|
|
312
|
+
activityOpen: boolean;
|
|
313
|
+
authoritativeQueuedCount: number;
|
|
314
|
+
suppressed: boolean;
|
|
315
|
+
}): boolean {
|
|
316
|
+
return (
|
|
317
|
+
!input.controlled &&
|
|
318
|
+
input.active === null &&
|
|
319
|
+
!input.activityOpen &&
|
|
320
|
+
input.authoritativeQueuedCount >= 1 &&
|
|
321
|
+
!input.suppressed
|
|
322
|
+
);
|
|
210
323
|
}
|
|
211
324
|
|
|
212
325
|
/** Select pill state from the goal's authoritative continuation projection. */
|
|
213
326
|
export function sessionChromeGoalPillState(
|
|
214
327
|
goalStatus: "active" | "paused" | "completed",
|
|
215
328
|
continuation: SessionGoal["continuation"] | null | undefined,
|
|
329
|
+
sessionStatus?: SessionStatus,
|
|
216
330
|
): GoalPillState {
|
|
217
331
|
if (goalStatus === "completed") return "completed";
|
|
218
332
|
if (goalStatus === "paused") return "paused";
|
|
333
|
+
if (sessionStatus === "failed") return "session_failed";
|
|
219
334
|
if (!continuation) return "invariant_broken";
|
|
220
335
|
if (continuation.state === "running") {
|
|
221
336
|
return continuation.reason === "goal_turn_running"
|
|
@@ -228,7 +343,13 @@ export function sessionChromeGoalPillState(
|
|
|
228
343
|
// next evaluation at `nextAttemptAt`) is an ordinary scheduled state.
|
|
229
344
|
if (continuation.state === "scheduled") return "scheduled";
|
|
230
345
|
if (continuation.state === "blocked") {
|
|
231
|
-
|
|
346
|
+
if (
|
|
347
|
+
continuation.reason === "human_turn_running" ||
|
|
348
|
+
continuation.reason === "system_work_pending"
|
|
349
|
+
) {
|
|
350
|
+
return "waiting";
|
|
351
|
+
}
|
|
352
|
+
// `held_for_input` is the agent's own wait_for_input hold (waiting for child
|
|
232
353
|
// results / external input until a deadline); it shares the Held pill.
|
|
233
354
|
return continuation.reason === "workstream_paused" || continuation.reason === "held_for_input"
|
|
234
355
|
? "held"
|
|
@@ -288,6 +409,12 @@ function pendingKindLabel(kind: SessionPendingInputPreview["kind"]): string {
|
|
|
288
409
|
return "Goal wake";
|
|
289
410
|
case "agent_message":
|
|
290
411
|
return "Update";
|
|
412
|
+
case "background_command_result":
|
|
413
|
+
return "Command result";
|
|
414
|
+
case "session_wait_timeout":
|
|
415
|
+
return "Wait ended";
|
|
416
|
+
case "media_generation_result":
|
|
417
|
+
return "Video result";
|
|
291
418
|
default:
|
|
292
419
|
return "Incoming";
|
|
293
420
|
}
|
|
@@ -307,18 +434,28 @@ function toneClass(tone: SessionChromeSignalTone, selected: boolean): string {
|
|
|
307
434
|
}
|
|
308
435
|
|
|
309
436
|
export function SessionChrome({
|
|
437
|
+
sessionStatus,
|
|
310
438
|
queue,
|
|
439
|
+
queueFocusTarget,
|
|
311
440
|
composer,
|
|
441
|
+
onComposerFocus,
|
|
312
442
|
goal,
|
|
313
443
|
agentsPanel,
|
|
444
|
+
commandsPanel,
|
|
445
|
+
commandsCount = 0,
|
|
314
446
|
agentsSignal,
|
|
315
447
|
onDismissIncoming,
|
|
448
|
+
onOpenSession,
|
|
316
449
|
readOnly = false,
|
|
317
450
|
className,
|
|
318
451
|
active: activeControlled,
|
|
319
452
|
defaultActive = null,
|
|
320
453
|
onActiveChange,
|
|
321
454
|
}: SessionChromeProps) {
|
|
455
|
+
const formatError = useErrorMessage();
|
|
456
|
+
const [activityRequested, setActivityOpen] = useState(
|
|
457
|
+
Boolean(defaultActive && ["incoming", "agents", "commands"].includes(defaultActive)),
|
|
458
|
+
);
|
|
322
459
|
const reactId = useId();
|
|
323
460
|
const panelId = `og-session-chrome-panel-${reactId}`;
|
|
324
461
|
const reduceMotion = useReducedMotion();
|
|
@@ -327,24 +464,14 @@ export function SessionChrome({
|
|
|
327
464
|
const turns = queue.queue;
|
|
328
465
|
const queueMutationFor = queue.mutationFor;
|
|
329
466
|
const queuedTurns = useMemo(
|
|
330
|
-
() => turns.filter((turn) =>
|
|
467
|
+
() => turns.filter((turn) => isAuthoritativeQueuedTurn(turn, queueMutationFor)),
|
|
331
468
|
[queueMutationFor, turns],
|
|
332
469
|
);
|
|
333
470
|
const queuedTurnIds = useMemo(() => new Set(queuedTurns.map((turn) => turn.id)), [queuedTurns]);
|
|
334
471
|
const optimisticQueued = useMemo(
|
|
335
472
|
() =>
|
|
336
|
-
(composer?.optimisticMessages ?? []).filter(
|
|
337
|
-
(message)
|
|
338
|
-
message.delivery === "send" &&
|
|
339
|
-
message.destination === "queue" &&
|
|
340
|
-
(!message.turnId || !queuedTurnIds.has(message.turnId)) &&
|
|
341
|
-
!(
|
|
342
|
-
message.turnId &&
|
|
343
|
-
message.appliedQueueVersion !== null &&
|
|
344
|
-
message.appliedQueueVersion !== undefined &&
|
|
345
|
-
queue.snapshot &&
|
|
346
|
-
queue.snapshot.version >= message.appliedQueueVersion
|
|
347
|
-
),
|
|
473
|
+
(composer?.optimisticMessages ?? []).filter((message) =>
|
|
474
|
+
isOptimisticQueuedMessage(message, queuedTurnIds, queue.snapshot),
|
|
348
475
|
),
|
|
349
476
|
[composer?.optimisticMessages, queue.snapshot, queuedTurnIds],
|
|
350
477
|
);
|
|
@@ -358,14 +485,84 @@ export function SessionChrome({
|
|
|
358
485
|
const stopping = stoppingKind !== null;
|
|
359
486
|
const canMutateQueue = !readOnly && composer !== undefined;
|
|
360
487
|
|
|
361
|
-
const
|
|
362
|
-
const
|
|
363
|
-
record
|
|
364
|
-
|
|
365
|
-
|
|
488
|
+
const elapsed = useLiveElapsed(record?.createdAt, Boolean(record));
|
|
489
|
+
const goalState = record
|
|
490
|
+
? sessionChromeGoalPillState(record.status, record.continuation, sessionStatus)
|
|
491
|
+
: null;
|
|
492
|
+
|
|
493
|
+
const initialAuthoritativeQueuedCount = countAuthoritativeQueuedTurns(
|
|
494
|
+
queue.queue,
|
|
495
|
+
queue.mutationFor,
|
|
496
|
+
);
|
|
497
|
+
const [activeUncontrolled, setActiveUncontrolled] = useState<SessionChromeSignalId | null>(() =>
|
|
498
|
+
sessionChromeInitialActive({
|
|
499
|
+
defaultActive,
|
|
500
|
+
authoritativeQueuedCount: initialAuthoritativeQueuedCount,
|
|
501
|
+
}),
|
|
502
|
+
);
|
|
503
|
+
const active = activeControlled !== undefined ? activeControlled : activeUncontrolled;
|
|
504
|
+
const rootRef = useRef<HTMLDivElement>(null);
|
|
505
|
+
const openedQueueTargetRef = useRef<string | null>(null);
|
|
506
|
+
const focusedQueueTargetRef = useRef<string | null>(null);
|
|
507
|
+
const queueTargetKey = queueFocusTarget
|
|
508
|
+
? `${queueFocusTarget.turnId}:${queueFocusTarget.requestId}`
|
|
509
|
+
: null;
|
|
510
|
+
useEffect(() => {
|
|
511
|
+
if (!queueTargetKey || openedQueueTargetRef.current === queueTargetKey) return;
|
|
512
|
+
openedQueueTargetRef.current = queueTargetKey;
|
|
513
|
+
if (activeControlled === undefined) setActiveUncontrolled("queue");
|
|
514
|
+
onActiveChange?.("queue");
|
|
515
|
+
}, [queueTargetKey, activeControlled, onActiveChange]);
|
|
516
|
+
useEffect(() => {
|
|
517
|
+
if (!queueFocusTarget || active !== "queue" || focusedQueueTargetRef.current === queueTargetKey)
|
|
518
|
+
return;
|
|
519
|
+
const root = rootRef.current;
|
|
520
|
+
if (!root) return;
|
|
521
|
+
const focus = () => {
|
|
522
|
+
const row = Array.from(root.querySelectorAll<HTMLElement>("[data-queue-turn-id]")).find(
|
|
523
|
+
(element) => element.dataset.queueTurnId === queueFocusTarget.turnId,
|
|
524
|
+
);
|
|
525
|
+
if (!row) return false;
|
|
526
|
+
focusedQueueTargetRef.current = queueTargetKey;
|
|
527
|
+
row.focus({ preventScroll: true });
|
|
528
|
+
row.scrollIntoView?.({ block: "nearest" });
|
|
529
|
+
return true;
|
|
530
|
+
};
|
|
531
|
+
if (focus()) return;
|
|
532
|
+
const observer = new MutationObserver(() => {
|
|
533
|
+
if (focus()) observer.disconnect();
|
|
534
|
+
});
|
|
535
|
+
observer.observe(root, { childList: true, subtree: true });
|
|
536
|
+
return () => observer.disconnect();
|
|
537
|
+
}, [queueFocusTarget, queueTargetKey, active, queuedTurns]);
|
|
538
|
+
const activityOpen =
|
|
539
|
+
activityRequested || Boolean(active && ["incoming", "agents", "commands"].includes(active));
|
|
540
|
+
const activityVisibleRef = useRef(activityOpen);
|
|
541
|
+
activityVisibleRef.current = activityOpen;
|
|
542
|
+
// Two independent suppressions, both occupancy-scoped:
|
|
543
|
+
// - admission: a live Send while idle must not open a drawer under the pointer
|
|
544
|
+
// - dismiss: closing the queue remembers that session until occupancy drains
|
|
545
|
+
const queueOfferAdmissionSuppressedRef = useRef(
|
|
546
|
+
defaultActive == null &&
|
|
547
|
+
initialAuthoritativeQueuedCount === 0 &&
|
|
548
|
+
countOptimisticQueuedMessages(composer?.optimisticMessages, queuedTurnIds, queue.snapshot) >
|
|
549
|
+
0,
|
|
366
550
|
);
|
|
367
|
-
const
|
|
551
|
+
const queueOfferDismissedSessionIdsRef = useRef<Set<string>>(new Set());
|
|
552
|
+
const occupancySessionId = queuedTurns[0]?.sessionId ?? null;
|
|
553
|
+
const setActive = (next: SessionChromeSignalId | null) => {
|
|
554
|
+
if (active === "queue" && next === null) {
|
|
555
|
+
if (occupancySessionId) {
|
|
556
|
+
queueOfferDismissedSessionIdsRef.current.add(occupancySessionId);
|
|
557
|
+
} else {
|
|
558
|
+
queueOfferAdmissionSuppressedRef.current = true;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
if (activeControlled === undefined) setActiveUncontrolled(next);
|
|
562
|
+
onActiveChange?.(next);
|
|
563
|
+
};
|
|
368
564
|
|
|
565
|
+
const hasCommandsPanel = commandsPanel != null;
|
|
369
566
|
const signals = useMemo(() => {
|
|
370
567
|
const rows: Array<{
|
|
371
568
|
id: SessionChromeSignalId;
|
|
@@ -437,6 +634,7 @@ export function SessionChrome({
|
|
|
437
634
|
const waiting =
|
|
438
635
|
goalState === "waiting" ||
|
|
439
636
|
goalState === "blocked" ||
|
|
637
|
+
goalState === "session_failed" ||
|
|
440
638
|
goalState === "held" ||
|
|
441
639
|
goalState === "paused";
|
|
442
640
|
const explanation = sessionChromeGoalPillExplanation(goalState, record);
|
|
@@ -450,16 +648,7 @@ export function SessionChrome({
|
|
|
450
648
|
: goalState === "pursuing" || goalState === "scheduled"
|
|
451
649
|
? "accent"
|
|
452
650
|
: "neutral",
|
|
453
|
-
icon:
|
|
454
|
-
goalState === "blocked" || goalState === "invariant_broken" ? (
|
|
455
|
-
<TriangleAlertIcon className="size-3" />
|
|
456
|
-
) : goalState === "waiting" ? (
|
|
457
|
-
<Loader2Icon className="size-3 animate-og-spin" />
|
|
458
|
-
) : goalState === "paused" || goalState === "held" ? (
|
|
459
|
-
<PauseIcon className="size-3" />
|
|
460
|
-
) : (
|
|
461
|
-
<ZapIcon className="size-3" />
|
|
462
|
-
),
|
|
651
|
+
icon: <TargetIcon className="size-3" />,
|
|
463
652
|
});
|
|
464
653
|
}
|
|
465
654
|
if (agentsSignal && agentsSignal.count > 0) {
|
|
@@ -472,8 +661,22 @@ export function SessionChrome({
|
|
|
472
661
|
icon: <BotIcon className="size-3" />,
|
|
473
662
|
});
|
|
474
663
|
}
|
|
664
|
+
if (commandsCount > 0 || (active === "commands" && hasCommandsPanel)) {
|
|
665
|
+
rows.push({
|
|
666
|
+
id: "commands",
|
|
667
|
+
label:
|
|
668
|
+
commandsCount > 0
|
|
669
|
+
? `${commandsCount} command${commandsCount === 1 ? "" : "s"}`
|
|
670
|
+
: "Commands",
|
|
671
|
+
tone: commandsCount > 0 ? "running" : "neutral",
|
|
672
|
+
icon: <TerminalIcon className="size-3" />,
|
|
673
|
+
});
|
|
674
|
+
}
|
|
475
675
|
return rows;
|
|
476
676
|
}, [
|
|
677
|
+
commandsCount,
|
|
678
|
+
hasCommandsPanel,
|
|
679
|
+
active,
|
|
477
680
|
agentsSignal,
|
|
478
681
|
elapsed,
|
|
479
682
|
goalState,
|
|
@@ -485,14 +688,6 @@ export function SessionChrome({
|
|
|
485
688
|
record,
|
|
486
689
|
]);
|
|
487
690
|
|
|
488
|
-
const [activeUncontrolled, setActiveUncontrolled] = useState<SessionChromeSignalId | null>(
|
|
489
|
-
defaultActive,
|
|
490
|
-
);
|
|
491
|
-
const active = activeControlled !== undefined ? activeControlled : activeUncontrolled;
|
|
492
|
-
const setActive = (next: SessionChromeSignalId | null) => {
|
|
493
|
-
if (activeControlled === undefined) setActiveUncontrolled(next);
|
|
494
|
-
onActiveChange?.(next);
|
|
495
|
-
};
|
|
496
691
|
const optimisticQueueKeys = optimisticQueued.map((message) => message.clientEventId).join(",");
|
|
497
692
|
const previousOptimisticQueueKeys = useRef(optimisticQueueKeys);
|
|
498
693
|
const [queueArrivalNonce, setQueueArrivalNonce] = useState(0);
|
|
@@ -505,7 +700,45 @@ export function SessionChrome({
|
|
|
505
700
|
// the pointer. A stable, paint-only receipt on the queue chip communicates
|
|
506
701
|
// destination without participating in layout.
|
|
507
702
|
setQueueArrivalNonce((current) => current + 1);
|
|
508
|
-
|
|
703
|
+
if (activeControlled === undefined && active === null) {
|
|
704
|
+
queueOfferAdmissionSuppressedRef.current = true;
|
|
705
|
+
}
|
|
706
|
+
}, [active, activeControlled, optimisticQueueKeys, optimisticQueued]);
|
|
707
|
+
const queueOccupied = queuedTurns.length > 0 || optimisticQueued.length > 0;
|
|
708
|
+
useEffect(() => {
|
|
709
|
+
if (queueOccupied) return;
|
|
710
|
+
// A later wave may offer again. A prior session's dismiss must not stick
|
|
711
|
+
// after this instance has actually gone empty.
|
|
712
|
+
queueOfferAdmissionSuppressedRef.current = false;
|
|
713
|
+
queueOfferDismissedSessionIdsRef.current.clear();
|
|
714
|
+
}, [queueOccupied]);
|
|
715
|
+
const queueOfferSuppressed =
|
|
716
|
+
queueOfferAdmissionSuppressedRef.current ||
|
|
717
|
+
(occupancySessionId != null &&
|
|
718
|
+
queueOfferDismissedSessionIdsRef.current.has(occupancySessionId));
|
|
719
|
+
useEffect(() => {
|
|
720
|
+
if (
|
|
721
|
+
!sessionChromeShouldOfferQueue({
|
|
722
|
+
controlled: activeControlled !== undefined,
|
|
723
|
+
active,
|
|
724
|
+
activityOpen,
|
|
725
|
+
authoritativeQueuedCount: queuedTurns.length,
|
|
726
|
+
suppressed: queueOfferSuppressed,
|
|
727
|
+
})
|
|
728
|
+
) {
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
if (activeControlled === undefined) setActiveUncontrolled("queue");
|
|
732
|
+
onActiveChange?.("queue");
|
|
733
|
+
}, [
|
|
734
|
+
active,
|
|
735
|
+
activeControlled,
|
|
736
|
+
activityOpen,
|
|
737
|
+
occupancySessionId,
|
|
738
|
+
onActiveChange,
|
|
739
|
+
queueOfferSuppressed,
|
|
740
|
+
queuedTurns.length,
|
|
741
|
+
]);
|
|
509
742
|
const [replaceDraftFor, setReplaceDraftFor] = useState<string | null>(null);
|
|
510
743
|
|
|
511
744
|
const chipRefs = useRef<Partial<Record<SessionChromeSignalId, HTMLButtonElement | null>>>({});
|
|
@@ -513,6 +746,10 @@ export function SessionChrome({
|
|
|
513
746
|
const [pill, setPill] = useState({ left: 0, top: 0, width: 0, height: 0, opacity: 0 });
|
|
514
747
|
|
|
515
748
|
const signalIds = signals.map((signal) => signal.id).join(",");
|
|
749
|
+
useEffect(() => {
|
|
750
|
+
if (!signals.some((signal) => ["incoming", "agents", "commands"].includes(signal.id)))
|
|
751
|
+
setActivityOpen(false);
|
|
752
|
+
}, [signals]);
|
|
516
753
|
useEffect(() => {
|
|
517
754
|
if (active && !signalIds.split(",").includes(active)) {
|
|
518
755
|
if (activeControlled === undefined) setActiveUncontrolled(null);
|
|
@@ -535,7 +772,10 @@ export function SessionChrome({
|
|
|
535
772
|
return;
|
|
536
773
|
}
|
|
537
774
|
const chip = chipRefs.current[active];
|
|
538
|
-
if (!chip)
|
|
775
|
+
if (!chip) {
|
|
776
|
+
setPill((prev) => ({ ...prev, opacity: 0 }));
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
539
779
|
// Measure against the chip's own box so a wrapped multi-row rail never
|
|
540
780
|
// stretches the highlight into a tall stripe across every signal.
|
|
541
781
|
const railBox = rail.getBoundingClientRect();
|
|
@@ -563,6 +803,22 @@ export function SessionChrome({
|
|
|
563
803
|
}, [active, signals]);
|
|
564
804
|
|
|
565
805
|
const open = active !== null;
|
|
806
|
+
// Collapsed queue chip shows the latest queued message so a Send that lands
|
|
807
|
+
// in the queue is visible without opening the list; Steer acts on that
|
|
808
|
+
// message once the server has confirmed it.
|
|
809
|
+
const latestOptimisticQueued = optimisticQueued[optimisticQueued.length - 1];
|
|
810
|
+
const latestQueuedTurn = queuedTurns[queuedTurns.length - 1];
|
|
811
|
+
const queuePeek: { text: string | null; turnId: string | null } | null =
|
|
812
|
+
queue.error || queue.mutationError
|
|
813
|
+
? null
|
|
814
|
+
: latestOptimisticQueued
|
|
815
|
+
? { text: latestOptimisticQueued.text.trim() || null, turnId: null }
|
|
816
|
+
: latestQueuedTurn
|
|
817
|
+
? {
|
|
818
|
+
text: queuedTurnPresentation(latestQueuedTurn).text.trim() || null,
|
|
819
|
+
turnId: latestQueuedTurn.id,
|
|
820
|
+
}
|
|
821
|
+
: null;
|
|
566
822
|
|
|
567
823
|
if (signals.length === 0 && !stopping) return null;
|
|
568
824
|
|
|
@@ -572,7 +828,11 @@ export function SessionChrome({
|
|
|
572
828
|
|
|
573
829
|
const panelBody =
|
|
574
830
|
active === "incoming" ? (
|
|
575
|
-
<IncomingPanel
|
|
831
|
+
<IncomingPanel
|
|
832
|
+
inputs={incoming}
|
|
833
|
+
onDismiss={onDismissIncoming}
|
|
834
|
+
onOpenSession={onOpenSession}
|
|
835
|
+
/>
|
|
576
836
|
) : active === "queue" ? (
|
|
577
837
|
<QueuePanel
|
|
578
838
|
turns={queuedTurns}
|
|
@@ -582,6 +842,7 @@ export function SessionChrome({
|
|
|
582
842
|
onRefresh={queue.refresh}
|
|
583
843
|
onClearMutationError={queue.clearMutationError}
|
|
584
844
|
onRetryOptimistic={composer?.retryOptimisticMessage}
|
|
845
|
+
onRestoreOptimistic={composer?.restoreOptimisticMessage}
|
|
585
846
|
onRemoveOptimistic={composer?.removeOptimisticMessage}
|
|
586
847
|
readOnly={!canMutateQueue}
|
|
587
848
|
mutationFor={queue.mutationFor}
|
|
@@ -597,7 +858,10 @@ export function SessionChrome({
|
|
|
597
858
|
expectedDraftRevision: composer.draftRevision,
|
|
598
859
|
replaceDraft: true,
|
|
599
860
|
});
|
|
600
|
-
if (checkedOut)
|
|
861
|
+
if (checkedOut) {
|
|
862
|
+
composer.applyDraft(checkedOut);
|
|
863
|
+
onComposerFocus?.();
|
|
864
|
+
}
|
|
601
865
|
})();
|
|
602
866
|
}
|
|
603
867
|
: undefined
|
|
@@ -614,7 +878,10 @@ export function SessionChrome({
|
|
|
614
878
|
expectedDraftRevision: composer.draftRevision,
|
|
615
879
|
replaceDraft: false,
|
|
616
880
|
});
|
|
617
|
-
if (checkedOut)
|
|
881
|
+
if (checkedOut) {
|
|
882
|
+
composer.applyDraft(checkedOut);
|
|
883
|
+
onComposerFocus?.();
|
|
884
|
+
}
|
|
618
885
|
})();
|
|
619
886
|
},
|
|
620
887
|
);
|
|
@@ -645,6 +912,8 @@ export function SessionChrome({
|
|
|
645
912
|
/>
|
|
646
913
|
) : active === "goal" && record && goalState && goal ? (
|
|
647
914
|
<GoalPanel goal={goal} state={goalState} elapsed={elapsed} readOnly={readOnly} />
|
|
915
|
+
) : active === "commands" ? (
|
|
916
|
+
<div data-og-session-chrome-panel="commands">{commandsPanel}</div>
|
|
648
917
|
) : active === "agents" ? (
|
|
649
918
|
<div data-og-session-chrome-panel="agents">
|
|
650
919
|
{agentsPanel ?? <p className="text-og-xs text-og-fg-muted">No agent details.</p>}
|
|
@@ -656,6 +925,7 @@ export function SessionChrome({
|
|
|
656
925
|
<div
|
|
657
926
|
className={cn("og-session-chrome og-root w-full", className)}
|
|
658
927
|
data-testid="session-chrome"
|
|
928
|
+
ref={rootRef}
|
|
659
929
|
data-og-session-chrome=""
|
|
660
930
|
data-og-session-chrome-open={open ? "true" : "false"}
|
|
661
931
|
>
|
|
@@ -666,15 +936,9 @@ export function SessionChrome({
|
|
|
666
936
|
)}
|
|
667
937
|
style={{
|
|
668
938
|
borderRadius: "var(--_og-session-chrome-radius)",
|
|
669
|
-
background:
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
borderColor: open
|
|
673
|
-
? "var(--_og-session-chrome-border-open)"
|
|
674
|
-
: "var(--_og-session-chrome-border)",
|
|
675
|
-
boxShadow: open
|
|
676
|
-
? "var(--og-session-chrome-shadow-open)"
|
|
677
|
-
: "var(--og-session-chrome-shadow)",
|
|
939
|
+
background: "transparent",
|
|
940
|
+
borderColor: "transparent",
|
|
941
|
+
boxShadow: "none",
|
|
678
942
|
transitionDuration: "var(--og-session-chrome-duration)",
|
|
679
943
|
transitionTimingFunction: "var(--_og-session-chrome-ease)",
|
|
680
944
|
}}
|
|
@@ -690,9 +954,9 @@ export function SessionChrome({
|
|
|
690
954
|
>
|
|
691
955
|
<div
|
|
692
956
|
ref={railRef}
|
|
693
|
-
className="relative flex flex-
|
|
957
|
+
className="relative flex flex-nowrap items-center"
|
|
694
958
|
style={{
|
|
695
|
-
gap: "
|
|
959
|
+
gap: "10px",
|
|
696
960
|
}}
|
|
697
961
|
>
|
|
698
962
|
<motion.div
|
|
@@ -712,71 +976,213 @@ export function SessionChrome({
|
|
|
712
976
|
}}
|
|
713
977
|
transition={{ duration: shellDuration, ease }}
|
|
714
978
|
/>
|
|
715
|
-
{signals
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
979
|
+
{signals
|
|
980
|
+
.filter((signal) => !["incoming", "agents", "commands"].includes(signal.id))
|
|
981
|
+
.map((signal) => {
|
|
982
|
+
const selected = active === signal.id;
|
|
983
|
+
return (
|
|
984
|
+
<div
|
|
985
|
+
key={signal.id}
|
|
986
|
+
role="group"
|
|
987
|
+
aria-label={
|
|
988
|
+
signal.id === "queue"
|
|
989
|
+
? "Queued messages and actions"
|
|
990
|
+
: signal.id === "goal"
|
|
991
|
+
? "Goal and actions"
|
|
992
|
+
: signal.label
|
|
993
|
+
}
|
|
994
|
+
className={cn(
|
|
995
|
+
"group/signal relative z-[1] inline-flex min-w-0 max-w-full items-center rounded-og-md",
|
|
996
|
+
"bg-og-surface-2/60 px-0.5",
|
|
997
|
+
selected && "bg-og-surface-3",
|
|
998
|
+
)}
|
|
999
|
+
>
|
|
1000
|
+
<button
|
|
1001
|
+
type="button"
|
|
1002
|
+
ref={(node) => {
|
|
1003
|
+
chipRefs.current[signal.id] = node;
|
|
1004
|
+
}}
|
|
1005
|
+
aria-expanded={selected}
|
|
1006
|
+
aria-controls={panelId}
|
|
1007
|
+
aria-label={
|
|
1008
|
+
signal.id === "goal"
|
|
1009
|
+
? `Goal · ${goalState === "pursuing" ? "Running" : signal.label}`
|
|
1010
|
+
: selected
|
|
1011
|
+
? `Close ${signal.label}`
|
|
1012
|
+
: undefined
|
|
1013
|
+
}
|
|
1014
|
+
data-testid={`session-chrome-${signal.id}`}
|
|
1015
|
+
data-og-session-chrome-signal={signal.id}
|
|
1016
|
+
title={signal.title ?? signal.label}
|
|
1017
|
+
onClick={() => {
|
|
1018
|
+
setActivityOpen(false);
|
|
1019
|
+
setActive(selected ? null : signal.id);
|
|
1020
|
+
}}
|
|
1021
|
+
className={cn(
|
|
1022
|
+
"group relative z-[1] inline-flex min-w-0 min-h-[var(--og-session-chrome-chip-min-height)] max-w-full items-center gap-1 rounded-og-md py-1 text-left text-og-xs outline-hidden",
|
|
1023
|
+
// Coarse pointers keep a 44px target (session-pins acceptance).
|
|
1024
|
+
"pointer-coarse:min-h-11",
|
|
1025
|
+
"transition-colors duration-150 motion-reduce:transition-none",
|
|
1026
|
+
"hover:text-og-fg focus-visible:bg-og-surface-3/50",
|
|
1027
|
+
selected ? "text-og-fg" : "text-og-fg-muted",
|
|
1028
|
+
)}
|
|
1029
|
+
style={{
|
|
1030
|
+
paddingInline: "var(--og-session-chrome-chip-pad-x)",
|
|
1031
|
+
}}
|
|
1032
|
+
>
|
|
1033
|
+
{signal.id === "queue" && queueArrivalNonce > 0 && !reduceMotion ? (
|
|
1034
|
+
<motion.span
|
|
1035
|
+
key={queueArrivalNonce}
|
|
1036
|
+
aria-hidden="true"
|
|
1037
|
+
data-testid="session-chrome-queue-arrival"
|
|
1038
|
+
className="pointer-events-none absolute inset-0 rounded-og-md bg-og-accent-soft"
|
|
1039
|
+
initial={{ opacity: 0 }}
|
|
1040
|
+
animate={{ opacity: [0, 0.38, 0] }}
|
|
1041
|
+
transition={{ duration: 0.72, times: [0, 0.18, 1], ease }}
|
|
1042
|
+
/>
|
|
1043
|
+
) : null}
|
|
1044
|
+
<span className={cn("shrink-0", toneClass(signal.tone, selected))}>
|
|
1045
|
+
{signal.icon}
|
|
762
1046
|
</span>
|
|
763
|
-
<span
|
|
764
|
-
{
|
|
1047
|
+
<span
|
|
1048
|
+
className={cn(
|
|
1049
|
+
"font-medium text-og-fg",
|
|
1050
|
+
signal.id === "queue" && queuePeek?.text && !selected
|
|
1051
|
+
? "shrink-0"
|
|
1052
|
+
: "min-w-0 truncate",
|
|
1053
|
+
)}
|
|
1054
|
+
>
|
|
1055
|
+
{signal.id === "goal" ? "Goal · " : null}
|
|
1056
|
+
{signal.id === "goal"
|
|
1057
|
+
? goalState === "pursuing"
|
|
1058
|
+
? "Running"
|
|
1059
|
+
: signal.label
|
|
1060
|
+
: signal.id === "queue"
|
|
1061
|
+
? queue.error || queue.mutationError
|
|
1062
|
+
? signal.label
|
|
1063
|
+
: `${queuedTurns.length + optimisticQueued.length} queued`
|
|
1064
|
+
: signal.label}
|
|
765
1065
|
</span>
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
1066
|
+
{signal.id === "queue" && queuePeek?.text && !selected ? (
|
|
1067
|
+
<AnimatePresence initial={false} mode="popLayout">
|
|
1068
|
+
<motion.span
|
|
1069
|
+
key={queuePeek.text}
|
|
1070
|
+
data-testid="session-chrome-queue-peek"
|
|
1071
|
+
className="min-w-0 max-w-[min(24rem,60vw)] truncate text-og-fg-muted"
|
|
1072
|
+
initial={reduceMotion ? false : { opacity: 0, y: 3 }}
|
|
1073
|
+
animate={{ opacity: 1, y: 0 }}
|
|
1074
|
+
exit={{ opacity: 0, transition: { duration: crossfadeDuration } }}
|
|
1075
|
+
transition={{ duration: crossfadeDuration, ease }}
|
|
1076
|
+
>
|
|
1077
|
+
{queuePeek.text}
|
|
1078
|
+
</motion.span>
|
|
1079
|
+
</AnimatePresence>
|
|
1080
|
+
) : null}
|
|
1081
|
+
</button>
|
|
1082
|
+
{signal.id === "goal" && goal && record && !readOnly ? (
|
|
1083
|
+
<div className="flex shrink-0 items-center pr-1 pl-0.5">
|
|
1084
|
+
{record.status === "active" || record.status === "paused" ? (
|
|
1085
|
+
<IconAction
|
|
1086
|
+
label={record.status === "paused" ? "Resume goal" : "Pause goal"}
|
|
1087
|
+
tip={record.status === "paused" ? "Resume goal" : "Pause goal"}
|
|
1088
|
+
disabled={goal.updating}
|
|
1089
|
+
onClick={() =>
|
|
1090
|
+
void (record.status === "paused"
|
|
1091
|
+
? goal.resume()
|
|
1092
|
+
: goal.pause("Paused from session chrome"))
|
|
1093
|
+
}
|
|
1094
|
+
>
|
|
1095
|
+
{goal.updating ? (
|
|
1096
|
+
<Loader2Icon className="size-3 animate-og-spin" />
|
|
1097
|
+
) : record.status === "paused" ? (
|
|
1098
|
+
<PlayIcon className="size-3" />
|
|
1099
|
+
) : (
|
|
1100
|
+
<PauseIcon className="size-3" />
|
|
1101
|
+
)}
|
|
1102
|
+
</IconAction>
|
|
1103
|
+
) : null}
|
|
1104
|
+
<IconAction
|
|
1105
|
+
label="Clear goal"
|
|
1106
|
+
tip="Clear goal"
|
|
1107
|
+
danger
|
|
1108
|
+
disabled={goal.updating}
|
|
1109
|
+
onClick={() => void goal.deleteGoal()}
|
|
1110
|
+
>
|
|
1111
|
+
<Trash2Icon className="size-3" />
|
|
1112
|
+
</IconAction>
|
|
1113
|
+
</div>
|
|
1114
|
+
) : signal.id === "queue" && canMutateQueue && queuePeek && !selected ? (
|
|
1115
|
+
<div className="flex shrink-0 items-center pr-1 pl-0.5">
|
|
1116
|
+
<IconAction
|
|
1117
|
+
label="Steer latest queued message"
|
|
1118
|
+
analyticsAction="steer"
|
|
1119
|
+
text="Steer"
|
|
1120
|
+
tip={QUEUE_STEER_TIP}
|
|
1121
|
+
disabled={
|
|
1122
|
+
!queuePeek.turnId ||
|
|
1123
|
+
queue.mutating ||
|
|
1124
|
+
Boolean(queue.mutationFor(queuePeek.turnId))
|
|
1125
|
+
}
|
|
1126
|
+
onClick={() => {
|
|
1127
|
+
if (queuePeek.turnId) void queue.steerTurn(queuePeek.turnId);
|
|
1128
|
+
}}
|
|
1129
|
+
>
|
|
1130
|
+
{queuePeek.turnId && queue.mutationFor(queuePeek.turnId) === "steer" ? (
|
|
1131
|
+
<Loader2Icon className="size-3 animate-og-spin" />
|
|
1132
|
+
) : (
|
|
1133
|
+
<CornerDownRightIcon className="size-3" />
|
|
1134
|
+
)}
|
|
1135
|
+
</IconAction>
|
|
1136
|
+
</div>
|
|
1137
|
+
) : null}
|
|
1138
|
+
</div>
|
|
1139
|
+
);
|
|
1140
|
+
})}
|
|
1141
|
+
{signals.some((signal) => ["incoming", "agents", "commands"].includes(signal.id)) ? (
|
|
1142
|
+
<button
|
|
1143
|
+
type="button"
|
|
1144
|
+
aria-label="Session activity"
|
|
1145
|
+
aria-describedby={commandsCount > 0 ? `${panelId}-commands-count` : undefined}
|
|
1146
|
+
title={activityOpen ? "Close activity" : "Inbox, agents and commands"}
|
|
1147
|
+
aria-controls={panelId}
|
|
1148
|
+
aria-expanded={activityOpen}
|
|
1149
|
+
onClick={() => {
|
|
1150
|
+
setActivityOpen(!activityOpen);
|
|
1151
|
+
setActive(
|
|
1152
|
+
activityOpen
|
|
1153
|
+
? null
|
|
1154
|
+
: commandsCount > 0 && hasCommandsPanel
|
|
1155
|
+
? "commands"
|
|
1156
|
+
: (signals.find((signal) =>
|
|
1157
|
+
["incoming", "agents", "commands"].includes(signal.id),
|
|
1158
|
+
)?.id ?? null),
|
|
1159
|
+
);
|
|
1160
|
+
}}
|
|
1161
|
+
className={cn(
|
|
1162
|
+
"ml-auto inline-flex min-h-8 shrink-0 items-center justify-center gap-1.5 rounded-og-md px-2 text-og-xs transition-colors outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent/40 pointer-coarse:min-h-11 pointer-coarse:min-w-11",
|
|
1163
|
+
activityOpen
|
|
1164
|
+
? "bg-og-surface-3 text-og-fg"
|
|
1165
|
+
: "text-og-fg-muted hover:bg-og-surface-2 hover:text-og-fg",
|
|
1166
|
+
)}
|
|
1167
|
+
>
|
|
1168
|
+
<ActivityIcon className="size-3.5" />
|
|
1169
|
+
<span className="sr-only">Activity</span>
|
|
1170
|
+
{commandsCount > 0 ? (
|
|
1171
|
+
<>
|
|
769
1172
|
<span
|
|
770
|
-
|
|
771
|
-
className="
|
|
772
|
-
|
|
773
|
-
>
|
|
774
|
-
|
|
1173
|
+
aria-hidden="true"
|
|
1174
|
+
className="size-1.5 shrink-0 animate-og-pulse rounded-full bg-og-fg-muted motion-reduce:animate-none"
|
|
1175
|
+
/>
|
|
1176
|
+
<span id={`${panelId}-commands-count`}>
|
|
1177
|
+
{commandsCount} command{commandsCount === 1 ? "" : "s"}
|
|
775
1178
|
</span>
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
1179
|
+
</>
|
|
1180
|
+
) : null}
|
|
1181
|
+
{incoming.length > 0 ? (
|
|
1182
|
+
<span className="size-1.5 rounded-full bg-og-accent" />
|
|
1183
|
+
) : null}
|
|
1184
|
+
</button>
|
|
1185
|
+
) : null}
|
|
780
1186
|
{stopping ? (
|
|
781
1187
|
<span
|
|
782
1188
|
role="status"
|
|
@@ -794,6 +1200,47 @@ export function SessionChrome({
|
|
|
794
1200
|
</div>
|
|
795
1201
|
</div>
|
|
796
1202
|
|
|
1203
|
+
<AnimatePresence initial={false}>
|
|
1204
|
+
{activityOpen ? (
|
|
1205
|
+
<motion.div
|
|
1206
|
+
key="activity-tabs"
|
|
1207
|
+
initial={{ height: 0, opacity: 0 }}
|
|
1208
|
+
animate={{ height: "auto", opacity: 1 }}
|
|
1209
|
+
exit={{ height: 0, opacity: 0 }}
|
|
1210
|
+
transition={{ duration: shellDuration, ease }}
|
|
1211
|
+
style={{ overflow: "hidden" }}
|
|
1212
|
+
>
|
|
1213
|
+
<div className="mt-1 flex items-center gap-1 rounded-t-og-lg bg-og-surface-2/50 px-2 py-1">
|
|
1214
|
+
{signals
|
|
1215
|
+
.filter((signal) => ["incoming", "agents", "commands"].includes(signal.id))
|
|
1216
|
+
.map((signal) => (
|
|
1217
|
+
<button
|
|
1218
|
+
key={signal.id}
|
|
1219
|
+
type="button"
|
|
1220
|
+
aria-expanded={active === signal.id}
|
|
1221
|
+
onClick={() => {
|
|
1222
|
+
if (activityVisibleRef.current) setActive(signal.id);
|
|
1223
|
+
}}
|
|
1224
|
+
className={cn(
|
|
1225
|
+
"inline-flex min-h-9 items-center gap-1.5 rounded-og-md px-2 text-og-xs pointer-coarse:min-h-11",
|
|
1226
|
+
active === signal.id
|
|
1227
|
+
? "bg-og-surface-3 text-og-fg"
|
|
1228
|
+
: "text-og-fg-muted hover:text-og-fg",
|
|
1229
|
+
)}
|
|
1230
|
+
>
|
|
1231
|
+
{signal.icon}
|
|
1232
|
+
{signal.id === "incoming" ? `${incoming.length} incoming` : signal.label}
|
|
1233
|
+
</button>
|
|
1234
|
+
))}
|
|
1235
|
+
</div>
|
|
1236
|
+
</motion.div>
|
|
1237
|
+
) : null}
|
|
1238
|
+
</AnimatePresence>
|
|
1239
|
+
{goal?.mutationError ? (
|
|
1240
|
+
<p role="alert" className="px-3 pb-2 text-og-xs text-og-danger">
|
|
1241
|
+
Goal action not confirmed. {formatError(goal.mutationError)}
|
|
1242
|
+
</p>
|
|
1243
|
+
) : null}
|
|
797
1244
|
<div
|
|
798
1245
|
id={panelId}
|
|
799
1246
|
data-og-session-chrome-panel-shell=""
|
|
@@ -811,7 +1258,12 @@ export function SessionChrome({
|
|
|
811
1258
|
>
|
|
812
1259
|
<div className="min-h-0 overflow-hidden">
|
|
813
1260
|
<div
|
|
814
|
-
className=
|
|
1261
|
+
className={cn(
|
|
1262
|
+
"relative overflow-y-auto overscroll-contain",
|
|
1263
|
+
activityOpen
|
|
1264
|
+
? "rounded-b-og-lg bg-og-surface-2/50"
|
|
1265
|
+
: "mt-1 rounded-og-lg bg-og-surface-2/50",
|
|
1266
|
+
)}
|
|
815
1267
|
style={{
|
|
816
1268
|
maxHeight: "var(--og-session-chrome-panel-max-height)",
|
|
817
1269
|
paddingInline: "var(--og-session-chrome-panel-pad-x)",
|
|
@@ -819,7 +1271,7 @@ export function SessionChrome({
|
|
|
819
1271
|
}}
|
|
820
1272
|
>
|
|
821
1273
|
<AnimatePresence initial={false}>
|
|
822
|
-
{active && panelBody ? (
|
|
1274
|
+
{active && active !== "commands" && panelBody ? (
|
|
823
1275
|
<motion.div
|
|
824
1276
|
key={active}
|
|
825
1277
|
data-og-session-chrome-panel-frame={active}
|
|
@@ -842,6 +1294,16 @@ export function SessionChrome({
|
|
|
842
1294
|
</motion.div>
|
|
843
1295
|
) : null}
|
|
844
1296
|
</AnimatePresence>
|
|
1297
|
+
{active === "commands" ? (
|
|
1298
|
+
<motion.div
|
|
1299
|
+
key="commands"
|
|
1300
|
+
initial={reduceMotion ? false : { opacity: 0 }}
|
|
1301
|
+
animate={{ opacity: 1 }}
|
|
1302
|
+
transition={{ duration: crossfadeDuration, ease }}
|
|
1303
|
+
>
|
|
1304
|
+
{panelBody}
|
|
1305
|
+
</motion.div>
|
|
1306
|
+
) : null}
|
|
845
1307
|
</div>
|
|
846
1308
|
</div>
|
|
847
1309
|
</div>
|
|
@@ -854,47 +1316,123 @@ export function SessionChrome({
|
|
|
854
1316
|
function IncomingPanel({
|
|
855
1317
|
inputs,
|
|
856
1318
|
onDismiss,
|
|
1319
|
+
onOpenSession,
|
|
857
1320
|
}: {
|
|
858
1321
|
inputs: SessionPendingInputPreview[];
|
|
859
1322
|
onDismiss?: ((inputId: string) => void) | undefined;
|
|
1323
|
+
onOpenSession?: ((sessionId: string) => void) | undefined;
|
|
860
1324
|
}) {
|
|
1325
|
+
// When a sandbox is shut down or lost, every command on it reports at once.
|
|
1326
|
+
// One row reads better than dozens of identical ones; each result still
|
|
1327
|
+
// reaches the agent. Ordinary results keep their own rows.
|
|
1328
|
+
const lostWithSandbox = inputs.filter(isLostWithSandboxResult);
|
|
1329
|
+
const grouped = new Set(
|
|
1330
|
+
lostWithSandbox.length >= 2 ? lostWithSandbox.map((input) => input.id) : [],
|
|
1331
|
+
);
|
|
1332
|
+
const firstGrouped = lostWithSandbox.length >= 2 ? lostWithSandbox[0]!.id : null;
|
|
861
1333
|
return (
|
|
862
|
-
<
|
|
863
|
-
className="
|
|
864
|
-
|
|
865
|
-
|
|
1334
|
+
<div>
|
|
1335
|
+
<p className="mb-2 text-og-xs text-og-fg-subtle">Waiting to be included in an agent turn.</p>
|
|
1336
|
+
<ul
|
|
1337
|
+
className="flex flex-col gap-0.5"
|
|
1338
|
+
aria-label="Incoming updates"
|
|
1339
|
+
data-og-session-chrome-panel="incoming"
|
|
1340
|
+
>
|
|
1341
|
+
{inputs.map((input) =>
|
|
1342
|
+
grouped.has(input.id) ? (
|
|
1343
|
+
input.id === firstGrouped ? (
|
|
1344
|
+
<CommandResultsRow key={input.id} inputs={lostWithSandbox} onDismiss={onDismiss} />
|
|
1345
|
+
) : null
|
|
1346
|
+
) : (
|
|
1347
|
+
<li
|
|
1348
|
+
key={input.id}
|
|
1349
|
+
className="group flex items-start gap-1.5 rounded-og-sm px-1.5 py-1 transition-colors hover:bg-[var(--_og-session-chrome-row-hover)]"
|
|
1350
|
+
>
|
|
1351
|
+
<span
|
|
1352
|
+
className={cn(
|
|
1353
|
+
"mt-px shrink-0 rounded px-1 py-px text-[10px] font-medium leading-4",
|
|
1354
|
+
input.classification === "action_required" || input.classification === "failure"
|
|
1355
|
+
? "bg-og-status-waiting/12 text-og-status-waiting"
|
|
1356
|
+
: "bg-og-surface-3/80 text-og-fg-muted",
|
|
1357
|
+
)}
|
|
1358
|
+
>
|
|
1359
|
+
{pendingKindLabel(input.kind)}
|
|
1360
|
+
</span>
|
|
1361
|
+
<div className="min-w-0 flex-1">
|
|
1362
|
+
<p className="break-words text-og-xs leading-4 text-og-fg">{input.summary}</p>
|
|
1363
|
+
<ChildSessionLink
|
|
1364
|
+
kind={input.kind}
|
|
1365
|
+
sourceId={input.sourceId}
|
|
1366
|
+
onOpenSession={onOpenSession}
|
|
1367
|
+
/>
|
|
1368
|
+
</div>
|
|
1369
|
+
{onDismiss ? (
|
|
1370
|
+
<div className="flex shrink-0 items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100 max-sm:opacity-100">
|
|
1371
|
+
<IconAction
|
|
1372
|
+
label={`Dismiss incoming ${pendingKindLabel(input.kind)}`}
|
|
1373
|
+
tip="Dismiss"
|
|
1374
|
+
onClick={() => onDismiss(input.id)}
|
|
1375
|
+
danger
|
|
1376
|
+
>
|
|
1377
|
+
<Trash2Icon className="size-3" />
|
|
1378
|
+
</IconAction>
|
|
1379
|
+
</div>
|
|
1380
|
+
) : null}
|
|
1381
|
+
</li>
|
|
1382
|
+
),
|
|
1383
|
+
)}
|
|
1384
|
+
</ul>
|
|
1385
|
+
</div>
|
|
1386
|
+
);
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
/** Matches the worker's notice for a command whose sandbox is gone. */
|
|
1390
|
+
function isLostWithSandboxResult(input: SessionPendingInputPreview): boolean {
|
|
1391
|
+
return (
|
|
1392
|
+
input.kind === "background_command_result" &&
|
|
1393
|
+
input.summary.includes("is no longer running because its sandbox was shut down or lost")
|
|
1394
|
+
);
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
function commandResultsSummary(inputs: SessionPendingInputPreview[]): string {
|
|
1398
|
+
return `${inputs.length} background commands are no longer running because their sandbox was shut down or lost. Whether they finished is unknown.`;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
function CommandResultsRow({
|
|
1402
|
+
inputs,
|
|
1403
|
+
onDismiss,
|
|
1404
|
+
}: {
|
|
1405
|
+
inputs: SessionPendingInputPreview[];
|
|
1406
|
+
onDismiss?: ((inputId: string) => void) | undefined;
|
|
1407
|
+
}) {
|
|
1408
|
+
return (
|
|
1409
|
+
<li
|
|
1410
|
+
className="group flex items-start gap-1.5 rounded-og-sm px-1.5 py-1 transition-colors hover:bg-[var(--_og-session-chrome-row-hover)]"
|
|
1411
|
+
data-og-session-chrome-command-results={inputs.length}
|
|
866
1412
|
>
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
>
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
1413
|
+
<span className="mt-px shrink-0 rounded bg-og-status-waiting/12 px-1 py-px text-[10px] font-medium leading-4 text-og-status-waiting">
|
|
1414
|
+
Command results
|
|
1415
|
+
</span>
|
|
1416
|
+
<div className="min-w-0 flex-1">
|
|
1417
|
+
<p className="break-words text-og-xs leading-4 text-og-fg">
|
|
1418
|
+
{commandResultsSummary(inputs)}
|
|
1419
|
+
</p>
|
|
1420
|
+
</div>
|
|
1421
|
+
{onDismiss ? (
|
|
1422
|
+
<div className="flex shrink-0 items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100 max-sm:opacity-100">
|
|
1423
|
+
<IconAction
|
|
1424
|
+
label="Dismiss incoming command results"
|
|
1425
|
+
tip="Dismiss all"
|
|
1426
|
+
onClick={() => {
|
|
1427
|
+
for (const input of inputs) onDismiss(input.id);
|
|
1428
|
+
}}
|
|
1429
|
+
danger
|
|
879
1430
|
>
|
|
880
|
-
|
|
881
|
-
</
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
<IconAction
|
|
886
|
-
label={`Dismiss incoming ${pendingKindLabel(input.kind)}`}
|
|
887
|
-
tip="Dismiss"
|
|
888
|
-
onClick={() => onDismiss(input.id)}
|
|
889
|
-
danger
|
|
890
|
-
>
|
|
891
|
-
<Trash2Icon className="size-3" />
|
|
892
|
-
</IconAction>
|
|
893
|
-
</div>
|
|
894
|
-
) : null}
|
|
895
|
-
</li>
|
|
896
|
-
))}
|
|
897
|
-
</ul>
|
|
1431
|
+
<Trash2Icon className="size-3" />
|
|
1432
|
+
</IconAction>
|
|
1433
|
+
</div>
|
|
1434
|
+
) : null}
|
|
1435
|
+
</li>
|
|
898
1436
|
);
|
|
899
1437
|
}
|
|
900
1438
|
|
|
@@ -906,6 +1444,7 @@ function QueuePanel({
|
|
|
906
1444
|
onRefresh,
|
|
907
1445
|
onClearMutationError,
|
|
908
1446
|
onRetryOptimistic,
|
|
1447
|
+
onRestoreOptimistic,
|
|
909
1448
|
onRemoveOptimistic,
|
|
910
1449
|
readOnly,
|
|
911
1450
|
mutationFor,
|
|
@@ -924,6 +1463,7 @@ function QueuePanel({
|
|
|
924
1463
|
onRefresh: () => Promise<void>;
|
|
925
1464
|
onClearMutationError: () => void;
|
|
926
1465
|
onRetryOptimistic?: ((clientEventId: string) => void) | undefined;
|
|
1466
|
+
onRestoreOptimistic?: ((clientEventId: string) => void) | undefined;
|
|
927
1467
|
onRemoveOptimistic?: ((clientEventId: string) => void) | undefined;
|
|
928
1468
|
readOnly: boolean;
|
|
929
1469
|
mutationFor: UseTurnQueueResult["mutationFor"];
|
|
@@ -968,14 +1508,14 @@ function QueuePanel({
|
|
|
968
1508
|
const voice = presentation.kind !== "prompt";
|
|
969
1509
|
const pending = mutationFor(turn.id);
|
|
970
1510
|
const settling = !interactiveTurnIds.has(turn.id);
|
|
971
|
-
const beforeUp
|
|
972
|
-
const beforeDown = index < turns.length - 1 ? (turns[index + 2]?.id ?? null) : null;
|
|
1511
|
+
const { beforeUp, beforeDown } = queueNeighborAnchors(turns, index);
|
|
973
1512
|
const showActions = !readOnly && (onEdit || onSteer || onRemove || onMove);
|
|
974
1513
|
const confirmingReplace = replaceDraftFor === turn.id;
|
|
975
1514
|
return (
|
|
976
1515
|
<li
|
|
977
1516
|
key={turn.id}
|
|
978
1517
|
data-queue-turn-id={turn.id}
|
|
1518
|
+
tabIndex={-1}
|
|
979
1519
|
className="group flex flex-col gap-1 rounded-og-sm px-1.5 py-1 transition-colors hover:bg-[var(--_og-session-chrome-row-hover)]"
|
|
980
1520
|
>
|
|
981
1521
|
<div className="flex items-start gap-1.5">
|
|
@@ -989,34 +1529,69 @@ function QueuePanel({
|
|
|
989
1529
|
{index + 1}
|
|
990
1530
|
</span>
|
|
991
1531
|
)}
|
|
992
|
-
<
|
|
993
|
-
{presentation.text}
|
|
994
|
-
|
|
1532
|
+
<CompactQueueItemContent
|
|
1533
|
+
text={presentation.text}
|
|
1534
|
+
annotations={turn.annotations ?? []}
|
|
1535
|
+
/>
|
|
995
1536
|
{showActions ? (
|
|
996
|
-
<div className="flex shrink-0 items-center gap-0.5
|
|
997
|
-
{
|
|
998
|
-
|
|
1537
|
+
<div className="flex shrink-0 items-center gap-0.5">
|
|
1538
|
+
{/* Reorder, edit and delete stay on hover; Steer is always visible. */}
|
|
1539
|
+
<div className="flex shrink-0 items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100 max-sm:opacity-100">
|
|
1540
|
+
{onMove && turns.length > 1 ? (
|
|
1541
|
+
<>
|
|
1542
|
+
<IconAction
|
|
1543
|
+
label={`Move queued prompt ${index + 1} up`}
|
|
1544
|
+
tip="Move up"
|
|
1545
|
+
disabled={settling || pending !== null || index === 0}
|
|
1546
|
+
onClick={() => onMove(turn.id, beforeUp)}
|
|
1547
|
+
>
|
|
1548
|
+
<ArrowUpIcon className="size-3" />
|
|
1549
|
+
</IconAction>
|
|
1550
|
+
<IconAction
|
|
1551
|
+
label={`Move queued prompt ${index + 1} down`}
|
|
1552
|
+
tip="Move down"
|
|
1553
|
+
disabled={settling || pending !== null || index >= turns.length - 1}
|
|
1554
|
+
onClick={() => onMove(turn.id, beforeDown)}
|
|
1555
|
+
>
|
|
1556
|
+
<ArrowDownIcon className="size-3" />
|
|
1557
|
+
</IconAction>
|
|
1558
|
+
</>
|
|
1559
|
+
) : null}
|
|
1560
|
+
{onEdit ? (
|
|
999
1561
|
<IconAction
|
|
1000
|
-
label={`
|
|
1001
|
-
tip=
|
|
1002
|
-
disabled={settling || pending !== null
|
|
1003
|
-
onClick={() =>
|
|
1562
|
+
label={`Edit queued prompt ${index + 1}`}
|
|
1563
|
+
tip={QUEUE_EDIT_TIP}
|
|
1564
|
+
disabled={settling || pending !== null}
|
|
1565
|
+
onClick={() => onEdit(turn)}
|
|
1004
1566
|
>
|
|
1005
|
-
|
|
1567
|
+
{pending === "edit" ? (
|
|
1568
|
+
<Loader2Icon className="size-3 animate-og-spin" />
|
|
1569
|
+
) : (
|
|
1570
|
+
<PencilIcon className="size-3" />
|
|
1571
|
+
)}
|
|
1006
1572
|
</IconAction>
|
|
1573
|
+
) : null}
|
|
1574
|
+
{onRemove ? (
|
|
1007
1575
|
<IconAction
|
|
1008
|
-
label={`
|
|
1009
|
-
tip=
|
|
1010
|
-
disabled={settling || pending !== null
|
|
1011
|
-
onClick={() =>
|
|
1576
|
+
label={`Remove queued prompt ${index + 1}`}
|
|
1577
|
+
tip={QUEUE_DELETE_TIP}
|
|
1578
|
+
disabled={settling || pending !== null}
|
|
1579
|
+
onClick={() => onRemove(turn.id)}
|
|
1580
|
+
danger
|
|
1012
1581
|
>
|
|
1013
|
-
|
|
1582
|
+
{pending === "delete" ? (
|
|
1583
|
+
<Loader2Icon className="size-3 animate-og-spin" />
|
|
1584
|
+
) : (
|
|
1585
|
+
<Trash2Icon className="size-3" />
|
|
1586
|
+
)}
|
|
1014
1587
|
</IconAction>
|
|
1015
|
-
|
|
1016
|
-
|
|
1588
|
+
) : null}
|
|
1589
|
+
</div>
|
|
1017
1590
|
{onSteer ? (
|
|
1018
1591
|
<IconAction
|
|
1019
1592
|
label={`Steer queued prompt ${index + 1}`}
|
|
1593
|
+
analyticsAction="steer"
|
|
1594
|
+
text="Steer"
|
|
1020
1595
|
tip={QUEUE_STEER_TIP}
|
|
1021
1596
|
disabled={settling || pending !== null}
|
|
1022
1597
|
onClick={() => onSteer(turn.id)}
|
|
@@ -1024,36 +1599,7 @@ function QueuePanel({
|
|
|
1024
1599
|
{pending === "steer" ? (
|
|
1025
1600
|
<Loader2Icon className="size-3 animate-og-spin" />
|
|
1026
1601
|
) : (
|
|
1027
|
-
<
|
|
1028
|
-
)}
|
|
1029
|
-
</IconAction>
|
|
1030
|
-
) : null}
|
|
1031
|
-
{onEdit ? (
|
|
1032
|
-
<IconAction
|
|
1033
|
-
label={`Edit queued prompt ${index + 1}`}
|
|
1034
|
-
tip={QUEUE_EDIT_TIP}
|
|
1035
|
-
disabled={settling || pending !== null}
|
|
1036
|
-
onClick={() => onEdit(turn)}
|
|
1037
|
-
>
|
|
1038
|
-
{pending === "edit" ? (
|
|
1039
|
-
<Loader2Icon className="size-3 animate-og-spin" />
|
|
1040
|
-
) : (
|
|
1041
|
-
<PencilIcon className="size-3" />
|
|
1042
|
-
)}
|
|
1043
|
-
</IconAction>
|
|
1044
|
-
) : null}
|
|
1045
|
-
{onRemove ? (
|
|
1046
|
-
<IconAction
|
|
1047
|
-
label={`Remove queued prompt ${index + 1}`}
|
|
1048
|
-
tip={QUEUE_DELETE_TIP}
|
|
1049
|
-
disabled={settling || pending !== null}
|
|
1050
|
-
onClick={() => onRemove(turn.id)}
|
|
1051
|
-
danger
|
|
1052
|
-
>
|
|
1053
|
-
{pending === "delete" ? (
|
|
1054
|
-
<Loader2Icon className="size-3 animate-og-spin" />
|
|
1055
|
-
) : (
|
|
1056
|
-
<Trash2Icon className="size-3" />
|
|
1602
|
+
<CornerDownRightIcon className="size-3" />
|
|
1057
1603
|
)}
|
|
1058
1604
|
</IconAction>
|
|
1059
1605
|
) : null}
|
|
@@ -1062,25 +1608,22 @@ function QueuePanel({
|
|
|
1062
1608
|
</div>
|
|
1063
1609
|
{confirmingReplace ? (
|
|
1064
1610
|
<div className="rounded-og-sm border border-og-status-waiting/30 bg-og-status-waiting/10 p-2 text-og-xs text-og-fg">
|
|
1065
|
-
<p>
|
|
1066
|
-
<p className="mt-0.5 text-og-fg-muted">
|
|
1067
|
-
The current draft will be permanently discarded; this queued prompt is preserved
|
|
1068
|
-
until you confirm.
|
|
1069
|
-
</p>
|
|
1611
|
+
<p>{QUEUE_REPLACE_DRAFT_COPY.title}</p>
|
|
1612
|
+
<p className="mt-0.5 text-og-fg-muted">{QUEUE_REPLACE_DRAFT_COPY.detail}</p>
|
|
1070
1613
|
<div className="mt-2 flex justify-end gap-1.5">
|
|
1071
1614
|
<button
|
|
1072
1615
|
type="button"
|
|
1073
1616
|
className="rounded-og-sm px-2 py-1 font-medium hover:bg-og-surface-3/70 focus-visible:ring-2 focus-visible:ring-og-accent/40"
|
|
1074
1617
|
onClick={onCancelReplace}
|
|
1075
1618
|
>
|
|
1076
|
-
|
|
1619
|
+
{QUEUE_REPLACE_DRAFT_COPY.keep}
|
|
1077
1620
|
</button>
|
|
1078
1621
|
<button
|
|
1079
1622
|
type="button"
|
|
1080
|
-
className="rounded-og-sm bg-og-
|
|
1623
|
+
className="rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-2 py-1 font-medium hover:bg-og-primary-hover focus-visible:ring-2 focus-visible:ring-og-accent/40"
|
|
1081
1624
|
onClick={onConfirmReplace}
|
|
1082
1625
|
>
|
|
1083
|
-
|
|
1626
|
+
{QUEUE_REPLACE_DRAFT_COPY.replace}
|
|
1084
1627
|
</button>
|
|
1085
1628
|
</div>
|
|
1086
1629
|
</div>
|
|
@@ -1105,19 +1648,24 @@ function QueuePanel({
|
|
|
1105
1648
|
<span className="shrink-0 font-og-mono text-[10px] leading-4 text-og-fg-subtle">
|
|
1106
1649
|
{turns.length + index + 1}
|
|
1107
1650
|
</span>
|
|
1108
|
-
<
|
|
1109
|
-
{message.text}
|
|
1110
|
-
|
|
1651
|
+
<div className="min-w-0 flex-1">
|
|
1652
|
+
<CompactQueueItemContent text={message.text} annotations={message.annotations} />
|
|
1653
|
+
{message.state === "failed" && message.error ? (
|
|
1654
|
+
<p className="break-words text-og-xs">{message.error}</p>
|
|
1655
|
+
) : null}
|
|
1656
|
+
</div>
|
|
1111
1657
|
<span className="sr-only">
|
|
1112
1658
|
{message.state === "failed"
|
|
1113
|
-
?
|
|
1659
|
+
? message.outcomeUnknown
|
|
1660
|
+
? "Not confirmed"
|
|
1661
|
+
: "Message not sent"
|
|
1114
1662
|
: message.state === "sending"
|
|
1115
1663
|
? "Placing in queue"
|
|
1116
1664
|
: "Queued"}
|
|
1117
1665
|
</span>
|
|
1118
1666
|
{message.state === "failed" ? (
|
|
1119
1667
|
<div className="flex shrink-0 items-center gap-1 text-[10px]">
|
|
1120
|
-
{onRetryOptimistic ? (
|
|
1668
|
+
{message.retryable !== false && onRetryOptimistic ? (
|
|
1121
1669
|
<button
|
|
1122
1670
|
type="button"
|
|
1123
1671
|
className="rounded-og-sm px-1.5 py-1 font-medium hover:bg-og-surface-2 pointer-coarse:min-h-11 pointer-coarse:min-w-11"
|
|
@@ -1126,6 +1674,15 @@ function QueuePanel({
|
|
|
1126
1674
|
Retry
|
|
1127
1675
|
</button>
|
|
1128
1676
|
) : null}
|
|
1677
|
+
{message.retryable === false && onRestoreOptimistic ? (
|
|
1678
|
+
<button
|
|
1679
|
+
type="button"
|
|
1680
|
+
className="rounded-og-sm px-1.5 py-1 font-medium hover:bg-og-surface-2 pointer-coarse:min-h-11 pointer-coarse:min-w-11"
|
|
1681
|
+
onClick={() => onRestoreOptimistic(message.clientEventId)}
|
|
1682
|
+
>
|
|
1683
|
+
Edit message
|
|
1684
|
+
</button>
|
|
1685
|
+
) : null}
|
|
1129
1686
|
{onRemoveOptimistic ? (
|
|
1130
1687
|
<button
|
|
1131
1688
|
type="button"
|
|
@@ -1184,6 +1741,30 @@ function QueuePanel({
|
|
|
1184
1741
|
);
|
|
1185
1742
|
}
|
|
1186
1743
|
|
|
1744
|
+
function CompactQueueItemContent({
|
|
1745
|
+
text,
|
|
1746
|
+
annotations,
|
|
1747
|
+
}: {
|
|
1748
|
+
text: string;
|
|
1749
|
+
annotations: readonly TimelineAnnotationLike[];
|
|
1750
|
+
}) {
|
|
1751
|
+
const content = queueItemContent(text, annotations.length);
|
|
1752
|
+
return (
|
|
1753
|
+
<div className="flex min-w-0 flex-1 items-center gap-1.5">
|
|
1754
|
+
{content === "text" ? (
|
|
1755
|
+
<p className="min-w-0 flex-1 truncate text-og-xs leading-4 text-og-fg">{text}</p>
|
|
1756
|
+
) : content === "unavailable" ? (
|
|
1757
|
+
<p className="min-w-0 flex-1 truncate text-og-xs leading-4 text-og-fg-muted italic">
|
|
1758
|
+
{QUEUE_ITEM_CONTENT_UNAVAILABLE}
|
|
1759
|
+
</p>
|
|
1760
|
+
) : null}
|
|
1761
|
+
{annotations.length > 0 ? (
|
|
1762
|
+
<TimelineAnnotationsChip annotations={annotations} className="shrink-0" compact />
|
|
1763
|
+
) : null}
|
|
1764
|
+
</div>
|
|
1765
|
+
);
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1187
1768
|
function GoalPanel({
|
|
1188
1769
|
goal,
|
|
1189
1770
|
state,
|
|
@@ -1195,6 +1776,7 @@ function GoalPanel({
|
|
|
1195
1776
|
elapsed: string | null;
|
|
1196
1777
|
readOnly: boolean;
|
|
1197
1778
|
}) {
|
|
1779
|
+
const formatError = useErrorMessage();
|
|
1198
1780
|
const record = goal.goal;
|
|
1199
1781
|
if (!record) return null;
|
|
1200
1782
|
const canToggle = !readOnly && (record.status === "active" || record.status === "paused");
|
|
@@ -1206,7 +1788,7 @@ function GoalPanel({
|
|
|
1206
1788
|
<span>{sessionChromeGoalPillLabel(state, record)}</span>
|
|
1207
1789
|
{elapsed ? (
|
|
1208
1790
|
<span className="tabular-nums normal-case tracking-normal text-og-fg-muted">
|
|
1209
|
-
· {elapsed}
|
|
1791
|
+
· Created {elapsed} ago
|
|
1210
1792
|
</span>
|
|
1211
1793
|
) : null}
|
|
1212
1794
|
<span className="normal-case tracking-normal text-og-fg-muted">· v{record.version}</span>
|
|
@@ -1227,7 +1809,7 @@ function GoalPanel({
|
|
|
1227
1809
|
) : null}
|
|
1228
1810
|
{record.continuation?.lastError ? (
|
|
1229
1811
|
<p className="rounded-og-sm bg-og-status-waiting/10 px-1.5 py-1 text-og-xs leading-4 text-og-status-waiting">
|
|
1230
|
-
{record.continuation.lastError}
|
|
1812
|
+
{formatError(record.continuation.lastError)}
|
|
1231
1813
|
</p>
|
|
1232
1814
|
) : null}
|
|
1233
1815
|
<div className="flex flex-wrap items-center justify-between gap-1.5 pt-0.5">
|
|
@@ -1288,7 +1870,9 @@ const QUEUE_EDIT_TIP = "Edit in composer";
|
|
|
1288
1870
|
const QUEUE_DELETE_TIP = "Delete this queued prompt";
|
|
1289
1871
|
|
|
1290
1872
|
function IconAction({
|
|
1873
|
+
text,
|
|
1291
1874
|
label,
|
|
1875
|
+
analyticsAction,
|
|
1292
1876
|
tip,
|
|
1293
1877
|
onClick,
|
|
1294
1878
|
disabled,
|
|
@@ -1296,6 +1880,9 @@ function IconAction({
|
|
|
1296
1880
|
children,
|
|
1297
1881
|
}: {
|
|
1298
1882
|
label: string;
|
|
1883
|
+
/** Stable, content-free control label a host's product analytics may read. */
|
|
1884
|
+
analyticsAction?: "steer";
|
|
1885
|
+
text?: string;
|
|
1299
1886
|
tip: ReactNode;
|
|
1300
1887
|
onClick: () => void;
|
|
1301
1888
|
disabled?: boolean;
|
|
@@ -1308,16 +1895,20 @@ function IconAction({
|
|
|
1308
1895
|
<button
|
|
1309
1896
|
type="button"
|
|
1310
1897
|
aria-label={label}
|
|
1898
|
+
data-analytics-action={analyticsAction}
|
|
1311
1899
|
disabled={disabled}
|
|
1312
1900
|
onClick={onClick}
|
|
1313
1901
|
className={cn(
|
|
1314
|
-
"inline-flex size-6 items-center justify-center rounded-og-sm
|
|
1902
|
+
"inline-flex size-6 items-center justify-center rounded-og-sm outline-hidden transition-colors",
|
|
1315
1903
|
"hover:bg-og-surface-2 hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent/40",
|
|
1316
1904
|
"disabled:pointer-events-none disabled:opacity-40 pointer-coarse:size-9",
|
|
1905
|
+
text ? "text-og-fg" : "text-og-fg-subtle",
|
|
1906
|
+
text && "w-auto gap-1 px-1.5 text-og-xs pointer-coarse:w-auto",
|
|
1317
1907
|
danger && "hover:text-og-danger",
|
|
1318
1908
|
)}
|
|
1319
1909
|
>
|
|
1320
1910
|
{children}
|
|
1911
|
+
{text}
|
|
1321
1912
|
</button>
|
|
1322
1913
|
</TooltipTrigger>
|
|
1323
1914
|
<TooltipContent side="top">{tip}</TooltipContent>
|