@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
|
@@ -11,12 +11,16 @@ export type UseSessionLineageOptions = EmbeddedSessionLineageClientOverride & {
|
|
|
11
11
|
/** Refresh interval (ms). Off by default. */
|
|
12
12
|
pollIntervalMs?: number | undefined;
|
|
13
13
|
enabled?: boolean | undefined;
|
|
14
|
+
/** Optional shared causal clock invoked when each network read starts. */
|
|
15
|
+
beginRead?: (() => number) | undefined;
|
|
14
16
|
};
|
|
15
17
|
|
|
16
18
|
export type UseSessionLineageResult = {
|
|
17
19
|
lineage: SessionLineageResponse | null;
|
|
18
20
|
loading: boolean;
|
|
19
21
|
error: Error | null;
|
|
22
|
+
/** Causal generation captured when the accepted lineage read started. */
|
|
23
|
+
readGeneration: number;
|
|
20
24
|
refresh: () => Promise<void>;
|
|
21
25
|
};
|
|
22
26
|
|
|
@@ -63,12 +67,29 @@ export function useSessionLineage(
|
|
|
63
67
|
const { client, workspaceId, workspaceControlEvent, registerSessionReconciler } =
|
|
64
68
|
useEmbeddedSessionLineage(options);
|
|
65
69
|
const enabled = (options.enabled ?? true) && Boolean(sessionId);
|
|
70
|
+
const nextReadGeneration = useRef(0);
|
|
71
|
+
const beginRead = options.beginRead;
|
|
66
72
|
const load = useCallback(
|
|
67
|
-
async () =>
|
|
68
|
-
sessionId
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
async (signal?: AbortSignal) => {
|
|
74
|
+
if (!sessionId) {
|
|
75
|
+
return {
|
|
76
|
+
lineage: { ancestors: [], children: [], truncated: false },
|
|
77
|
+
readGeneration: 0,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
let readGeneration = 0;
|
|
81
|
+
const lineage = await client.getSessionLineage(workspaceId, sessionId, {
|
|
82
|
+
signal,
|
|
83
|
+
onRequestStart: (sharedReadGeneration) => {
|
|
84
|
+
readGeneration = sharedReadGeneration ?? beginRead?.() ?? ++nextReadGeneration.current;
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
return {
|
|
88
|
+
lineage,
|
|
89
|
+
readGeneration,
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
[beginRead, client, workspaceId, sessionId],
|
|
72
93
|
);
|
|
73
94
|
const state = usePolledValue(load, { pollIntervalMs: options.pollIntervalMs, enabled });
|
|
74
95
|
const refresh = state.refresh;
|
|
@@ -123,9 +144,10 @@ export function useSessionLineage(
|
|
|
123
144
|
{ events: options.events, enabled: enabled && options.events !== undefined },
|
|
124
145
|
);
|
|
125
146
|
return {
|
|
126
|
-
lineage: state.data,
|
|
147
|
+
lineage: state.data?.lineage ?? null,
|
|
127
148
|
loading: state.loading,
|
|
128
149
|
error: state.error,
|
|
150
|
+
readGeneration: state.data?.readGeneration ?? 0,
|
|
129
151
|
refresh,
|
|
130
152
|
};
|
|
131
153
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
SessionEvent,
|
|
3
3
|
SessionMcpApprovalPolicy,
|
|
4
|
-
|
|
4
|
+
SessionMcpApprovalPolicyTarget,
|
|
5
5
|
UpdateSessionMcpApprovalPolicyResponse,
|
|
6
6
|
} from "@opengeni/sdk";
|
|
7
7
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
@@ -38,7 +38,7 @@ export type UseSessionMcpApprovalPolicyOptions = EmbeddedSessionMcpApprovalPolic
|
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
export type UseSessionMcpApprovalPolicyResult = {
|
|
41
|
-
server:
|
|
41
|
+
server: SessionMcpApprovalPolicyTarget | null;
|
|
42
42
|
policy: SessionMcpApprovalPolicy | null;
|
|
43
43
|
loading: boolean;
|
|
44
44
|
error: Error | null;
|
|
@@ -61,7 +61,7 @@ export function useSessionMcpApprovalPolicy(
|
|
|
61
61
|
): UseSessionMcpApprovalPolicyResult {
|
|
62
62
|
const { client, workspaceId } = useEmbeddedSessionMcpApprovalPolicy(options);
|
|
63
63
|
const enabled = (options.enabled ?? true) && Boolean(sessionId && serverId);
|
|
64
|
-
const [override, setOverride] = useState<
|
|
64
|
+
const [override, setOverride] = useState<SessionMcpApprovalPolicyTarget | null>(null);
|
|
65
65
|
const targetKey = `${workspaceId}\u0000${sessionId ?? ""}\u0000${serverId ?? ""}`;
|
|
66
66
|
const authoritativeGeneration = useRef(0);
|
|
67
67
|
const mutationIdentity = useMemo(() => ({ client, targetKey }), [client, targetKey]);
|
|
@@ -75,7 +75,7 @@ export function useSessionMcpApprovalPolicy(
|
|
|
75
75
|
type PolicyRead = {
|
|
76
76
|
targetKey: string;
|
|
77
77
|
generation: number;
|
|
78
|
-
server:
|
|
78
|
+
server: SessionMcpApprovalPolicyTarget | null;
|
|
79
79
|
};
|
|
80
80
|
const load = useCallback(async (): Promise<PolicyRead> => {
|
|
81
81
|
const generation = authoritativeGeneration.current;
|
|
@@ -86,7 +86,15 @@ export function useSessionMcpApprovalPolicy(
|
|
|
86
86
|
return {
|
|
87
87
|
targetKey,
|
|
88
88
|
generation,
|
|
89
|
-
server:
|
|
89
|
+
server:
|
|
90
|
+
session.mcpServers.find((server) => server.id === serverId) ??
|
|
91
|
+
(session.mcpApprovalPolicies && Object.hasOwn(session.mcpApprovalPolicies, serverId)
|
|
92
|
+
? {
|
|
93
|
+
id: serverId,
|
|
94
|
+
source: "workspace",
|
|
95
|
+
requireApproval: session.mcpApprovalPolicies[serverId]!,
|
|
96
|
+
}
|
|
97
|
+
: null),
|
|
90
98
|
};
|
|
91
99
|
}, [client, serverId, sessionId, targetKey, workspaceId]);
|
|
92
100
|
const {
|
package/src/hooks/use-session.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Session, SessionEvent } from "@opengeni/sdk";
|
|
2
|
-
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { useEmbeddedSessionRead, type EmbeddedSessionReadClientOverride } from "../session-context";
|
|
4
4
|
import {
|
|
5
5
|
useMutationRunner,
|
|
@@ -12,12 +12,18 @@ export type UseSessionOptions = EmbeddedSessionReadClientOverride &
|
|
|
12
12
|
SessionEventFeedOptions & {
|
|
13
13
|
/** Re-fetch on an interval (ms). Off by default — pair with `useSessionEvents` for live status. */
|
|
14
14
|
pollIntervalMs?: number | undefined;
|
|
15
|
+
/** Optional shared causal clock invoked when each network read starts. */
|
|
16
|
+
beginRead?: (() => number) | undefined;
|
|
15
17
|
};
|
|
16
18
|
|
|
17
19
|
export type UseSessionResult = {
|
|
18
20
|
session: Session | null;
|
|
19
21
|
loading: boolean;
|
|
20
22
|
error: Error | null;
|
|
23
|
+
/** Monotonic revision of accepted authoritative detail reads. */
|
|
24
|
+
readRevision: number;
|
|
25
|
+
/** Causal generation captured when the accepted network read started. */
|
|
26
|
+
readGeneration: number;
|
|
21
27
|
refresh: () => Promise<void>;
|
|
22
28
|
/** Manually rename the session (PATCH, source='user'). Returns the updated session, or null on failure. */
|
|
23
29
|
updateTitle: (title: string) => Promise<Session | null>;
|
|
@@ -32,6 +38,16 @@ export function isTitleEvent(event: Pick<SessionEvent, "type">): boolean {
|
|
|
32
38
|
return event.type === "session.title_set";
|
|
33
39
|
}
|
|
34
40
|
|
|
41
|
+
function isSessionDetailEvent(event: Pick<SessionEvent, "type">): boolean {
|
|
42
|
+
return (
|
|
43
|
+
isTitleEvent(event) ||
|
|
44
|
+
event.type.startsWith("session.command.") ||
|
|
45
|
+
event.type.startsWith("session.wait.") ||
|
|
46
|
+
event.type === "session.status.changed" ||
|
|
47
|
+
event.type === "system.update.pending"
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
35
51
|
/** Fetch one session (with optional polling), live-patching its title on `session.title_set`. */
|
|
36
52
|
export function useSession(
|
|
37
53
|
sessionId: string | null | undefined,
|
|
@@ -41,16 +57,33 @@ export function useSession(
|
|
|
41
57
|
useEmbeddedSessionRead(options);
|
|
42
58
|
const enabled = (options.enabled ?? true) && Boolean(sessionId);
|
|
43
59
|
const [override, setOverride] = useState<Session | null>(null);
|
|
60
|
+
const nextReadRevision = useRef(0);
|
|
61
|
+
const nextReadGeneration = useRef(0);
|
|
62
|
+
const beginRead = options.beginRead;
|
|
44
63
|
const { run, mutating, mutationError, clearMutationError } = useMutationRunner();
|
|
45
|
-
const load = useCallback(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
64
|
+
const load = useCallback(
|
|
65
|
+
async (signal?: AbortSignal) => {
|
|
66
|
+
if (!sessionId) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
let readGeneration = 0;
|
|
70
|
+
const fetched = await client.getSession(workspaceId, sessionId, {
|
|
71
|
+
fresh: true,
|
|
72
|
+
signal,
|
|
73
|
+
onRequestStart: () => {
|
|
74
|
+
readGeneration = beginRead?.() ?? ++nextReadGeneration.current;
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
// A fresh server read supersedes any optimistic/event-driven override.
|
|
78
|
+
setOverride(null);
|
|
79
|
+
return {
|
|
80
|
+
session: fetched,
|
|
81
|
+
revision: ++nextReadRevision.current,
|
|
82
|
+
readGeneration,
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
[beginRead, client, workspaceId, sessionId],
|
|
86
|
+
);
|
|
54
87
|
const { data, loading, error, refresh } = usePolledValue(load, {
|
|
55
88
|
pollIntervalMs: options.pollIntervalMs,
|
|
56
89
|
enabled,
|
|
@@ -63,7 +96,9 @@ export function useSession(
|
|
|
63
96
|
return registerSessionReconciler(sessionId, "session", refresh);
|
|
64
97
|
}, [enabled, refresh, registerSessionReconciler, sessionId]);
|
|
65
98
|
|
|
66
|
-
const base = data ?? null;
|
|
99
|
+
const base = data?.session ?? null;
|
|
100
|
+
const readRevision = data?.revision ?? 0;
|
|
101
|
+
const readGeneration = data?.readGeneration ?? 0;
|
|
67
102
|
// The override only ever carries title/titleSource patches; it is reset on
|
|
68
103
|
// every fresh load so it can never go stale against the server snapshot.
|
|
69
104
|
const session = useMemo(
|
|
@@ -74,10 +109,35 @@ export function useSession(
|
|
|
74
109
|
[base, override],
|
|
75
110
|
);
|
|
76
111
|
|
|
112
|
+
const sharedEvents = options.events;
|
|
113
|
+
|
|
77
114
|
// Live-patch the title on auto (agent) + cross-client (user/agent) renames so
|
|
78
115
|
// the UI reflects the new title without polling or a full re-fetch.
|
|
79
116
|
const onTitleEvent = useCallback(
|
|
80
117
|
(event: SessionEvent) => {
|
|
118
|
+
// Reconciliation emits only the last matching member of a shared batch.
|
|
119
|
+
// A later title must not hide an earlier command activity change.
|
|
120
|
+
if (
|
|
121
|
+
sharedEvents?.some(
|
|
122
|
+
(item) =>
|
|
123
|
+
item.sessionId === sessionId &&
|
|
124
|
+
!isTitleEvent(item) &&
|
|
125
|
+
isSessionDetailEvent(item) &&
|
|
126
|
+
item.sequence > (base?.lastSequence ?? -1),
|
|
127
|
+
)
|
|
128
|
+
) {
|
|
129
|
+
void refresh();
|
|
130
|
+
} else if (!isTitleEvent(event)) {
|
|
131
|
+
if (!base || event.sequence > base.lastSequence) void refresh();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// The fetched session row is the authoritative title projection through
|
|
135
|
+
// lastSequence. Shared feeds may replay that historical tail after the
|
|
136
|
+
// fetch; applying it would undo a row-only migration quarantine. Only an
|
|
137
|
+
// event committed after this snapshot may live-patch the title.
|
|
138
|
+
if (!base || event.sequence <= base.lastSequence) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
81
141
|
const payload = (event.payload ?? {}) as { title?: unknown; source?: unknown };
|
|
82
142
|
const title = payload.title;
|
|
83
143
|
if (typeof title !== "string") {
|
|
@@ -87,15 +147,12 @@ export function useSession(
|
|
|
87
147
|
payload.source === "user" || payload.source === "agent" ? payload.source : null;
|
|
88
148
|
setOverride((current): Session | null => {
|
|
89
149
|
const next = current ?? base;
|
|
90
|
-
if (!next) {
|
|
91
|
-
return current;
|
|
92
|
-
}
|
|
93
150
|
return { ...next, title, titleSource: source };
|
|
94
151
|
});
|
|
95
152
|
},
|
|
96
|
-
[base],
|
|
153
|
+
[base, refresh, sharedEvents, sessionId],
|
|
97
154
|
);
|
|
98
|
-
useSessionEventTrigger(client, workspaceId, sessionId,
|
|
155
|
+
useSessionEventTrigger(client, workspaceId, sessionId, isSessionDetailEvent, onTitleEvent, {
|
|
99
156
|
enabled,
|
|
100
157
|
...(options.events !== undefined ? { events: options.events } : {}),
|
|
101
158
|
});
|
|
@@ -118,6 +175,8 @@ export function useSession(
|
|
|
118
175
|
session,
|
|
119
176
|
loading,
|
|
120
177
|
error,
|
|
178
|
+
readRevision,
|
|
179
|
+
readGeneration,
|
|
121
180
|
refresh,
|
|
122
181
|
updateTitle,
|
|
123
182
|
updating: mutating,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { KeyboardEvent } from "react";
|
|
2
2
|
import { useCallback, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { useErrorMessage } from "../lib/error-message";
|
|
3
4
|
import {
|
|
4
5
|
argHint,
|
|
5
6
|
filterCommands,
|
|
@@ -81,6 +82,7 @@ export type UseSlashCommandsResult = {
|
|
|
81
82
|
};
|
|
82
83
|
|
|
83
84
|
export function useSlashCommands(options: UseSlashCommandsOptions): UseSlashCommandsResult {
|
|
85
|
+
const formatError = useErrorMessage();
|
|
84
86
|
const { commands, context, handlers, value, setValue } = options;
|
|
85
87
|
const [highlight, setHighlight] = useState(0);
|
|
86
88
|
// Escape closes the palette but keeps the draft. We remember the dismissed
|
|
@@ -153,9 +155,9 @@ export function useSlashCommands(options: UseSlashCommandsOptions): UseSlashComm
|
|
|
153
155
|
if (!context) {
|
|
154
156
|
return null;
|
|
155
157
|
}
|
|
156
|
-
return { ...context, ...handlers, confirm: () => handlers.confirm(command) };
|
|
158
|
+
return { ...context, ...handlers, formatError, confirm: () => handlers.confirm(command) };
|
|
157
159
|
},
|
|
158
|
-
[context, handlers],
|
|
160
|
+
[context, handlers, formatError],
|
|
159
161
|
);
|
|
160
162
|
|
|
161
163
|
const execute = useCallback(
|
|
@@ -173,10 +175,10 @@ export function useSlashCommands(options: UseSlashCommandsOptions): UseSlashComm
|
|
|
173
175
|
setValue("");
|
|
174
176
|
}
|
|
175
177
|
} catch (cause) {
|
|
176
|
-
ctx.notice({ tone: "error", message:
|
|
178
|
+
ctx.notice({ tone: "error", message: formatError(cause) });
|
|
177
179
|
}
|
|
178
180
|
},
|
|
179
|
-
[buildContext, setValue],
|
|
181
|
+
[buildContext, setValue, formatError],
|
|
180
182
|
);
|
|
181
183
|
|
|
182
184
|
const autocomplete = useCallback(
|
|
@@ -359,10 +361,3 @@ export function useSlashCommands(options: UseSlashCommandsOptions): UseSlashComm
|
|
|
359
361
|
autocompleteHighlighted,
|
|
360
362
|
};
|
|
361
363
|
}
|
|
362
|
-
|
|
363
|
-
function errorMessage(cause: unknown): string {
|
|
364
|
-
if (cause instanceof Error) {
|
|
365
|
-
return cause.message;
|
|
366
|
-
}
|
|
367
|
-
return String(cause);
|
|
368
|
-
}
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
} from "@opengeni/sdk";
|
|
11
11
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
12
12
|
import { useEmbeddedSession, type EmbeddedSessionClientOverride } from "../session-context";
|
|
13
|
+
import { normalizeError } from "../lib/error-message";
|
|
13
14
|
import {
|
|
14
15
|
useDebouncedCallback,
|
|
15
16
|
usePageLiveActivity,
|
|
@@ -42,6 +43,17 @@ function queueSnapshotCovers(
|
|
|
42
43
|
export type QueueMutationKind = "move" | "edit" | "steer" | "delete";
|
|
43
44
|
const EMPTY_PENDING_BY_TURN: Readonly<Record<string, QueueMutationKind>> = {};
|
|
44
45
|
|
|
46
|
+
export type AcceptedQueueSteer = {
|
|
47
|
+
turnId: string;
|
|
48
|
+
triggerEventId: string;
|
|
49
|
+
text: string;
|
|
50
|
+
annotations: SessionTurn["annotations"];
|
|
51
|
+
resources: SessionTurn["resources"];
|
|
52
|
+
tools: SessionTurn["tools"];
|
|
53
|
+
occurredAt: string;
|
|
54
|
+
state: "sending" | "queued";
|
|
55
|
+
};
|
|
56
|
+
|
|
45
57
|
export type UseTurnQueueOptions = EmbeddedSessionClientOverride &
|
|
46
58
|
SessionEventFeedOptions & {
|
|
47
59
|
pollIntervalMs?: number | undefined;
|
|
@@ -77,6 +89,8 @@ export type UseTurnQueueResult = {
|
|
|
77
89
|
mutating: boolean;
|
|
78
90
|
mutationError: Error | null;
|
|
79
91
|
clearMutationError: () => void;
|
|
92
|
+
/** Immediate chat bridge while the durable Steer event catches up over SSE. */
|
|
93
|
+
acceptedSteers?: AcceptedQueueSteer[] | undefined;
|
|
80
94
|
};
|
|
81
95
|
|
|
82
96
|
/**
|
|
@@ -99,6 +113,7 @@ export function useTurnQueue(
|
|
|
99
113
|
const [error, setError] = useState<Error | null>(null);
|
|
100
114
|
const [mutationError, setMutationError] = useState<Error | null>(null);
|
|
101
115
|
const [pendingByTurn, setPendingByTurn] = useState<Record<string, QueueMutationKind>>({});
|
|
116
|
+
const [acceptedSteers, setAcceptedSteers] = useState<AcceptedQueueSteer[]>([]);
|
|
102
117
|
const pendingRef = useRef<Record<string, QueueMutationKind>>({});
|
|
103
118
|
const readGeneration = useRef(0);
|
|
104
119
|
const targetKeyRef = useRef(targetKey);
|
|
@@ -118,8 +133,26 @@ export function useTurnQueue(
|
|
|
118
133
|
setError(null);
|
|
119
134
|
setMutationError(null);
|
|
120
135
|
setPendingByTurn({});
|
|
136
|
+
setAcceptedSteers([]);
|
|
121
137
|
}, [enabled, targetKey]);
|
|
122
138
|
|
|
139
|
+
useEffect(() => {
|
|
140
|
+
if (acceptedSteers.length === 0 || options.events === undefined) return;
|
|
141
|
+
const durablyStartedTurnIds = new Set(
|
|
142
|
+
options.events.flatMap((event) =>
|
|
143
|
+
event.type === "turn.started" && event.turnId ? [event.turnId] : [],
|
|
144
|
+
),
|
|
145
|
+
);
|
|
146
|
+
if (durablyStartedTurnIds.size === 0) return;
|
|
147
|
+
// steer_requested can reach the browser before the timeline projection
|
|
148
|
+
// that moves the queued user.message into chat. Keep this bridge through
|
|
149
|
+
// physical cancellation; turn.started is the first boundary at which the
|
|
150
|
+
// replacement timeline must already be visible.
|
|
151
|
+
setAcceptedSteers((current) =>
|
|
152
|
+
current.filter((steer) => !durablyStartedTurnIds.has(steer.turnId)),
|
|
153
|
+
);
|
|
154
|
+
}, [acceptedSteers.length, options.events]);
|
|
155
|
+
|
|
123
156
|
const acceptSnapshot = useCallback(
|
|
124
157
|
(ownedTargetKey: string, next: SessionQueueSnapshot | null): boolean => {
|
|
125
158
|
if (targetKeyRef.current !== ownedTargetKey) return false;
|
|
@@ -234,6 +267,7 @@ export function useTurnQueue(
|
|
|
234
267
|
command: (
|
|
235
268
|
current: SessionQueueSnapshot,
|
|
236
269
|
turn: SessionTurn,
|
|
270
|
+
clientEventId: string,
|
|
237
271
|
) => Promise<SessionQueueMutationResponse>,
|
|
238
272
|
): Promise<SessionQueueMutationResponse | null> => {
|
|
239
273
|
const ownedTargetKey = targetKey;
|
|
@@ -247,8 +281,17 @@ export function useTurnQueue(
|
|
|
247
281
|
setStateTargetKey(ownedTargetKey);
|
|
248
282
|
setPendingByTurn(pendingRef.current);
|
|
249
283
|
setMutationError(null);
|
|
284
|
+
const clientEventId = operationKey();
|
|
250
285
|
try {
|
|
251
|
-
|
|
286
|
+
let result: SessionQueueMutationResponse;
|
|
287
|
+
try {
|
|
288
|
+
result = await command(current, turn, clientEventId);
|
|
289
|
+
} catch (cause) {
|
|
290
|
+
if (!isOutcomeUnknownError(cause)) throw cause;
|
|
291
|
+
// Same-key replay is a fact check against the durable receipt. It
|
|
292
|
+
// cannot duplicate the command even if the first response was lost.
|
|
293
|
+
result = await command(current, turn, clientEventId);
|
|
294
|
+
}
|
|
252
295
|
if (targetKeyRef.current !== ownedTargetKey) return null;
|
|
253
296
|
acceptSnapshot(ownedTargetKey, result.snapshot);
|
|
254
297
|
return result;
|
|
@@ -272,9 +315,9 @@ export function useTurnQueue(
|
|
|
272
315
|
|
|
273
316
|
const moveTurn = useCallback(
|
|
274
317
|
async (turnId: string, beforeTurnId: string | null): Promise<boolean> => {
|
|
275
|
-
const result = await mutate(turnId, "move", (current) =>
|
|
318
|
+
const result = await mutate(turnId, "move", (current, _turn, clientEventId) =>
|
|
276
319
|
client.moveQueueItem(workspaceId, sessionId!, turnId, {
|
|
277
|
-
clientEventId
|
|
320
|
+
clientEventId,
|
|
278
321
|
expectedQueueVersion: current.version,
|
|
279
322
|
beforeTurnId,
|
|
280
323
|
}),
|
|
@@ -289,9 +332,9 @@ export function useTurnQueue(
|
|
|
289
332
|
turnId: string,
|
|
290
333
|
edit: { expectedDraftRevision: number; replaceDraft: boolean },
|
|
291
334
|
): Promise<ComposerDraft | null> => {
|
|
292
|
-
const result = await mutate(turnId, "edit", (_current, turn) =>
|
|
335
|
+
const result = await mutate(turnId, "edit", (_current, turn, clientEventId) =>
|
|
293
336
|
client.editQueueItem(workspaceId, sessionId!, turnId, {
|
|
294
|
-
clientEventId
|
|
337
|
+
clientEventId,
|
|
295
338
|
expectedTurnVersion: turn.version,
|
|
296
339
|
expectedDraftRevision: edit.expectedDraftRevision,
|
|
297
340
|
replaceDraft: edit.replaceDraft,
|
|
@@ -304,23 +347,71 @@ export function useTurnQueue(
|
|
|
304
347
|
|
|
305
348
|
const steerTurn = useCallback(
|
|
306
349
|
async (turnId: string): Promise<boolean> => {
|
|
307
|
-
const
|
|
350
|
+
const ownedTargetKey = targetKey;
|
|
351
|
+
const turn = snapshotRef.current?.items.find((candidate) => candidate.id === turnId);
|
|
352
|
+
if (targetKeyRef.current !== ownedTargetKey) return false;
|
|
353
|
+
if (!turn) {
|
|
354
|
+
setMutationError(new Error("That queued prompt changed before Steer could be sent."));
|
|
355
|
+
await load();
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
const optimistic: AcceptedQueueSteer = {
|
|
359
|
+
turnId: turn.id,
|
|
360
|
+
triggerEventId: turn.triggerEventId,
|
|
361
|
+
text: turn.prompt,
|
|
362
|
+
annotations: turn.annotations ?? [],
|
|
363
|
+
resources: turn.resources,
|
|
364
|
+
tools: turn.tools,
|
|
365
|
+
occurredAt: new Date().toISOString(),
|
|
366
|
+
state: "sending",
|
|
367
|
+
};
|
|
368
|
+
setAcceptedSteers((current) => [
|
|
369
|
+
...current.filter((steer) => steer.turnId !== turnId),
|
|
370
|
+
optimistic,
|
|
371
|
+
]);
|
|
372
|
+
const result = await mutate(turnId, "steer", (current, queuedTurn, clientEventId) =>
|
|
308
373
|
client.steerQueueItem(workspaceId, sessionId!, turnId, {
|
|
309
|
-
clientEventId
|
|
310
|
-
expectedTurnVersion:
|
|
374
|
+
clientEventId,
|
|
375
|
+
expectedTurnVersion: queuedTurn.version,
|
|
311
376
|
controlEtag: current.effectiveControl.controlEtag,
|
|
312
377
|
}),
|
|
313
378
|
);
|
|
314
|
-
|
|
379
|
+
if (targetKeyRef.current !== ownedTargetKey) return false;
|
|
380
|
+
// The active turn can finish while the operator clicks Steer. In that
|
|
381
|
+
// race the queued prompt is atomically claimed before the steer command,
|
|
382
|
+
// so the command conflicts but the user's prompt already advanced into
|
|
383
|
+
// chat. Reconciled absence is success, not a scary unknown-outcome lie.
|
|
384
|
+
const advancedWithoutSteer =
|
|
385
|
+
result === null &&
|
|
386
|
+
snapshotRef.current !== null &&
|
|
387
|
+
!snapshotRef.current.items.some((candidate) => candidate.id === turnId);
|
|
388
|
+
if (advancedWithoutSteer) {
|
|
389
|
+
setMutationError(null);
|
|
390
|
+
setAcceptedSteers((current) => current.filter((steer) => steer.turnId !== turnId));
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
const accepted =
|
|
394
|
+
result !== null ||
|
|
395
|
+
snapshotRef.current?.items.some(
|
|
396
|
+
(candidate) => candidate.id === turnId && candidate.metadata.delivery === "steer",
|
|
397
|
+
) === true;
|
|
398
|
+
setAcceptedSteers((current) =>
|
|
399
|
+
accepted
|
|
400
|
+
? current.map((steer) =>
|
|
401
|
+
steer.turnId === turnId ? { ...steer, state: "queued" as const } : steer,
|
|
402
|
+
)
|
|
403
|
+
: current.filter((steer) => steer.turnId !== turnId),
|
|
404
|
+
);
|
|
405
|
+
return accepted;
|
|
315
406
|
},
|
|
316
|
-
[client, mutate, sessionId, workspaceId],
|
|
407
|
+
[client, load, mutate, sessionId, targetKey, workspaceId],
|
|
317
408
|
);
|
|
318
409
|
|
|
319
410
|
const removeTurn = useCallback(
|
|
320
411
|
async (turnId: string): Promise<boolean> => {
|
|
321
|
-
const result = await mutate(turnId, "delete", (_current, turn) =>
|
|
412
|
+
const result = await mutate(turnId, "delete", (_current, turn, clientEventId) =>
|
|
322
413
|
client.deleteQueueItem(workspaceId, sessionId!, turnId, {
|
|
323
|
-
clientEventId
|
|
414
|
+
clientEventId,
|
|
324
415
|
expectedTurnVersion: turn.version,
|
|
325
416
|
reason: "Deleted from the prompt queue",
|
|
326
417
|
}),
|
|
@@ -364,6 +455,7 @@ export function useTurnQueue(
|
|
|
364
455
|
clearMutationError: useCallback(() => {
|
|
365
456
|
if (targetKeyRef.current === targetKey) setMutationError(null);
|
|
366
457
|
}, [targetKey]),
|
|
458
|
+
acceptedSteers: identityMatches ? acceptedSteers : [],
|
|
367
459
|
};
|
|
368
460
|
}
|
|
369
461
|
|
|
@@ -372,5 +464,13 @@ function operationKey(): string {
|
|
|
372
464
|
}
|
|
373
465
|
|
|
374
466
|
function asError(cause: unknown): Error {
|
|
375
|
-
return
|
|
467
|
+
return normalizeError(cause);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function isOutcomeUnknownError(cause: unknown): boolean {
|
|
471
|
+
return (
|
|
472
|
+
typeof cause === "object" &&
|
|
473
|
+
cause !== null &&
|
|
474
|
+
(cause as { outcomeUnknown?: unknown }).outcomeUnknown === true
|
|
475
|
+
);
|
|
376
476
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { OpenGeniClient } from "@opengeni/sdk";
|
|
2
|
+
import {
|
|
3
|
+
getMyUsage,
|
|
4
|
+
type UsageAllowancePeriod,
|
|
5
|
+
type WorkspaceUsageResponse,
|
|
6
|
+
} from "@opengeni/sdk/usage-allowances";
|
|
7
|
+
import { useCallback, useContext, useEffect, useMemo, useRef } from "react";
|
|
8
|
+
|
|
9
|
+
import { OpenGeniContext } from "../session-context";
|
|
10
|
+
import { summarizeUsage, type UsageSummary } from "../usage/summary";
|
|
11
|
+
import { usePolledValue } from "./internal";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Anything that can read the signed-in member's own usage: the root SDK client
|
|
15
|
+
* pointed at your session proxy (`getMyUsage`), or any client exposing
|
|
16
|
+
* `requestJson` (for example the narrower browser client).
|
|
17
|
+
*/
|
|
18
|
+
export type UsageClientLike =
|
|
19
|
+
| Pick<OpenGeniClient, "getMyUsage">
|
|
20
|
+
| Pick<OpenGeniClient, "requestJson">;
|
|
21
|
+
|
|
22
|
+
export type UseUsageOptions = {
|
|
23
|
+
/** Defaults to the `<OpenGeniProvider>` client. */
|
|
24
|
+
client?: UsageClientLike | undefined;
|
|
25
|
+
/** Defaults to the `<OpenGeniProvider>` workspace. */
|
|
26
|
+
workspaceId?: string | undefined;
|
|
27
|
+
/** `"current"` (default) or a `YYYY-MM` allowance period. */
|
|
28
|
+
period?: UsageAllowancePeriod | undefined;
|
|
29
|
+
/** Re-read on an interval. Off by default; usage changes only when work settles. */
|
|
30
|
+
pollIntervalMs?: number | undefined;
|
|
31
|
+
enabled?: boolean | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Re-read whenever this value changes, keeping the current reading while it
|
|
34
|
+
* loads. Pass something that changes when work settles (a turn count, the
|
|
35
|
+
* session status) so the meter follows real usage without polling.
|
|
36
|
+
*/
|
|
37
|
+
refreshKey?: unknown;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type UseUsageResult = {
|
|
41
|
+
/** The raw `/usage/me` response: the workspace pool and your own row. */
|
|
42
|
+
usage: WorkspaceUsageResponse | null;
|
|
43
|
+
/** What to tell this member; null until loaded. */
|
|
44
|
+
summary: UsageSummary | null;
|
|
45
|
+
loading: boolean;
|
|
46
|
+
error: Error | null;
|
|
47
|
+
refresh: () => Promise<void>;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
function readOwnUsage(
|
|
51
|
+
client: UsageClientLike,
|
|
52
|
+
workspaceId: string,
|
|
53
|
+
period: UsageAllowancePeriod | undefined,
|
|
54
|
+
signal: AbortSignal | undefined,
|
|
55
|
+
): Promise<WorkspaceUsageResponse> {
|
|
56
|
+
const query = period === undefined ? {} : { period };
|
|
57
|
+
const options = signal ? { signal } : {};
|
|
58
|
+
if ("getMyUsage" in client && typeof client.getMyUsage === "function") {
|
|
59
|
+
return client.getMyUsage(workspaceId, query, options);
|
|
60
|
+
}
|
|
61
|
+
if ("requestJson" in client && typeof client.requestJson === "function") {
|
|
62
|
+
return getMyUsage(client, workspaceId, query, options);
|
|
63
|
+
}
|
|
64
|
+
throw new Error("@opengeni/react: the usage client needs getMyUsage or requestJson.");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The signed-in member's own usage in one workspace, read through `/usage/me`
|
|
69
|
+
* (the session proxy serves exactly this route). Never reads another member.
|
|
70
|
+
*/
|
|
71
|
+
export function useUsage(options: UseUsageOptions = {}): UseUsageResult {
|
|
72
|
+
const context = useContext(OpenGeniContext);
|
|
73
|
+
const client = (options.client ?? context?.client) as UsageClientLike | undefined;
|
|
74
|
+
const workspaceId = options.workspaceId ?? context?.workspaceId;
|
|
75
|
+
if (!client || !workspaceId) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
"@opengeni/react: useUsage needs a client and workspace. Wrap the tree in <OpenGeniProvider> or pass { client, workspaceId }.",
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
const period = options.period;
|
|
81
|
+
const load = useCallback(
|
|
82
|
+
(signal?: AbortSignal) => readOwnUsage(client, workspaceId, period, signal),
|
|
83
|
+
[client, workspaceId, period],
|
|
84
|
+
);
|
|
85
|
+
const state = usePolledValue(load, {
|
|
86
|
+
pollIntervalMs: options.pollIntervalMs,
|
|
87
|
+
enabled: options.enabled,
|
|
88
|
+
});
|
|
89
|
+
const refreshKey = options.refreshKey;
|
|
90
|
+
const seenKey = useRef(refreshKey);
|
|
91
|
+
const refresh = state.refresh;
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (Object.is(seenKey.current, refreshKey)) return;
|
|
94
|
+
seenKey.current = refreshKey;
|
|
95
|
+
void refresh();
|
|
96
|
+
}, [refreshKey, refresh]);
|
|
97
|
+
const usage = state.data;
|
|
98
|
+
const summary = useMemo(() => (usage ? summarizeUsage(usage) : null), [usage]);
|
|
99
|
+
return { usage, summary, loading: state.loading, error: state.error, refresh };
|
|
100
|
+
}
|