@opengeni/react 0.57.0 → 1.0.2-canary.37191796234001
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +654 -22
- package/dist/accounts.d.ts +64 -0
- package/dist/accounts.js +822 -0
- package/dist/accounts.js.map +1 -0
- package/dist/approvals.d.ts +2 -1
- package/dist/artifacts-document.js +3 -2
- package/dist/artifacts-presentation.js +3 -2
- package/dist/artifacts-spreadsheet.js +2 -2
- package/dist/artifacts.d.ts +4 -1
- package/dist/artifacts.js +518 -42
- package/dist/artifacts.js.map +1 -1
- package/dist/browser-viewer-GTR5XQ7X.js +16 -0
- package/dist/capability-catalog-row.d.ts +20 -0
- package/dist/capability-logo-fallback.d.ts +3 -0
- package/dist/chat-interactive-block-UGBTNB3L.js +11 -0
- package/dist/chat-interactive-block-UGBTNB3L.js.map +1 -0
- package/dist/{chunk-5UQPNLIO.js → chunk-23J2ZNXT.js} +4117 -3896
- package/dist/chunk-23J2ZNXT.js.map +1 -0
- package/dist/chunk-447JLCBU.js +209 -0
- package/dist/chunk-447JLCBU.js.map +1 -0
- package/dist/chunk-4RVYOY4O.js +379 -0
- package/dist/chunk-4RVYOY4O.js.map +1 -0
- package/dist/chunk-5CVXZA3Y.js +292 -0
- package/dist/chunk-5CVXZA3Y.js.map +1 -0
- package/dist/chunk-5J4FOW6Q.js +108 -0
- package/dist/chunk-5J4FOW6Q.js.map +1 -0
- package/dist/chunk-A2PI6UMY.js +41 -0
- package/dist/chunk-A2PI6UMY.js.map +1 -0
- package/dist/{chunk-7WCLAEFV.js → chunk-A4UJB2MM.js} +37 -27
- package/dist/chunk-A4UJB2MM.js.map +1 -0
- package/dist/chunk-B3V6TG77.js +41 -0
- package/dist/chunk-B3V6TG77.js.map +1 -0
- package/dist/chunk-BRM6FVZA.js +302 -0
- package/dist/chunk-BRM6FVZA.js.map +1 -0
- package/dist/chunk-C5X5AJXK.js +182 -0
- package/dist/chunk-C5X5AJXK.js.map +1 -0
- package/dist/chunk-CR7U7HAR.js +453 -0
- package/dist/chunk-CR7U7HAR.js.map +1 -0
- package/dist/{chunk-R3AZOAB5.js → chunk-DYWBUX5Q.js} +29 -123
- package/dist/chunk-DYWBUX5Q.js.map +1 -0
- package/dist/chunk-E3G7SAYZ.js +3124 -0
- package/dist/chunk-E3G7SAYZ.js.map +1 -0
- package/dist/chunk-ELCE5SXV.js +359 -0
- package/dist/chunk-ELCE5SXV.js.map +1 -0
- package/dist/chunk-ERGYJIBB.js +21 -0
- package/dist/chunk-ERGYJIBB.js.map +1 -0
- package/dist/chunk-FFA2OVOV.js +319 -0
- package/dist/chunk-FFA2OVOV.js.map +1 -0
- package/dist/chunk-FZCP527Y.js +116 -0
- package/dist/chunk-FZCP527Y.js.map +1 -0
- package/dist/chunk-GIMRELBW.js +14 -0
- package/dist/chunk-GIMRELBW.js.map +1 -0
- package/dist/{chunk-6KLX2RH5.js → chunk-H2NJQORO.js} +1069 -79
- package/dist/chunk-H2NJQORO.js.map +1 -0
- package/dist/chunk-I7IWRQLN.js +1608 -0
- package/dist/chunk-I7IWRQLN.js.map +1 -0
- package/dist/{chunk-HA46CYQK.js → chunk-IQUCRAT7.js} +792 -537
- package/dist/chunk-IQUCRAT7.js.map +1 -0
- package/dist/chunk-IWIDV7SB.js +1 -0
- package/dist/chunk-IWIDV7SB.js.map +1 -0
- package/dist/chunk-J2QWVSQY.js +312 -0
- package/dist/chunk-J2QWVSQY.js.map +1 -0
- package/dist/chunk-JFNEV4LU.js +2733 -0
- package/dist/chunk-JFNEV4LU.js.map +1 -0
- package/dist/chunk-JT4JW7BC.js +54 -0
- package/dist/chunk-JT4JW7BC.js.map +1 -0
- package/dist/chunk-K3HQAKQX.js +24 -0
- package/dist/chunk-K3HQAKQX.js.map +1 -0
- package/dist/{chunk-C5ZPSSS5.js → chunk-NEXLLTP4.js} +2 -1
- package/dist/{chunk-C5ZPSSS5.js.map → chunk-NEXLLTP4.js.map} +1 -1
- package/dist/chunk-NZUI76EM.js +371 -0
- package/dist/chunk-NZUI76EM.js.map +1 -0
- package/dist/{chunk-PEI6RANI.js → chunk-PNY3JKBJ.js} +309 -74
- package/dist/chunk-PNY3JKBJ.js.map +1 -0
- package/dist/{chunk-IGC6A2ZI.js → chunk-Q5QBEZIQ.js} +777 -246
- package/dist/chunk-Q5QBEZIQ.js.map +1 -0
- package/dist/chunk-RHREZ7BO.js +11 -0
- package/dist/chunk-RHREZ7BO.js.map +1 -0
- package/dist/chunk-SCOTPE2I.js +589 -0
- package/dist/chunk-SCOTPE2I.js.map +1 -0
- package/dist/{chunk-B6WPZSTT.js → chunk-SJZDKVW2.js} +1331 -1163
- package/dist/chunk-SJZDKVW2.js.map +1 -0
- package/dist/chunk-TMJRG4YC.js +12803 -0
- package/dist/chunk-TMJRG4YC.js.map +1 -0
- package/dist/chunk-TMYGL6X5.js +742 -0
- package/dist/chunk-TMYGL6X5.js.map +1 -0
- package/dist/chunk-UGLEYEMP.js +33 -0
- package/dist/chunk-UGLEYEMP.js.map +1 -0
- package/dist/chunk-UK4TINKT.js +27 -0
- package/dist/chunk-UK4TINKT.js.map +1 -0
- package/dist/chunk-UTRTG6LH.js +220 -0
- package/dist/chunk-UTRTG6LH.js.map +1 -0
- package/dist/chunk-WEHMPOXK.js +39 -0
- package/dist/chunk-WEHMPOXK.js.map +1 -0
- package/dist/chunk-WRHIZYZF.js +988 -0
- package/dist/chunk-WRHIZYZF.js.map +1 -0
- package/dist/{chunk-HUIKIDM5.js → chunk-WUISZ3WU.js} +223 -115
- package/dist/chunk-WUISZ3WU.js.map +1 -0
- package/dist/chunk-XCHWDJ22.js +107 -0
- package/dist/chunk-XCHWDJ22.js.map +1 -0
- package/dist/chunk-XOAMRDDK.js +481 -0
- package/dist/chunk-XOAMRDDK.js.map +1 -0
- package/dist/chunk-XUW2UWQM.js +299 -0
- package/dist/chunk-XUW2UWQM.js.map +1 -0
- package/dist/{chunk-KCGXPP5V.js → chunk-Y2PRMYLC.js} +11 -6
- package/dist/chunk-Y2PRMYLC.js.map +1 -0
- package/dist/chunk-YBXQDQFX.js +1772 -0
- package/dist/chunk-YBXQDQFX.js.map +1 -0
- package/dist/{chunk-KZ73RL76.js → chunk-YQEAA6LT.js} +7 -3
- package/dist/chunk-YQEAA6LT.js.map +1 -0
- package/dist/chunk-YV4L3ILF.js +9 -0
- package/dist/chunk-YV4L3ILF.js.map +1 -0
- package/dist/{chunk-LLOLUHVG.js → chunk-YWFG7ZX7.js} +1358 -2746
- package/dist/chunk-YWFG7ZX7.js.map +1 -0
- package/dist/chunk-ZYRGEKWS.js +216 -0
- package/dist/chunk-ZYRGEKWS.js.map +1 -0
- package/dist/client.d.ts +7 -4
- package/dist/clipboard.js +1 -0
- package/dist/commands/types.d.ts +2 -0
- package/dist/components/anthropic-mark.d.ts +3 -0
- package/dist/components/approval-surface.d.ts +15 -0
- package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
- package/dist/components/artifacts/artifact-sandbox.d.ts +27 -0
- package/dist/components/artifacts/artifact-surface.d.ts +3 -1
- package/dist/components/artifacts/chat-interactive-block.d.ts +29 -0
- package/dist/components/artifacts/deferred-chat-media.d.ts +15 -0
- package/dist/components/artifacts/document-editor.d.ts +4 -2
- package/dist/components/artifacts/editable-artifact-ui.d.ts +2 -1
- package/dist/components/artifacts/editable-artifact-view.d.ts +46 -0
- package/dist/components/artifacts/editable-document.d.ts +1 -1
- package/dist/components/artifacts/editable-presentation.d.ts +2 -2
- package/dist/components/artifacts/editable-spreadsheet.d.ts +2 -1
- package/dist/components/artifacts/index.d.ts +8 -1
- package/dist/components/artifacts/inline-html-document.d.ts +2 -0
- package/dist/components/artifacts/latest-task-runner.d.ts +15 -0
- package/dist/components/artifacts/presentation-editor.d.ts +6 -2
- package/dist/components/artifacts/published-html-artifact-frame.d.ts +48 -3
- package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
- package/dist/components/artifacts/site-view.d.ts +23 -0
- package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
- package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
- package/dist/components/browser-select-control.d.ts +16 -0
- package/dist/components/browser-viewer.d.ts +10 -1
- package/dist/components/chat-composer.d.ts +21 -3
- package/dist/components/child-session-link.d.ts +5 -0
- package/dist/components/claude-mark.d.ts +3 -0
- package/dist/components/code-editor.d.ts +1 -4
- package/dist/components/composer.d.ts +45 -4
- package/dist/components/computer-viewer.d.ts +4 -1
- package/dist/components/copy-button.d.ts +3 -1
- package/dist/components/desktop-viewer.d.ts +1 -1
- package/dist/components/enrollment-consent.d.ts +6 -3
- package/dist/components/file-browser.d.ts +10 -1
- package/dist/components/fleet-tile.d.ts +2 -2
- package/dist/components/grok-mark.d.ts +26 -0
- package/dist/components/human-input-form.d.ts +21 -2
- package/dist/components/human-input-surface.d.ts +6 -3
- package/dist/components/machine-card.d.ts +4 -1
- package/dist/components/machines/machine-detail.d.ts +4 -1
- package/dist/components/machines/machine-operation-policy.d.ts +11 -0
- package/dist/components/machines-dashboard.d.ts +3 -1
- package/dist/components/markdown-table-layout.d.ts +12 -0
- package/dist/components/markdown.d.ts +47 -3
- package/dist/components/message-timeline.d.ts +72 -9
- package/dist/components/model-mark.d.ts +29 -0
- package/dist/components/model-policy-picker-menu.d.ts +9 -0
- package/dist/components/model-policy-picker.d.ts +62 -13
- package/dist/components/open-geni-chat.d.ts +55 -0
- package/dist/components/open-geni-links.d.ts +68 -0
- package/dist/components/openrouter-mark.d.ts +6 -0
- package/dist/components/pierre-file.d.ts +1 -1
- package/dist/components/preview-loading.d.ts +2 -0
- package/dist/components/queue-item-content.d.ts +9 -0
- package/dist/components/sandbox-files.d.ts +13 -2
- package/dist/components/sandbox-workspace.d.ts +43 -3
- package/dist/components/session-capability-frame.d.ts +35 -0
- package/dist/components/session-chrome.d.ts +66 -8
- package/dist/components/session-commands-panel.d.ts +6 -0
- package/dist/components/session-commands.d.ts +6 -0
- package/dist/components/session-connection-request.d.ts +8 -0
- package/dist/components/session-conversation.d.ts +86 -0
- package/dist/components/session-list.d.ts +36 -0
- package/dist/components/session-mcp-capability-card.d.ts +41 -0
- package/dist/components/timeline-anchor.d.ts +24 -0
- package/dist/components/timeline-annotation-chrome.d.ts +25 -0
- package/dist/components/timeline-annotation-layout.d.ts +42 -0
- package/dist/components/timeline-annotation-markers.d.ts +8 -0
- package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
- package/dist/components/timeline-annotation-shared.d.ts +31 -0
- package/dist/components/timeline-annotations-dialog.d.ts +3 -2
- package/dist/components/timeline-annotations.d.ts +13 -3
- package/dist/components/timeline-reading-progress.d.ts +11 -0
- package/dist/components/timeline-search.d.ts +34 -0
- package/dist/components/timeline-settlement.d.ts +16 -0
- package/dist/components/tip-follow.d.ts +16 -0
- package/dist/components/usage-limit-notice.d.ts +49 -0
- package/dist/components/usage-member-list.d.ts +91 -0
- package/dist/components/usage-meter.d.ts +73 -0
- package/dist/components/use-viewer-menu-dismiss.d.ts +2 -0
- package/dist/components/user-message-body.d.ts +10 -1
- package/dist/components/workspace-dock.d.ts +6 -2
- package/dist/composer.d.ts +5 -4
- package/dist/composer.js +15 -9
- package/dist/computer-viewer-ENHVAZ2Q.js +19 -0
- package/dist/computer-viewer-ENHVAZ2Q.js.map +1 -0
- package/dist/connect-account-identity.d.ts +8 -0
- package/dist/connect-accounts.d.ts +15 -0
- package/dist/connect-chooser.d.ts +18 -0
- package/dist/connect-panel.d.ts +18 -0
- package/dist/connect-setup.d.ts +16 -0
- package/dist/connect.d.ts +21 -0
- package/dist/connect.js +2129 -0
- package/dist/connect.js.map +1 -0
- package/dist/connection-catalog.d.ts +38 -0
- package/dist/connection-discovery.d.ts +12 -0
- package/dist/connection-installed.d.ts +17 -0
- package/dist/connection-logo.d.ts +9 -0
- package/dist/connection-service-logo.d.ts +8 -0
- package/dist/connection-service-presentation.d.ts +13 -0
- package/dist/connection-skeleton.d.ts +5 -0
- package/dist/connection-type-picker.d.ts +6 -0
- package/dist/conversation-timeline.d.ts +5 -0
- package/dist/desktop.d.ts +7 -0
- package/dist/desktop.js +26 -0
- package/dist/desktop.js.map +1 -0
- package/dist/device-authorization.d.ts +23 -0
- package/dist/diffs.d.ts +8 -0
- package/dist/diffs.js +14 -0
- package/dist/diffs.js.map +1 -0
- package/dist/discovery-cache.d.ts +5 -0
- package/dist/editor.d.ts +7 -0
- package/dist/editor.js +21 -0
- package/dist/editor.js.map +1 -0
- package/dist/embedded-session-client.d.ts +23 -0
- package/dist/file-node-visibility.d.ts +15 -0
- package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-YZ3ZKWMM.js} +2 -1
- package/dist/fleet-decision-row-YZ3ZKWMM.js.map +1 -0
- package/dist/hooks/channel-cache.d.ts +23 -0
- package/dist/hooks/latest-question.d.ts +25 -0
- package/dist/hooks/shared-machines-list.d.ts +14 -0
- package/dist/hooks/use-attached-browsers.d.ts +2 -1
- package/dist/hooks/use-browser-frame-stream.d.ts +1 -1
- package/dist/hooks/use-browser-session.d.ts +12 -1
- package/dist/hooks/use-channels.d.ts +1 -0
- package/dist/hooks/use-codex-accounts.d.ts +25 -7
- package/dist/hooks/use-composer.d.ts +45 -9
- package/dist/hooks/use-computer-frame-stream.d.ts +1 -1
- package/dist/hooks/use-computer-input-posture.d.ts +13 -0
- package/dist/hooks/use-computer-session.d.ts +2 -0
- package/dist/hooks/use-connect.d.ts +22 -0
- package/dist/hooks/use-desktop-stream.d.ts +1 -1
- package/dist/hooks/use-file-attachments.d.ts +21 -2
- package/dist/hooks/use-machine-chip.d.ts +3 -3
- package/dist/hooks/use-machines.d.ts +19 -1
- package/dist/hooks/use-sandbox-files.d.ts +5 -1
- package/dist/hooks/use-session-background-commands.d.ts +14 -0
- package/dist/hooks/use-session-events.d.ts +30 -8
- package/dist/hooks/use-session-lineage.d.ts +4 -0
- package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
- package/dist/hooks/use-session.d.ts +6 -0
- package/dist/hooks/use-turn-queue.d.ts +12 -0
- package/dist/hooks/use-usage.d.ts +40 -0
- package/dist/hooks/use-workspace-edit.d.ts +4 -0
- package/dist/hooks/use-workspace-sessions.d.ts +27 -5
- package/dist/human-input.d.ts +3 -1
- package/dist/identity-link-accounts.d.ts +11 -0
- package/dist/identity-link-consent.d.ts +18 -0
- package/dist/index.d.ts +60 -17
- package/dist/index.js +2237 -6200
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +1 -1
- package/dist/interaction.js +35 -184
- package/dist/interaction.js.map +1 -1
- package/dist/latest-question-755OW5DS.js +117 -0
- package/dist/latest-question-755OW5DS.js.map +1 -0
- package/dist/lib/error-message.d.ts +7 -0
- package/dist/lib/format.d.ts +36 -2
- package/dist/lib/host-theme.d.ts +70 -0
- package/dist/lib/interaction-errors.d.ts +6 -0
- package/dist/lib/menu-styles.d.ts +22 -0
- package/dist/lib/pierre-diffs-loader.d.ts +20 -0
- package/dist/lib/workbench-peers.d.ts +36 -0
- package/dist/lib/xterm-theme.d.ts +7 -5
- package/dist/machines.d.ts +4 -2
- package/dist/machines.js +14 -4
- package/dist/markdown-table-layout-QXSLK4BY.js +106 -0
- package/dist/markdown-table-layout-QXSLK4BY.js.map +1 -0
- package/dist/mcp-connection-status.d.ts +14 -0
- package/dist/model-policy-picker-menu-PWRI7R2X.js +14 -0
- package/dist/model-policy-picker-menu-PWRI7R2X.js.map +1 -0
- package/dist/model-policy.d.ts +19 -3
- package/dist/model-policy.js +9 -1
- package/dist/older-history.d.ts +30 -0
- package/dist/platform-activity-row-627BFZ46.js +182 -0
- package/dist/platform-activity-row-627BFZ46.js.map +1 -0
- package/dist/plugin-details.d.ts +14 -0
- package/dist/plugin-discovery.d.ts +25 -0
- package/dist/provider.d.ts +13 -1
- package/dist/{queue-surface-implementation-2KVJTYXH.js → queue-surface-implementation-ZHFI5JBP.js} +131 -44
- package/dist/queue-surface-implementation-ZHFI5JBP.js.map +1 -0
- package/dist/realtime/realtime-control.d.ts +10 -3
- package/dist/realtime.js +229 -83
- package/dist/realtime.js.map +1 -1
- package/dist/sandbox-files-BBC47SLD.js +20 -0
- package/dist/sandbox-files-BBC47SLD.js.map +1 -0
- package/dist/session-auth-recommendation.d.ts +5 -0
- package/dist/session-capability-policy.d.ts +12 -0
- package/dist/session-ui.d.ts +30 -2
- package/dist/session-ui.js +85 -7
- package/dist/session-ui.js.map +1 -1
- package/dist/session.d.ts +8 -2
- package/dist/session.js +30 -19
- package/dist/sites-ui.d.ts +34 -0
- package/dist/sites.d.ts +3 -0
- package/dist/sites.js +11 -0
- package/dist/sites.js.map +1 -0
- package/dist/skill-discovery.d.ts +47 -0
- package/dist/terminal.d.ts +8 -0
- package/dist/terminal.js +31 -0
- package/dist/terminal.js.map +1 -0
- package/dist/timeline/activity-rail.d.ts +11 -2
- package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
- package/dist/timeline/compaction-copy.d.ts +10 -0
- package/dist/timeline/entrance.d.ts +13 -1
- package/dist/timeline/genie-loading.d.ts +34 -0
- package/dist/timeline/index.d.ts +6 -2
- package/dist/timeline/knowledge-receipt.d.ts +17 -0
- package/dist/timeline/platform-activity-row.d.ts +14 -0
- package/dist/timeline/presented-image.d.ts +6 -0
- package/dist/timeline/projection.d.ts +31 -2
- package/dist/timeline/registry.d.ts +2 -0
- package/dist/timeline/retained-image.d.ts +18 -0
- package/dist/timeline/rolling-activity.d.ts +11 -0
- package/dist/timeline/screenshot-lightbox.d.ts +16 -1
- package/dist/timeline/shared.d.ts +8 -3
- package/dist/timeline/startup-preference.d.ts +3 -0
- package/dist/timeline/startup-timings.d.ts +4 -0
- package/dist/timeline/tool-display-name.d.ts +2 -1
- package/dist/timeline/turn-summary.d.ts +32 -3
- package/dist/timeline/types.d.ts +141 -7
- package/dist/timeline-annotation-markers-GNDHTGBD.js +165 -0
- package/dist/timeline-annotation-markers-GNDHTGBD.js.map +1 -0
- package/dist/timeline-annotation-selection-DMLMM2TX.js +241 -0
- package/dist/timeline-annotation-selection-DMLMM2TX.js.map +1 -0
- package/dist/timeline-annotations-dialog-ELRDBHTS.js +273 -0
- package/dist/timeline-annotations-dialog-ELRDBHTS.js.map +1 -0
- package/dist/types/machines.d.ts +2 -2
- package/dist/usage/allowance-copy.d.ts +25 -0
- package/dist/usage/summary.d.ts +35 -0
- package/dist/usage.d.ts +13 -0
- package/dist/usage.js +1074 -0
- package/dist/usage.js.map +1 -0
- package/package.json +44 -4
- package/src/accounts.tsx +1072 -0
- package/src/approvals.ts +8 -1
- package/src/artifacts.ts +42 -0
- package/src/assets/README.md +8 -0
- package/src/assets/gmail.ico +0 -0
- package/src/assets/outlook.ico +0 -0
- package/src/capability-catalog-row.tsx +94 -0
- package/src/capability-logo-fallback.ts +22 -0
- package/src/client.ts +22 -13
- package/src/commands/registry.ts +18 -15
- package/src/commands/types.ts +2 -0
- package/src/components/anthropic-mark.tsx +10 -0
- package/src/components/approval-surface.tsx +171 -37
- package/src/components/artifacts/artifact-chrome.tsx +413 -0
- package/src/components/artifacts/artifact-sandbox.tsx +185 -0
- package/src/components/artifacts/artifact-surface.tsx +39 -19
- package/src/components/artifacts/chat-interactive-block.tsx +260 -0
- package/src/components/artifacts/deferred-chat-media.tsx +67 -0
- package/src/components/artifacts/document-editor.tsx +141 -16
- package/src/components/artifacts/editable-artifact-ui.tsx +4 -2
- package/src/components/artifacts/editable-artifact-view.tsx +187 -0
- package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
- package/src/components/artifacts/editable-document.tsx +37 -36
- package/src/components/artifacts/editable-presentation.tsx +36 -18
- package/src/components/artifacts/editable-spreadsheet.tsx +5 -2
- package/src/components/artifacts/index.ts +44 -0
- package/src/components/artifacts/inline-html-document.ts +24 -0
- package/src/components/artifacts/latest-task-runner.ts +49 -0
- package/src/components/artifacts/presentation-editor.tsx +323 -67
- package/src/components/artifacts/published-html-artifact-frame.tsx +338 -5
- package/src/components/artifacts/session-artifact-viewer.tsx +376 -0
- package/src/components/artifacts/site-view.tsx +116 -0
- package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
- package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
- package/src/components/artifacts/spreadsheet-grid.tsx +12 -13
- package/src/components/artifacts/visualization-assets/base.css +1015 -0
- package/src/components/artifacts/visualization-assets/helpers.html +349 -0
- package/src/components/artifacts/visualization-assets.gen.ts +3 -0
- package/src/components/browser-select-control.tsx +312 -0
- package/src/components/browser-viewer.tsx +1054 -314
- package/src/components/chat-composer.tsx +131 -85
- package/src/components/child-session-link.tsx +27 -0
- package/src/components/claude-mark.tsx +10 -0
- package/src/components/code-editor.tsx +13 -16
- package/src/components/composer-transcription-control.tsx +7 -5
- package/src/components/composer.tsx +376 -49
- package/src/components/computer-viewer.tsx +1041 -329
- package/src/components/copy-button.tsx +13 -5
- package/src/components/desktop-viewer.tsx +1 -1
- package/src/components/enrollment-consent.tsx +65 -7
- package/src/components/enrollment-device-flow.tsx +1 -1
- package/src/components/file-browser.tsx +158 -34
- package/src/components/fleet-tile.tsx +8 -16
- package/src/components/generated-video-player.tsx +4 -2
- package/src/components/grok-mark.tsx +33 -0
- package/src/components/human-input-form.tsx +455 -114
- package/src/components/human-input-surface.tsx +18 -7
- package/src/components/interaction-intervention-banner.tsx +2 -2
- package/src/components/machine-card.tsx +119 -4
- package/src/components/machine-dock-bar.tsx +1 -1
- package/src/components/machine-input-display.ts +23 -2
- package/src/components/machines/machine-detail.tsx +52 -2
- package/src/components/machines/machine-operation-policy.tsx +179 -0
- package/src/components/machines-dashboard.tsx +8 -17
- package/src/components/markdown-table-layout.ts +132 -0
- package/src/components/markdown.tsx +473 -44
- package/src/components/message-timeline.tsx +2498 -663
- package/src/components/model-mark.tsx +90 -0
- package/src/components/model-picker.tsx +15 -4
- package/src/components/model-policy-picker-menu.tsx +424 -0
- package/src/components/model-policy-picker.tsx +337 -381
- package/src/components/open-geni-chat.tsx +319 -0
- package/src/components/open-geni-links.tsx +179 -0
- package/src/components/openrouter-mark.tsx +13 -0
- package/src/components/pierre-diff.tsx +41 -16
- package/src/components/pierre-file.tsx +36 -11
- package/src/components/preview-loading.tsx +154 -0
- package/src/components/queue-item-content.ts +14 -0
- package/src/components/queue-surface-implementation.tsx +132 -42
- package/src/components/queue-surface-state.tsx +3 -1
- package/src/components/sandbox-files.tsx +267 -35
- package/src/components/sandbox-terminal.tsx +48 -11
- package/src/components/sandbox-workspace.tsx +337 -135
- package/src/components/session-capability-frame.tsx +192 -0
- package/src/components/session-chrome.tsx +1027 -328
- package/src/components/session-commands-panel.tsx +126 -0
- package/src/components/session-commands.tsx +18 -0
- package/src/components/session-connection-request.tsx +97 -0
- package/src/components/session-conversation.tsx +512 -0
- package/src/components/session-list.tsx +250 -0
- package/src/components/session-mcp-capability-card.tsx +680 -0
- package/src/components/session-status.tsx +1 -1
- package/src/components/timeline-anchor.tsx +119 -0
- package/src/components/timeline-annotation-chrome.tsx +196 -0
- package/src/components/timeline-annotation-layout.ts +268 -0
- package/src/components/timeline-annotation-markers.tsx +185 -0
- package/src/components/timeline-annotation-reveal-context.ts +9 -0
- package/src/components/timeline-annotation-selection.tsx +106 -54
- package/src/components/timeline-annotation-shared.ts +245 -0
- package/src/components/timeline-annotations-dialog.tsx +185 -128
- package/src/components/timeline-annotations.tsx +189 -45
- package/src/components/timeline-reading-progress.ts +80 -0
- package/src/components/timeline-search.tsx +168 -0
- package/src/components/timeline-settlement.ts +60 -0
- package/src/components/tip-follow.ts +70 -7
- package/src/components/tooltip.tsx +38 -5
- package/src/components/usage-limit-notice.tsx +179 -0
- package/src/components/usage-member-list.tsx +792 -0
- package/src/components/usage-meter.tsx +382 -0
- package/src/components/use-viewer-menu-dismiss.ts +33 -0
- package/src/components/user-message-body.tsx +194 -49
- package/src/components/workspace-dock.tsx +141 -175
- package/src/composer.ts +6 -1
- package/src/connect-account-identity.tsx +34 -0
- package/src/connect-accounts.tsx +233 -0
- package/src/connect-chooser.tsx +336 -0
- package/src/connect-panel.tsx +99 -0
- package/src/connect-setup.tsx +307 -0
- package/src/connect.ts +60 -0
- package/src/connection-assets.d.ts +4 -0
- package/src/connection-catalog.tsx +162 -0
- package/src/connection-discovery.tsx +235 -0
- package/src/connection-installed.tsx +51 -0
- package/src/connection-logo.tsx +37 -0
- package/src/connection-service-logo.tsx +55 -0
- package/src/connection-service-presentation.ts +46 -0
- package/src/connection-skeleton.tsx +16 -0
- package/src/connection-type-picker.tsx +36 -0
- package/src/conversation-timeline.ts +92 -0
- package/src/desktop.ts +24 -0
- package/src/device-authorization.tsx +98 -0
- package/src/diffs.ts +16 -0
- package/src/discovery-cache.ts +42 -0
- package/src/editor.ts +13 -0
- package/src/embedded-session-client.ts +104 -0
- package/src/file-node-visibility.ts +66 -0
- package/src/hooks/channel-cache.ts +104 -0
- package/src/hooks/internal.ts +3 -2
- package/src/hooks/latest-question.ts +164 -0
- package/src/hooks/shared-machines-list.ts +239 -0
- package/src/hooks/use-attached-browsers.ts +5 -1
- package/src/hooks/use-available-models.ts +20 -14
- package/src/hooks/use-browser-frame-stream.ts +25 -3
- package/src/hooks/use-browser-session.ts +271 -71
- package/src/hooks/use-browser-sessions.ts +7 -1
- package/src/hooks/use-channels.ts +32 -10
- package/src/hooks/use-codex-accounts.ts +78 -21
- package/src/hooks/use-composer.ts +1034 -320
- package/src/hooks/use-computer-frame-stream.ts +39 -16
- package/src/hooks/use-computer-input-posture.ts +94 -0
- package/src/hooks/use-computer-session.ts +110 -32
- package/src/hooks/use-computer-sessions.ts +8 -1
- package/src/hooks/use-connect.ts +23 -0
- package/src/hooks/use-desktop-stream.ts +19 -28
- package/src/hooks/use-file-attachments.ts +118 -10
- package/src/hooks/use-goal.ts +36 -9
- package/src/hooks/use-human-input.ts +31 -4
- package/src/hooks/use-last-started-turn-policy.ts +15 -13
- package/src/hooks/use-machine-chip.ts +23 -6
- package/src/hooks/use-machines.ts +104 -6
- package/src/hooks/use-sandbox-files.ts +253 -150
- package/src/hooks/use-sandbox-git.ts +58 -29
- package/src/hooks/use-session-background-commands.ts +67 -0
- package/src/hooks/use-session-capabilities.ts +21 -2
- package/src/hooks/use-session-events.ts +759 -433
- package/src/hooks/use-session-lineage.ts +28 -6
- package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
- package/src/hooks/use-session.ts +75 -16
- package/src/hooks/use-slash-commands.ts +6 -11
- package/src/hooks/use-turn-queue.ts +113 -13
- package/src/hooks/use-usage.ts +100 -0
- package/src/hooks/use-voice-input.ts +12 -1
- package/src/hooks/use-workspace-capture.ts +3 -2
- package/src/hooks/use-workspace-edit.ts +23 -5
- package/src/hooks/use-workspace-sessions.ts +99 -11
- package/src/human-input.ts +12 -1
- package/src/identity-link-accounts.tsx +148 -0
- package/src/identity-link-consent.tsx +192 -0
- package/src/index.ts +157 -12
- package/src/interaction.ts +1 -0
- package/src/lib/error-message.ts +37 -0
- package/src/lib/format.ts +150 -14
- package/src/lib/host-theme.ts +511 -0
- package/src/lib/interaction-errors.ts +33 -0
- package/src/lib/menu-styles.ts +44 -0
- package/src/lib/pierre-diffs-loader.ts +53 -0
- package/src/lib/workbench-peers.ts +62 -0
- package/src/lib/xterm-theme.ts +23 -21
- package/src/machines.ts +9 -1
- package/src/mcp-connection-status.ts +35 -0
- package/src/model-policy.ts +223 -69
- package/src/older-history.ts +87 -0
- package/src/plugin-details.tsx +185 -0
- package/src/plugin-discovery.tsx +196 -0
- package/src/provider.tsx +55 -14
- package/src/realtime/dropdown-menu.tsx +19 -12
- package/src/realtime/realtime-control.tsx +274 -60
- package/src/session-auth-recommendation.ts +48 -0
- package/src/session-capability-policy.ts +83 -0
- package/src/session-context.ts +1 -0
- package/src/session-ui.ts +66 -2
- package/src/session.ts +18 -1
- package/src/sites-ui.tsx +402 -0
- package/src/sites.ts +3 -0
- package/src/skill-discovery.tsx +208 -0
- package/src/terminal.ts +26 -0
- package/src/timeline/activity-rail.tsx +171 -80
- package/src/timeline/allowance-exhausted-row.tsx +86 -0
- package/src/timeline/compaction-copy.ts +42 -0
- package/src/timeline/entrance.tsx +28 -3
- package/src/timeline/fleet-decision-projection.ts +2 -1
- package/src/timeline/fleet-decision-row.tsx +1 -0
- package/src/timeline/genie-loading.tsx +136 -0
- package/src/timeline/index.ts +11 -0
- package/src/timeline/knowledge-receipt.tsx +100 -0
- package/src/timeline/parsers.ts +2 -2
- package/src/timeline/platform-activity-row.tsx +216 -0
- package/src/timeline/presented-image.ts +49 -0
- package/src/timeline/projection.ts +1600 -84
- package/src/timeline/registry.ts +15 -3
- package/src/timeline/retained-image.ts +97 -0
- package/src/timeline/rolling-activity.tsx +92 -0
- package/src/timeline/screenshot-lightbox.tsx +115 -17
- package/src/timeline/shared.tsx +47 -15
- package/src/timeline/startup-preference.ts +33 -0
- package/src/timeline/startup-timings.tsx +145 -0
- package/src/timeline/tool-display-name.ts +8 -6
- package/src/timeline/tool-renderers.tsx +497 -128
- package/src/timeline/turn-summary.tsx +208 -44
- package/src/timeline/types.ts +186 -7
- package/src/types/machines.ts +10 -0
- package/src/usage/allowance-copy.ts +64 -0
- package/src/usage/summary.ts +93 -0
- package/src/usage.ts +50 -0
- package/styles/compiled.css +2098 -757
- package/styles/connect.css +284 -0
- package/styles/connect.d.ts +1 -0
- package/styles/effective-tokens.css +1 -0
- package/styles/index.css +201 -9
- package/styles/responsive.css +27 -1
- package/styles/session-capability.css +44 -0
- package/styles/tokens.css +135 -65
- package/dist/chunk-5UQPNLIO.js.map +0 -1
- package/dist/chunk-6KLX2RH5.js.map +0 -1
- package/dist/chunk-7WCLAEFV.js.map +0 -1
- package/dist/chunk-B6WPZSTT.js.map +0 -1
- package/dist/chunk-FK6VG4LL.js +0 -90
- package/dist/chunk-FK6VG4LL.js.map +0 -1
- package/dist/chunk-HA46CYQK.js.map +0 -1
- package/dist/chunk-HUIKIDM5.js.map +0 -1
- package/dist/chunk-IGC6A2ZI.js.map +0 -1
- package/dist/chunk-KCGXPP5V.js.map +0 -1
- package/dist/chunk-KZ73RL76.js.map +0 -1
- package/dist/chunk-LAKLF4PA.js +0 -141
- package/dist/chunk-LAKLF4PA.js.map +0 -1
- package/dist/chunk-LLOLUHVG.js.map +0 -1
- package/dist/chunk-MKPIAGVL.js +0 -465
- package/dist/chunk-MKPIAGVL.js.map +0 -1
- package/dist/chunk-PEI6RANI.js.map +0 -1
- package/dist/chunk-R3AZOAB5.js.map +0 -1
- package/dist/chunk-WSK7G5LE.js +0 -170
- package/dist/chunk-WSK7G5LE.js.map +0 -1
- package/dist/chunk-XBZWOM2K.js +0 -218
- package/dist/chunk-XBZWOM2K.js.map +0 -1
- package/dist/chunk-Y7OEDUJ5.js +0 -8810
- package/dist/chunk-Y7OEDUJ5.js.map +0 -1
- package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
- package/dist/hooks/use-packs.d.ts +0 -32
- package/dist/interactive-workbench-viewers-TOHBXJEE.js +0 -15
- package/dist/queue-surface-implementation-2KVJTYXH.js.map +0 -1
- package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
- package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
- package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
- package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
- package/src/hooks/use-packs.ts +0 -157
- /package/dist/{interactive-workbench-viewers-TOHBXJEE.js.map → browser-viewer-GTR5XQ7X.js.map} +0 -0
|
@@ -6,7 +6,15 @@ import {
|
|
|
6
6
|
type DesktopRfbLike,
|
|
7
7
|
type DesktopStreamCapability,
|
|
8
8
|
} from "@opengeni/sdk";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
type RefObject,
|
|
11
|
+
useCallback,
|
|
12
|
+
useEffect,
|
|
13
|
+
useRef,
|
|
14
|
+
useState,
|
|
15
|
+
useSyncExternalStore,
|
|
16
|
+
} from "react";
|
|
17
|
+
import { desktopViewerPeers } from "../lib/workbench-peers";
|
|
10
18
|
import { type DesktopWebSocketFactory, useRelayFrameStream } from "./use-relay-frame-stream";
|
|
11
19
|
|
|
12
20
|
export type UseDesktopStreamOptions = {
|
|
@@ -17,7 +25,7 @@ export type UseDesktopStreamOptions = {
|
|
|
17
25
|
/** Read-only by default (v1 ruling H). interactive only when cap.mode allows. */
|
|
18
26
|
interactive?: boolean | undefined;
|
|
19
27
|
scaleViewport?: boolean | undefined;
|
|
20
|
-
/** Custom RFB factory
|
|
28
|
+
/** Custom RFB factory. Otherwise call enableDesktopViewer() on the desktop subpath. */
|
|
21
29
|
rfbFactory?: DesktopRfbFactory | undefined;
|
|
22
30
|
/** Additional WebSocket protocols for an authenticated placement proxy. */
|
|
23
31
|
webSocketProtocols?: string[] | undefined;
|
|
@@ -35,29 +43,6 @@ export type UseDesktopStreamResult = {
|
|
|
35
43
|
sendKey?: ((keysym: number, code: string, down?: boolean) => boolean) | undefined;
|
|
36
44
|
};
|
|
37
45
|
|
|
38
|
-
/** Lazy-load @novnc/novnc's RFB as the default factory. Imported inside the
|
|
39
|
-
* connect effect so SSR / non-desktop bundles never pull the DOM-only lib.
|
|
40
|
-
* @novnc/novnc ships no types and a single `export default class RFB`. The
|
|
41
|
-
* specifier is STATIC (`import("@novnc/novnc")`) so Vite can pre-bundle and
|
|
42
|
-
* resolve it — a runtime-string indirection with `@vite-ignore` (the previous
|
|
43
|
-
* approach) hands the browser a bare specifier and throws
|
|
44
|
-
* "Failed to resolve module specifier '@novnc/novnc'". The dynamic form keeps
|
|
45
|
-
* it out of the SSR / non-desktop critical path while staying resolvable. */
|
|
46
|
-
async function defaultRfbFactory(): Promise<DesktopRfbFactory> {
|
|
47
|
-
const mod = (await import("@novnc/novnc")) as unknown as {
|
|
48
|
-
default: new (
|
|
49
|
-
t: HTMLElement,
|
|
50
|
-
u: string,
|
|
51
|
-
o: {
|
|
52
|
-
credentials?: { password?: string | undefined } | undefined;
|
|
53
|
-
wsProtocols?: string[] | undefined;
|
|
54
|
-
},
|
|
55
|
-
) => DesktopRfbLike;
|
|
56
|
-
};
|
|
57
|
-
const RFB = mod.default;
|
|
58
|
-
return (target, url, opts) => new RFB(target, url, opts);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
46
|
/**
|
|
62
47
|
* Drive the noVNC RFB lifecycle from a `DesktopStreamCapability`, using the
|
|
63
48
|
* SDK's `desktop.ts` reducer + `desktopSocketUrl`. SSR-safe: the RFB import and
|
|
@@ -87,6 +72,12 @@ export function useDesktopStream(options: UseDesktopStreamOptions): UseDesktopSt
|
|
|
87
72
|
webSocketProtocols,
|
|
88
73
|
webSocketFactory,
|
|
89
74
|
} = options;
|
|
75
|
+
const peerRevision = useSyncExternalStore(
|
|
76
|
+
desktopViewerPeers.subscribe,
|
|
77
|
+
desktopViewerPeers.revision,
|
|
78
|
+
desktopViewerPeers.revision,
|
|
79
|
+
);
|
|
80
|
+
const factoryRevision = rfbFactory ? 0 : peerRevision;
|
|
90
81
|
|
|
91
82
|
// The self-hosted PNG-frame path. Always invoked (rules of hooks); dormant
|
|
92
83
|
// unless `transport === "relay-frames"`, in which case it owns the surface.
|
|
@@ -188,7 +179,7 @@ export function useDesktopStream(options: UseDesktopStreamOptions): UseDesktopSt
|
|
|
188
179
|
|
|
189
180
|
void (async () => {
|
|
190
181
|
try {
|
|
191
|
-
const factory = rfbFactoryRef.current ?? (await
|
|
182
|
+
const factory = rfbFactoryRef.current ?? (await desktopViewerPeers.load());
|
|
192
183
|
if (disposed) return;
|
|
193
184
|
const socketUrl = desktopSocketUrl({ url });
|
|
194
185
|
setBoth(nextDesktopState(stateRef.current, { type: "negotiated" }));
|
|
@@ -232,11 +223,11 @@ export function useDesktopStream(options: UseDesktopStreamOptions): UseDesktopSt
|
|
|
232
223
|
};
|
|
233
224
|
// ONLY a real transport change reconnects: a fresh url (rotation), a new
|
|
234
225
|
// credential (RFB password OR bearer subprotocol), the transport flipping,
|
|
235
|
-
// or an explicit manual reconnect
|
|
226
|
+
// a newly registered default peer loader, or an explicit manual reconnect
|
|
236
227
|
// (`nonce`). `interactive`/`scaleViewport`/`mode`/`rfbFactory` are read via
|
|
237
228
|
// refs and applied live below — they must never re-open the socket.
|
|
238
229
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
239
|
-
}, [url, token, transport, webSocketProtocolsKey, nonce]);
|
|
230
|
+
}, [url, token, transport, webSocketProtocolsKey, nonce, factoryRevision]);
|
|
240
231
|
|
|
241
232
|
// Apply take-control / return-control to the OPEN connection in place. noVNC
|
|
242
233
|
// honours `viewOnly` live, so flipping it neither blinks the surface nor drops
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
useEmbeddedFileAttachments,
|
|
5
5
|
type EmbeddedFileAttachmentClientOverride,
|
|
6
6
|
} from "../session-context";
|
|
7
|
+
import { useErrorMessage } from "../lib/error-message";
|
|
7
8
|
|
|
8
9
|
export type UseFileAttachmentsOptions = EmbeddedFileAttachmentClientOverride & {
|
|
9
10
|
/**
|
|
@@ -13,6 +14,8 @@ export type UseFileAttachmentsOptions = EmbeddedFileAttachmentClientOverride & {
|
|
|
13
14
|
* UseFileAttachmentsResult.addFiles} (the explicit picker / drop path)
|
|
14
15
|
* bypasses it.
|
|
15
16
|
*/
|
|
17
|
+
/** Retain original uploads in the chat owner’s personal scope when private. */
|
|
18
|
+
scope?: "workspace" | "personal";
|
|
16
19
|
pasteFilter?: ((file: File) => boolean) | undefined;
|
|
17
20
|
};
|
|
18
21
|
|
|
@@ -26,7 +29,11 @@ export type FileAttachment = {
|
|
|
26
29
|
file?: FileAsset | undefined;
|
|
27
30
|
/** Object-URL for an inline preview; minted for `image/*` files only. */
|
|
28
31
|
previewUrl?: string | undefined;
|
|
32
|
+
/** Stable SDK failure code for UI behavior that must not parse error copy. */
|
|
33
|
+
errorCode?: "secure_context_required" | undefined;
|
|
29
34
|
error?: string | undefined;
|
|
35
|
+
/** Original diagnostic failure; presentation copy is kept separately in `error`. */
|
|
36
|
+
errorCause?: unknown;
|
|
30
37
|
};
|
|
31
38
|
|
|
32
39
|
export type UseFileAttachmentsResult = {
|
|
@@ -50,12 +57,25 @@ export type UseFileAttachmentsResult = {
|
|
|
50
57
|
addFromPaste: (event: { clipboardData: DataTransfer | null }) => void;
|
|
51
58
|
/** Restore already-ready server assets without recreating browser-local bytes. */
|
|
52
59
|
restoreReadyFiles: (files: Iterable<FileAsset>) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve a ready image's short-lived server preview URL on demand. Optional
|
|
62
|
+
* for upload-only embedded clients; local object-URL previews remain usable
|
|
63
|
+
* without it.
|
|
64
|
+
*/
|
|
65
|
+
loadPreview?: ((id: string, signal?: AbortSignal) => Promise<string | undefined>) | undefined;
|
|
53
66
|
/**
|
|
54
67
|
* Re-run the upload for a `failed` attachment, in place (same id, same
|
|
55
68
|
* source file). No-op for an id that isn't a known failed upload.
|
|
56
69
|
*/
|
|
57
70
|
retry: (id: string) => void;
|
|
58
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* Keep an attachment's object-URL alive for a consumer that outlives its
|
|
73
|
+
* queue entry (for example, an open route-level lightbox). The returned
|
|
74
|
+
* release is idempotent; pending revocation finishes after the last holder
|
|
75
|
+
* releases. Returns `undefined` when the attachment has no local preview.
|
|
76
|
+
*/
|
|
77
|
+
retainPreview: (id: string) => (() => void) | undefined;
|
|
78
|
+
/** Remove one attachment; revokes its object-URL after retained users finish. */
|
|
59
79
|
remove: (id: string) => void;
|
|
60
80
|
/**
|
|
61
81
|
* Remove only finalized files whose durable ids were accepted by a send.
|
|
@@ -63,12 +83,33 @@ export type UseFileAttachmentsResult = {
|
|
|
63
83
|
* next message.
|
|
64
84
|
*/
|
|
65
85
|
removeReadyFiles: (fileIds: Iterable<string>) => void;
|
|
66
|
-
/** Remove all attachments and revoke every object-URL. */
|
|
86
|
+
/** Remove all attachments and revoke every unretained object-URL. */
|
|
67
87
|
clear: () => void;
|
|
68
88
|
};
|
|
69
89
|
|
|
70
90
|
const isImage = (file: File): boolean => file.type.startsWith("image/");
|
|
71
91
|
|
|
92
|
+
let fallbackAttachmentId = 0;
|
|
93
|
+
|
|
94
|
+
function createAttachmentId(): string {
|
|
95
|
+
const cryptoSource = globalThis.crypto;
|
|
96
|
+
if (typeof cryptoSource?.randomUUID === "function") return cryptoSource.randomUUID();
|
|
97
|
+
fallbackAttachmentId += 1;
|
|
98
|
+
// This id is only a browser-local React key and retry lookup, never durable
|
|
99
|
+
// authority. Keep attachment tracking usable when HTTP withholds randomUUID
|
|
100
|
+
// or Web Crypto is unavailable so the SDK's typed failure reaches the card.
|
|
101
|
+
return `attachment:${Date.now().toString(36)}:${fallbackAttachmentId.toString(36)}`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function secureContextRequiredErrorCode(error: unknown): "secure_context_required" | undefined {
|
|
105
|
+
return typeof error === "object" &&
|
|
106
|
+
error !== null &&
|
|
107
|
+
"code" in error &&
|
|
108
|
+
error.code === "secure_context_required"
|
|
109
|
+
? error.code
|
|
110
|
+
: undefined;
|
|
111
|
+
}
|
|
112
|
+
|
|
72
113
|
/**
|
|
73
114
|
* Upload-and-track state for files attached to the next message. Owns the
|
|
74
115
|
* full client-side upload layer: a per-file `uploading | ready | failed`
|
|
@@ -82,8 +123,11 @@ export function useFileAttachments(
|
|
|
82
123
|
options: UseFileAttachmentsOptions = {},
|
|
83
124
|
): UseFileAttachmentsResult {
|
|
84
125
|
const { client, workspaceId } = useEmbeddedFileAttachments(options);
|
|
126
|
+
const formatError = useErrorMessage();
|
|
85
127
|
const pasteFilter = options.pasteFilter ?? isImage;
|
|
86
128
|
const [attachments, setAttachments] = useState<FileAttachment[]>([]);
|
|
129
|
+
const attachmentsRef = useRef(attachments);
|
|
130
|
+
attachmentsRef.current = attachments;
|
|
87
131
|
// Keep the source File per attachment id so a failed upload can be retried
|
|
88
132
|
// in place. Cleared on remove/clear so it never outlives its attachment.
|
|
89
133
|
const sources = useRef<Map<string, File>>(new Map());
|
|
@@ -91,17 +135,41 @@ export function useFileAttachments(
|
|
|
91
135
|
// state update when its component unmounts in the same batch that minted the
|
|
92
136
|
// preview. The registry remains available to cleanup even before a render.
|
|
93
137
|
const previewUrls = useRef<Map<string, string>>(new Map());
|
|
138
|
+
const previewRetainers = useRef<Map<string, number>>(new Map());
|
|
139
|
+
const pendingPreviewRevocations = useRef<Set<string>>(new Set());
|
|
94
140
|
const revokePreview = useCallback((id: string) => {
|
|
95
141
|
const previewUrl = previewUrls.current.get(id);
|
|
96
142
|
if (!previewUrl) return;
|
|
143
|
+
if ((previewRetainers.current.get(id) ?? 0) > 0) {
|
|
144
|
+
pendingPreviewRevocations.current.add(id);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
97
147
|
previewUrls.current.delete(id);
|
|
148
|
+
pendingPreviewRevocations.current.delete(id);
|
|
98
149
|
URL.revokeObjectURL(previewUrl);
|
|
99
150
|
}, []);
|
|
100
151
|
const revokeAllPreviews = useCallback(() => {
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
152
|
+
for (const id of previewUrls.current.keys()) revokePreview(id);
|
|
153
|
+
}, [revokePreview]);
|
|
154
|
+
const retainPreview = useCallback(
|
|
155
|
+
(id: string): (() => void) | undefined => {
|
|
156
|
+
if (!previewUrls.current.has(id)) return undefined;
|
|
157
|
+
previewRetainers.current.set(id, (previewRetainers.current.get(id) ?? 0) + 1);
|
|
158
|
+
let released = false;
|
|
159
|
+
return () => {
|
|
160
|
+
if (released) return;
|
|
161
|
+
released = true;
|
|
162
|
+
const remaining = (previewRetainers.current.get(id) ?? 1) - 1;
|
|
163
|
+
if (remaining > 0) {
|
|
164
|
+
previewRetainers.current.set(id, remaining);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
previewRetainers.current.delete(id);
|
|
168
|
+
if (pendingPreviewRevocations.current.has(id)) revokePreview(id);
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
[revokePreview],
|
|
172
|
+
);
|
|
105
173
|
// Ready-file reconciliation uses functional state updaters, which React may
|
|
106
174
|
// evaluate during a concurrent render that later suspends or is abandoned.
|
|
107
175
|
// Diff only committed attachment sets here so URL revocation cannot run from
|
|
@@ -150,6 +218,7 @@ export function useFileAttachments(
|
|
|
150
218
|
filename: file.name || "file",
|
|
151
219
|
contentType: file.type || "application/octet-stream",
|
|
152
220
|
data: file,
|
|
221
|
+
...(options.scope ? { scope: options.scope } : {}),
|
|
153
222
|
})
|
|
154
223
|
.then((asset) => {
|
|
155
224
|
if (scopeGeneration.current !== generation) return;
|
|
@@ -167,7 +236,9 @@ export function useFileAttachments(
|
|
|
167
236
|
name: asset.filename,
|
|
168
237
|
contentType: asset.contentType,
|
|
169
238
|
sizeBytes: asset.sizeBytes,
|
|
239
|
+
errorCode: undefined,
|
|
170
240
|
error: undefined,
|
|
241
|
+
errorCause: undefined,
|
|
171
242
|
}
|
|
172
243
|
: attachment,
|
|
173
244
|
),
|
|
@@ -181,20 +252,22 @@ export function useFileAttachments(
|
|
|
181
252
|
? {
|
|
182
253
|
...attachment,
|
|
183
254
|
status: "failed",
|
|
184
|
-
|
|
255
|
+
errorCode: secureContextRequiredErrorCode(error),
|
|
256
|
+
error: formatError(error),
|
|
257
|
+
errorCause: error,
|
|
185
258
|
}
|
|
186
259
|
: attachment,
|
|
187
260
|
),
|
|
188
261
|
);
|
|
189
262
|
});
|
|
190
263
|
},
|
|
191
|
-
[client, workspaceId],
|
|
264
|
+
[client, workspaceId, options.scope, formatError],
|
|
192
265
|
);
|
|
193
266
|
|
|
194
267
|
const addFiles = useCallback(
|
|
195
268
|
(files: Iterable<File>) => {
|
|
196
269
|
for (const file of files) {
|
|
197
|
-
const id =
|
|
270
|
+
const id = createAttachmentId();
|
|
198
271
|
sources.current.set(id, file);
|
|
199
272
|
const previewUrl = isImage(file) ? URL.createObjectURL(file) : undefined;
|
|
200
273
|
if (previewUrl) previewUrls.current.set(id, previewUrl);
|
|
@@ -224,7 +297,13 @@ export function useFileAttachments(
|
|
|
224
297
|
setAttachments((current) =>
|
|
225
298
|
current.map((attachment) =>
|
|
226
299
|
attachment.id === id
|
|
227
|
-
? {
|
|
300
|
+
? {
|
|
301
|
+
...attachment,
|
|
302
|
+
status: "uploading",
|
|
303
|
+
errorCode: undefined,
|
|
304
|
+
error: undefined,
|
|
305
|
+
errorCause: undefined,
|
|
306
|
+
}
|
|
228
307
|
: attachment,
|
|
229
308
|
),
|
|
230
309
|
);
|
|
@@ -274,7 +353,9 @@ export function useFileAttachments(
|
|
|
274
353
|
sizeBytes: file.sizeBytes,
|
|
275
354
|
status: "ready",
|
|
276
355
|
file,
|
|
356
|
+
errorCode: undefined,
|
|
277
357
|
error: undefined,
|
|
358
|
+
errorCause: undefined,
|
|
278
359
|
}
|
|
279
360
|
: {
|
|
280
361
|
id: `restored:${file.id}`,
|
|
@@ -296,6 +377,31 @@ export function useFileAttachments(
|
|
|
296
377
|
[workspaceId],
|
|
297
378
|
);
|
|
298
379
|
|
|
380
|
+
const loadPreview = useCallback(
|
|
381
|
+
async (id: string, signal?: AbortSignal): Promise<string | undefined> => {
|
|
382
|
+
const generation = scopeGeneration.current;
|
|
383
|
+
const attachment = attachmentsRef.current.find((candidate) => candidate.id === id);
|
|
384
|
+
const createDownloadUrl = client.createFileDownloadUrl;
|
|
385
|
+
if (
|
|
386
|
+
!attachment ||
|
|
387
|
+
attachment.status !== "ready" ||
|
|
388
|
+
!attachment.file ||
|
|
389
|
+
!attachment.contentType.startsWith("image/") ||
|
|
390
|
+
typeof createDownloadUrl !== "function" ||
|
|
391
|
+
signal?.aborted
|
|
392
|
+
) {
|
|
393
|
+
return undefined;
|
|
394
|
+
}
|
|
395
|
+
const fileId = attachment.file.id;
|
|
396
|
+
const signed = await createDownloadUrl.call(client, workspaceId, fileId, { signal });
|
|
397
|
+
if (scopeGeneration.current !== generation || signal?.aborted) return undefined;
|
|
398
|
+
const current = attachmentsRef.current.find((candidate) => candidate.id === id);
|
|
399
|
+
if (current?.status !== "ready" || current.file?.id !== fileId) return undefined;
|
|
400
|
+
return signed.url;
|
|
401
|
+
},
|
|
402
|
+
[client, workspaceId],
|
|
403
|
+
);
|
|
404
|
+
|
|
299
405
|
const remove = useCallback(
|
|
300
406
|
(id: string) => {
|
|
301
407
|
sources.current.delete(id);
|
|
@@ -337,7 +443,9 @@ export function useFileAttachments(
|
|
|
337
443
|
addFiles,
|
|
338
444
|
addFromPaste,
|
|
339
445
|
restoreReadyFiles,
|
|
446
|
+
...(typeof client.createFileDownloadUrl === "function" ? { loadPreview } : {}),
|
|
340
447
|
retry,
|
|
448
|
+
retainPreview,
|
|
341
449
|
remove,
|
|
342
450
|
removeReadyFiles,
|
|
343
451
|
clear,
|
package/src/hooks/use-goal.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { OpenGeniApiError, type SessionEvent, type SessionGoal } from "@opengeni/sdk";
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { useEmbeddedGoal, type EmbeddedGoalClientOverride } from "../session-context";
|
|
4
|
+
import { normalizeError } from "../lib/error-message";
|
|
4
5
|
import {
|
|
5
6
|
useDebouncedCallback,
|
|
6
7
|
useMutationRunner,
|
|
@@ -83,14 +84,26 @@ export function useGoal(
|
|
|
83
84
|
const { run, mutating, mutationError, clearMutationError } = useMutationRunner();
|
|
84
85
|
const generation = useRef(0);
|
|
85
86
|
const targetKeyRef = useRef<string | null>(null);
|
|
87
|
+
const loadAbort = useRef<AbortController | null>(null);
|
|
88
|
+
|
|
89
|
+
const retireLoads = useCallback(() => {
|
|
90
|
+
generation.current += 1;
|
|
91
|
+
loadAbort.current?.abort();
|
|
92
|
+
loadAbort.current = null;
|
|
93
|
+
}, []);
|
|
86
94
|
|
|
87
95
|
const load = useCallback(async (): Promise<void> => {
|
|
88
96
|
if (!sessionId) {
|
|
89
97
|
return;
|
|
90
98
|
}
|
|
91
99
|
const ticket = ++generation.current;
|
|
100
|
+
loadAbort.current?.abort();
|
|
101
|
+
const controller = new AbortController();
|
|
102
|
+
loadAbort.current = controller;
|
|
92
103
|
try {
|
|
93
|
-
const fetched = await client.getGoal(workspaceId, sessionId
|
|
104
|
+
const fetched = await client.getGoal(workspaceId, sessionId, {
|
|
105
|
+
signal: controller.signal,
|
|
106
|
+
});
|
|
94
107
|
if (ticket === generation.current) {
|
|
95
108
|
setGoal(fetched);
|
|
96
109
|
setError(null);
|
|
@@ -105,9 +118,11 @@ export function useGoal(
|
|
|
105
118
|
setGoal(null);
|
|
106
119
|
setError(null);
|
|
107
120
|
} else {
|
|
108
|
-
setError(
|
|
121
|
+
setError(normalizeError(cause));
|
|
109
122
|
}
|
|
110
123
|
setLoading(false);
|
|
124
|
+
} finally {
|
|
125
|
+
if (loadAbort.current === controller) loadAbort.current = null;
|
|
111
126
|
}
|
|
112
127
|
}, [client, workspaceId, sessionId]);
|
|
113
128
|
|
|
@@ -119,13 +134,16 @@ export function useGoal(
|
|
|
119
134
|
setError(null);
|
|
120
135
|
}
|
|
121
136
|
if (!enabled || !pageLive) {
|
|
137
|
+
retireLoads();
|
|
122
138
|
setLoading(false);
|
|
123
139
|
return;
|
|
124
140
|
}
|
|
125
141
|
if (sharedFeed) {
|
|
126
|
-
|
|
142
|
+
// A shared log supplies invalidations, not the authoritative goal snapshot.
|
|
143
|
+
setLoading(true);
|
|
144
|
+
void load();
|
|
127
145
|
return () => {
|
|
128
|
-
|
|
146
|
+
retireLoads();
|
|
129
147
|
};
|
|
130
148
|
}
|
|
131
149
|
setLoading(true);
|
|
@@ -133,7 +151,7 @@ export function useGoal(
|
|
|
133
151
|
if (pollIntervalMs === undefined || pollIntervalMs <= 0) {
|
|
134
152
|
void load();
|
|
135
153
|
return () => {
|
|
136
|
-
|
|
154
|
+
retireLoads();
|
|
137
155
|
};
|
|
138
156
|
}
|
|
139
157
|
let cancelled = false;
|
|
@@ -149,9 +167,18 @@ export function useGoal(
|
|
|
149
167
|
return () => {
|
|
150
168
|
cancelled = true;
|
|
151
169
|
if (timer !== null) clearTimeout(timer);
|
|
152
|
-
|
|
170
|
+
retireLoads();
|
|
153
171
|
};
|
|
154
|
-
}, [
|
|
172
|
+
}, [
|
|
173
|
+
load,
|
|
174
|
+
enabled,
|
|
175
|
+
pageLive,
|
|
176
|
+
workspaceId,
|
|
177
|
+
sessionId,
|
|
178
|
+
options.pollIntervalMs,
|
|
179
|
+
retireLoads,
|
|
180
|
+
sharedFeed,
|
|
181
|
+
]);
|
|
155
182
|
|
|
156
183
|
const scheduleRefresh = useDebouncedCallback(() => void load());
|
|
157
184
|
useSessionEventTrigger(client, workspaceId, sessionId, isGoalRefreshEvent, scheduleRefresh, {
|
|
@@ -203,11 +230,11 @@ export function useGoal(
|
|
|
203
230
|
return true as const;
|
|
204
231
|
});
|
|
205
232
|
if (ok) {
|
|
206
|
-
|
|
233
|
+
retireLoads();
|
|
207
234
|
setGoal(null);
|
|
208
235
|
setError(null);
|
|
209
236
|
}
|
|
210
|
-
}, [client, workspaceId, sessionId, run]);
|
|
237
|
+
}, [client, workspaceId, sessionId, run, retireLoads]);
|
|
211
238
|
|
|
212
239
|
return {
|
|
213
240
|
goal,
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
useEmbeddedHumanInputSession,
|
|
9
9
|
type EmbeddedHumanInputClientOverride,
|
|
10
10
|
} from "../session-context";
|
|
11
|
+
import { isActionableHumanInputRequest } from "../human-input";
|
|
11
12
|
import {
|
|
12
13
|
useDebouncedCallback,
|
|
13
14
|
useMutationRunner,
|
|
@@ -70,8 +71,11 @@ export function useHumanInputRequests(
|
|
|
70
71
|
enabled,
|
|
71
72
|
pollIntervalMs: options.pollIntervalMs,
|
|
72
73
|
});
|
|
74
|
+
const loadedRequests = state.data;
|
|
75
|
+
const refreshRequests = state.refresh;
|
|
73
76
|
const mutation = useMutationRunner(`${workspaceId}\u0000${sessionId ?? ""}`);
|
|
74
77
|
const [respondingRequestId, setRespondingRequestId] = useState<string | null>(null);
|
|
78
|
+
const [deadlineVersion, setDeadlineVersion] = useState(0);
|
|
75
79
|
const respondingRequestRef = useRef<string | null>(null);
|
|
76
80
|
|
|
77
81
|
useEffect(() => {
|
|
@@ -89,6 +93,25 @@ export function useHumanInputRequests(
|
|
|
89
93
|
...(options.events !== undefined ? { events: options.events } : {}),
|
|
90
94
|
});
|
|
91
95
|
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
const now = Date.now();
|
|
98
|
+
const nextDeadline = (loadedRequests ?? []).reduce<number | null>((next, request) => {
|
|
99
|
+
if (request.status !== "pending" || !request.expiresAt) return next;
|
|
100
|
+
const deadline = Date.parse(request.expiresAt);
|
|
101
|
+
if (!Number.isFinite(deadline) || deadline <= now) return next;
|
|
102
|
+
return next === null ? deadline : Math.min(next, deadline);
|
|
103
|
+
}, null);
|
|
104
|
+
if (nextDeadline === null) return;
|
|
105
|
+
const timer = globalThis.setTimeout(
|
|
106
|
+
() => {
|
|
107
|
+
setDeadlineVersion((current) => current + 1);
|
|
108
|
+
void refreshRequests();
|
|
109
|
+
},
|
|
110
|
+
Math.min(2_147_483_647, Math.max(0, nextDeadline - now + 1)),
|
|
111
|
+
);
|
|
112
|
+
return () => globalThis.clearTimeout(timer);
|
|
113
|
+
}, [loadedRequests, refreshRequests]);
|
|
114
|
+
|
|
92
115
|
const respond = useCallback(
|
|
93
116
|
async (
|
|
94
117
|
requestId: string,
|
|
@@ -115,11 +138,15 @@ export function useHumanInputRequests(
|
|
|
115
138
|
[client, mutation, sessionId, state, workspaceId],
|
|
116
139
|
);
|
|
117
140
|
|
|
141
|
+
const now = Date.now();
|
|
142
|
+
void deadlineVersion;
|
|
118
143
|
return {
|
|
119
|
-
requests: [...(state.data ?? [])]
|
|
120
|
-
(
|
|
121
|
-
|
|
122
|
-
|
|
144
|
+
requests: [...(state.data ?? [])]
|
|
145
|
+
.filter((request) => isActionableHumanInputRequest(request, now))
|
|
146
|
+
.sort(
|
|
147
|
+
(left, right) =>
|
|
148
|
+
left.createdAt.localeCompare(right.createdAt) || left.id.localeCompare(right.id),
|
|
149
|
+
),
|
|
123
150
|
loading: state.loading,
|
|
124
151
|
error: state.error,
|
|
125
152
|
refresh: state.refresh,
|
|
@@ -33,7 +33,7 @@ function policyFromTurn(turn: SessionTurn | null | undefined): LastStartedTurnPo
|
|
|
33
33
|
return {
|
|
34
34
|
model: turn.model,
|
|
35
35
|
reasoningEffort: turn.reasoningEffort,
|
|
36
|
-
latencyMode: turn.latencyMode
|
|
36
|
+
latencyMode: turn.latencyMode,
|
|
37
37
|
turnId: turn.id,
|
|
38
38
|
};
|
|
39
39
|
}
|
|
@@ -47,25 +47,26 @@ export function useLastStartedTurnPolicy(
|
|
|
47
47
|
sessionId: string | null | undefined,
|
|
48
48
|
options: UseLastStartedTurnPolicyOptions = {},
|
|
49
49
|
): UseLastStartedTurnPolicyResult {
|
|
50
|
-
const { client, workspaceId,
|
|
51
|
-
useOpenGeni(options);
|
|
50
|
+
const { client, workspaceId, registerSessionReconciler } = useOpenGeni(options);
|
|
52
51
|
const enabled = (options.enabled ?? true) && Boolean(sessionId);
|
|
53
52
|
|
|
54
|
-
const load = useCallback(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
const load = useCallback(
|
|
54
|
+
async (signal?: AbortSignal): Promise<LastStartedTurnPolicy | null> => {
|
|
55
|
+
if (!sessionId) return null;
|
|
56
|
+
const turns = await client.listTurns(workspaceId, sessionId, {
|
|
57
|
+
latestStarted: true,
|
|
58
|
+
signal,
|
|
59
|
+
});
|
|
60
|
+
return policyFromTurn(turns[0]);
|
|
61
|
+
},
|
|
62
|
+
[client, workspaceId, sessionId],
|
|
63
|
+
);
|
|
59
64
|
|
|
60
65
|
const { data, loading, error, refresh } = usePolledValue(load, {
|
|
61
66
|
pollIntervalMs: options.pollIntervalMs,
|
|
62
67
|
enabled,
|
|
63
68
|
});
|
|
64
69
|
|
|
65
|
-
useEffect(() => {
|
|
66
|
-
if (enabled && workspaceControlEvent) void refresh();
|
|
67
|
-
}, [enabled, refresh, workspaceControlEvent]);
|
|
68
|
-
|
|
69
70
|
useEffect(() => {
|
|
70
71
|
if (!sessionId || !enabled) return;
|
|
71
72
|
return registerSessionReconciler(sessionId, "last-started-turn-policy", refresh);
|
|
@@ -73,7 +74,8 @@ export function useLastStartedTurnPolicy(
|
|
|
73
74
|
|
|
74
75
|
// Shared-feed only: the session header lives outside the route event log and
|
|
75
76
|
// must not open a second SSE. Without `events`, rely on the initial fetch +
|
|
76
|
-
// optional poll /
|
|
77
|
+
// optional poll / reconciler. Pause/resume controls do not change the last
|
|
78
|
+
// admitted turn; its own turn.started event supplies that invalidation.
|
|
77
79
|
useSessionEventTrigger(
|
|
78
80
|
client,
|
|
79
81
|
workspaceId,
|
|
@@ -4,13 +4,13 @@ import type { SessionCapabilitiesState } from "./use-session-capabilities";
|
|
|
4
4
|
import { sandboxAcceptsLiveIo } from "../lib/sandbox-liveness";
|
|
5
5
|
import { connectionStatusForState } from "../types/machines";
|
|
6
6
|
|
|
7
|
-
/** The one truthful machine indicator.
|
|
8
|
-
*
|
|
7
|
+
/** The one truthful machine indicator. Managed cold compute is sleeping; a
|
|
8
|
+
* Connected Machine that is genuinely unreachable remains offline. */
|
|
9
9
|
export type MachineChipState = "live" | "waking" | "offline";
|
|
10
10
|
|
|
11
11
|
export type MachineChip = {
|
|
12
12
|
state: MachineChipState;
|
|
13
|
-
/** A ready-to-render label ("Live" / "Waking…" / "
|
|
13
|
+
/** A ready-to-render label ("Live" / "Waking…" / "Sleeping · saved 3m ago"). */
|
|
14
14
|
label: string;
|
|
15
15
|
/** The capture time backing an offline/stale label (ISO), or null. M4 may
|
|
16
16
|
* reformat this; `label` already embeds a relative form. */
|
|
@@ -64,7 +64,8 @@ export function formatAsOf(capturedAt: string, now: number): string {
|
|
|
64
64
|
export function deriveMachineChip(input: DeriveMachineChipInput): MachineChip {
|
|
65
65
|
const now = input.now ?? Date.now();
|
|
66
66
|
const asOf = input.capturedAt ?? null;
|
|
67
|
-
const
|
|
67
|
+
const managedRestingLabel = asOf ? `Sleeping · saved ${formatAsOf(asOf, now)}` : "Sleeping";
|
|
68
|
+
const offlineLabel = "Offline";
|
|
68
69
|
|
|
69
70
|
// A connected machine has no Modal group lease, so capability negotiation
|
|
70
71
|
// legitimately reports `cold` until a stream holder is minted. Its fleet
|
|
@@ -86,6 +87,16 @@ export function deriveMachineChip(input: DeriveMachineChipInput): MachineChip {
|
|
|
86
87
|
const selfhostedOffline =
|
|
87
88
|
input.activeIsSelfhosted === true && input.activeMachineState === "offline";
|
|
88
89
|
|
|
90
|
+
// Capability negotiation has definitively failed. A retained warm intent
|
|
91
|
+
// must not turn that error into the optimistic Waking state.
|
|
92
|
+
if (input.capabilitiesState === "error") {
|
|
93
|
+
return {
|
|
94
|
+
state: "offline",
|
|
95
|
+
label: input.activeIsSelfhosted === true ? offlineLabel : managedRestingLabel,
|
|
96
|
+
asOf,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
89
100
|
// 2. Actively coming up: negotiation in flight, an edit/terminal is warming, or
|
|
90
101
|
// the active machine is (re)connecting. Never when self-hosted is hard-offline.
|
|
91
102
|
const machineWarming =
|
|
@@ -97,8 +108,14 @@ export function deriveMachineChip(input: DeriveMachineChipInput): MachineChip {
|
|
|
97
108
|
return { state: "waking", label: "Waking…", asOf };
|
|
98
109
|
}
|
|
99
110
|
|
|
100
|
-
// 3.
|
|
101
|
-
|
|
111
|
+
// 3. Managed cold compute is sleeping with saved-workspace freshness. A
|
|
112
|
+
// Connected Machine is only described as Offline when its reachability is
|
|
113
|
+
// genuinely unavailable; capture time is not a heartbeat.
|
|
114
|
+
return {
|
|
115
|
+
state: "offline",
|
|
116
|
+
label: input.activeIsSelfhosted === true ? offlineLabel : managedRestingLabel,
|
|
117
|
+
asOf,
|
|
118
|
+
};
|
|
102
119
|
}
|
|
103
120
|
|
|
104
121
|
export type UseMachineChipOptions = DeriveMachineChipInput;
|