@opengeni/react 4.2.1-canary.39642758903001 → 4.3.1
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/dist/app/app-state.js +27 -27
- package/dist/app/components/Composer.js +27 -26
- package/dist/app/components/agent/agent-capability-picker.js +5 -5
- package/dist/app/components/artifacts/artifact-library.js +19 -19
- package/dist/app/components/artifacts/chat-interactive-block.js +16 -16
- package/dist/app/components/artifacts/inline-chat-image.js +31 -30
- package/dist/app/components/artifacts/retained-file-preview.js +35 -34
- package/dist/app/components/artifacts/retained-text-preview.js +5 -5
- package/dist/app/components/artifacts/site-audience.js +5 -5
- package/dist/app/components/artifacts/site-conversations.js +24 -22
- package/dist/app/components/artifacts/site-data.js +20 -20
- package/dist/app/components/artifacts/site-publishing.js +39 -39
- package/dist/app/components/artifacts/site-settings.js +48 -48
- package/dist/app/components/billing-class-mark.js +5 -5
- package/dist/app/components/capabilities/capability-detail-sheet.js +9 -9
- package/dist/app/components/capabilities/capability-logo-source.js +13 -12
- package/dist/app/components/capabilities/connection-account-picker.js +2 -2
- package/dist/app/components/capabilities/connector-tool-permissions.js +5 -5
- package/dist/app/components/capabilities/native-connect-setup.js +14 -13
- package/dist/app/components/capabilities/native-connect-setup.js.map +1 -1
- package/dist/app/components/capabilities/perform-capability-action.js +3 -3
- package/dist/app/components/capabilities/prepared-mcp-setup-card.js +15 -14
- package/dist/app/components/capabilities/session-capability-card.js +78 -77
- package/dist/app/components/capabilities/session-capability-card.js.map +1 -1
- package/dist/app/components/capabilities/session-custom-mcp-card.js +20 -19
- package/dist/app/components/capabilities/session-github-card.js +25 -24
- package/dist/app/components/capabilities/session-machine-card.js +38 -38
- package/dist/app/components/capabilities/use-capabilities-catalog.js +3 -3
- package/dist/app/components/capabilities/use-connection-accounts.js +1 -1
- package/dist/app/components/command-menu/chat-switcher.d.ts +12 -0
- package/dist/app/components/command-menu/chat-switcher.js +142 -0
- package/dist/app/components/command-menu/chat-switcher.js.map +1 -0
- package/dist/app/components/command-menu/command-menu.d.ts +15 -0
- package/dist/app/components/command-menu/command-menu.js +812 -0
- package/dist/app/components/command-menu/command-menu.js.map +1 -0
- package/dist/app/components/command-menu/keycaps.d.ts +21 -0
- package/dist/app/components/command-menu/keycaps.js +12 -0
- package/dist/app/components/command-menu/shortcut-sheet.d.ts +12 -0
- package/dist/app/components/command-menu/shortcut-sheet.js +150 -0
- package/dist/app/components/command-menu/shortcut-sheet.js.map +1 -0
- package/dist/app/components/composer-capabilities-menu-body.js +3 -3
- package/dist/app/components/composer-mobile-plus-panel.js +21 -21
- package/dist/app/components/composer-mobile-plus.js +3 -3
- package/dist/app/components/credit-required-gate.js +1 -1
- package/dist/app/components/credit-required-prompt.js +16 -16
- package/dist/app/components/credits/coupon-redeem.js +2 -2
- package/dist/app/components/credits/credit-refusal-notice.d.ts +18 -0
- package/dist/app/components/credits/credit-refusal-notice.js +17 -0
- package/dist/app/components/cross-slot-deep-link-recovery.js +1 -1
- package/dist/app/components/desktop/app-shots.js +6 -6
- package/dist/app/components/desktop/this-computer.js +4 -4
- package/dist/app/components/feedback.js +5 -5
- package/dist/app/components/follow-up-repository-menu-body.js +7 -7
- package/dist/app/components/follow-up-repository-picker.js +3 -3
- package/dist/app/components/github-app-connect-launcher.js +1 -1
- package/dist/app/components/knowledge/agent-learning-settings.js +6 -6
- package/dist/app/components/machines/connect-machine-dialog.js +18 -18
- package/dist/app/components/manual-repository-editor.js +2 -2
- package/dist/app/components/markdown.js +10 -9
- package/dist/app/components/message-context-pills.js +2 -2
- package/dist/app/components/models/models-ui.js +10 -10
- package/dist/app/components/pickers.js +10 -10
- package/dist/app/components/rail/rail-context.d.ts +6 -0
- package/dist/app/components/rail/rail-context.js +3 -3
- package/dist/app/components/rail/rail-sections.js +61 -55
- package/dist/app/components/rail/session-browse-order-controls.js +2 -2
- package/dist/app/components/rail/session-header.js +50 -36
- package/dist/app/components/rail/session-list.js +59 -52
- package/dist/app/components/rail/session-row-hover-details.js +25 -23
- package/dist/app/components/rail/session-shell.js +96 -91
- package/dist/app/components/repository-picker.js +7 -7
- package/dist/app/components/secrets/session-secrets-panel.js +4 -4
- package/dist/app/components/session/agent-configuration-panel.js +34 -34
- package/dist/app/components/session/banners.js +12 -11
- package/dist/app/components/session/codex-account-indicator.js +12 -12
- package/dist/app/components/session/composer-menu-radio.js +2 -2
- package/dist/app/components/session/conversation-find.js +1 -1
- package/dist/app/components/session/editable-artifacts-workspace.js +45 -45
- package/dist/app/components/session/failed-session-banner.js +12 -12
- package/dist/app/components/session/human-input.js +48 -47
- package/dist/app/components/session/inspector.js +80 -79
- package/dist/app/components/session/inspector.js.map +1 -1
- package/dist/app/components/session/message-actions.js +5 -5
- package/dist/app/components/session/message-resource-attachments.js +21 -20
- package/dist/app/components/session/message-resource-attachments.js.map +1 -1
- package/dist/app/components/session/model-account-indicator.js +11 -11
- package/dist/app/components/session/model-context-inspector.js +2 -2
- package/dist/app/components/session/model-recovery-notice.js +3 -3
- package/dist/app/components/session/new-session-settings-menu.js +13 -13
- package/dist/app/components/session/sandbox-switcher.js +16 -16
- package/dist/app/components/session/sandbox-workspace.js +68 -67
- package/dist/app/components/session/search-markdown-highlight.js +11 -10
- package/dist/app/components/session/search-results-view.js +12 -11
- package/dist/app/components/session/session-admin-access.js +11 -11
- package/dist/app/components/session/session-retention.js +4 -4
- package/dist/app/components/session/session-search-dialog.d.ts +5 -0
- package/dist/app/components/session/session-search-dialog.js +22 -12
- package/dist/app/components/session/session-search-dialog.js.map +1 -1
- package/dist/app/components/session/session-skill-reviews.js +3 -3
- package/dist/app/components/session/session-tenancy-control.js +25 -25
- package/dist/app/components/session/session-usage-limit-section.js +9 -9
- package/dist/app/components/session/session-wait-status.js +11 -9
- package/dist/app/components/session/session-wait-status.js.map +1 -1
- package/dist/app/components/session/subagents.js +17 -15
- package/dist/app/components/session/subscription-account-menu.js +2 -2
- package/dist/app/components/session-connectors-menu-body.js +6 -6
- package/dist/app/components/settings/row-select.js +1 -1
- package/dist/app/components/transcription-settings.js +2 -2
- package/dist/app/components/ui/destructive-confirm.js +8 -8
- package/dist/app/components/usage/usage-entry.js +6 -6
- package/dist/app/components/workspace-composer-plus.js +22 -21
- package/dist/app/embed/session-app.js +264 -258
- package/dist/app/lib/actions/actions-provider.d.ts +30 -0
- package/dist/app/lib/actions/actions-provider.js +32 -0
- package/dist/app/lib/actions/chat-directory.d.ts +30 -0
- package/dist/app/lib/actions/chat-operations.d.ts +11 -0
- package/dist/app/lib/actions/chat-switcher.d.ts +31 -0
- package/dist/app/lib/actions/chords.d.ts +40 -0
- package/dist/app/lib/actions/events.d.ts +6 -0
- package/dist/app/lib/actions/rank.d.ts +17 -0
- package/dist/app/lib/actions/registry.d.ts +71 -0
- package/dist/app/lib/codex-usage-query.js +3 -3
- package/dist/app/lib/composer-connectors.js +14 -13
- package/dist/app/lib/console-text.js +2 -2
- package/dist/app/lib/credit-coverage.d.ts +21 -0
- package/dist/app/lib/credit-coverage.js +15 -0
- package/dist/app/lib/deployment-free-model.js +2 -2
- package/dist/app/lib/events.js +19 -18
- package/dist/app/lib/failed-session-copy.js +5 -5
- package/dist/app/lib/free-credit-gap.d.ts +9 -0
- package/dist/app/lib/free-credit-gap.js +4 -2
- package/dist/app/lib/integration-connect-analytics.d.ts +1 -1
- package/dist/app/lib/integration-connect-analytics.js +1 -1
- package/dist/app/lib/integration-connect-redirect.js +1 -1
- package/dist/app/lib/model-access-onboarding.js +4 -4
- package/dist/app/lib/model-policy.js +1 -1
- package/dist/app/lib/models-route.d.ts +6 -2
- package/dist/app/lib/models-route.js +6 -3
- package/dist/app/lib/models-route.js.map +1 -1
- package/dist/app/lib/move-chat-to-machine.js +3 -3
- package/dist/app/lib/session-branch-cache.js +15 -13
- package/dist/app/lib/session-create.js +2 -2
- package/dist/app/lib/session-group-pagination.js +15 -13
- package/dist/app/lib/session-hover-facts.js +16 -14
- package/dist/app/lib/session-model.js +3 -3
- package/dist/app/lib/session-rail.js +11 -9
- package/dist/app/lib/session-rename.js +3 -3
- package/dist/app/lib/session-search-route.d.ts +1 -1
- package/dist/app/lib/session-search-route.js +1 -1
- package/dist/app/lib/session-ui-features.d.ts +11 -3
- package/dist/app/lib/session-ui-features.js +1 -1
- package/dist/app/lib/sessions-group.js +15 -13
- package/dist/app/lib/turn-failure-analytics.js +7 -7
- package/dist/app/lib/unavailable-session-model.js +2 -2
- package/dist/app/lib/use-duplicate-site.js +2 -2
- package/dist/app/lib/use-follow-up-repositories.js +3 -3
- package/dist/app/lib/use-workspace-machines.js +8 -8
- package/dist/app/lib/use-workspace-model-catalog.js +6 -6
- package/dist/app/lib/use-workspace-rigs.js +4 -4
- package/dist/app/lib/workspace-navigation-preference.js +5 -5
- package/dist/app/lib/workspace-scope-context.js +4 -4
- package/dist/app/routes/artifacts.js +124 -122
- package/dist/app/routes/artifacts.js.map +1 -1
- package/dist/app/routes/retained-artifact.js +69 -68
- package/dist/app/routes/retained-artifact.js.map +1 -1
- package/dist/app/routes/session-unavailable.js +3 -3
- package/dist/app/routes/session.js +168 -166
- package/dist/app/routes/sessions-index-hydration.js +3 -3
- package/dist/app/routes/sessions-index.js +122 -116
- package/dist/artifacts-document.js +4 -4
- package/dist/artifacts-presentation.js +4 -4
- package/dist/artifacts-spreadsheet.js +4 -4
- package/dist/artifacts.js +39 -39
- package/dist/{browser-viewer-ZRFZX3VN.js → browser-viewer-HPUMK7UP.js} +7 -7
- package/dist/{chat-interactive-block-HUMYWVCK.js → chat-interactive-block-22PPECCT.js} +6 -6
- package/dist/{chunk-GVIQ7H62.js → chunk-2LUBBDZV.js} +5 -5
- package/dist/{chunk-SWWYYGQO.js → chunk-325C2TCI.js} +5 -2
- package/dist/chunk-325C2TCI.js.map +1 -0
- package/dist/{chunk-XMMVIY7B.js → chunk-3CCJWHQY.js} +2 -2
- package/dist/{chunk-XS2FZ6DX.js → chunk-3F5ZPIWI.js} +2 -2
- package/dist/{chunk-72US6QNB.js → chunk-3J2YZRY5.js} +2 -2
- package/dist/{chunk-D4YQF4E3.js → chunk-3SMJ2BIQ.js} +2 -2
- package/dist/{chunk-TBJINQXA.js → chunk-3WCYK36X.js} +17 -17
- package/dist/{chunk-WPCF34V6.js → chunk-3WG3CRL7.js} +14 -14
- package/dist/{chunk-JI5BYQKO.js → chunk-3X46PNBX.js} +14 -14
- package/dist/{chunk-UO36FC3S.js → chunk-46I7MMAL.js} +6 -2
- package/dist/chunk-46I7MMAL.js.map +1 -0
- package/dist/{chunk-PBK44WJC.js → chunk-4GJ37O6G.js} +2 -2
- package/dist/chunk-4IWBQUQU.js +152 -0
- package/dist/chunk-4IWBQUQU.js.map +1 -0
- package/dist/{chunk-LEXPBQ56.js → chunk-4SKJX3C4.js} +6 -6
- package/dist/{chunk-ZA6YD2LW.js → chunk-57SYK776.js} +2 -2
- package/dist/{chunk-22LBKJDE.js → chunk-5DIAN5GQ.js} +12 -12
- package/dist/{chunk-LJ3TDK2L.js → chunk-5FA455GR.js} +4 -4
- package/dist/{chunk-N2BEUKXT.js → chunk-5FBZDEHE.js} +228 -228
- package/dist/chunk-5FBZDEHE.js.map +1 -0
- package/dist/{chunk-YPR5INHV.js → chunk-5X3E2Z3D.js} +4 -4
- package/dist/{chunk-OXNWZTEU.js → chunk-5ZJCL6X4.js} +5 -5
- package/dist/{chunk-62OAZ4LO.js → chunk-6C5GQQMC.js} +12 -12
- package/dist/{chunk-VGITH57T.js → chunk-6ERTXDZM.js} +4 -4
- package/dist/{chunk-ZQ7XQZCF.js → chunk-6FX73Y4I.js} +8 -8
- package/dist/{chunk-QZO2KK2F.js → chunk-6P44NG6Y.js} +2 -2
- package/dist/{chunk-N2DDJLTM.js → chunk-6T7Y33JA.js} +3 -3
- package/dist/{chunk-RBAGC2MJ.js → chunk-75VE5QUS.js} +22 -22
- package/dist/{chunk-MRXOGI3O.js → chunk-77CUDSHG.js} +9 -9
- package/dist/{chunk-F2GXK2Z6.js → chunk-7G446JFO.js} +431 -348
- package/dist/chunk-7G446JFO.js.map +1 -0
- package/dist/{chunk-GZ65XQR5.js → chunk-7T7FHSGS.js} +3 -3
- package/dist/{chunk-YGAH34CD.js → chunk-A3S26JSP.js} +8 -8
- package/dist/{chunk-GYPAO6RS.js → chunk-A664GSDM.js} +8 -8
- package/dist/{chunk-JSZSNMDR.js → chunk-ASUYLXKO.js} +2 -2
- package/dist/{chunk-RTK7SUPL.js → chunk-AUUJLVA3.js} +7 -7
- package/dist/{chunk-OOTBYSCA.js → chunk-BBWKPNJB.js} +5 -5
- package/dist/{chunk-BGZIMIUU.js → chunk-BCUYWOQU.js} +2 -2
- package/dist/{chunk-EKN4N4LS.js → chunk-BDFMNJZJ.js} +2 -2
- package/dist/{chunk-YZKGOWCC.js → chunk-BIDXQAGO.js} +2 -2
- package/dist/{chunk-Q2UUANHF.js → chunk-BIKAJ4DY.js} +5 -5
- package/dist/{chunk-5IQBF2X3.js → chunk-BJPJ2OUX.js} +3 -3
- package/dist/{chunk-EY2EMHZW.js → chunk-BPM2OTYK.js} +8 -8
- package/dist/{chunk-MT4TBRQB.js → chunk-BSWS2RUZ.js} +2 -2
- package/dist/{chunk-T7YD3VGK.js → chunk-C52MNKXU.js} +12 -12
- package/dist/{chunk-THNW33K7.js → chunk-CEUDV4OA.js} +18 -18
- package/dist/{chunk-GRLPRM56.js → chunk-CFEFYPNR.js} +8 -2
- package/dist/chunk-CFEFYPNR.js.map +1 -0
- package/dist/{chunk-LHGIS6SZ.js → chunk-CVK74BH7.js} +2 -2
- package/dist/{chunk-DFO2UCYG.js → chunk-CW5I65ZX.js} +11 -11
- package/dist/chunk-DKNTQDVL.js +86 -0
- package/dist/chunk-DKNTQDVL.js.map +1 -0
- package/dist/{chunk-SKRLKQEG.js → chunk-DOSC2HRQ.js} +79 -79
- package/dist/{chunk-KVB6XDLP.js → chunk-DPJ2CWVN.js} +2 -2
- package/dist/{chunk-4J6V4DH7.js → chunk-DXMRO2MU.js} +3 -3
- package/dist/{chunk-42I4O4WQ.js → chunk-EE55IDDR.js} +26 -26
- package/dist/{chunk-2RA6XABP.js → chunk-EEERTLFF.js} +12 -12
- package/dist/{chunk-PTOTKUKO.js → chunk-EEO744XR.js} +8 -8
- package/dist/{chunk-LD3HVI2J.js → chunk-EMFGBAQL.js} +6 -6
- package/dist/{chunk-FQGUK4ST.js → chunk-ENPJKVMN.js} +38 -38
- package/dist/{chunk-HDHK3SXK.js → chunk-EU6RLHMP.js} +4 -4
- package/dist/{chunk-G7VLL3PG.js → chunk-F2YABPRJ.js} +13 -4
- package/dist/chunk-F2YABPRJ.js.map +1 -0
- package/dist/{chunk-MRUWRQBX.js → chunk-FET6XHGS.js} +2 -2
- package/dist/{chunk-M6KUY3YH.js → chunk-FIICQA55.js} +2 -2
- package/dist/{chunk-NLWLCYCT.js → chunk-FTZXCPE3.js} +19 -19
- package/dist/{chunk-FN2KA3MJ.js → chunk-FUS76DO4.js} +3 -3
- package/dist/{chunk-AM4IIPWI.js → chunk-G7N5NPRJ.js} +2 -2
- package/dist/{chunk-CCQ7YKOD.js → chunk-GBYZ6653.js} +2 -2
- package/dist/{chunk-SOOWLNC5.js → chunk-GJUPLSC5.js} +330 -109
- package/dist/chunk-GJUPLSC5.js.map +1 -0
- package/dist/{chunk-YKKVIJVX.js → chunk-GQDSC6QZ.js} +5 -5
- package/dist/chunk-GQGNRL2L.js +53 -0
- package/dist/chunk-GQGNRL2L.js.map +1 -0
- package/dist/{chunk-5X6JP75Q.js → chunk-GRSODLVO.js} +4 -4
- package/dist/{chunk-73YP3R5X.js → chunk-GSESCQFY.js} +4 -4
- package/dist/{chunk-KWB5U3ZT.js → chunk-GWRW4N3T.js} +199 -137
- package/dist/chunk-GWRW4N3T.js.map +1 -0
- package/dist/{chunk-RTR7RNG4.js → chunk-GYRU4PNM.js} +9 -7
- package/dist/{chunk-RTR7RNG4.js.map → chunk-GYRU4PNM.js.map} +1 -1
- package/dist/{chunk-MZLEBFUZ.js → chunk-GZD6VBIK.js} +3 -3
- package/dist/{chunk-IZR2QRFF.js → chunk-H3HH5AHS.js} +4 -4
- package/dist/{chunk-DN3TKURW.js → chunk-H3LIIAGE.js} +4 -54
- package/dist/chunk-H3LIIAGE.js.map +1 -0
- package/dist/{chunk-NPLEQMNM.js → chunk-H5GWAG4I.js} +7 -5
- package/dist/{chunk-NPLEQMNM.js.map → chunk-H5GWAG4I.js.map} +1 -1
- package/dist/{chunk-OJPUVUB6.js → chunk-HAOZCLLA.js} +3 -3
- package/dist/{chunk-ZBHDGAYL.js → chunk-HEFE4OZJ.js} +2 -2
- package/dist/{chunk-WTG34JVA.js → chunk-HI75UTI6.js} +2 -2
- package/dist/{chunk-OMBIG3NC.js → chunk-HM633ROV.js} +14 -14
- package/dist/{chunk-WDFZWSKD.js → chunk-HRIP4M6H.js} +3 -3
- package/dist/{chunk-A2BCW6CQ.js → chunk-HU2DRFFI.js} +3 -3
- package/dist/{chunk-PO35PBAB.js → chunk-HVH7FFJH.js} +2 -2
- package/dist/{chunk-EG7KNUF7.js → chunk-HYTXTKST.js} +18 -18
- package/dist/{chunk-TFHG75A4.js → chunk-I4XMDFUJ.js} +7 -7
- package/dist/{chunk-IZHVZZQA.js → chunk-ICAUYWSL.js} +9 -9
- package/dist/{chunk-ZSERYHHT.js → chunk-IDMXEPHL.js} +150 -150
- package/dist/chunk-IDMXEPHL.js.map +1 -0
- package/dist/{chunk-DCLPWYP3.js → chunk-IEVPJ3G6.js} +2 -2
- package/dist/{chunk-EVWZHDSF.js → chunk-IKH3VTA4.js} +2 -2
- package/dist/{chunk-L5UCO2UV.js → chunk-ILBSBZGC.js} +13 -4
- package/dist/chunk-ILBSBZGC.js.map +1 -0
- package/dist/{chunk-IO6K6UYJ.js → chunk-IQ64BNAG.js} +4 -2
- package/dist/chunk-IQ64BNAG.js.map +1 -0
- package/dist/{chunk-TYHLEFD2.js → chunk-IZJNMRIR.js} +9 -9
- package/dist/{chunk-D2SR3TEB.js → chunk-J243WGUA.js} +2 -2
- package/dist/{chunk-QGSGIYE3.js → chunk-J2C6LB6W.js} +4 -4
- package/dist/{chunk-MT6TRTXF.js → chunk-J5MEDX7C.js} +9 -9
- package/dist/{chunk-6QHUKBJP.js → chunk-J7SKOO44.js} +2 -2
- package/dist/{chunk-W2QK7PYS.js → chunk-JAAST75A.js} +11 -11
- package/dist/{chunk-NQCMS4AJ.js → chunk-JQCGPTZ6.js} +9 -9
- package/dist/chunk-JRJUSKDY.js +832 -0
- package/dist/chunk-JRJUSKDY.js.map +1 -0
- package/dist/{chunk-CMUXJHGH.js → chunk-JRSCWQMC.js} +9 -9
- package/dist/{chunk-Q4OHNGGB.js → chunk-JRXHSVD5.js} +4 -4
- package/dist/{chunk-SD2K5ZN5.js → chunk-JXYLDT6X.js} +4 -4
- package/dist/{chunk-S3M5WCZW.js → chunk-KA4LV7G6.js} +35 -50
- package/dist/chunk-KA4LV7G6.js.map +1 -0
- package/dist/{chunk-IXX6ZOL2.js → chunk-KGTMHEAP.js} +7 -7
- package/dist/{chunk-22OBGVEJ.js → chunk-KOXVGPW4.js} +3 -3
- package/dist/{chunk-NOZ5CGZE.js → chunk-L5GPPMUB.js} +2 -2
- package/dist/{chunk-KIHYJM5F.js → chunk-LXJT4WAW.js} +58 -58
- package/dist/{chunk-KIHYJM5F.js.map → chunk-LXJT4WAW.js.map} +1 -1
- package/dist/{chunk-4FOOHMTU.js → chunk-LY6727IF.js} +1 -1
- package/dist/{chunk-PT7MTXRE.js → chunk-MAOCN7J6.js} +2 -2
- package/dist/{chunk-4K2JSJNX.js → chunk-MB5LZVDO.js} +2 -2
- package/dist/chunk-MF464AKA.js +139 -0
- package/dist/chunk-MF464AKA.js.map +1 -0
- package/dist/{chunk-UYSZKDQY.js → chunk-MK54JLE4.js} +1 -1
- package/dist/chunk-MK54JLE4.js.map +1 -0
- package/dist/{chunk-5LES64PP.js → chunk-MKOQAVOE.js} +21 -21
- package/dist/{chunk-BMV2SNYX.js → chunk-MUPWNSEJ.js} +18 -18
- package/dist/{chunk-Y5TRG22C.js → chunk-NRXIECWC.js} +2 -2
- package/dist/{chunk-GOE7G5JX.js → chunk-NWSAF6P5.js} +2 -2
- package/dist/chunk-OB3YGXHQ.js +158 -0
- package/dist/chunk-OB3YGXHQ.js.map +1 -0
- package/dist/{chunk-DUM363VS.js → chunk-OFZQJNF6.js} +5 -5
- package/dist/{chunk-CKN5QPEL.js → chunk-OMF7POEY.js} +2 -2
- package/dist/{chunk-MVXKO2BD.js → chunk-OXD6ET34.js} +1 -1
- package/dist/{chunk-47JUEVME.js → chunk-PALX6HWV.js} +21 -21
- package/dist/{chunk-B6OGSG7I.js → chunk-PE3BLBDT.js} +3 -3
- package/dist/{chunk-RVISSNVE.js → chunk-PMZKJOG6.js} +15 -15
- package/dist/{chunk-CESAMXWX.js → chunk-PQUTMG3S.js} +2 -2
- package/dist/{chunk-7VFCOKPG.js → chunk-PWBGODZU.js} +3 -3
- package/dist/{chunk-MOPAXD2H.js → chunk-QCADUTYX.js} +2 -2
- package/dist/{chunk-CT5FBO7E.js → chunk-RPOUJI25.js} +1 -1
- package/dist/{chunk-VE3FKXJ7.js → chunk-RUSXEE7X.js} +35 -32
- package/dist/chunk-RUSXEE7X.js.map +1 -0
- package/dist/{chunk-WKHYOS72.js → chunk-RW4GFE56.js} +3 -3
- package/dist/{chunk-FH4GO7HO.js → chunk-RYLVVDR7.js} +1 -1
- package/dist/{chunk-QZRDCFHI.js → chunk-S66SBBFQ.js} +5 -5
- package/dist/{chunk-CQJFIPAH.js → chunk-S7TNV2I7.js} +14 -14
- package/dist/{chunk-ZBQSIGGR.js → chunk-SC773IMJ.js} +13 -13
- package/dist/{chunk-RZV7SXED.js → chunk-SF3M27AN.js} +37 -12
- package/dist/chunk-SF3M27AN.js.map +1 -0
- package/dist/{chunk-FBJ2HK7A.js → chunk-SGPJ3YS2.js} +20 -20
- package/dist/{chunk-A2EWJQXX.js → chunk-SM5QX6UK.js} +4 -4
- package/dist/chunk-SWCLN6JE.js +40 -0
- package/dist/chunk-SWCLN6JE.js.map +1 -0
- package/dist/{chunk-OS3EQOIS.js → chunk-T4F5TW2X.js} +29 -24
- package/dist/chunk-T4F5TW2X.js.map +1 -0
- package/dist/{chunk-RKZWCTXV.js → chunk-TAEKDMEF.js} +2 -2
- package/dist/{chunk-6AVCAUGL.js → chunk-TASEV25T.js} +3 -3
- package/dist/{chunk-3XOISKZC.js → chunk-TLGDPMUX.js} +6 -6
- package/dist/{chunk-MOF3XSUM.js → chunk-TREHTIBD.js} +3 -2
- package/dist/chunk-TREHTIBD.js.map +1 -0
- package/dist/{chunk-HUQHJSPV.js → chunk-TTPXGD5S.js} +68 -33
- package/dist/chunk-TTPXGD5S.js.map +1 -0
- package/dist/{chunk-NFCYIZHX.js → chunk-TXIIBNCA.js} +7 -3
- package/dist/{chunk-NFCYIZHX.js.map → chunk-TXIIBNCA.js.map} +1 -1
- package/dist/{chunk-5IUW34PG.js → chunk-TY3QYPJ6.js} +7 -7
- package/dist/{chunk-VQFR4EU4.js → chunk-U3JK5VJV.js} +2 -2
- package/dist/{chunk-2AWMJO54.js → chunk-U42P3RMZ.js} +5 -5
- package/dist/{chunk-2RIUMV7S.js → chunk-UBIJBLUK.js} +234 -234
- package/dist/chunk-UBIJBLUK.js.map +1 -0
- package/dist/{chunk-GUU75DES.js → chunk-UEJTOPLW.js} +8 -8
- package/dist/{chunk-QWCTYLMD.js → chunk-URDONAEJ.js} +240 -204
- package/dist/chunk-URDONAEJ.js.map +1 -0
- package/dist/{chunk-OZOEWLGR.js → chunk-UT6JAORE.js} +4 -4
- package/dist/{chunk-5TELOQA6.js → chunk-UTHPUINA.js} +3 -3
- package/dist/{chunk-SOV7DTTU.js → chunk-V6HZ2HJZ.js} +67 -67
- package/dist/{chunk-SOV7DTTU.js.map → chunk-V6HZ2HJZ.js.map} +1 -1
- package/dist/{chunk-26RQ6JBR.js → chunk-VBVCNH6D.js} +5 -5
- package/dist/{chunk-P646DND6.js → chunk-VCMQPCME.js} +2 -2
- package/dist/{chunk-LV7FMIMM.js → chunk-VGUHAHHV.js} +2 -2
- package/dist/{chunk-GYVXARCY.js → chunk-VIBPFVU4.js} +41 -41
- package/dist/{chunk-KHPOKZ6Z.js → chunk-VMAC66JX.js} +6 -6
- package/dist/{chunk-SHKRS6I5.js → chunk-VRPNETPK.js} +3 -3
- package/dist/{chunk-6U4J6RVS.js → chunk-WCHW4XN7.js} +14 -14
- package/dist/{chunk-CJH6QUQJ.js → chunk-WD3UXNJV.js} +3 -3
- package/dist/{chunk-H5EVWF6L.js → chunk-WR67FJMX.js} +4 -4
- package/dist/{chunk-XLIJ36RG.js → chunk-WRMQ7EX4.js} +5 -5
- package/dist/{chunk-VVFWOBAM.js → chunk-WTJUKYB2.js} +15 -16
- package/dist/chunk-WTJUKYB2.js.map +1 -0
- package/dist/{chunk-7KLCFJ5G.js → chunk-X4PPGXQG.js} +2 -2
- package/dist/{chunk-ZE2JTVCQ.js → chunk-X5BMQXFD.js} +11 -11
- package/dist/{chunk-OYJY4Y4A.js → chunk-XFNLU7EW.js} +14 -7
- package/dist/chunk-XFNLU7EW.js.map +1 -0
- package/dist/{chunk-UECU6LZI.js → chunk-XXRBOSWV.js} +3 -3
- package/dist/{chunk-SPKAIDWX.js → chunk-XZEFCPBL.js} +2 -2
- package/dist/{chunk-EZ5NYRHK.js → chunk-YL6N7QLA.js} +5 -5
- package/dist/{chunk-Q2ZJOECN.js → chunk-YMVTIV5L.js} +19 -19
- package/dist/chunk-YMVTIV5L.js.map +1 -0
- package/dist/{chunk-VAIESMPY.js → chunk-YVBHGMKC.js} +4 -4
- package/dist/{chunk-AR62NQXE.js → chunk-Z2S5VQG7.js} +2 -2
- package/dist/{chunk-2MXUB3ZO.js → chunk-Z5OGTWMZ.js} +15 -2
- package/dist/chunk-Z5OGTWMZ.js.map +1 -0
- package/dist/{chunk-7UQJEADK.js → chunk-ZL2O4BYP.js} +2 -2
- package/dist/{chunk-FOOITLHR.js → chunk-ZZHBT5WQ.js} +2 -2
- package/dist/{chunk-X6VJQJYY.js → chunk-ZZWHKC6A.js} +3 -3
- package/dist/components/timeline-annotation-shared.d.ts +1 -9
- package/dist/composer-messages.js +2 -2
- package/dist/composer.js +15 -15
- package/dist/{computer-viewer-D4NHQB5D.js → computer-viewer-S6TE6TN7.js} +8 -8
- package/dist/connect.js +12 -11
- package/dist/desktop.js +2 -2
- package/dist/editor.js +2 -2
- package/dist/{embedded-new-voice-X4ZW6SY4.js → embedded-new-voice-ZDZPGX25.js} +8 -8
- package/dist/{embedded-voice-4OD6Z3HU.js → embedded-voice-FKCUXSJO.js} +8 -8
- package/dist/{fleet-decision-row-5UCJXTDP.js → fleet-decision-row-VCGWYJAV.js} +2 -2
- package/dist/hooks/page-wake.d.ts +21 -0
- package/dist/hooks/use-session-events.d.ts +1 -0
- package/dist/index.js +206 -205
- package/dist/interaction.js +9 -9
- package/dist/{latest-question-VGVNUGAU.js → latest-question-SINEV4U6.js} +3 -3
- package/dist/lib/format.d.ts +3 -2
- package/dist/machines.js +6 -6
- package/dist/messages/en.d.ts +12 -3
- package/dist/messages.js +1 -1
- package/dist/model-picker-model.js +2 -2
- package/dist/{model-policy-picker-menu-XOPYY6YA.js → model-policy-picker-menu-66JPM3G5.js} +6 -6
- package/dist/model-policy-picker-menu-66JPM3G5.js.map +1 -0
- package/dist/model-policy.js +1 -1
- package/dist/native-previews.js +3 -3
- package/dist/{platform-activity-row-56XOVTRA.js → platform-activity-row-LU5WABI2.js} +2 -2
- package/dist/{queue-surface-implementation-OZDOBJ6W.js → queue-surface-implementation-Y4OUVS7N.js} +8 -7
- package/dist/{queue-surface-implementation-OZDOBJ6W.js.map → queue-surface-implementation-Y4OUVS7N.js.map} +1 -1
- package/dist/realtime.js +7 -7
- package/dist/{sandbox-files-LJCR437H.js → sandbox-files-NBIVKVCZ.js} +11 -11
- package/dist/sandbox-files-NBIVKVCZ.js.map +1 -0
- package/dist/session-app.js +266 -260
- package/dist/session-list-model.js +3 -3
- package/dist/{session-realtime-UISLBZ4A.js → session-realtime-3PALSNMJ.js} +3 -3
- package/dist/session-realtime-3PALSNMJ.js.map +1 -0
- package/dist/session-realtime.js +2 -2
- package/dist/session-ui.js +62 -61
- package/dist/session.d.ts +1 -1
- package/dist/session.js +17 -17
- package/dist/sites.js +2 -2
- package/dist/terminal.js +2 -2
- package/dist/this-computer.js +3 -3
- package/dist/timeline/annotation-model.d.ts +48 -0
- package/dist/{timeline-annotation-markers-ACT7XRMW.js → timeline-annotation-markers-6526H2NM.js} +11 -9
- package/dist/{timeline-annotation-markers-ACT7XRMW.js.map → timeline-annotation-markers-6526H2NM.js.map} +1 -1
- package/dist/{timeline-annotation-selection-2IA7T5VR.js → timeline-annotation-selection-KV5SM6TA.js} +16 -62
- package/dist/timeline-annotation-selection-KV5SM6TA.js.map +1 -0
- package/dist/{timeline-annotations-dialog-W5B2HMYY.js → timeline-annotations-dialog-7CDHWC7Y.js} +12 -10
- package/dist/{timeline-annotations-dialog-W5B2HMYY.js.map → timeline-annotations-dialog-7CDHWC7Y.js.map} +1 -1
- package/dist/timeline-model.d.ts +3 -0
- package/dist/timeline-model.js +40 -14
- package/dist/ui/access-list.js +24 -24
- package/dist/ui/choice-cards.js +2 -2
- package/dist/ui/composer-menu-action.js +2 -2
- package/dist/ui/context-menu.d.ts +3 -1
- package/dist/ui/context-menu.js +3 -1
- package/dist/ui/detail-page.js +3 -3
- package/dist/ui/detail-sheet.js +3 -3
- package/dist/ui/diff-view.js +3 -3
- package/dist/ui/disclosure.js +5 -5
- package/dist/ui/dropdown-menu.js +1 -1
- package/dist/ui/flush-form-page.js +5 -5
- package/dist/ui/form-dialog.js +4 -4
- package/dist/ui/list-row.js +5 -5
- package/dist/ui/load-failure.js +3 -3
- package/dist/ui/page-actions.js +3 -3
- package/dist/ui/revision-history.js +11 -11
- package/dist/ui/role-select.js +8 -8
- package/dist/ui/segmented-control.js +1 -1
- package/dist/ui/settings-nav.js +3 -3
- package/dist/ui/toolbar.js +3 -3
- package/dist/usage.js +2 -2
- package/dist/workbench.js +11 -11
- package/package.json +4 -4
- package/src/app/app-state.tsx +2 -1
- package/src/app/components/command-menu/chat-switcher.tsx +135 -0
- package/src/app/components/command-menu/command-menu.tsx +840 -0
- package/src/app/components/command-menu/keycaps.tsx +56 -0
- package/src/app/components/command-menu/shortcut-sheet.tsx +155 -0
- package/src/app/components/credits/credit-refusal-notice.test.tsx +132 -0
- package/src/app/components/credits/credit-refusal-notice.tsx +92 -0
- package/src/app/components/rail/rail-context.tsx +28 -5
- package/src/app/components/rail/rail-sections.tsx +3 -5
- package/src/app/components/rail/session-header-mute.test.tsx +23 -1
- package/src/app/components/rail/session-header.test.tsx +21 -2
- package/src/app/components/rail/session-header.tsx +31 -1
- package/src/app/components/rail/session-list.tsx +89 -16
- package/src/app/components/rail/session-shell.tsx +0 -14
- package/src/app/components/session/session-search-dialog.tsx +12 -1
- package/src/app/embed/session-app.tsx +6 -3
- package/src/app/lib/actions/actions-provider.tsx +486 -0
- package/src/app/lib/actions/actions.test.ts +249 -0
- package/src/app/lib/actions/chat-directory.ts +231 -0
- package/src/app/lib/actions/chat-operations.ts +145 -0
- package/src/app/lib/actions/chat-switcher.ts +62 -0
- package/src/app/lib/actions/chords.ts +185 -0
- package/src/app/lib/actions/events.ts +10 -0
- package/src/app/lib/actions/rank.ts +119 -0
- package/src/app/lib/actions/registry.ts +333 -0
- package/src/app/lib/credit-coverage.test.ts +83 -0
- package/src/app/lib/credit-coverage.tsx +48 -0
- package/src/app/lib/free-credit-gap.test.ts +32 -1
- package/src/app/lib/free-credit-gap.tsx +32 -2
- package/src/app/lib/integration-connect-analytics.test.ts +1 -0
- package/src/app/lib/integration-connect-analytics.tsx +4 -0
- package/src/app/lib/models-route.test.ts +18 -0
- package/src/app/lib/models-route.tsx +26 -4
- package/src/app/lib/session-search-route.tsx +6 -1
- package/src/app/lib/session-ui-features.tsx +28 -9
- package/src/app/routes/session.tsx +74 -16
- package/src/app/routes/sessions-index.tsx +83 -4
- package/src/components/timeline-annotation-selection.tsx +9 -64
- package/src/components/timeline-annotation-shared.ts +9 -57
- package/src/hooks/page-wake.ts +80 -0
- package/src/hooks/use-session-events.ts +309 -81
- package/src/lib/format.ts +3 -2
- package/src/messages/en.ts +13 -3
- package/src/model-picker-model.ts +3 -0
- package/src/model-policy.ts +9 -1
- package/src/session.ts +1 -0
- package/src/timeline/annotation-model.ts +217 -0
- package/src/timeline/projection.ts +27 -21
- package/src/timeline-model.ts +14 -0
- package/src/ui/context-menu.tsx +16 -0
- package/src/ui/dropdown-menu.tsx +4 -1
- package/src/ui/segmented-control.tsx +3 -0
- package/styles/compiled.css +92 -0
- package/dist/app/lib/keyboard-shortcuts.d.ts +0 -51
- package/dist/app/lib/keyboard-shortcuts.js +0 -16
- package/dist/chunk-2MXUB3ZO.js.map +0 -1
- package/dist/chunk-2RIUMV7S.js.map +0 -1
- package/dist/chunk-53IXIUYP.js +0 -39
- package/dist/chunk-53IXIUYP.js.map +0 -1
- package/dist/chunk-DN3TKURW.js.map +0 -1
- package/dist/chunk-F2GXK2Z6.js.map +0 -1
- package/dist/chunk-G7VLL3PG.js.map +0 -1
- package/dist/chunk-GRLPRM56.js.map +0 -1
- package/dist/chunk-HUQHJSPV.js.map +0 -1
- package/dist/chunk-IO6K6UYJ.js.map +0 -1
- package/dist/chunk-KWB5U3ZT.js.map +0 -1
- package/dist/chunk-L5UCO2UV.js.map +0 -1
- package/dist/chunk-MOF3XSUM.js.map +0 -1
- package/dist/chunk-N2BEUKXT.js.map +0 -1
- package/dist/chunk-OS3EQOIS.js.map +0 -1
- package/dist/chunk-OYJY4Y4A.js.map +0 -1
- package/dist/chunk-Q2ZJOECN.js.map +0 -1
- package/dist/chunk-QWCTYLMD.js.map +0 -1
- package/dist/chunk-RZV7SXED.js.map +0 -1
- package/dist/chunk-S3M5WCZW.js.map +0 -1
- package/dist/chunk-SOOWLNC5.js.map +0 -1
- package/dist/chunk-SWWYYGQO.js.map +0 -1
- package/dist/chunk-UO36FC3S.js.map +0 -1
- package/dist/chunk-UYSZKDQY.js.map +0 -1
- package/dist/chunk-VE3FKXJ7.js.map +0 -1
- package/dist/chunk-VVFWOBAM.js.map +0 -1
- package/dist/chunk-ZSERYHHT.js.map +0 -1
- package/dist/timeline-annotation-selection-2IA7T5VR.js.map +0 -1
- package/src/app/lib/keyboard-shortcuts.test.ts +0 -47
- package/src/app/lib/keyboard-shortcuts.tsx +0 -58
- /package/dist/app/{lib/keyboard-shortcuts.js.map → components/command-menu/keycaps.js.map} +0 -0
- /package/dist/{browser-viewer-ZRFZX3VN.js.map → app/components/credits/credit-refusal-notice.js.map} +0 -0
- /package/dist/{chat-interactive-block-HUMYWVCK.js.map → app/lib/actions/actions-provider.js.map} +0 -0
- /package/dist/{computer-viewer-D4NHQB5D.js.map → app/lib/credit-coverage.js.map} +0 -0
- /package/dist/{embedded-new-voice-X4ZW6SY4.js.map → browser-viewer-HPUMK7UP.js.map} +0 -0
- /package/dist/{embedded-voice-4OD6Z3HU.js.map → chat-interactive-block-22PPECCT.js.map} +0 -0
- /package/dist/{chunk-GVIQ7H62.js.map → chunk-2LUBBDZV.js.map} +0 -0
- /package/dist/{chunk-XMMVIY7B.js.map → chunk-3CCJWHQY.js.map} +0 -0
- /package/dist/{chunk-XS2FZ6DX.js.map → chunk-3F5ZPIWI.js.map} +0 -0
- /package/dist/{chunk-72US6QNB.js.map → chunk-3J2YZRY5.js.map} +0 -0
- /package/dist/{chunk-D4YQF4E3.js.map → chunk-3SMJ2BIQ.js.map} +0 -0
- /package/dist/{chunk-TBJINQXA.js.map → chunk-3WCYK36X.js.map} +0 -0
- /package/dist/{chunk-WPCF34V6.js.map → chunk-3WG3CRL7.js.map} +0 -0
- /package/dist/{chunk-JI5BYQKO.js.map → chunk-3X46PNBX.js.map} +0 -0
- /package/dist/{chunk-PBK44WJC.js.map → chunk-4GJ37O6G.js.map} +0 -0
- /package/dist/{chunk-LEXPBQ56.js.map → chunk-4SKJX3C4.js.map} +0 -0
- /package/dist/{chunk-ZA6YD2LW.js.map → chunk-57SYK776.js.map} +0 -0
- /package/dist/{chunk-22LBKJDE.js.map → chunk-5DIAN5GQ.js.map} +0 -0
- /package/dist/{chunk-LJ3TDK2L.js.map → chunk-5FA455GR.js.map} +0 -0
- /package/dist/{chunk-YPR5INHV.js.map → chunk-5X3E2Z3D.js.map} +0 -0
- /package/dist/{chunk-OXNWZTEU.js.map → chunk-5ZJCL6X4.js.map} +0 -0
- /package/dist/{chunk-62OAZ4LO.js.map → chunk-6C5GQQMC.js.map} +0 -0
- /package/dist/{chunk-VGITH57T.js.map → chunk-6ERTXDZM.js.map} +0 -0
- /package/dist/{chunk-ZQ7XQZCF.js.map → chunk-6FX73Y4I.js.map} +0 -0
- /package/dist/{chunk-QZO2KK2F.js.map → chunk-6P44NG6Y.js.map} +0 -0
- /package/dist/{chunk-N2DDJLTM.js.map → chunk-6T7Y33JA.js.map} +0 -0
- /package/dist/{chunk-RBAGC2MJ.js.map → chunk-75VE5QUS.js.map} +0 -0
- /package/dist/{chunk-MRXOGI3O.js.map → chunk-77CUDSHG.js.map} +0 -0
- /package/dist/{chunk-GZ65XQR5.js.map → chunk-7T7FHSGS.js.map} +0 -0
- /package/dist/{chunk-YGAH34CD.js.map → chunk-A3S26JSP.js.map} +0 -0
- /package/dist/{chunk-GYPAO6RS.js.map → chunk-A664GSDM.js.map} +0 -0
- /package/dist/{chunk-JSZSNMDR.js.map → chunk-ASUYLXKO.js.map} +0 -0
- /package/dist/{chunk-RTK7SUPL.js.map → chunk-AUUJLVA3.js.map} +0 -0
- /package/dist/{chunk-OOTBYSCA.js.map → chunk-BBWKPNJB.js.map} +0 -0
- /package/dist/{chunk-BGZIMIUU.js.map → chunk-BCUYWOQU.js.map} +0 -0
- /package/dist/{chunk-EKN4N4LS.js.map → chunk-BDFMNJZJ.js.map} +0 -0
- /package/dist/{chunk-YZKGOWCC.js.map → chunk-BIDXQAGO.js.map} +0 -0
- /package/dist/{chunk-Q2UUANHF.js.map → chunk-BIKAJ4DY.js.map} +0 -0
- /package/dist/{chunk-5IQBF2X3.js.map → chunk-BJPJ2OUX.js.map} +0 -0
- /package/dist/{chunk-EY2EMHZW.js.map → chunk-BPM2OTYK.js.map} +0 -0
- /package/dist/{chunk-MT4TBRQB.js.map → chunk-BSWS2RUZ.js.map} +0 -0
- /package/dist/{chunk-T7YD3VGK.js.map → chunk-C52MNKXU.js.map} +0 -0
- /package/dist/{chunk-THNW33K7.js.map → chunk-CEUDV4OA.js.map} +0 -0
- /package/dist/{chunk-LHGIS6SZ.js.map → chunk-CVK74BH7.js.map} +0 -0
- /package/dist/{chunk-DFO2UCYG.js.map → chunk-CW5I65ZX.js.map} +0 -0
- /package/dist/{chunk-SKRLKQEG.js.map → chunk-DOSC2HRQ.js.map} +0 -0
- /package/dist/{chunk-KVB6XDLP.js.map → chunk-DPJ2CWVN.js.map} +0 -0
- /package/dist/{chunk-4J6V4DH7.js.map → chunk-DXMRO2MU.js.map} +0 -0
- /package/dist/{chunk-42I4O4WQ.js.map → chunk-EE55IDDR.js.map} +0 -0
- /package/dist/{chunk-2RA6XABP.js.map → chunk-EEERTLFF.js.map} +0 -0
- /package/dist/{chunk-PTOTKUKO.js.map → chunk-EEO744XR.js.map} +0 -0
- /package/dist/{chunk-LD3HVI2J.js.map → chunk-EMFGBAQL.js.map} +0 -0
- /package/dist/{chunk-FQGUK4ST.js.map → chunk-ENPJKVMN.js.map} +0 -0
- /package/dist/{chunk-HDHK3SXK.js.map → chunk-EU6RLHMP.js.map} +0 -0
- /package/dist/{chunk-MRUWRQBX.js.map → chunk-FET6XHGS.js.map} +0 -0
- /package/dist/{chunk-M6KUY3YH.js.map → chunk-FIICQA55.js.map} +0 -0
- /package/dist/{chunk-NLWLCYCT.js.map → chunk-FTZXCPE3.js.map} +0 -0
- /package/dist/{chunk-FN2KA3MJ.js.map → chunk-FUS76DO4.js.map} +0 -0
- /package/dist/{chunk-AM4IIPWI.js.map → chunk-G7N5NPRJ.js.map} +0 -0
- /package/dist/{chunk-CCQ7YKOD.js.map → chunk-GBYZ6653.js.map} +0 -0
- /package/dist/{chunk-YKKVIJVX.js.map → chunk-GQDSC6QZ.js.map} +0 -0
- /package/dist/{chunk-5X6JP75Q.js.map → chunk-GRSODLVO.js.map} +0 -0
- /package/dist/{chunk-73YP3R5X.js.map → chunk-GSESCQFY.js.map} +0 -0
- /package/dist/{chunk-MZLEBFUZ.js.map → chunk-GZD6VBIK.js.map} +0 -0
- /package/dist/{chunk-IZR2QRFF.js.map → chunk-H3HH5AHS.js.map} +0 -0
- /package/dist/{chunk-OJPUVUB6.js.map → chunk-HAOZCLLA.js.map} +0 -0
- /package/dist/{chunk-ZBHDGAYL.js.map → chunk-HEFE4OZJ.js.map} +0 -0
- /package/dist/{chunk-WTG34JVA.js.map → chunk-HI75UTI6.js.map} +0 -0
- /package/dist/{chunk-OMBIG3NC.js.map → chunk-HM633ROV.js.map} +0 -0
- /package/dist/{chunk-WDFZWSKD.js.map → chunk-HRIP4M6H.js.map} +0 -0
- /package/dist/{chunk-A2BCW6CQ.js.map → chunk-HU2DRFFI.js.map} +0 -0
- /package/dist/{chunk-PO35PBAB.js.map → chunk-HVH7FFJH.js.map} +0 -0
- /package/dist/{chunk-EG7KNUF7.js.map → chunk-HYTXTKST.js.map} +0 -0
- /package/dist/{chunk-TFHG75A4.js.map → chunk-I4XMDFUJ.js.map} +0 -0
- /package/dist/{chunk-IZHVZZQA.js.map → chunk-ICAUYWSL.js.map} +0 -0
- /package/dist/{chunk-DCLPWYP3.js.map → chunk-IEVPJ3G6.js.map} +0 -0
- /package/dist/{chunk-EVWZHDSF.js.map → chunk-IKH3VTA4.js.map} +0 -0
- /package/dist/{chunk-TYHLEFD2.js.map → chunk-IZJNMRIR.js.map} +0 -0
- /package/dist/{chunk-D2SR3TEB.js.map → chunk-J243WGUA.js.map} +0 -0
- /package/dist/{chunk-QGSGIYE3.js.map → chunk-J2C6LB6W.js.map} +0 -0
- /package/dist/{chunk-MT6TRTXF.js.map → chunk-J5MEDX7C.js.map} +0 -0
- /package/dist/{chunk-6QHUKBJP.js.map → chunk-J7SKOO44.js.map} +0 -0
- /package/dist/{chunk-W2QK7PYS.js.map → chunk-JAAST75A.js.map} +0 -0
- /package/dist/{chunk-NQCMS4AJ.js.map → chunk-JQCGPTZ6.js.map} +0 -0
- /package/dist/{chunk-CMUXJHGH.js.map → chunk-JRSCWQMC.js.map} +0 -0
- /package/dist/{chunk-Q4OHNGGB.js.map → chunk-JRXHSVD5.js.map} +0 -0
- /package/dist/{chunk-SD2K5ZN5.js.map → chunk-JXYLDT6X.js.map} +0 -0
- /package/dist/{chunk-IXX6ZOL2.js.map → chunk-KGTMHEAP.js.map} +0 -0
- /package/dist/{chunk-22OBGVEJ.js.map → chunk-KOXVGPW4.js.map} +0 -0
- /package/dist/{chunk-NOZ5CGZE.js.map → chunk-L5GPPMUB.js.map} +0 -0
- /package/dist/{chunk-4FOOHMTU.js.map → chunk-LY6727IF.js.map} +0 -0
- /package/dist/{chunk-PT7MTXRE.js.map → chunk-MAOCN7J6.js.map} +0 -0
- /package/dist/{chunk-4K2JSJNX.js.map → chunk-MB5LZVDO.js.map} +0 -0
- /package/dist/{chunk-5LES64PP.js.map → chunk-MKOQAVOE.js.map} +0 -0
- /package/dist/{chunk-BMV2SNYX.js.map → chunk-MUPWNSEJ.js.map} +0 -0
- /package/dist/{chunk-Y5TRG22C.js.map → chunk-NRXIECWC.js.map} +0 -0
- /package/dist/{chunk-GOE7G5JX.js.map → chunk-NWSAF6P5.js.map} +0 -0
- /package/dist/{chunk-DUM363VS.js.map → chunk-OFZQJNF6.js.map} +0 -0
- /package/dist/{chunk-CKN5QPEL.js.map → chunk-OMF7POEY.js.map} +0 -0
- /package/dist/{chunk-MVXKO2BD.js.map → chunk-OXD6ET34.js.map} +0 -0
- /package/dist/{chunk-47JUEVME.js.map → chunk-PALX6HWV.js.map} +0 -0
- /package/dist/{chunk-B6OGSG7I.js.map → chunk-PE3BLBDT.js.map} +0 -0
- /package/dist/{chunk-RVISSNVE.js.map → chunk-PMZKJOG6.js.map} +0 -0
- /package/dist/{chunk-CESAMXWX.js.map → chunk-PQUTMG3S.js.map} +0 -0
- /package/dist/{chunk-7VFCOKPG.js.map → chunk-PWBGODZU.js.map} +0 -0
- /package/dist/{chunk-MOPAXD2H.js.map → chunk-QCADUTYX.js.map} +0 -0
- /package/dist/{chunk-CT5FBO7E.js.map → chunk-RPOUJI25.js.map} +0 -0
- /package/dist/{chunk-WKHYOS72.js.map → chunk-RW4GFE56.js.map} +0 -0
- /package/dist/{chunk-FH4GO7HO.js.map → chunk-RYLVVDR7.js.map} +0 -0
- /package/dist/{chunk-QZRDCFHI.js.map → chunk-S66SBBFQ.js.map} +0 -0
- /package/dist/{chunk-CQJFIPAH.js.map → chunk-S7TNV2I7.js.map} +0 -0
- /package/dist/{chunk-ZBQSIGGR.js.map → chunk-SC773IMJ.js.map} +0 -0
- /package/dist/{chunk-FBJ2HK7A.js.map → chunk-SGPJ3YS2.js.map} +0 -0
- /package/dist/{chunk-A2EWJQXX.js.map → chunk-SM5QX6UK.js.map} +0 -0
- /package/dist/{chunk-RKZWCTXV.js.map → chunk-TAEKDMEF.js.map} +0 -0
- /package/dist/{chunk-6AVCAUGL.js.map → chunk-TASEV25T.js.map} +0 -0
- /package/dist/{chunk-3XOISKZC.js.map → chunk-TLGDPMUX.js.map} +0 -0
- /package/dist/{chunk-5IUW34PG.js.map → chunk-TY3QYPJ6.js.map} +0 -0
- /package/dist/{chunk-VQFR4EU4.js.map → chunk-U3JK5VJV.js.map} +0 -0
- /package/dist/{chunk-2AWMJO54.js.map → chunk-U42P3RMZ.js.map} +0 -0
- /package/dist/{chunk-GUU75DES.js.map → chunk-UEJTOPLW.js.map} +0 -0
- /package/dist/{chunk-OZOEWLGR.js.map → chunk-UT6JAORE.js.map} +0 -0
- /package/dist/{chunk-5TELOQA6.js.map → chunk-UTHPUINA.js.map} +0 -0
- /package/dist/{chunk-26RQ6JBR.js.map → chunk-VBVCNH6D.js.map} +0 -0
- /package/dist/{chunk-P646DND6.js.map → chunk-VCMQPCME.js.map} +0 -0
- /package/dist/{chunk-LV7FMIMM.js.map → chunk-VGUHAHHV.js.map} +0 -0
- /package/dist/{chunk-GYVXARCY.js.map → chunk-VIBPFVU4.js.map} +0 -0
- /package/dist/{chunk-KHPOKZ6Z.js.map → chunk-VMAC66JX.js.map} +0 -0
- /package/dist/{chunk-SHKRS6I5.js.map → chunk-VRPNETPK.js.map} +0 -0
- /package/dist/{chunk-6U4J6RVS.js.map → chunk-WCHW4XN7.js.map} +0 -0
- /package/dist/{chunk-CJH6QUQJ.js.map → chunk-WD3UXNJV.js.map} +0 -0
- /package/dist/{chunk-H5EVWF6L.js.map → chunk-WR67FJMX.js.map} +0 -0
- /package/dist/{chunk-XLIJ36RG.js.map → chunk-WRMQ7EX4.js.map} +0 -0
- /package/dist/{chunk-7KLCFJ5G.js.map → chunk-X4PPGXQG.js.map} +0 -0
- /package/dist/{chunk-ZE2JTVCQ.js.map → chunk-X5BMQXFD.js.map} +0 -0
- /package/dist/{chunk-UECU6LZI.js.map → chunk-XXRBOSWV.js.map} +0 -0
- /package/dist/{chunk-SPKAIDWX.js.map → chunk-XZEFCPBL.js.map} +0 -0
- /package/dist/{chunk-EZ5NYRHK.js.map → chunk-YL6N7QLA.js.map} +0 -0
- /package/dist/{chunk-VAIESMPY.js.map → chunk-YVBHGMKC.js.map} +0 -0
- /package/dist/{chunk-AR62NQXE.js.map → chunk-Z2S5VQG7.js.map} +0 -0
- /package/dist/{chunk-7UQJEADK.js.map → chunk-ZL2O4BYP.js.map} +0 -0
- /package/dist/{chunk-FOOITLHR.js.map → chunk-ZZHBT5WQ.js.map} +0 -0
- /package/dist/{chunk-X6VJQJYY.js.map → chunk-ZZWHKC6A.js.map} +0 -0
- /package/dist/{model-policy-picker-menu-XOPYY6YA.js.map → computer-viewer-S6TE6TN7.js.map} +0 -0
- /package/dist/{sandbox-files-LJCR437H.js.map → embedded-new-voice-ZDZPGX25.js.map} +0 -0
- /package/dist/{session-realtime-UISLBZ4A.js.map → embedded-voice-FKCUXSJO.js.map} +0 -0
- /package/dist/{fleet-decision-row-5UCJXTDP.js.map → fleet-decision-row-VCGWYJAV.js.map} +0 -0
- /package/dist/{latest-question-VGVNUGAU.js.map → latest-question-SINEV4U6.js.map} +0 -0
- /package/dist/{platform-activity-row-56XOVTRA.js.map → platform-activity-row-LU5WABI2.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/model-policy.ts"],"sourcesContent":["import {\n compareModelPickerOrder,\n modelPickerBillingClassFor,\n type ModelPickerBillingClass,\n} from \"@opengeni/sdk/model-picker-order\";\nimport { modelDisplayName } from \"@opengeni/sdk/model-display\";\nimport type { ClientModel, ReasoningEffort, WorkspaceModelCatalogModel } from \"@opengeni/sdk\";\nimport { type OpenGeniText } from \"./messages/runtime\";\n\nexport type PickerBillingClass = ModelPickerBillingClass;\n\nexport type PickerModelRow<TCatalog extends ClientModel = WorkspaceModelCatalogModel> = {\n id: string;\n label: string;\n /** Catalog-curated compact label for dense UI; fall back to `label` when absent. */\n shortLabel?: string | undefined;\n billingClass: PickerBillingClass;\n billingClassLabel: string;\n selectable: boolean;\n unavailableReason: string | null;\n fundingHint?: string | undefined;\n provider: string;\n providerLabel: string;\n catalog: TCatalog;\n};\n\nexport type LatencyModeId = \"standard\" | \"priority\" | \"fast\" | \"ultrafast\";\n\nconst BILLING_CLASS_LABELS = (t: OpenGeniText): Record<PickerBillingClass, string> => ({\n opengeni_credits: t(\"modelPolicy.models\"),\n external: t(\"modelPolicy.external\"),\n codex_subscription: t(\"modelPolicy.codex\"),\n supergrok_subscription: \"SuperGrok\",\n claude_subscription: t(\"modelPolicy.claudeSubscription\"),\n // Who connected the key (organization or workspace) is a settings fact, not\n // a model choice: both scopes share one label and one picker group.\n byok: t(\"modelPolicy.apiKeys\"),\n organization_byok: t(\"modelPolicy.apiKeys\"),\n});\n\n/** Models settings keeps naming who connected the key. */\nconst SCOPED_BILLING_CLASS_LABELS = (t: OpenGeniText): Record<PickerBillingClass, string> => ({\n ...BILLING_CLASS_LABELS(t),\n byok: t(\"modelPolicy.workspaceProviders\"),\n organization_byok: t(\"modelPolicy.organizationProviders\"),\n});\n\nconst AVAILABILITY_REASON_LABELS = (t: OpenGeniText): Record<string, string> => ({\n missing_credential: t(\"modelPolicy.credentialsRequired\"),\n needs_reauth: t(\"modelPolicy.reconnectRequired\"),\n credential_not_ready: t(\"modelPolicy.credentialNotReady\"),\n not_entitled: t(\"modelPolicy.notEntitled\"),\n provider_unhealthy: t(\"modelPolicy.providerUnavailable\"),\n policy_blocked: t(\"modelPolicy.blockedByWorkspacePolicy\"),\n unsupported: t(\"modelPolicy.unsupported\"),\n credits_disabled: t(\"modelPolicy.opengeniCreditsOff\"),\n});\n\nexport function billingClassForModel(model: ClientModel): PickerBillingClass {\n if (\n model.provider === \"organization-gateway\" ||\n model.provider === \"organization-openrouter\" ||\n model.provider === \"organization-opper\"\n ) {\n return \"organization_byok\";\n }\n if (\n model.provider?.startsWith(\"workspace-openai-\") ||\n model.provider?.startsWith(\"workspace-azure-openai-\")\n )\n return \"byok\";\n if (\n model.provider === \"workspace-gateway\" ||\n model.provider === \"workspace-openrouter\" ||\n model.provider === \"workspace-opper\"\n ) {\n return \"byok\";\n }\n return modelPickerBillingClassFor(model);\n}\n\nexport function billingClassLabel(t: OpenGeniText, billingClass: PickerBillingClass): string {\n return BILLING_CLASS_LABELS(t)[billingClass];\n}\n\n/** The group label that names the connection scope, for Models settings only. */\nexport function scopedBillingClassLabel(t: OpenGeniText, billingClass: PickerBillingClass): string {\n return SCOPED_BILLING_CLASS_LABELS(t)[billingClass];\n}\n\nexport function availabilityReasonLabel(\n t: OpenGeniText,\n reason: WorkspaceModelCatalogModel[\"availability\"][\"reason\"],\n): string | null {\n if (!reason) {\n return null;\n }\n return AVAILABILITY_REASON_LABELS(t)[reason] ?? t(\"modelPolicy.unavailable\");\n}\n\nexport function effortOptionsForModel(model: ClientModel): ReasoningEffort[] {\n const efforts = model.capabilities?.reasoning.efforts;\n if (!efforts || efforts.length === 0) {\n return [\"low\"];\n }\n const order: ReasoningEffort[] = [\"none\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"];\n return order.filter((effort) => efforts.includes(effort));\n}\n\nexport function defaultEffortForModel(model: ClientModel): ReasoningEffort {\n const options = effortOptionsForModel(model);\n const configured = model.capabilities?.reasoning.defaultEffort;\n if (configured && options.includes(configured)) {\n return configured;\n }\n return options[0] ?? \"low\";\n}\n\nexport function coerceReasoningEffortForModel(\n model: ClientModel,\n effort: ReasoningEffort,\n): ReasoningEffort {\n const options = effortOptionsForModel(model);\n if (options.includes(effort)) {\n return effort;\n }\n return defaultEffortForModel(model);\n}\n\n/** Whether the composer offers (and therefore labels) a reasoning-effort choice. */\nexport function modelOffersEffortChoice(model: ClientModel): boolean {\n return (\n effortOptionsForModel(model).length > 1 && model.capabilities?.reasoning.runnable !== false\n );\n}\n\n/**\n * The composer model pill at phone width: the catalog's compact name (falling\n * back to the display name) and the effort label when effort is a choice.\n */\nexport function compactModelPill(\n t: OpenGeniText,\n models: readonly ClientModel[],\n modelId: string,\n effort: ReasoningEffort | null | undefined,\n): { name: string; effort: string | null } {\n const row = findPickerRow(projectClientModelRows(t, [...models]), modelId);\n return {\n name: row?.shortLabel ?? row?.label ?? modelDisplayName(modelId),\n effort:\n row && effort && modelOffersEffortChoice(row.catalog)\n ? labelReasoningEffort(t, effort)\n : null,\n };\n}\n\nexport function runnableLatencyModesForModel(model: ClientModel): LatencyModeId[] {\n const modes = model.capabilities?.latencyModes ?? [];\n return modes.filter((mode) => mode.runnable).map((mode) => mode.id);\n}\n\nexport function labelLatencyMode(t: OpenGeniText, mode: LatencyModeId): string {\n if (mode === \"fast\") {\n return t(\"modelPolicy.fast\");\n }\n if (mode === \"ultrafast\") {\n return t(\"modelPolicy.ultrafast\");\n }\n if (mode === \"priority\") {\n return t(\"modelPolicy.priority\");\n }\n return t(\"modelPolicy.standard\");\n}\n\nexport function labelReasoningEffort(t: OpenGeniText, effort: ReasoningEffort): string {\n if (effort === \"xhigh\") {\n return t(\"modelPolicy.extraHigh\");\n }\n return effort.slice(0, 1).toUpperCase() + effort.slice(1);\n}\n\n/** Payment prompts must use cost policy, never the presentation group. */\nexport function modelUsesCredits(model: ClientModel | undefined): boolean {\n if (model?.cost !== undefined) return model.cost === \"credits\";\n return model?.billing?.metering === \"opengeni_credits\";\n}\n\nexport function payerSummaryForModel(t: OpenGeniText, model: ClientModel): string {\n if (model.cost === \"free\") {\n return t(\"modelPolicy.freeInThisDeployment\");\n }\n if (model.cost === \"credits\") {\n return t(\"modelPolicy.opengeniCredits\");\n }\n if (model.cost === \"subscription\") {\n return model.credentialSource?.kind === \"connected_subscription\" &&\n model.credentialSource.provider === \"claude\"\n ? t(\"modelPolicy.claudeSubscriptionExternalBilling\")\n : model.source === \"supergrok\"\n ? t(\"modelPolicy.supergrokSubscriptionExternalBilling\")\n : t(\"modelPolicy.codexSubscriptionExternalBilling\");\n }\n if (model.cost === \"workspace\") {\n return workspaceProviderPayerSummary(t, model);\n }\n if (model.cost === \"organization\") {\n return organizationProviderPayerSummary(t, model);\n }\n\n // Older client-config payloads do not carry `cost`; preserve their existing\n // settlement-derived label until every deployment has rolled forward.\n const billing = model.billing;\n if (!billing) {\n return t(\"modelPolicy.routeUnknown\");\n }\n if (billing.metering === \"opengeni_credits\") {\n return t(\"modelPolicy.opengeniCreditsAutomaticManagedRoute\");\n }\n if (billing.upstreamPayer === \"connected_subscription\") {\n return model.credentialSource?.kind === \"connected_subscription\" &&\n model.credentialSource.provider === \"claude\"\n ? t(\"modelPolicy.claudeSubscriptionExternalBilling\")\n : model.source === \"supergrok\"\n ? t(\"modelPolicy.supergrokSubscriptionExternalBilling\")\n : t(\"modelPolicy.codexSubscriptionExternalBilling\");\n }\n if (billing.upstreamPayer === \"workspace\") {\n return workspaceProviderPayerSummary(t, model);\n }\n if (billing.upstreamPayer === \"organization\") {\n return organizationProviderPayerSummary(t, model);\n }\n return billing.upstreamPayer === \"deployment\"\n ? t(\"modelPolicy.opengeniNoModelCredits\")\n : t(\"modelPolicy.externalProviderNoOpengeniCredits\");\n}\n\nexport function advancedSourceSummary(t: OpenGeniText, model: ClientModel): string | null {\n const source = model.credentialSource;\n if (!source) {\n return model.billing?.metering === \"external\" && model.billing.upstreamPayer === \"deployment\"\n ? t(\"modelPolicy.deploymentProvidedConnection\")\n : null;\n }\n if (source.kind === \"connected_subscription\") {\n return source.provider === \"claude\"\n ? t(\"modelPolicy.connectedClaudeSubscription\")\n : source.provider === \"xai\"\n ? t(\"modelPolicy.connectedSupergrokSubscription\")\n : t(\"modelPolicy.connectedCodexSubscription\");\n }\n if (source.kind === \"workspace_connection\") {\n if (model.provider === \"workspace-openrouter\") {\n return t(\"modelPolicy.workspaceOpenrouterConnection\");\n }\n if (model.provider === \"workspace-opper\") {\n return t(\"modelPolicy.workspaceOpperConnection\");\n }\n if (model.provider === \"workspace-gateway\" || model.source === \"workspace_gateway\") {\n return t(\"modelPolicy.workspaceVercelAiGateway\");\n }\n return t(\"modelPolicy.workspaceProviderConnection\");\n }\n if (source.kind === \"deployment\") {\n return source.mechanism === \"azure_ad_bearer\"\n ? t(\"modelPolicy.deploymentAzureIdentity\")\n : t(\"modelPolicy.deploymentApiKey\");\n }\n return null;\n}\n\nfunction workspaceProviderPayerSummary(t: OpenGeniText, model: ClientModel): string {\n if (model.provider === \"workspace-anthropic\")\n return t(\"modelPolicy.billedToTheWorkspaceAnthropic\");\n if (model.provider === \"workspace-claude-subscription\")\n return t(\"modelPolicy.usesTheWorkspaceClaudeSubscription\");\n if (model.provider === \"workspace-openrouter\") {\n return t(\"modelPolicy.billedToTheWorkspaceOpenrouter\");\n }\n if (model.provider === \"workspace-opper\") {\n return t(\"modelPolicy.billedToTheWorkspaceOpper\");\n }\n if (model.provider === \"workspace-gateway\" || model.source === \"workspace_gateway\") {\n return t(\"modelPolicy.billedToTheWorkspaceVercel\");\n }\n return t(\"modelPolicy.billedToTheWorkspaceProvider\");\n}\n\nfunction organizationProviderPayerSummary(t: OpenGeniText, model: ClientModel): string {\n if (model.provider === \"organization-anthropic\")\n return t(\"modelPolicy.billedToTheOrganizationAnthropic\");\n if (model.provider === \"organization-claude-subscription\")\n return t(\"modelPolicy.usesTheConnectedClaudeSubscription\");\n if (model.provider === \"organization-openrouter\") {\n return t(\"modelPolicy.billedToTheOrganizationOpenrouter\");\n }\n if (model.provider === \"organization-opper\") {\n return t(\"modelPolicy.billedToTheOrganizationOpper\");\n }\n if (model.provider === \"organization-gateway\") {\n return t(\"modelPolicy.billedToTheOrganizationVercel\");\n }\n return t(\"modelPolicy.billedToTheOrganizationProvider\");\n}\n\n/**\n * The curated compact label, else a derived one for narrow triggers: the name\n * without trailing access and release-stage qualifiers (\"Muse Spark 1.3\n * Contributor Free\" → \"Muse Spark 1.3\"), which the picker's groups and\n * descriptions already carry. Claude names are already family-free\n * (\"Opus 5.5\") in the shared display name.\n */\nfunction compactLabel(catalog: ClientModel): { shortLabel?: string } {\n if (catalog.shortLabel) return { shortLabel: catalog.shortLabel };\n const name = modelDisplayName(catalog);\n const trimmed = withoutTrailingQualifiers(name);\n return trimmed !== name ? { shortLabel: trimmed } : {};\n}\n\nconst TRAILING_QUALIFIERS = new Set([\n \"free\",\n \"contributor\",\n \"preview\",\n \"beta\",\n \"experimental\",\n \"exp\",\n \"latest\",\n]);\n\n/** Drops trailing qualifier words (\"Free\", \"Preview\", \"(free)\") while a name remains. */\nfunction withoutTrailingQualifiers(name: string): string {\n const words = name.trim().split(/\\s+/u);\n while (words.length > 1) {\n const last = words\n .at(-1)!\n .replace(/^[([]|[)\\]]$/gu, \"\")\n .toLowerCase();\n if (!TRAILING_QUALIFIERS.has(last)) break;\n words.pop();\n }\n return words.join(\" \");\n}\n\n/**\n * Older published Site hosts list bare `{ id }` rows. A row without readiness\n * or availability is one the server offers, so it is ready and selectable.\n */\nexport function projectPickerRows(\n t: OpenGeniText,\n models: WorkspaceModelCatalogModel[],\n): PickerModelRow[] {\n return models\n .filter((catalog) => (catalog.credentialReadiness?.status ?? \"ready\") === \"ready\")\n .map((catalog) => {\n const billingClass = billingClassForModel(catalog);\n const selectable = catalog.availability?.selectable ?? true;\n return {\n id: catalog.id,\n label: modelDisplayName(catalog),\n ...compactLabel(catalog),\n billingClass,\n billingClassLabel: billingClassLabel(t, billingClass),\n selectable,\n fundingHint:\n catalog.creditFunding === \"promotional\"\n ? t(\"modelPolicy.freeCredits\")\n : catalog.creditFunding === \"general\"\n ? t(\"modelPolicy.usesCredits\")\n : catalog.creditFunding === \"unavailable\"\n ? t(\"modelPolicy.needsCredits\")\n : undefined,\n unavailableReason: selectable\n ? null\n : availabilityReasonLabel(t, catalog.availability?.reason ?? null),\n provider: catalog.provider,\n providerLabel: catalog.providerLabel,\n catalog,\n };\n });\n}\n\n/** Project the lightweight client-config model list into the same picker contract. */\nexport function projectClientModelRows(\n t: OpenGeniText,\n models: ClientModel[],\n): PickerModelRow<ClientModel>[] {\n return models.map((catalog) => {\n const billingClass = billingClassForModel(catalog);\n return {\n id: catalog.id,\n label: modelDisplayName(catalog),\n ...compactLabel(catalog),\n billingClass,\n billingClassLabel: billingClassLabel(t, billingClass),\n selectable: true,\n unavailableReason: null,\n provider: catalog.provider,\n providerLabel: catalog.providerLabel,\n catalog,\n };\n });\n}\n\nexport function sortPickerRows<TCatalog extends ClientModel>(\n rows: PickerModelRow<TCatalog>[],\n): PickerModelRow<TCatalog>[] {\n return [...rows].sort(compareModelPickerOrder);\n}\n\nexport function findPickerRow<TCatalog extends ClientModel>(\n rows: PickerModelRow<TCatalog>[],\n modelId: string,\n): PickerModelRow<TCatalog> | null {\n return rows.find((row) => row.id === modelId) ?? null;\n}\n\nexport type GroupPickerRowsOptions = {\n codexOnly?: boolean;\n /**\n * Default true: organization- and workspace-connected keys share one group\n * and identical copies show once. Models settings passes false.\n */\n collapseScopes?: boolean | undefined;\n /** Kept visible when it has an identical twin (see below). */\n selectedId?: string | undefined;\n};\n\n/**\n * Organization- and workspace-connected API keys are one choice for the person\n * picking a model, so they share one group.\n */\nfunction displayGroupFor(billingClass: PickerBillingClass): PickerBillingClass {\n return billingClass === \"organization_byok\" ? \"byok\" : billingClass;\n}\n\n/**\n * The same model through the same provider kind, whichever scope connected it:\n * `organization-anthropic/claude-opus-5-5` and `workspace-anthropic/claude-opus-5-5`\n * share a key, while OpenRouter and the Anthropic API never do (different\n * accounts and bills).\n */\nfunction scopeFreeIdentity(row: PickerModelRow<ClientModel>): string | null {\n const provider = row.provider.replace(/^(?:organization|workspace)-/, \"\");\n if (provider === row.provider) return null;\n const upstream =\n row.catalog.deployment?.upstreamModelId ??\n (row.id.startsWith(`${row.provider}/`) ? row.id.slice(row.provider.length + 1) : row.id);\n return `${provider}\\u0000${upstream}`;\n}\n\n/**\n * Two rows that are the same model through the same provider kind, connected\n * by the organization and by the workspace, are one choice: show one. Keep the\n * current selection, else a selectable row, else the first in picker order.\n */\nfunction prefersTwin<TCatalog extends ClientModel>(\n candidate: PickerModelRow<TCatalog>,\n current: PickerModelRow<TCatalog>,\n selectedId: string | undefined,\n): boolean {\n if (selectedId !== undefined && current.id === selectedId) return false;\n if (selectedId !== undefined && candidate.id === selectedId) return true;\n return candidate.selectable && !current.selectable;\n}\n\nexport function groupPickerRowsByBillingClass(\n t: OpenGeniText,\n rows: PickerModelRow[],\n options?: GroupPickerRowsOptions,\n): Array<{ billingClass: PickerBillingClass; label: string; rows: PickerModelRow[] }>;\nexport function groupPickerRowsByBillingClass<TCatalog extends ClientModel>(\n t: OpenGeniText,\n rows: PickerModelRow<TCatalog>[],\n options?: GroupPickerRowsOptions,\n): Array<{\n billingClass: PickerBillingClass;\n label: string;\n rows: PickerModelRow<TCatalog>[];\n}>;\nexport function groupPickerRowsByBillingClass<TCatalog extends ClientModel>(\n t: OpenGeniText,\n rows: PickerModelRow<TCatalog>[],\n options?: GroupPickerRowsOptions,\n): Array<{\n billingClass: PickerBillingClass;\n label: string;\n rows: PickerModelRow<TCatalog>[];\n}> {\n const sorted = sortPickerRows(rows);\n const groups: Array<{\n billingClass: PickerBillingClass;\n label: string;\n rows: PickerModelRow<TCatalog>[];\n }> = [];\n for (const row of sorted) {\n const collapse = options?.collapseScopes !== false;\n const billingClass = collapse ? displayGroupFor(row.billingClass) : row.billingClass;\n const existing = groups.find((group) => group.billingClass === billingClass);\n if (existing) {\n const identity = collapse ? scopeFreeIdentity(row) : null;\n const twin =\n identity === null\n ? -1\n : existing.rows.findIndex((candidate) => scopeFreeIdentity(candidate) === identity);\n if (twin < 0) {\n existing.rows.push(row);\n } else if (prefersTwin(row, existing.rows[twin]!, options?.selectedId)) {\n existing.rows[twin] = row;\n }\n continue;\n }\n groups.push({\n billingClass,\n label:\n billingClass === row.billingClass\n ? row.billingClassLabel\n : billingClassLabel(t, billingClass),\n rows: [row],\n });\n }\n const codexIndex = groups.findIndex((group) => group.billingClass === \"codex_subscription\");\n const codex = groups[codexIndex];\n const selectableOpenGeni = groups\n .find((group) => group.billingClass === \"opengeni_credits\")\n ?.rows.filter((row) => row.selectable);\n // Presentation only: never change the catalog/default model ordering or selection.\n const onlyFreeOpenGeni =\n selectableOpenGeni !== undefined &&\n selectableOpenGeni.length > 0 &&\n selectableOpenGeni.every((row) => row.catalog.cost === \"free\");\n if (\n codex &&\n codex.rows.some((row) => row.selectable) &&\n (options?.codexOnly || onlyFreeOpenGeni)\n ) {\n groups.splice(codexIndex, 1);\n groups.unshift(codex);\n }\n return groups;\n}\nexport { modelDisplayName, modelVendor } from \"@opengeni/sdk/model-display\";\n"],"mappings":"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","names":["modelDisplayName"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/app/components/rail/session-header.tsx"],"sourcesContent":["// The session header bar — the slim canvas top strip's contents on a session\n// route. Split out of the session shell as a PURE, presentational component: it takes\n// plain session data + callbacks and renders the two-line identity block\n// (breadcrumb → title) on the left and the action cluster on the right\n// (provider+model·effort·speed, sandbox, pin, connection, status, panel).\n// The live children that need their own hooks — the sandbox switcher and the\n// codex account indicator — arrive as slots so the whole bar can be rendered\n// (and screenshotted) in isolation. `CanvasTopStrip` in session-shell owns the\n// data wiring and passes the real slots.\nimport { t } from \"../../lib/console-text\";\nimport { OPEN_WORKSTREAM_CONTROL_EVENT } from \"../../../workstream-control-event\";\nimport {\n SessionStatus as SessionStatusBadge,\n SESSION_STATUS_META,\n StatusDot,\n} from \"../../../components/session-status\";\nimport { sessionDisplayStatus, type SessionDisplayStatus } from \"../../../session-status-model\";\nimport { ModelMark } from \"../../../components/model-mark\";\nimport { modelDisplayName } from \"@opengeni/sdk/model-display\";\nimport type { SessionEventsConnectionState } from \"../../../hooks/use-session-events\";\nimport type { SessionSummary } from \"@opengeni/sdk\";\nimport { SiteOriginLink } from \"../session/site-origin-link\";\nimport {\n ArchiveIcon,\n ArchiveRestoreIcon,\n BellIcon,\n BellOffIcon,\n CalendarClockIcon,\n GaugeIcon,\n LockIcon,\n MoreHorizontalIcon,\n PanelRightCloseIcon,\n PanelRightOpenIcon,\n PauseIcon,\n PencilIcon,\n PinIcon,\n SearchIcon,\n ShieldCheckIcon,\n ShieldOffIcon,\n SmartphoneIcon,\n} from \"lucide-react\";\nimport { useCallback, useRef, useState, type ReactNode } from \"react\";\n\nimport { BillingClassMark, type BillingClass } from \"../billing-class-mark\";\nimport { ConnectionPill } from \"../common\";\nimport {\n GrantSessionAdminAccessDialog,\n SessionAdminAccessIndicator,\n type SessionAdminAccessControl,\n} from \"../session/session-admin-access\";\nimport { SessionAncestryBreadcrumb } from \"../session/subagents\";\nimport { Button } from \"../../../ui/button\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuMeta,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../../../ui/dropdown-menu\";\nimport { Skeleton } from \"../../../ui/skeleton\";\nimport { requestConversationFind } from \"../../lib/conversation-find-event\";\nimport { currentPhoneAppPlatform, openInAppUrl } from \"../../lib/open-in-app\";\nimport { sessionControlPaused, sessionInputWait } from \"../../lib/session-rail\";\nimport { useSessionStartup } from \"../../lib/session-startup\";\nimport { isCodexProductModel } from \"../../lib/session-model\";\nimport {\n SESSION_TITLE_MAX_LENGTH,\n sessionDisplayTitle,\n useInlineRename,\n type InlineRename,\n} from \"../../lib/session-rename\";\nimport { pinLiveAnnouncement } from \"../../lib/pin-live-announcement\";\nimport type { SessionRepliesMute } from \"../../lib/inbox\";\nimport { labelEffort, type IntelligenceEffort } from \"../../lib/session-tools\";\nimport type { LatencyMode, Session } from \"../../types\";\nimport { usePage } from \"../../lib/navigation\";\nimport { useUiEventTarget } from \"../../lib/ui-events\";\n\nexport function SessionHeader({\n session,\n ancestors,\n onOpenSchedule,\n lineageLoading,\n lineageError,\n connectionState,\n status,\n keyAuthRequired,\n onForgetAccessKey,\n inspectorOpen,\n onToggleInspector,\n onRename,\n onPin,\n onArchive,\n repliesMute,\n adminAccess,\n onOpenUsageLimit,\n sandboxSlot,\n codexSlot,\n accessSlot,\n leading,\n lastStartedModel,\n lastStartedReasoningEffort,\n lastStartedLatencyMode,\n billingClass,\n modelLabel,\n modelLogoUrl,\n policyLoading,\n}: {\n session: Session;\n /** Root-to-direct-parent order. */\n ancestors: SessionSummary[];\n /**\n * Present only when a scheduled task started this session. Opens that task on\n * the Schedules page so the reader can see or edit what put this here.\n */\n onOpenSchedule?: ((() => void) | null) | undefined;\n lineageLoading?: boolean | undefined;\n lineageError?: Error | null | undefined;\n connectionState: SessionEventsConnectionState;\n status: Session[\"status\"];\n keyAuthRequired: boolean;\n onForgetAccessKey: () => void;\n inspectorOpen: boolean;\n /** Absent: the surface shows no session panel, so no toggle. */\n onToggleInspector?: (() => void) | undefined;\n onRename: (workspaceId: string, sessionId: string, title: string) => Promise<Session | null>;\n onPin: (session: Session, pinned: boolean) => Promise<Session | null>;\n /** Archives or restores this root session. Absent hides the action. */\n onArchive?: ((session: Session, archived: boolean) => Promise<void>) | undefined;\n /**\n * The signed-in person's mute on this session's replies. Absent hides the\n * action (sub-agents, people without an inbox, servers without it).\n */\n repliesMute?: SessionRepliesMute | null | undefined;\n /**\n * This session's admin access, when the viewer can see it on or give it.\n * Absent hides the shield and the menu action.\n */\n adminAccess?: SessionAdminAccessControl | null | undefined;\n /**\n * Opens this chat's usage limit (Agent tab > Usage). Absent hides the menu\n * item, for servers without usage limits.\n */\n onOpenUsageLimit?: ((() => void) | null) | undefined;\n /** The \"Run on <machine>\" control — a live component in production. */\n sandboxSlot?: ReactNode | undefined;\n /**\n * Replaces the static provider mark when the session is on Codex — same icon,\n * clickable for account status/switch. Absent for host-credit sessions.\n */\n codexSlot?: ReactNode | undefined;\n /** Compact session access state/menu, lazy-mounted by the route shell. */\n accessSlot?: ReactNode | undefined;\n /** Leading control (the mobile hamburger); absent on desktop. */\n leading?: ReactNode | undefined;\n /**\n * Model·effort·latency from the newest turn that durably emitted `turn.started`.\n * Historical — does not follow the composer next-turn picker. Falls back to\n * session creation defaults before any turn has admitted.\n */\n lastStartedModel?: string | undefined;\n lastStartedReasoningEffort?: IntelligenceEffort | undefined;\n lastStartedLatencyMode?: LatencyMode | undefined;\n /** Billing rail: Codex account chip, or the mark for makers without a logo. */\n billingClass?: BillingClass | undefined;\n /** Product model label (e.g. GPT-5.6 Luna). */\n modelLabel?: string | undefined;\n modelLogoUrl?: string | undefined;\n /**\n * True while last-started policy and/or model catalog are still resolving.\n * Avoids flashing session defaults (wrong provider) before admitted truth.\n */\n policyLoading?: boolean | undefined;\n}) {\n const uiEvents = useUiEventTarget(\"document\");\n const page = usePage();\n const waiting = sessionInputWait({ ...session, status });\n // A session the runtime could not start reads as stuck, not \"Waiting on you\".\n const displayStatus = sessionDisplayStatus({\n status,\n admissionBlock: session.admissionBlock,\n });\n const startup = useSessionStartup({ ...session, status });\n const startupLabel =\n startup === \"starting\"\n ? \"Starting\"\n : startup === \"delayed\" || startup === \"retrying\"\n ? \"Waiting to start\"\n : undefined;\n const modelId = lastStartedModel?.trim() || session.model;\n const resolvedBilling: BillingClass =\n billingClass ?? (isCodexProductModel(modelId) ? \"codex_subscription\" : \"opengeni_credits\");\n const resolvedModel = modelLabel?.trim() || modelDisplayName(modelId);\n const displayEffort: IntelligenceEffort = lastStartedReasoningEffort ?? session.reasoningEffort;\n const displayLatency: LatencyMode = lastStartedLatencyMode ?? session.latencyMode;\n // Codex → clickable account chip. Other rails → static provider icon only\n // (never invent a text \"Opengeni\"/\"BYOK\" word). Don't key off `codexSlot != null`.\n const isCodexRail = resolvedBilling === \"codex_subscription\";\n const policyBits = [\n resolvedModel,\n labelEffort(displayEffort),\n displayLatency === \"fast\"\n ? \"Fast\"\n : displayLatency === \"ultrafast\"\n ? \"Ultrafast\"\n : displayLatency === \"priority\"\n ? \"Priority\"\n : null,\n ].filter((bit): bit is string => Boolean(bit));\n const rename = useInlineRename(session, onRename);\n const pin = useSessionPinToggle(session, onPin);\n const canArchive = Boolean(onArchive) && session.parentSessionId === null;\n const [grantAdminOpen, setGrantAdminOpen] = useState(false);\n // Menu actions that move focus (rename input, find field) run after the menu\n // has closed, so its focus restoration cannot steal focus back to the trigger.\n const afterMenuClose = useRef<(() => void) | null>(null);\n const providerControl = isCodexRail ? (\n (codexSlot ?? (\n <BillingClassMark\n billingClass=\"codex_subscription\"\n className=\"size-3.5 shrink-0 text-fg-muted\"\n aria-label=\"\"\n />\n ))\n ) : (\n // The model maker's logo; the payment rail only when the maker has none.\n <ModelMark\n model={{ id: modelId, logoUrl: modelLogoUrl }}\n className=\"size-3.5 text-fg-muted\"\n fallback={<BillingClassMark billingClass={resolvedBilling} className=\"size-3.5 shrink-0\" />}\n />\n );\n return (\n // An elevated band, not just canvas-with-a-hairline: reading as a real top\n // bar was the light-theme fix — a near-white header on a near-white canvas\n // needs its own surface + a crisp divider to look intentional (and it lifts\n // the dark bar a touch above the canvas too).\n <header\n data-window-drag\n data-titlebar\n className=\"@container/titlebar flex min-h-14 min-w-0 shrink-0 items-center gap-1 border-b border-border bg-canvas/80 pb-1 pl-[max(clamp(0.5rem,2.5vw,1.25rem),env(safe-area-inset-left))] pr-[max(clamp(0.5rem,2.5vw,1.25rem),env(safe-area-inset-right))] pt-[max(0.375rem,env(safe-area-inset-top))] backdrop-blur supports-[backdrop-filter]:bg-canvas/65 flex-wrap\"\n >\n {leading}\n {/* The title takes every pixel the actions leave; it truncates last. */}\n <div className=\"flex min-w-20 flex-[1_1_5rem] flex-col justify-center gap-0.5\">\n {/* Child sessions link back to the manager that spawned them, and a\n session links to its current schedules. */}\n <div className=\"flex min-w-0 items-center gap-1.5\">\n <SessionAncestryBreadcrumb\n workspaceId={session.workspaceId}\n parentSessionId={session.parentSessionId}\n ancestors={ancestors}\n loading={lineageLoading}\n error={lineageError}\n />\n <SiteOriginLink session={session} />\n {onOpenSchedule ? (\n <button\n type=\"button\"\n onClick={onOpenSchedule}\n className=\"inline-flex shrink-0 items-center gap-1 rounded border border-border px-1.5 py-0.5 text-2xs text-fg-muted transition-colors hover:border-border-strong hover:text-fg\"\n title=\"Open schedules for this session\"\n >\n <CalendarClockIcon aria-hidden className=\"size-3\" />\n Schedule\n </button>\n ) : null}\n </div>\n <div className=\"flex min-w-0 items-center gap-1.5\">\n <SessionTitleEditor session={session} rename={rename} />\n {/* Below lg the lifecycle is a dot beside the title; the full badge\n and connection pill take over from lg. */}\n <CompactSessionStatus\n paused={sessionControlPaused(session)}\n waiting={Boolean(waiting)}\n status={displayStatus}\n label={startupLabel}\n />\n {accessSlot}\n {adminAccess ? (\n <SessionAdminAccessIndicator\n control={adminAccess}\n onChangeTimeLimit={() => setGrantAdminOpen(true)}\n />\n ) : null}\n </div>\n </div>\n <div className=\"ml-auto flex shrink-0 items-center justify-end gap-0.5 lg:min-w-0 lg:max-w-full lg:shrink lg:flex-wrap lg:gap-2\">\n {/* Provider + model · effort · speed stay one cluster on the action side. */}\n <div className=\"hidden min-w-0 max-w-[min(100%,18rem)] items-center gap-1.5 overflow-hidden text-2xs leading-4 text-fg-muted lg:flex xl:max-w-[22rem]\">\n {policyLoading ? (\n <span\n className=\"inline-flex items-center gap-1.5\"\n aria-busy=\"true\"\n aria-label=\"Loading model\"\n >\n <Skeleton className=\"h-6 w-11 shrink-0 rounded-full\" />\n <Skeleton className=\"h-3 w-36\" />\n </span>\n ) : (\n <span className=\"inline-flex min-w-0 items-center gap-1.5 truncate font-medium text-fg-muted\">\n {providerControl}\n <span className=\"min-w-0 truncate font-normal\">\n {policyBits.map((bit, index) => (\n <span key={bit}>\n {index > 0 ? \" · \" : null}\n {bit}\n </span>\n ))}\n </span>\n </span>\n )}\n </div>\n {/* Below lg, machine, find and pin live in the \"…\" menu. */}\n <span className=\"hidden min-w-0 lg:contents\">{sandboxSlot}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={() => requestConversationFind(uiEvents)}\n aria-label=\"Find in conversation\"\n data-conversation-find-trigger=\"\"\n title=\"Find in conversation (Ctrl/Cmd+F)\"\n className=\"hidden pointer-coarse:size-11 lg:inline-flex\"\n >\n <SearchIcon className=\"size-4\" />\n </Button>\n <Button\n type=\"button\"\n variant={session.pinned ? \"secondary\" : \"ghost\"}\n size=\"icon-sm\"\n aria-label={session.pinned ? \"Unpin session\" : \"Pin session\"}\n aria-pressed={Boolean(session.pinned)}\n aria-busy={pin.busy}\n disabled={pin.busy}\n className=\"hidden pointer-coarse:size-11 lg:inline-flex\"\n onClick={pin.toggle}\n >\n <PinIcon className={session.pinned ? \"size-4 fill-current\" : \"size-4\"} />\n </Button>\n <span className=\"sr-only\" aria-live=\"polite\" aria-atomic=\"true\">\n {pin.announcement}\n </span>\n <div className=\"hidden items-center gap-2 lg:flex\">\n <ConnectionPill state={connectionState} />\n {/* Admission vs lifecycle are different axes, but showing both when\n control is Active (Running + Active) is redundant noise. When\n paused, admission is the headline — hide lifecycle so we don't\n imply the session is still \"Running\"/\"Idle\" under a pause gate. */}\n {!sessionControlPaused(session) ? (\n waiting ? (\n <span\n className=\"inline-flex shrink-0 items-center gap-1.5 rounded-full border border-border bg-surface px-2 py-0.5 text-control font-medium text-fg-muted\"\n data-session-wait-badge=\"\"\n >\n <span aria-hidden className=\"size-1.5 rounded-full bg-current\" />\n Waiting\n </span>\n ) : (\n <SessionStatusBadge status={displayStatus} label={startupLabel} />\n )\n ) : (\n <WorkstreamControlIndicator session={session} />\n )}\n </div>\n <span className=\"sr-only lg:hidden\">Connection {connectionState}.</span>\n {keyAuthRequired ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={onForgetAccessKey}\n aria-label=\"Clear access key\"\n className=\"pointer-coarse:size-11\"\n >\n <LockIcon className=\"size-4\" />\n </Button>\n ) : null}\n {onToggleInspector ? (\n <Button\n type=\"button\"\n variant={inspectorOpen ? \"secondary\" : \"ghost\"}\n size=\"icon-sm\"\n onClick={onToggleInspector}\n aria-label={inspectorOpen ? \"Hide workspace\" : \"Open workspace\"}\n title={inspectorOpen ? \"Hide workspace\" : \"Open workspace\"}\n className=\"pointer-coarse:size-11\"\n >\n {inspectorOpen ? (\n <PanelRightCloseIcon className=\"size-4\" />\n ) : (\n <PanelRightOpenIcon className=\"size-4\" />\n )}\n </Button>\n ) : null}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label=\"More session actions\"\n title=\"More\"\n className=\"pointer-coarse:size-11\"\n >\n <MoreHorizontalIcon className=\"size-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"end\"\n className=\"w-56\"\n onCloseAutoFocus={(event) => {\n const action = afterMenuClose.current;\n if (!action) return;\n afterMenuClose.current = null;\n event.preventDefault();\n action();\n }}\n >\n <DropdownMenuItem\n className=\"lg:hidden\"\n onSelect={() => {\n afterMenuClose.current = () => requestConversationFind(uiEvents);\n }}\n >\n <SearchIcon />\n Find\n </DropdownMenuItem>\n <DropdownMenuItem\n onSelect={() => {\n afterMenuClose.current = rename.startEditing;\n }}\n >\n <PencilIcon />\n Rename\n </DropdownMenuItem>\n <DropdownMenuItem\n className=\"lg:hidden\"\n disabled={pin.busy}\n onSelect={() => pin.toggle()}\n >\n <PinIcon className={session.pinned ? \"fill-current\" : undefined} />\n {session.pinned ? \"Unpin\" : \"Pin\"}\n </DropdownMenuItem>\n {currentPhoneAppPlatform() ? (\n <DropdownMenuItem\n onSelect={() => {\n page.assign(openInAppUrl(page.href()));\n }}\n >\n <SmartphoneIcon />\n Open in app\n </DropdownMenuItem>\n ) : null}\n {sandboxSlot ? (\n <div className=\"flex min-h-9 items-center px-2 empty:hidden lg:hidden\">\n {sandboxSlot}\n </div>\n ) : null}\n {repliesMute ? (\n <DropdownMenuItem disabled={repliesMute.busy} onSelect={() => repliesMute.toggle()}>\n {repliesMute.muted ? <BellIcon /> : <BellOffIcon />}\n {repliesMute.muted ? \"Unmute replies\" : \"Mute replies\"}\n </DropdownMenuItem>\n ) : null}\n {onOpenUsageLimit ? (\n <DropdownMenuItem\n onSelect={() => {\n afterMenuClose.current = onOpenUsageLimit;\n }}\n >\n <GaugeIcon />\n Usage limit\n </DropdownMenuItem>\n ) : null}\n {adminAccess?.state.active && adminAccess.state.canRevoke ? (\n <DropdownMenuItem disabled={adminAccess.busy} onSelect={() => adminAccess.revoke()}>\n <ShieldOffIcon />\n Turn off admin access\n </DropdownMenuItem>\n ) : adminAccess && !adminAccess.state.active && adminAccess.state.canGrant ? (\n <DropdownMenuItem\n disabled={adminAccess.busy}\n onSelect={() => {\n afterMenuClose.current = () => setGrantAdminOpen(true);\n }}\n >\n <ShieldCheckIcon />\n Give admin access…\n </DropdownMenuItem>\n ) : null}\n {canArchive ? (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onSelect={() => void onArchive?.(session, !session.archived)}>\n {session.archived ? <ArchiveRestoreIcon /> : <ArchiveIcon />}\n {session.archived ? \"Restore\" : \"Archive\"}\n {session.archived ? <DropdownMenuMeta>Archived</DropdownMenuMeta> : null}\n </DropdownMenuItem>\n </>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n {adminAccess ? (\n <GrantSessionAdminAccessDialog\n control={adminAccess}\n open={grantAdminOpen}\n onOpenChange={setGrantAdminOpen}\n />\n ) : null}\n </div>\n </header>\n );\n}\n\n/** Small-screen status: a dot beside the title, named for assistive tech. */\nfunction CompactSessionStatus({\n paused,\n waiting,\n status,\n label,\n}: {\n paused: boolean;\n waiting: boolean;\n status: SessionDisplayStatus;\n label?: string | undefined;\n}) {\n if (paused) {\n return (\n <span\n data-compact-session-status=\"paused\"\n title=\"Paused\"\n className=\"inline-flex shrink-0 items-center lg:hidden\"\n >\n <PauseIcon aria-hidden className=\"size-2.5 shrink-0 fill-current text-status-waiting\" />\n <span className=\"sr-only\">Paused</span>\n </span>\n );\n }\n if (waiting) {\n return (\n <span\n data-compact-session-status=\"waiting\"\n title=\"Waiting\"\n className=\"inline-flex shrink-0 items-center lg:hidden\"\n >\n <span aria-hidden className=\"size-2 rounded-full bg-status-waiting\" />\n <span className=\"sr-only\">Waiting</span>\n </span>\n );\n }\n const name = label ?? SESSION_STATUS_META(t)[status].label;\n return (\n <span\n data-compact-session-status={status}\n data-status={status}\n title={name}\n className=\"inline-flex shrink-0 items-center lg:hidden\"\n >\n <StatusDot status={status} className=\"size-2\" />\n <span className=\"sr-only\">{name}</span>\n </span>\n );\n}\n\n/** Pause-only header chip (Active is not shown — lifecycle status covers “go”). */\nfunction WorkstreamControlIndicator({ session }: { session: Session }) {\n const control = session.effectiveControl;\n if (control.state !== \"paused\" || session.status === \"cancelled\") {\n return null;\n }\n const blocker = control.primaryBlocker;\n const label =\n blocker?.kind === \"workspace\"\n ? \"Workspace paused\"\n : control.directState === \"paused\" || blocker?.sessionId === session.id\n ? \"Paused here\"\n : `Paused by ${blocker?.displayName ?? \"parent\"}`;\n return (\n <button\n type=\"button\"\n aria-label={`${label}. Open workstream controls`}\n title={`${label} · open workstream controls`}\n onClick={() => {\n document.dispatchEvent(new Event(OPEN_WORKSTREAM_CONTROL_EVENT));\n }}\n className=\"inline-flex min-w-0 max-w-48 items-center gap-1.5 rounded-full border border-status-waiting/35 bg-status-waiting/10 px-2 py-0.5 text-xs font-medium text-fg hover:bg-status-waiting/15\"\n >\n <PauseIcon className=\"size-3 shrink-0 fill-current text-status-waiting\" />\n <span className=\"hidden truncate sm:inline\">{label}</span>\n {control.additionalBlockerCount > 0 ? (\n <span className=\"hidden shrink-0 sm:inline\">+{control.additionalBlockerCount}</span>\n ) : null}\n </button>\n );\n}\n\n/** Pin toggle shared by the desktop pin button and the phone \"…\" menu item. */\nfunction useSessionPinToggle(\n session: Session,\n onPin: (session: Session, pinned: boolean) => Promise<Session | null>,\n) {\n const [busy, setBusy] = useState(false);\n const [announcement, setAnnouncement] = useState(\"\");\n const announcementSequence = useRef(0);\n const announce = useCallback((message: string) => {\n announcementSequence.current += 1;\n setAnnouncement(pinLiveAnnouncement(message, announcementSequence.current));\n }, []);\n const toggle = useCallback(() => {\n if (busy) return;\n const nextPinned = !session.pinned;\n setBusy(true);\n void onPin(session, nextPinned)\n .then((updated) => {\n announce(\n updated\n ? `Session ${nextPinned ? \"pinned\" : \"unpinned\"}.`\n : `Session was not ${nextPinned ? \"pinned\" : \"unpinned\"}.`,\n );\n })\n .catch(() => {\n announce(`Session was not ${nextPinned ? \"pinned\" : \"unpinned\"}.`);\n })\n .finally(() => setBusy(false));\n }, [announce, busy, onPin, session]);\n return { busy, toggle, announcement };\n}\n\n/**\n * The session header title — display by default, click the title (or the\n * hover pencil / \"…\" > Rename) to rename inline. Prefers the durable session.title\n * (agent- or user-set), falling back to the initial message / \"Untitled\n * session\" exactly like the rail list. Enter saves, Esc cancels, blur saves; an\n * empty/unchanged value is a no-op cancel. The live title (context.session)\n * flows in through the session.title_set SSE event the react useSession hook\n * applies, so cross-client renames and agent titling reflect here without a\n * reload. The shared `useInlineRename` hook keeps this behaviour identical to\n * the rail row's rename.\n */\nfunction SessionTitleEditor(props: { session: Session; rename: InlineRename }) {\n const display = sessionDisplayTitle(props.session);\n const rename = props.rename;\n\n if (rename.editing) {\n return (\n // A calm in-place edit: same size and position as the display title, a\n // soft surface tint + hairline instead of a loud focus ring. The global\n // focus-ring rule is what painted the old blue box; opting out here keeps\n // the rename feeling like editing the text, not filling in a form field.\n <input\n ref={rename.inputRef}\n data-session-title-current={display}\n value={rename.draft}\n onChange={(event) => rename.setDraft(event.target.value)}\n onBlur={() => void rename.commit()}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n void rename.commit();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n rename.cancel();\n }\n }}\n maxLength={SESSION_TITLE_MAX_LENGTH}\n aria-label=\"Session title\"\n dir=\"auto\"\n className=\"-mx-1.5 w-full truncate rounded-md bg-surface-2/70 px-1.5 text-[15px] font-semibold leading-6 tracking-[-0.01em] outline-hidden ring-1 ring-border-strong focus:outline-hidden focus-visible:outline-hidden\"\n style={{ outline: \"none\" }}\n />\n );\n }\n\n return (\n <div className=\"group/title flex min-w-0 items-center gap-0.5\">\n <button\n type=\"button\"\n onClick={rename.startEditing}\n title={`${display} · click to rename`}\n dir=\"auto\"\n className=\"min-w-0 shrink truncate rounded-sm text-left text-[15px] font-semibold leading-6 tracking-[-0.01em] text-fg hover:text-fg focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring/40 pointer-coarse:min-h-11 pointer-coarse:px-2\"\n >\n {display}\n </button>\n {/* The pencil earns its pixels only when relevant: hidden at rest and\n revealed on hover/focus. Touch screens rename by tapping the title\n (or \"…\" > Rename), so the title keeps the row's width. */}\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n onClick={rename.startEditing}\n aria-label=\"Rename session\"\n className=\"shrink-0 text-fg-subtle opacity-0 transition-opacity hover:text-fg focus-visible:opacity-100 group-hover/title:opacity-100 pointer-coarse:hidden\"\n >\n <PencilIcon className=\"size-3\" />\n </Button>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,SAAS,wBAAwB;AAIjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,aAAa,QAAQ,gBAAgC;AAkLxD,SAkRQ,UAlRR,KAuCM,YAvCN;AA5IC,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAkEG;AACD,QAAM,WAAW,iBAAiB,UAAU;AAC5C,QAAM,OAAO,QAAQ;AACrB,QAAM,UAAU,iBAAiB,EAAE,GAAG,SAAS,OAAO,CAAC;AAEvD,QAAM,gBAAgB,qBAAqB;AAAA,IACzC;AAAA,IACA,gBAAgB,QAAQ;AAAA,EAC1B,CAAC;AACD,QAAM,UAAU,kBAAkB,EAAE,GAAG,SAAS,OAAO,CAAC;AACxD,QAAM,eACJ,YAAY,aACR,aACA,YAAY,aAAa,YAAY,aACnC,qBACA;AACR,QAAM,UAAU,kBAAkB,KAAK,KAAK,QAAQ;AACpD,QAAM,kBACJ,iBAAiB,oBAAoB,OAAO,IAAI,uBAAuB;AACzE,QAAM,gBAAgB,YAAY,KAAK,KAAK,iBAAiB,OAAO;AACpE,QAAM,gBAAoC,8BAA8B,QAAQ;AAChF,QAAM,iBAA8B,0BAA0B,QAAQ;AAGtE,QAAM,cAAc,oBAAoB;AACxC,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,YAAY,aAAa;AAAA,IACzB,mBAAmB,SACf,SACA,mBAAmB,cACjB,cACA,mBAAmB,aACjB,aACA;AAAA,EACV,EAAE,OAAO,CAAC,QAAuB,QAAQ,GAAG,CAAC;AAC7C,QAAM,SAAS,gBAAgB,SAAS,QAAQ;AAChD,QAAM,MAAM,oBAAoB,SAAS,KAAK;AAC9C,QAAM,aAAa,QAAQ,SAAS,KAAK,QAAQ,oBAAoB;AACrE,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,KAAK;AAG1D,QAAM,iBAAiB,OAA4B,IAAI;AACvD,QAAM,kBAAkB,cACrB,aACC;AAAA,IAAC;AAAA;AAAA,MACC,cAAa;AAAA,MACb,WAAU;AAAA,MACV,cAAW;AAAA;AAAA,EACb;AAAA;AAAA,IAIF;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,IAAI,SAAS,SAAS,aAAa;AAAA,QAC5C,WAAU;AAAA,QACV,UAAU,oBAAC,oBAAiB,cAAc,iBAAiB,WAAU,qBAAoB;AAAA;AAAA,IAC3F;AAAA;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA,IAKE;AAAA,MAAC;AAAA;AAAA,QACC,oBAAgB;AAAA,QAChB,iBAAa;AAAA,QACb,WAAU;AAAA,QAET;AAAA;AAAA,UAED,qBAAC,SAAI,WAAU,iEAGb;AAAA,iCAAC,SAAI,WAAU,qCACb;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,aAAa,QAAQ;AAAA,kBACrB,iBAAiB,QAAQ;AAAA,kBACzB;AAAA,kBACA,SAAS;AAAA,kBACT,OAAO;AAAA;AAAA,cACT;AAAA,cACA,oBAAC,kBAAe,SAAkB;AAAA,cACjC,iBACC;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAS;AAAA,kBACT,WAAU;AAAA,kBACV,OAAM;AAAA,kBAEN;AAAA,wCAAC,qBAAkB,eAAW,MAAC,WAAU,UAAS;AAAA,oBAAE;AAAA;AAAA;AAAA,cAEtD,IACE;AAAA,eACN;AAAA,YACA,qBAAC,SAAI,WAAU,qCACb;AAAA,kCAAC,sBAAmB,SAAkB,QAAgB;AAAA,cAGtD;AAAA,gBAAC;AAAA;AAAA,kBACC,QAAQ,qBAAqB,OAAO;AAAA,kBACpC,SAAS,QAAQ,OAAO;AAAA,kBACxB,QAAQ;AAAA,kBACR,OAAO;AAAA;AAAA,cACT;AAAA,cACC;AAAA,cACA,cACC;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAS;AAAA,kBACT,mBAAmB,MAAM,kBAAkB,IAAI;AAAA;AAAA,cACjD,IACE;AAAA,eACN;AAAA,aACF;AAAA,UACA,qBAAC,SAAI,WAAU,mHAEb;AAAA,gCAAC,SAAI,WAAU,yIACZ,0BACC;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,aAAU;AAAA,gBACV,cAAW;AAAA,gBAEX;AAAA,sCAAC,YAAS,WAAU,kCAAiC;AAAA,kBACrD,oBAAC,YAAS,WAAU,YAAW;AAAA;AAAA;AAAA,YACjC,IAEA,qBAAC,UAAK,WAAU,+EACb;AAAA;AAAA,cACD,oBAAC,UAAK,WAAU,gCACb,qBAAW,IAAI,CAAC,KAAK,UACpB,qBAAC,UACE;AAAA,wBAAQ,IAAI,WAAQ;AAAA,gBACpB;AAAA,mBAFQ,GAGX,CACD,GACH;AAAA,eACF,GAEJ;AAAA,YAEA,oBAAC,UAAK,WAAU,8BAA8B,uBAAY;AAAA,YAC1D;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,MAAM,wBAAwB,QAAQ;AAAA,gBAC/C,cAAW;AAAA,gBACX,kCAA+B;AAAA,gBAC/B,OAAM;AAAA,gBACN,WAAU;AAAA,gBAEV,8BAAC,cAAW,WAAU,UAAS;AAAA;AAAA,YACjC;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS,QAAQ,SAAS,cAAc;AAAA,gBACxC,MAAK;AAAA,gBACL,cAAY,QAAQ,SAAS,kBAAkB;AAAA,gBAC/C,gBAAc,QAAQ,QAAQ,MAAM;AAAA,gBACpC,aAAW,IAAI;AAAA,gBACf,UAAU,IAAI;AAAA,gBACd,WAAU;AAAA,gBACV,SAAS,IAAI;AAAA,gBAEb,8BAAC,WAAQ,WAAW,QAAQ,SAAS,wBAAwB,UAAU;AAAA;AAAA,YACzE;AAAA,YACA,oBAAC,UAAK,WAAU,WAAU,aAAU,UAAS,eAAY,QACtD,cAAI,cACP;AAAA,YACA,qBAAC,SAAI,WAAU,qCACb;AAAA,kCAAC,kBAAe,OAAO,iBAAiB;AAAA,cAKvC,CAAC,qBAAqB,OAAO,IAC5B,UACE;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,2BAAwB;AAAA,kBAExB;AAAA,wCAAC,UAAK,eAAW,MAAC,WAAU,oCAAmC;AAAA,oBAAE;AAAA;AAAA;AAAA,cAEnE,IAEA,oBAAC,iBAAmB,QAAQ,eAAe,OAAO,cAAc,IAGlE,oBAAC,8BAA2B,SAAkB;AAAA,eAElD;AAAA,YACA,qBAAC,UAAK,WAAU,qBAAoB;AAAA;AAAA,cAAY;AAAA,cAAgB;AAAA,eAAC;AAAA,YAChE,kBACC;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT,cAAW;AAAA,gBACX,WAAU;AAAA,gBAEV,8BAAC,YAAS,WAAU,UAAS;AAAA;AAAA,YAC/B,IACE;AAAA,YACH,oBACC;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS,gBAAgB,cAAc;AAAA,gBACvC,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT,cAAY,gBAAgB,mBAAmB;AAAA,gBAC/C,OAAO,gBAAgB,mBAAmB;AAAA,gBAC1C,WAAU;AAAA,gBAET,0BACC,oBAAC,uBAAoB,WAAU,UAAS,IAExC,oBAAC,sBAAmB,WAAU,UAAS;AAAA;AAAA,YAE3C,IACE;AAAA,YACJ,qBAAC,gBACC;AAAA,kCAAC,uBAAoB,SAAO,MAC1B;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACL,cAAW;AAAA,kBACX,OAAM;AAAA,kBACN,WAAU;AAAA,kBAEV,8BAAC,sBAAmB,WAAU,UAAS;AAAA;AAAA,cACzC,GACF;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAM;AAAA,kBACN,WAAU;AAAA,kBACV,kBAAkB,CAAC,UAAU;AAC3B,0BAAM,SAAS,eAAe;AAC9B,wBAAI,CAAC,OAAQ;AACb,mCAAe,UAAU;AACzB,0BAAM,eAAe;AACrB,2BAAO;AAAA,kBACT;AAAA,kBAEA;AAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAU;AAAA,wBACV,UAAU,MAAM;AACd,yCAAe,UAAU,MAAM,wBAAwB,QAAQ;AAAA,wBACjE;AAAA,wBAEA;AAAA,8CAAC,cAAW;AAAA,0BAAE;AAAA;AAAA;AAAA,oBAEhB;AAAA,oBACA;AAAA,sBAAC;AAAA;AAAA,wBACC,UAAU,MAAM;AACd,yCAAe,UAAU,OAAO;AAAA,wBAClC;AAAA,wBAEA;AAAA,8CAAC,cAAW;AAAA,0BAAE;AAAA;AAAA;AAAA,oBAEhB;AAAA,oBACA;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAU;AAAA,wBACV,UAAU,IAAI;AAAA,wBACd,UAAU,MAAM,IAAI,OAAO;AAAA,wBAE3B;AAAA,8CAAC,WAAQ,WAAW,QAAQ,SAAS,iBAAiB,QAAW;AAAA,0BAChE,QAAQ,SAAS,UAAU;AAAA;AAAA;AAAA,oBAC9B;AAAA,oBACC,wBAAwB,IACvB;AAAA,sBAAC;AAAA;AAAA,wBACC,UAAU,MAAM;AACd,+BAAK,OAAO,aAAa,KAAK,KAAK,CAAC,CAAC;AAAA,wBACvC;AAAA,wBAEA;AAAA,8CAAC,kBAAe;AAAA,0BAAE;AAAA;AAAA;AAAA,oBAEpB,IACE;AAAA,oBACH,cACC,oBAAC,SAAI,WAAU,yDACZ,uBACH,IACE;AAAA,oBACH,cACC,qBAAC,oBAAiB,UAAU,YAAY,MAAM,UAAU,MAAM,YAAY,OAAO,GAC9E;AAAA,kCAAY,QAAQ,oBAAC,YAAS,IAAK,oBAAC,eAAY;AAAA,sBAChD,YAAY,QAAQ,mBAAmB;AAAA,uBAC1C,IACE;AAAA,oBACH,mBACC;AAAA,sBAAC;AAAA;AAAA,wBACC,UAAU,MAAM;AACd,yCAAe,UAAU;AAAA,wBAC3B;AAAA,wBAEA;AAAA,8CAAC,aAAU;AAAA,0BAAE;AAAA;AAAA;AAAA,oBAEf,IACE;AAAA,oBACH,aAAa,MAAM,UAAU,YAAY,MAAM,YAC9C,qBAAC,oBAAiB,UAAU,YAAY,MAAM,UAAU,MAAM,YAAY,OAAO,GAC/E;AAAA,0CAAC,iBAAc;AAAA,sBAAE;AAAA,uBAEnB,IACE,eAAe,CAAC,YAAY,MAAM,UAAU,YAAY,MAAM,WAChE;AAAA,sBAAC;AAAA;AAAA,wBACC,UAAU,YAAY;AAAA,wBACtB,UAAU,MAAM;AACd,yCAAe,UAAU,MAAM,kBAAkB,IAAI;AAAA,wBACvD;AAAA,wBAEA;AAAA,8CAAC,mBAAgB;AAAA,0BAAE;AAAA;AAAA;AAAA,oBAErB,IACE;AAAA,oBACH,aACC,iCACE;AAAA,0CAAC,yBAAsB;AAAA,sBACvB,qBAAC,oBAAiB,UAAU,MAAM,KAAK,YAAY,SAAS,CAAC,QAAQ,QAAQ,GAC1E;AAAA,gCAAQ,WAAW,oBAAC,sBAAmB,IAAK,oBAAC,eAAY;AAAA,wBACzD,QAAQ,WAAW,YAAY;AAAA,wBAC/B,QAAQ,WAAW,oBAAC,oBAAiB,sBAAQ,IAAsB;AAAA,yBACtE;AAAA,uBACF,IACE;AAAA;AAAA;AAAA,cACN;AAAA,eACF;AAAA,YACC,cACC;AAAA,cAAC;AAAA;AAAA,gBACC,SAAS;AAAA,gBACT,MAAM;AAAA,gBACN,cAAc;AAAA;AAAA,YAChB,IACE;AAAA,aACN;AAAA;AAAA;AAAA,IACF;AAAA;AAEJ;AAGA,SAAS,qBAAqB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,MAAI,QAAQ;AACV,WACE;AAAA,MAAC;AAAA;AAAA,QACC,+BAA4B;AAAA,QAC5B,OAAM;AAAA,QACN,WAAU;AAAA,QAEV;AAAA,8BAAC,aAAU,eAAW,MAAC,WAAU,sDAAqD;AAAA,UACtF,oBAAC,UAAK,WAAU,WAAU,oBAAM;AAAA;AAAA;AAAA,IAClC;AAAA,EAEJ;AACA,MAAI,SAAS;AACX,WACE;AAAA,MAAC;AAAA;AAAA,QACC,+BAA4B;AAAA,QAC5B,OAAM;AAAA,QACN,WAAU;AAAA,QAEV;AAAA,8BAAC,UAAK,eAAW,MAAC,WAAU,yCAAwC;AAAA,UACpE,oBAAC,UAAK,WAAU,WAAU,qBAAO;AAAA;AAAA;AAAA,IACnC;AAAA,EAEJ;AACA,QAAM,OAAO,SAAS,oBAAoB,CAAC,EAAE,MAAM,EAAE;AACrD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,+BAA6B;AAAA,MAC7B,eAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAU;AAAA,MAEV;AAAA,4BAAC,aAAU,QAAgB,WAAU,UAAS;AAAA,QAC9C,oBAAC,UAAK,WAAU,WAAW,gBAAK;AAAA;AAAA;AAAA,EAClC;AAEJ;AAGA,SAAS,2BAA2B,EAAE,QAAQ,GAAyB;AACrE,QAAM,UAAU,QAAQ;AACxB,MAAI,QAAQ,UAAU,YAAY,QAAQ,WAAW,aAAa;AAChE,WAAO;AAAA,EACT;AACA,QAAM,UAAU,QAAQ;AACxB,QAAM,QACJ,SAAS,SAAS,cACd,qBACA,QAAQ,gBAAgB,YAAY,SAAS,cAAc,QAAQ,KACjE,gBACA,aAAa,SAAS,eAAe,QAAQ;AACrD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAY,GAAG,KAAK;AAAA,MACpB,OAAO,GAAG,KAAK;AAAA,MACf,SAAS,MAAM;AACb,iBAAS,cAAc,IAAI,MAAM,6BAA6B,CAAC;AAAA,MACjE;AAAA,MACA,WAAU;AAAA,MAEV;AAAA,4BAAC,aAAU,WAAU,oDAAmD;AAAA,QACxE,oBAAC,UAAK,WAAU,6BAA6B,iBAAM;AAAA,QAClD,QAAQ,yBAAyB,IAChC,qBAAC,UAAK,WAAU,6BAA4B;AAAA;AAAA,UAAE,QAAQ;AAAA,WAAuB,IAC3E;AAAA;AAAA;AAAA,EACN;AAEJ;AAGA,SAAS,oBACP,SACA,OACA;AACA,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,EAAE;AACnD,QAAM,uBAAuB,OAAO,CAAC;AACrC,QAAM,WAAW,YAAY,CAAC,YAAoB;AAChD,yBAAqB,WAAW;AAChC,oBAAgB,oBAAoB,SAAS,qBAAqB,OAAO,CAAC;AAAA,EAC5E,GAAG,CAAC,CAAC;AACL,QAAM,SAAS,YAAY,MAAM;AAC/B,QAAI,KAAM;AACV,UAAM,aAAa,CAAC,QAAQ;AAC5B,YAAQ,IAAI;AACZ,SAAK,MAAM,SAAS,UAAU,EAC3B,KAAK,CAAC,YAAY;AACjB;AAAA,QACE,UACI,WAAW,aAAa,WAAW,UAAU,MAC7C,mBAAmB,aAAa,WAAW,UAAU;AAAA,MAC3D;AAAA,IACF,CAAC,EACA,MAAM,MAAM;AACX,eAAS,mBAAmB,aAAa,WAAW,UAAU,GAAG;AAAA,IACnE,CAAC,EACA,QAAQ,MAAM,QAAQ,KAAK,CAAC;AAAA,EACjC,GAAG,CAAC,UAAU,MAAM,OAAO,OAAO,CAAC;AACnC,SAAO,EAAE,MAAM,QAAQ,aAAa;AACtC;AAaA,SAAS,mBAAmB,OAAmD;AAC7E,QAAM,UAAU,oBAAoB,MAAM,OAAO;AACjD,QAAM,SAAS,MAAM;AAErB,MAAI,OAAO,SAAS;AAClB;AAAA;AAAA;AAAA;AAAA;AAAA,MAKE;AAAA,QAAC;AAAA;AAAA,UACC,KAAK,OAAO;AAAA,UACZ,8BAA4B;AAAA,UAC5B,OAAO,OAAO;AAAA,UACd,UAAU,CAAC,UAAU,OAAO,SAAS,MAAM,OAAO,KAAK;AAAA,UACvD,QAAQ,MAAM,KAAK,OAAO,OAAO;AAAA,UACjC,WAAW,CAAC,UAAU;AACpB,gBAAI,MAAM,QAAQ,SAAS;AACzB,oBAAM,eAAe;AACrB,mBAAK,OAAO,OAAO;AAAA,YACrB,WAAW,MAAM,QAAQ,UAAU;AACjC,oBAAM,eAAe;AACrB,qBAAO,OAAO;AAAA,YAChB;AAAA,UACF;AAAA,UACA,WAAW;AAAA,UACX,cAAW;AAAA,UACX,KAAI;AAAA,UACJ,WAAU;AAAA,UACV,OAAO,EAAE,SAAS,OAAO;AAAA;AAAA,MAC3B;AAAA;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAU,iDACb;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,OAAO;AAAA,QAChB,OAAO,GAAG,OAAO;AAAA,QACjB,KAAI;AAAA,QACJ,WAAU;AAAA,QAET;AAAA;AAAA,IACH;AAAA,IAIA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,SAAS,OAAO;AAAA,QAChB,cAAW;AAAA,QACX,WAAU;AAAA,QAEV,8BAAC,cAAW,WAAU,UAAS;AAAA;AAAA,IACjC;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/model-picker-model.ts"],"sourcesContent":["/**\n * The model picker's presentation logic, free of any renderer: which rows show,\n * how they group and filter, and which thinking/latency controls apply. The web\n * menu and native sheets both render from this.\n */\nimport type { ClientModel, LatencyMode, ReasoningEffort } from \"@opengeni/sdk\";\nimport {\n coerceReasoningEffortForModel,\n effortOptionsForModel,\n findPickerRow,\n groupPickerRowsByBillingClass,\n payerSummaryForModel,\n projectClientModelRows,\n runnableLatencyModesForModel,\n scopedBillingClassLabel,\n type PickerBillingClass,\n type PickerModelRow,\n} from \"./model-policy\";\nimport { type OpenGeniText } from \"./messages/runtime\";\n\ntype ClientPickerModelRow = PickerModelRow<ClientModel>;\n\nexport type ModelPolicyPickerMessages = {\n label: string;\n loading: string;\n noModels: string;\n connectTitle: string;\n connectBody: string;\n connectAction: string;\n thinking: string;\n fast: string;\n fastRateHint: string;\n /** Label for the Standard/Fast/Ultrafast choice shown when a model offers Ultrafast. */\n speed?: string;\n standard?: string;\n ultrafast?: string;\n /** How Ultrafast counts against a ChatGPT/Codex plan's usage limits. */\n ultrafastUsageHint?: string;\n codexOnly: string;\n searchLabel?: string;\n searchPlaceholder?: string;\n currentModel?: string;\n noMatches?: string;\n unsupportedAttachments?: string;\n thinkingEffort?: string;\n selected?: string;\n free?: string;\n\n billingHints: Record<PickerBillingClass, string>;\n};\n\nexport const defaultModelPolicyPickerMessages = (t: OpenGeniText): ModelPolicyPickerMessages => ({\n label: t(\"modelPickerModel.modelAndEffort\"),\n loading: t(\"modelPickerModel.loadingModelCatalog\"),\n noModels: t(\"modelPickerModel.noModelsAvailable\"),\n connectTitle: t(\"modelPickerModel.connectAModel\"),\n connectBody: t(\"modelPickerModel.useASubscriptionOrA\"),\n connectAction: t(\"modelPickerModel.openModels\"),\n thinking: t(\"modelPickerModel.thinking\"),\n fast: t(\"modelPickerModel.fast\"),\n fastRateHint: \"2× rate\",\n speed: t(\"modelPickerModel.speed\"),\n standard: t(\"modelPolicy.standard\"),\n ultrafast: t(\"modelPolicy.ultrafast\"),\n ultrafastUsageHint: \"8× usage\",\n codexOnly: t(\"modelPickerModel.codexOnlySession\"),\n searchLabel: t(\"modelPickerModel.searchModelsOrProviders\"),\n searchPlaceholder: t(\"modelPickerModel.searchModelsOrProviders2\"),\n currentModel: t(\"modelPickerModel.currentModel\"),\n noMatches: t(\"modelPickerModel.noMatchingModelsTryA\"),\n unsupportedAttachments: t(\"modelPickerModel.thisModelCannotViewThe\"),\n thinkingEffort: t(\"modelPickerModel.thinkingEffort\"),\n selected: t(\"modelPickerModel.selected\"),\n free: t(\"modelPickerModel.free\"),\n\n billingHints: {\n opengeni_credits: t(\"modelPickerModel.providedByOpengeni\"),\n external: t(\"modelPickerModel.providerTermsAndLimitsApply\"),\n codex_subscription: t(\"modelPickerModel.chatgptCodexPlan\"),\n supergrok_subscription: t(\"modelPickerModel.supergrokXaiPlan\"),\n claude_subscription: t(\"modelPickerModel.claudePlan\"),\n byok: t(\"modelPickerModel.billedToTheConnectedProvider\"),\n organization_byok: t(\"modelPickerModel.billedToTheConnectedProvider\"),\n },\n});\n\n/** Host branding for one payment group; the icon type belongs to the renderer. */\nexport type ModelPickerGroupBranding<TIcon = unknown> = {\n label?: string | undefined;\n /** Omit to preserve the default; null hides the supporting text. */\n description?: string | null | undefined;\n /** Decorative, non-interactive content. Omit for the default; null hides it. */\n icon?: TIcon | undefined;\n};\n\nexport type ModelPickerGroupPresentation<TIcon = unknown> = Partial<\n Record<PickerBillingClass, ModelPickerGroupBranding<TIcon>>\n>;\n\n/** The renderer-neutral inputs every picker surface shares. */\nexport type ModelPickerInput<TIcon = unknown> = {\n groupPresentation?: ModelPickerGroupPresentation<TIcon> | undefined;\n models?: ClientModel[] | undefined;\n rows?: PickerModelRow[] | undefined;\n hasImageAttachments?: boolean | undefined;\n model: string;\n effort: ReasoningEffort;\n latencyMode: LatencyMode;\n codexOnly?: boolean | undefined;\n collapseScopes?: boolean | undefined;\n allowLatencyMode?: boolean | undefined;\n messages?: Partial<ModelPolicyPickerMessages> | undefined;\n};\n\n/** Models settings keeps naming who is billed for a key. */\nexport const SCOPED_BILLING_HINTS = (\n t: OpenGeniText,\n): Partial<Record<PickerBillingClass, string>> => ({\n byok: t(\"modelPickerModel.billedToTheWorkspaceProvider\"),\n organization_byok: t(\"modelPickerModel.billedToTheOrganizationProvider\"),\n});\n\nexport function isCodexPickerModel(model: ClientModel): boolean {\n return model.id.startsWith(\"codex/\") || model.source === \"codex\";\n}\n\n/** The payment group a selection the catalog no longer lists most likely belonged to. */\nexport function billingClassForMissingSelection(modelId: string): PickerBillingClass {\n if (modelId.startsWith(\"workspace-claude-subscription/\")) return \"claude_subscription\";\n if (modelId.startsWith(\"workspace-anthropic/\")) return \"byok\";\n if (modelId.startsWith(\"organization-claude-subscription/\")) return \"claude_subscription\";\n if (modelId.startsWith(\"organization-anthropic/\")) return \"organization_byok\";\n if (modelId.startsWith(\"workspace-gateway/\")) return \"byok\";\n if (modelId.startsWith(\"workspace-openrouter/\")) return \"byok\";\n if (modelId.startsWith(\"workspace-opper/\")) return \"byok\";\n // A deployment OpenRouter or Opper ID does not encode its workspace-facing cost.\n // Missing rows therefore use the credits-safe rail instead of falsely\n // claiming that an unknown former selection was externally funded.\n if (modelId.startsWith(\"openrouter/\")) return \"opengeni_credits\";\n if (modelId.startsWith(\"opper/\")) return \"opengeni_credits\";\n if (modelId.startsWith(\"codex/\")) return \"codex_subscription\";\n if (modelId.startsWith(\"supergrok/\")) return \"supergrok_subscription\";\n return \"opengeni_credits\";\n}\n\nfunction applyCodexOnly(\n rows: ClientPickerModelRow[],\n codexOnly: boolean,\n unavailableReason: string,\n): ClientPickerModelRow[] {\n if (!codexOnly) return rows;\n return rows.map((row) =>\n isCodexPickerModel(row.catalog)\n ? row\n : {\n ...row,\n selectable: false,\n unavailableReason: row.unavailableReason ?? unavailableReason,\n },\n );\n}\n\n/**\n * Host branding for a payment group. While scopes are collapsed, API keys are\n * one group, so either API-key presentation serves both.\n */\nexport function groupPresentationFor<TIcon>(\n props: {\n groupPresentation?: ModelPickerGroupPresentation<TIcon> | undefined;\n collapseScopes?: boolean | undefined;\n },\n billingClass: PickerBillingClass,\n): ModelPickerGroupBranding<TIcon> | undefined {\n const own = props.groupPresentation?.[billingClass];\n if (own !== undefined || props.collapseScopes === false) return own;\n if (billingClass === \"byok\") return props.groupPresentation?.organization_byok;\n if (billingClass === \"organization_byok\") return props.groupPresentation?.byok;\n return undefined;\n}\n\nexport function effectiveRows<TIcon>(\n t: OpenGeniText,\n props: ModelPickerInput<TIcon>,\n): ClientPickerModelRow[] {\n const rows =\n props.rows !== undefined ? props.rows : projectClientModelRows(t, props.models ?? []);\n const messages = { ...defaultModelPolicyPickerMessages(t), ...props.messages };\n return applyCodexOnly(rows, props.codexOnly === true, messages.codexOnly).map((row) => {\n const scoped =\n props.collapseScopes === false\n ? {\n ...row,\n label: row.catalog.label,\n billingClassLabel: scopedBillingClassLabel(t, row.billingClass),\n }\n : row;\n if (props.collapseScopes === false) {\n if (row.catalog.shortLabel) scoped.shortLabel = row.catalog.shortLabel;\n else delete scoped.shortLabel;\n }\n const label = groupPresentationFor(props, row.billingClass)?.label;\n return label === undefined ? scoped : { ...scoped, billingClassLabel: label };\n });\n}\n\nexport type ModelPickerMenuGroup = {\n billingClass: PickerBillingClass;\n label: string;\n description: string | null;\n rows: ClientPickerModelRow[];\n};\n\nexport type ModelPickerThinking = {\n efforts: ReasoningEffort[];\n value: ReasoningEffort;\n showThinking: boolean;\n /** The single Fast toggle; false when `speeds` replaces it. */\n showFast: boolean;\n /**\n * The speed choice for models that offer more than one faster mode\n * (Standard, Fast, Ultrafast), or null when the Fast toggle (or nothing) applies.\n */\n speeds: ModelPickerSpeed[] | null;\n /** The selected row cannot run, so its controls are read-only. */\n disabled: boolean;\n};\n\nexport type ModelPickerSpeed = {\n id: LatencyMode;\n label: string;\n /** What the speed costs relative to Standard, or null for Standard. */\n hint: string | null;\n};\n\nexport type ModelPickerMenuView = {\n messages: ModelPolicyPickerMessages;\n rows: ClientPickerModelRow[];\n selected: ClientPickerModelRow | null;\n /** Any row can run; otherwise the surface offers to connect models instead. */\n anySelectable: boolean;\n /** Whether the query is non-empty (decides \"no matches\" versus \"no models\"). */\n searching: boolean;\n groups: ModelPickerMenuGroup[];\n matchCount: number;\n /** Thinking and Fast controls for the selected model, or null when it has none. */\n thinking: ModelPickerThinking | null;\n /** The selected model cannot view images the draft carries. */\n unsupportedAttachments: boolean;\n};\n\n/** Everything a picker menu shows for this input and search query. */\nexport function modelPickerMenuView<TIcon>(\n t: OpenGeniText,\n props: ModelPickerInput<TIcon>,\n query: string,\n): ModelPickerMenuView {\n const messages = { ...defaultModelPolicyPickerMessages(t), ...props.messages };\n const rows = effectiveRows(t, props);\n const selected = findPickerRow(rows, props.model);\n const words = query.toLowerCase().trim().split(/\\s+/).filter(Boolean);\n const filtered = rows.filter((row) => {\n const description = groupPresentationFor(props, row.billingClass)?.description;\n const text =\n `${row.label} ${row.id} ${row.providerLabel} ${row.billingClassLabel} ${description === undefined ? payerSummaryForModel(t, row.catalog) : (description ?? \"\")}`.toLowerCase();\n return words.every((word) => text.includes(word));\n });\n const matchingIds = new Set(filtered.map((row) => row.id));\n const groups = groupPickerRowsByBillingClass(t, rows, {\n codexOnly: props.codexOnly === true,\n selectedId: props.model,\n collapseScopes: props.collapseScopes !== false,\n })\n .map((group) => {\n const presentation = groupPresentationFor(props, group.billingClass);\n const override = presentation?.description;\n const defaultHint =\n props.collapseScopes === false &&\n messages.billingHints[group.billingClass] ===\n defaultModelPolicyPickerMessages(t).billingHints[group.billingClass]\n ? (SCOPED_BILLING_HINTS(t)[group.billingClass] ??\n messages.billingHints[group.billingClass])\n : messages.billingHints[group.billingClass];\n return {\n billingClass: group.billingClass,\n label: presentation?.label ?? group.label,\n rows: group.rows.filter((row) => matchingIds.has(row.id)),\n description:\n override === undefined\n ? group.billingClass === \"opengeni_credits\"\n ? null\n : defaultHint\n : override,\n };\n })\n .filter((group) => group.rows.length > 0);\n const anySelectable = rows.some((row) => row.selectable);\n const unsupportedAttachments =\n props.hasImageAttachments === true &&\n selected?.catalog.capabilities?.inputModalities.includes(\"image\") === false;\n return {\n messages,\n rows,\n selected,\n anySelectable,\n searching: words.length > 0,\n groups,\n matchCount: filtered.length,\n thinking: selected ? modelPickerThinking(props, selected, messages) : null,\n unsupportedAttachments,\n };\n}\n\nfunction modelPickerThinking(\n props: Pick<ModelPickerInput, \"effort\" | \"allowLatencyMode\">,\n selected: ClientPickerModelRow,\n messages: ModelPolicyPickerMessages,\n): ModelPickerThinking | null {\n const efforts = effortOptionsForModel(selected.catalog);\n const showThinking =\n efforts.length > 1 && selected.catalog.capabilities?.reasoning.runnable !== false;\n const runnable =\n props.allowLatencyMode === false ? [] : runnableLatencyModesForModel(selected.catalog);\n const speeds = runnable.includes(\"ultrafast\") ? speedOptions(selected, runnable, messages) : null;\n const showFast = speeds === null && runnable.includes(\"fast\");\n if (!showThinking && !showFast && !speeds) return null;\n return {\n efforts,\n value: coerceReasoningEffortForModel(selected.catalog, props.effort),\n showThinking,\n showFast,\n speeds,\n disabled: !selected.selectable,\n };\n}\n\nfunction speedOptions(\n selected: ClientPickerModelRow,\n runnable: readonly LatencyMode[],\n messages: ModelPolicyPickerMessages,\n): ModelPickerSpeed[] {\n const speeds: ModelPickerSpeed[] = [\n { id: \"standard\", label: messages.standard ?? \"Standard\", hint: null },\n ];\n if (runnable.includes(\"fast\")) {\n speeds.push({ id: \"fast\", label: messages.fast, hint: messages.fastRateHint });\n }\n speeds.push({\n id: \"ultrafast\",\n label: messages.ultrafast ?? \"Ultrafast\",\n hint: ultrafastHint(selected, messages),\n });\n return speeds;\n}\n\n/** Plans count Ultrafast against usage limits; metered routes bill a multiple of the rate. */\nfunction ultrafastHint(\n selected: ClientPickerModelRow,\n messages: ModelPolicyPickerMessages,\n): string | null {\n if (selected.billingClass === \"codex_subscription\") return messages.ultrafastUsageHint ?? null;\n const bps = selected.catalog.capabilities?.latencyModes.find(\n (mode) => mode.id === \"ultrafast\",\n )?.billingMultiplierBps;\n return bps && bps > 10_000 ? `${bps / 10_000}× rate` : null;\n}\n\nexport type ModelPickerChoice = {\n /** The new model, or null when the row is already selected. */\n model: string | null;\n /** Always reported, so hosts can commit model and effort together. */\n effort: ReasoningEffort;\n /** Fast falls back to standard when the new model cannot run it. */\n latencyMode: LatencyMode | null;\n};\n\n/** What choosing a row changes, or null when the row cannot be chosen. */\nexport function modelPickerChoice(\n props: Pick<ModelPickerInput, \"model\" | \"effort\" | \"latencyMode\">,\n row: ClientPickerModelRow,\n): ModelPickerChoice | null {\n if (!row.selectable) return null;\n return {\n model: row.id === props.model ? null : row.id,\n effort: coerceReasoningEffortForModel(row.catalog, props.effort),\n latencyMode:\n props.latencyMode !== \"standard\" &&\n !runnableLatencyModesForModel(row.catalog).includes(props.latencyMode)\n ? \"standard\"\n : null,\n };\n}\n\n/** The web segmented control's short labels (\"X-high\" fits a phone row). */\nexport function compactEffortLabel(\n t: OpenGeniText,\n effort: ReasoningEffort,\n label: string,\n): string {\n return effort === \"xhigh\" ? t(\"modelPickerModel.xHigh\") : label;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/app/routes/sessions-index.tsx"],"sourcesContent":["import { useAppApi } from \"../lib/app-api\";\nimport { initialWorkspaceMachineCompute } from \"../lib/workspace-default-machine\";\nimport { t } from \"../lib/console-text\";\nimport { ANALYTICS_COLLECTION_ENABLED_EVENT } from \"../lib/analytics-consent\";\nimport { useWorkspaceRigs } from \"../lib/use-workspace-rigs\";\nimport { useRepositoryCatalogRefresh } from \"../lib/use-follow-up-repositories\";\nimport { useGitHubAppConnectLauncher } from \"../components/github-app-connect-launcher\";\nimport { openGitHubInstallationSettings } from \"../lib/github-app-connect\";\nimport { captureAnalyticsEvent } from \"../lib/analytics-observer\";\nimport { useWorkspaceMachines } from \"../lib/use-workspace-machines\";\nimport { useSessionListHintRefresh } from \"../lib/use-session-list-hint-refresh\";\nimport { useOpenGeni } from \"../../session-context\";\nimport {\n addsConnectorOutsideDefaults,\n changedConnectorExclusions,\n defaultConnectorSelection,\n newSessionConnectorCustomizeState,\n} from \"../lib/composer-connectors\";\n// The sessions index: the centered \"Start a session\" composer. The form is\n// organised top-down — (A) message + model/tools/repos pills → (B) WHERE SHOULD\n// THIS RUN? (when machines exist) → (C) rig or machine fields.\n// Goals are set by the agent (or later surfaces), not at create.\n//\n// \"Where should this run?\" is a first-class segmented control with two kinds:\n// Managed Sandbox (ephemeral, platform-owned — clones repos, injects env) vs\n// Connected Machine (a user-owned enrolled machine — its own checkout & git\n// auth, a working folder, no clone, no env injection). The kind gates the band\n// below it; invalid states (\"clone my repo onto a machine\") are unreachable by\n// construction.\n//\n// The Connected Machine path is opt-in when the deployment owns a managed\n// sandbox. On a selfhosted-primary deployment it is the only truthful default:\n// the composer selects an online machine and remains blocked when none exists.\nimport { FILE_ONLY_MESSAGE_TEXT, type ComposerState } from \"../../hooks/use-composer\";\nimport { LightboxProvider } from \"../../timeline\";\nimport { ModelMark } from \"../../components/model-mark\";\nimport { useChannels } from \"../../hooks/use-channels\";\nimport { useWorkspaceSessions } from \"../../hooks/use-workspace-sessions\";\nimport { resolveWorkspaceSessionToolDefaults, stableJson } from \"@opengeni/contracts\";\nimport { MACHINES_COMPOSER_POLL_MS, type MachineView } from \"../../machines\";\nimport {\n NewSessionRealtimeControl,\n prestartSessionRealtime,\n useRealtimeModelSelection,\n} from \"../../realtime\";\nimport {\n OpenGeniApiError,\n type NewSessionSelectionHistory,\n type Rig,\n type SessionRealtimeModel,\n} from \"@opengeni/sdk\";\nimport { Link, type PageHost, useNavigate, usePage } from \"../lib/navigation\";\nimport { ChevronDownIcon, CreditCardIcon, FolderIcon, LockIcon, PlusIcon } from \"lucide-react\";\nimport {\n createElement,\n lazy,\n Suspense,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { toast } from \"../lib/toast\";\n\nimport { BillingClassMark } from \"../components/billing-class-mark\";\nimport { ChannelCreateDialog } from \"../components/rail/channel-create-dialog\";\nimport { ConsoleComposer, useDraftAttachments } from \"../components/Composer\";\nimport { NewSessionStarters } from \"../components/new-session-starters\";\nimport { NewSessionDraftSyncNotice } from \"../components/new-session-draft-sync-notice\";\nimport { WorkspaceComposerPlus as ComposerMobilePlus } from \"../components/workspace-composer-plus\";\nimport {\n RunsOnMenuBody,\n RunsOnNotice,\n UsageLimitMenuBody,\n VisibilityMenuBody,\n hasRunsOnChoices,\n runsOnAttention,\n hasVisibilityChoice,\n runsOnSummary,\n visibilitySummary,\n} from \"../components/session/new-session-settings-menu\";\nimport {\n NO_SESSION_USAGE_LIMIT,\n parseSessionUsageLimitDraft,\n sessionUsageLimitCapability,\n sessionUsageLimitDraftSummary,\n type SessionUsageLimitDraft,\n} from \"../lib/session-usage-limit\";\nimport { ModelPicker, type SessionToolSelection } from \"../components/pickers\";\nimport {\n RepositoryContextMenuBody,\n type RepositoryContextPickerProps,\n} from \"../components/repository-picker\";\nimport { Button } from \"../../ui/button\";\nimport { sessionDisplayTitle } from \"../lib/session-rename\";\nimport {\n DropdownMenu,\n DropdownMenuCheck,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuTrigger,\n} from \"../../ui/dropdown-menu\";\nimport { Notice } from \"../../ui/notice\";\nimport { isTransientServiceFailure, OPENGENI_UPDATING_NOTICE } from \"../lib/transient-retry\";\nimport { useConnectionAccounts } from \"../components/capabilities/use-connection-accounts\";\nimport { StatusDot } from \"../../ui/status-dot\";\nimport { useAppContext, useLatestCallback } from \"../app-context\";\nimport { useBrowserAccountBridgeBlocker } from \"../lib/browser-account-bridge\";\nimport {\n EMPTY_COMPOSER_LAUNCH,\n composerLaunchSearchKey,\n modelProvidedAfterLaunch,\n type ComposerLaunchSearch,\n} from \"../lib/composer-launch\";\nimport {\n FOCUS_CREATE_COMPOSER_EVENT,\n type CreateComposerFocusIntent,\n} from \"../lib/create-composer-focus\";\nimport type { RepoDraft } from \"../lib/session-tools\";\nimport { composerFallbackModel } from \"../lib/model-access-onboarding\";\nimport { useForgetLastSession } from \"../lib/last-session-memory\";\nimport {\n isMachineComputeSelectable,\n resolveSelectableMachineSandboxId,\n} from \"../lib/machine-selectability\";\nimport {\n effortOptionsForModel,\n findPickerRow,\n modelUsesCredits,\n runnableLatencyModesForModel,\n type PickerModelRow,\n} from \"../lib/model-policy\";\nimport { isPersonalWorkspace } from \"../lib/managed-self-context\";\nimport { attachManualRepository } from \"../lib/manual-repositories\";\nimport { hasAccountPermission, hasWorkspacePermission } from \"../lib/permissions\";\nimport {\n isPersonalAttachmentConflict,\n newSessionFixedResourceCatalogFailed,\n newSessionPersonalResourceAttachment,\n personalResourceSelectionIdentityKey,\n reconcileNewSessionFixedResources,\n recoverNewSessionPersonalResourceAttachment,\n resolvePersonalResourceOwnerScope,\n} from \"../lib/personal-resource-attachments\";\nimport {\n recentSessionModelPresentation,\n recentSessionStatus,\n recentSessionsForHome,\n relativeTimeLabel,\n sessionRepoLabel,\n} from \"../../session-list-model\";\nimport { signupStarterSet } from \"../lib/signup-starter-set\";\nimport {\n useWorkspaceModelCatalog,\n type WorkspaceModelCatalogState,\n} from \"../lib/use-workspace-model-catalog\";\nimport { resolveWorkspaceAgentDefaults } from \"@opengeni/contracts\";\nimport { ComposerCapabilitiesChip } from \"../components/composer-capabilities-chip\";\nimport { useVaults } from \"../../hooks/use-vaults\";\nimport {\n SessionSecretsMenuBody,\n draftSecretsRows,\n sessionSecretsSummary,\n} from \"../components/secrets/session-secrets-panel\";\nimport {\n capabilityAvailability,\n capabilityOn,\n capabilitySummary,\n draftFromRequest,\n requestFromDraft,\n workspaceAgentDefaultsDraft,\n type AgentCapabilityDraft,\n} from \"../lib/agent-capabilities\";\nimport {\n emptySessionDraft,\n fitToolPolicyToAgentCapabilities,\n isSessionDraftComputeReady,\n newSessionCreateVisibility,\n newSessionDraftOptionsFromSessionDraft,\n rememberedMachineFolder,\n sessionDraftFromNewSessionDraftOptions,\n submissionFromSessionDraft,\n type SessionDraft,\n} from \"../lib/session-create\";\nimport {\n clientFirstPartyMcpToolPolicy,\n firstPartySessionToolOptionsFor,\n selectableSessionMcpServerIds,\n unavailableSessionMcpServerIds,\n newSessionDraftToolPolicy,\n rehydrateRepositoryResources,\n repositorySelectionFromResources,\n} from \"../lib/session-tools\";\nimport { useNewSessionDraft, type NewSessionDraftEditable } from \"../lib/use-new-session-draft\";\nimport { userErrorText } from \"../../ui/api-error\";\nimport {\n newSessionCreateSnapshot,\n runNewSessionRouteSubmission,\n type CreatedSessionRouteAuthority,\n} from \"./sessions-index-submission\";\nimport {\n hydratedNewSessionProjectProvenancePresent,\n initialNewSessionProjectLaunchIntent,\n newSessionProjectSelection,\n nextFocusedNewSessionProjectLaunchIntent,\n nextNewSessionProjectLaunchIntent,\n resolveAmbientNewSessionProjectChannelId,\n resolveHydratedNewSessionProjectSelection,\n} from \"./sessions-index-hydration\";\nimport type { Channel, SandboxBackend, Session } from \"../types\";\nimport { useUiEventTarget } from \"../lib/ui-events\";\n\nconst useCommitSynchronousEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\nconst EmptyCreditsNotice = lazy(() =>\n import(\"../components/credit-required-prompt\").then((module) => ({\n default: module.EmptyCreditsNotice,\n })),\n);\nconst CreditTopupPrompt = lazy(() =>\n import(\"../components/credit-required-prompt\").then((module) => ({\n default: module.CreditRequiredPrompt,\n })),\n);\n\nexport function SessionsIndexRoute({\n workspaceId,\n launch = EMPTY_COMPOSER_LAUNCH,\n}: {\n workspaceId: string;\n launch?: ComposerLaunchSearch | undefined;\n}) {\n const { accessKeyVersion, accessContext } = useAppContext();\n useForgetLastSession(accessContext.subjectId, workspaceId);\n return (\n <SessionsIndexRouteContent\n key={`${workspaceId}:${accessKeyVersion}`}\n workspaceId={workspaceId}\n launch={launch}\n />\n );\n}\n\nfunction SessionsIndexRouteContent({\n workspaceId,\n launch,\n}: {\n workspaceId: string;\n launch: ComposerLaunchSearch;\n}) {\n const uiEvents = useUiEventTarget(\"window\");\n const context = useAppContext();\n const api = useAppApi();\n const page = usePage();\n const connectionAccounts = useConnectionAccounts(\n context.client,\n {\n id: \"new-session\",\n workspaceId,\n selectedIds: [...context.selectedCapabilityToolIds],\n },\n context.workspaceCapabilityCatalog,\n context.accessContext === null\n ? null\n : hasWorkspacePermission(context.accessContext, workspaceId, \"connections:read\"),\n );\n const repositoryCatalogRefresh = useRepositoryCatalogRefresh(workspaceId, context);\n // Hosted here, outside the repository menu, so the menu closing when the\n // authorization popup opens does not unmount GitHub App setup.\n const githubAppConnect = useGitHubAppConnectLauncher(workspaceId);\n const firstPartyMcpToolPolicy = useMemo(\n () => clientFirstPartyMcpToolPolicy(context.clientConfig),\n [context.clientConfig],\n );\n const workspace = context.workspaces.find((candidate) => candidate.id === workspaceId) ?? null;\n const configuredToolDefaults = useMemo(\n () => resolveWorkspaceSessionToolDefaults(workspace?.settings),\n [workspace?.settings],\n );\n const defaultFirstPartyMcpTools = useMemo(\n () =>\n configuredToolDefaults?.firstPartyMcpTools?.filter((tool) =>\n firstPartyMcpToolPolicy.allowed.includes(tool),\n ) ?? firstPartyMcpToolPolicy.default,\n [configuredToolDefaults, firstPartyMcpToolPolicy],\n );\n const defaultSandboxBackend = context.clientConfig.defaultSandboxBackend;\n const firstPartyToolOptions = useMemo(\n () => firstPartySessionToolOptionsFor(firstPartyMcpToolPolicy.allowed),\n [firstPartyMcpToolPolicy],\n );\n const navigate = useNavigate();\n const modelCatalog = useWorkspaceModelCatalog(workspaceId);\n const channelsQuery = useChannels({ pollIntervalMs: 60_000 });\n const launchChannelId = launch.channelId === \"default\" ? null : launch.channelId;\n const [selectedChannelId, setSelectedChannelId] = useState<string | null>(\n launchChannelId ?? null,\n );\n const selectedChannelIdRef = useRef(selectedChannelId);\n const setSelectedProjectChannelId = useCallback((channelId: string | null) => {\n selectedChannelIdRef.current = channelId;\n setSelectedChannelId(channelId);\n }, []);\n const [selectionHistory, setSelectionHistory] = useState<NewSessionSelectionHistory>({\n projects: [],\n });\n const [projectProvenancePresent, setProjectProvenancePresent] = useState(\n launchChannelId !== undefined,\n );\n const remoteDraftHydratedRef = useRef(false);\n const previousLaunchChannelIdRef = useRef<string | null | undefined>(launchChannelId);\n const launchProjectIntentRef = useRef(initialNewSessionProjectLaunchIntent(launchChannelId));\n const recentChannelId = selectionHistory.projects[0]?.channelId ?? null;\n const [projectDialogOpen, setProjectDialogOpen] = useState(false);\n const [projectNameDraft, setProjectNameDraft] = useState(\"\");\n const { resetSessionView } = context;\n const [message, setMessage] = useState(\"\");\n const [creditTopupOpen, setCreditTopupOpen] = useState(false);\n const [draft, setDraft] = useState<SessionDraft>(() =>\n emptySessionDraft(defaultFirstPartyMcpTools, defaultSandboxBackend),\n );\n const personalWorkspace = isPersonalWorkspace(workspace, context.managedSelfContext);\n const [capabilitiesOpenRequest, setCapabilitiesOpenRequest] = useState<\n { panel: \"capabilities\"; nonce: number } | undefined\n >(undefined);\n // \"+\" > Capabilities: the workspace's defaults, or this chat's own choice.\n const agentAvailability = useMemo(\n () => capabilityAvailability(context.clientConfig.agentConfig),\n [context.clientConfig.agentConfig],\n );\n const workspaceAgentDraft = useMemo(\n () =>\n workspaceAgentDefaultsDraft({\n capabilities: resolveWorkspaceAgentDefaults(workspace?.settings)?.capabilities,\n legacyHumanInputOff: workspace?.settings.agentHumanInputEnabled === false,\n }),\n [workspace?.settings],\n );\n const composerAgentCapabilities = {\n customized: draft.agentCapabilities !== undefined,\n draft:\n draft.agentCapabilities !== undefined\n ? draftFromRequest(draft.agentCapabilities)\n : workspaceAgentDraft,\n availability: agentAvailability,\n onCustomizedChange: (customized: boolean) =>\n setDraft((current) => {\n if (!customized) {\n const { agentCapabilities: _dropped, ...rest } = current;\n return rest;\n }\n return {\n ...current,\n agentCapabilities: requestFromDraft(workspaceAgentDraft, agentAvailability),\n };\n }),\n onChange: (next: AgentCapabilityDraft) =>\n setDraft((current) => ({\n ...current,\n agentCapabilities: requestFromDraft(next, agentAvailability),\n })),\n };\n // \"+\" > Secrets: which vaults this chat may use. Shown only while its agent\n // can use secrets (the workspace default or this chat's own capabilities).\n const draftSecretsOn =\n agentAvailability.isAvailable(\"secrets\") &&\n capabilityOn(composerAgentCapabilities.draft.values, \"secrets\");\n const canListSecrets =\n hasWorkspacePermission(context.accessContext, workspaceId, \"secrets:list\") ||\n hasWorkspacePermission(context.accessContext, workspaceId, \"variable-sets:list\");\n const draftVaults = useVaults({\n client: context.client,\n workspaceId,\n enabled: canListSecrets && draftSecretsOn,\n });\n const draftVaultPolicy = draft.vaultPolicy ?? { mode: \"all\" as const };\n const draftVaultRows = draftVaults.vaults\n ? draftSecretsRows(draftVaults.vaults, draftVaultPolicy)\n : null;\n const attachments = useDraftAttachments(\n workspaceId,\n personalWorkspace || draft.visibility === \"private\" ? \"personal\" : \"workspace\",\n );\n const fixedResourceCatalogEnabled = draft.compute.kind === \"sandbox\";\n const canUseRigs = hasWorkspacePermission(context.accessContext, workspaceId, \"rigs:use\");\n const rigs = useWorkspaceRigs({\n enabled: fixedResourceCatalogEnabled && canUseRigs,\n });\n const [tenancyCapabilities, setTenancyCapabilities] = useState<{\n activated: boolean;\n canCreatePrivate: boolean;\n reason: \"available\" | \"not_activated\" | \"managed_session_required\" | \"unavailable\";\n defaultVisibility?: \"private\" | \"workspace\" | undefined;\n } | null>(null);\n const tenancyCapabilityGeneration = useRef(0);\n // Whether the person picked who can see this new chat. Until they do, it\n // starts with the organization's default.\n const visibilityChosenRef = useRef(false);\n useEffect(() => {\n const generation = ++tenancyCapabilityGeneration.current;\n visibilityChosenRef.current = false;\n setTenancyCapabilities(null);\n void context.client\n .getSessionTenancyCreateCapabilities(workspaceId)\n .then((capabilities) => {\n if (tenancyCapabilityGeneration.current !== generation) return;\n setTenancyCapabilities(capabilities);\n if (!capabilities.canCreatePrivate) {\n setDraft((current) =>\n current.visibility === \"private\" ? { ...current, visibility: \"workspace\" } : current,\n );\n } else if (capabilities.defaultVisibility === \"private\" && !visibilityChosenRef.current) {\n setDraft((current) =>\n current.visibility === \"private\" ? current : { ...current, visibility: \"private\" },\n );\n }\n })\n .catch(() => {\n if (tenancyCapabilityGeneration.current !== generation) return;\n setTenancyCapabilities({\n activated: false,\n canCreatePrivate: false,\n reason: \"unavailable\",\n });\n setDraft((current) =>\n current.visibility === \"private\" ? { ...current, visibility: \"workspace\" } : current,\n );\n });\n }, [context.client, personalWorkspace, workspaceId]);\n const createVisibility = newSessionCreateVisibility(\n personalWorkspace,\n draft.visibility,\n tenancyCapabilities?.canCreatePrivate === true,\n );\n const personalOwnerScope = resolvePersonalResourceOwnerScope({\n authMode: context.clientConfig.auth.mode,\n authSession: context.authSession,\n accessSubjectId: context.accessContext.subjectId,\n managedSelfContext: context.managedSelfContext,\n workspace,\n });\n const personalResourcesAvailable =\n personalOwnerScope !== null && (personalWorkspace || tenancyCapabilities?.activated === true);\n const personalResourceEligibilitySettled =\n personalWorkspace || personalOwnerScope === null || tenancyCapabilities !== null;\n // Sandbox Environments configure the managed sandbox; a deployment without\n // one has nothing for them to apply to.\n const noManagedSandbox = defaultSandboxBackend === \"none\";\n const selectableRigs = noManagedSandbox\n ? []\n : rigs.rigs.filter((rig) => rig.scope !== \"user\" || personalResourcesAvailable);\n const selectedRig = selectableRigs.find((candidate) => candidate.id === draft.rigId);\n const selectableRigIdsKey = selectableRigs.map((rig) => rig.id).join(\"\\u0000\");\n const fixedResourceSelection = reconcileNewSessionFixedResources({\n selectedRigId: draft.rigId,\n selectableRigIds: fixedResourceCatalogEnabled\n ? selectableRigs.map((rig) => rig.id)\n : draft.rigId\n ? [draft.rigId]\n : [],\n rigsSettled:\n !fixedResourceCatalogEnabled ||\n (personalResourceEligibilitySettled && !rigs.loading && rigs.error === null),\n });\n const fixedResourceCatalogError =\n draft.compute.kind === \"sandbox\" &&\n newSessionFixedResourceCatalogFailed({\n selectedRigId: draft.rigId,\n selectionResolved: fixedResourceSelection.selectionResolved,\n rigCatalogFailed: rigs.error !== null,\n });\n useEffect(() => {\n setDraft((current) => {\n if (current.compute.kind !== \"sandbox\") return current;\n const reconciled = reconcileNewSessionFixedResources({\n selectedRigId: current.rigId,\n selectableRigIds: selectableRigIdsKey ? selectableRigIdsKey.split(\"\\u0000\") : [],\n rigsSettled: personalResourceEligibilitySettled && !rigs.loading && rigs.error === null,\n });\n return reconciled.rigId === current.rigId ? current : { ...current, rigId: reconciled.rigId };\n });\n }, [\n draft.rigId,\n personalResourceEligibilitySettled,\n rigs.error,\n rigs.loading,\n selectableRigIdsKey,\n ]);\n const [fleetPollMs, setFleetPollMs] = useState<number | undefined>(undefined);\n const fleet = useWorkspaceMachines({ pollIntervalMs: fleetPollMs });\n const machines = fleet.machines.filter((machine) => machine.kind === \"selfhosted\");\n // \"+\" > Runs on: where the new chat runs and on which environment or folder.\n const runsOnChoices = {\n draft,\n machines,\n rigs: selectableRigs,\n workspaceDefaultRigId: workspace?.defaultRigId ?? null,\n selfhostedPrimary: defaultSandboxBackend === \"selfhosted\",\n noManagedSandbox,\n // A 404 means Connected Machines are off here, not a failure.\n fleetLoadFailed:\n fleet.error != null &&\n !(fleet.error instanceof OpenGeniApiError && fleet.error.status === 404),\n selectedChannelId,\n selectionHistory,\n };\n const fleetEmpty = machines.length === 0;\n const fleetLoadFailed =\n fleet.error != null && !(fleet.error instanceof OpenGeniApiError && fleet.error.status === 404);\n useEffect(() => {\n if (fleet.loading) return;\n setFleetPollMs(!fleetEmpty || fleetLoadFailed ? MACHINES_COMPOSER_POLL_MS : undefined);\n }, [fleet.loading, fleetEmpty, fleetLoadFailed]);\n const selectedMachineSandboxId =\n draft.compute.kind === \"machine\" ? draft.compute.sandboxId : null;\n const selectedMachine = selectedMachineSandboxId\n ? (machines.find((machine) => machine.sandboxId === selectedMachineSandboxId) ?? null)\n : null;\n const personalMachineSelected = selectedMachine?.scope === \"user\";\n const selectedPersonalResourceNames =\n draft.compute.kind === \"sandbox\"\n ? selectedRig?.scope === \"user\"\n ? [selectedRig.name]\n : []\n : personalMachineSelected && selectedMachine\n ? [selectedMachine.name]\n : [];\n const personalResourceSelectionKey = personalResourceSelectionIdentityKey({\n rigId: selectedRig?.scope === \"user\" ? selectedRig.id : null,\n connectedMachineId:\n personalMachineSelected && selectedMachine ? selectedMachine.enrollmentId : null,\n });\n const selectedPersonalResourceCount = personalResourceSelectionKey\n ? personalResourceSelectionKey.split(\"\\u0000\").length\n : 0;\n const [personalResourceCatalogRefreshPending, setPersonalResourceCatalogRefreshPending] =\n useState(false);\n const personalResourceCatalogRefreshGeneration = useRef(0);\n const personalResourceAttachment = newSessionPersonalResourceAttachment({\n personalResourceCount: selectedPersonalResourceCount,\n visibility: createVisibility,\n });\n const refreshPersonalResourceCatalogs = useLatestCallback(async (): Promise<void> => {\n const generation = ++personalResourceCatalogRefreshGeneration.current;\n setPersonalResourceCatalogRefreshPending(true);\n try {\n if (canUseRigs) await rigs.refresh();\n } finally {\n if (personalResourceCatalogRefreshGeneration.current === generation) {\n setPersonalResourceCatalogRefreshPending(false);\n }\n }\n });\n const recoverPersonalResourceAttachment = useLatestCallback(\n (error: unknown, attemptedInput: Parameters<typeof isPersonalAttachmentConflict>[1]): void => {\n if (!isPersonalAttachmentConflict(error, attemptedInput)) return;\n void recoverNewSessionPersonalResourceAttachment({\n error,\n attemptedInput,\n refreshCatalogs: refreshPersonalResourceCatalogs,\n });\n },\n );\n const [toolSelectionExplicit, setToolSelectionExplicit] = useState(false);\n // Whether the person chose the composer's model policy. False follows the\n // server-resolved new-chat default; undefined means an older server that\n // does not report the marker, so none is sent back.\n const [modelProvided, setModelProvided] = useState<boolean | undefined>(undefined);\n const [connectorCustomizing, setConnectorCustomizing] = useState(false);\n const [connectorExclusions, setConnectorExclusions] = useState<string[]>([]);\n const followWorkspaceConnectors = () => {\n connectionAccounts.resetEmptyChoices();\n setConnectorCustomizing(false);\n setToolSelectionExplicit(false);\n setConnectorExclusions([]);\n context.setSelectedCapabilityToolIds(\n defaultConnectorSelection(context.workspaceDefaultToolIds, []),\n );\n };\n const changeConnectorSelection = (selection: SessionToolSelection) => {\n // Choosing accounts is also an explicit connector customization. Apply it\n // in this event, rather than waiting for the header switch to re-render.\n if (!connectorCustomizing) setConnectorCustomizing(true);\n if (\n !toolSelectionExplicit &&\n addsConnectorOutsideDefaults(\n context.selectedCapabilityToolIds,\n selection.mcpServerIds,\n context.workspaceDefaultToolIds,\n )\n ) {\n setToolSelectionExplicit(true);\n } else if (!toolSelectionExplicit) {\n setConnectorExclusions((current) =>\n changedConnectorExclusions(\n current,\n context.selectedCapabilityToolIds,\n selection.mcpServerIds,\n ),\n );\n }\n context.setSelectedCapabilityToolIds(selection.mcpServerIds);\n };\n const [submitting, setSubmitting] = useState(false);\n // The new chat's usage limit: local to this composer (never the synced\n // draft or a remembered default), and only offered when the server can\n // enforce it.\n const usageLimitCapability = sessionUsageLimitCapability(context.clientConfig);\n const [usageLimitDraft, setUsageLimitDraft] =\n useState<SessionUsageLimitDraft>(NO_SESSION_USAGE_LIMIT);\n const [usageLimitSendBlocked, setUsageLimitSendBlocked] = useState(false);\n const [createdSessionAuthority, setCreatedSessionAuthority] =\n useState<CreatedSessionRouteAuthority | null>(null);\n const composerRegionRef = useRef<HTMLDivElement | null>(null);\n // 0 = no explicit request (mount uses ConsoleComposer autoFocus). >0 = same-route\n // new-session / shortcut asked us to put the caret back in the create composer.\n const [createComposerFocusGen, setCreateComposerFocusGen] = useState(0);\n const selectProject = useLatestCallback((channelId: string | null, explicit = true) => {\n const previousChannelId = selectedChannelIdRef.current;\n if (explicit) setProjectProvenancePresent(true);\n setSelectedProjectChannelId(channelId);\n setDraft((current) => {\n const selection = newSessionProjectSelection(\n selectionHistory,\n channelId,\n { channelId: previousChannelId, compute: current.compute },\n defaultSandboxBackend,\n );\n return selection.compute === current.compute\n ? current\n : { ...current, compute: selection.compute };\n });\n });\n const setExplicitComputeDraft = useLatestCallback((nextDraft: SessionDraft) => {\n setProjectProvenancePresent(true);\n setDraft(\n nextDraft.compute.kind === \"sandbox\" &&\n !nextDraft.compute.backend &&\n defaultSandboxBackend !== \"selfhosted\"\n ? {\n ...nextDraft,\n compute: {\n ...nextDraft.compute,\n backend: defaultSandboxBackend ?? \"\",\n },\n }\n : nextDraft,\n );\n });\n\n useEffect(() => {\n resetSessionView();\n }, [resetSessionView, workspaceId]);\n\n // Folder-launch links preselect their exact destination, including Default,\n // while the ordinary New session entry starts in Recents. Commit this intent\n // before pending draft continuations can run; keeping it in an effect also\n // preserves render purity and the useEffect server fallback preserves SSR.\n useCommitSynchronousEffect(() => {\n const previousLaunchChannelId = previousLaunchChannelIdRef.current;\n previousLaunchChannelIdRef.current = launchChannelId;\n launchProjectIntentRef.current = nextNewSessionProjectLaunchIntent(\n launchProjectIntentRef.current,\n previousLaunchChannelId,\n launchChannelId,\n );\n const channelId = resolveAmbientNewSessionProjectChannelId({\n launchChannelId,\n previousLaunchChannelId,\n recentChannelId,\n remoteDraftHydrated: remoteDraftHydratedRef.current,\n });\n if (channelId === undefined) return;\n if (launchChannelId === undefined && previousLaunchChannelId !== undefined) {\n setProjectProvenancePresent(false);\n }\n selectProject(channelId, launchChannelId !== undefined);\n }, [launchChannelId, recentChannelId, selectProject]);\n\n useEffect(() => {\n if (\n selectedChannelId !== null &&\n !channelsQuery.loading &&\n !channelsQuery.channels.some((channel) => channel.id === selectedChannelId)\n ) {\n selectProject(null, false);\n }\n }, [channelsQuery.channels, channelsQuery.loading, selectedChannelId, selectProject]);\n const createProject = useCallback(async () => {\n const name = projectNameDraft.trim();\n if (!name) return;\n const project = await channelsQuery.create({ name });\n if (!project) {\n toast.error(\"Couldn't create the project. The name may already be in use.\");\n return;\n }\n selectProject(project.id);\n setProjectDialogOpen(false);\n setProjectNameDraft(\"\");\n }, [channelsQuery, projectNameDraft, selectProject]);\n\n useEffect(() => {\n const onRequest = (event: Event) => {\n const requestedChannelId = (event as CustomEvent<CreateComposerFocusIntent>).detail\n ?.channelId;\n launchProjectIntentRef.current = nextFocusedNewSessionProjectLaunchIntent(\n launchProjectIntentRef.current,\n requestedChannelId,\n );\n if (requestedChannelId !== undefined) {\n selectProject(requestedChannelId);\n } else if (remoteDraftHydratedRef.current) {\n setProjectProvenancePresent(false);\n selectProject(recentChannelId, false);\n }\n setCreateComposerFocusGen((current) => current + 1);\n };\n uiEvents.addEventListener(FOCUS_CREATE_COMPOSER_EVENT, onRequest);\n return () => uiEvents.removeEventListener(FOCUS_CREATE_COMPOSER_EVENT, onRequest);\n }, [recentChannelId, selectProject, uiEvents]);\n\n const computeReady =\n isSessionDraftComputeReady(draft) &&\n (draft.compute.kind !== \"machine\" ||\n (!fleet.loading &&\n selectedMachine !== null &&\n isMachineComputeSelectable(selectedMachine.state)));\n const persistedToolPolicy = useMemo(\n () =>\n fitToolPolicyToAgentCapabilities(\n newSessionDraftToolPolicy({\n selectedMcpServerIds: context.selectedCapabilityToolIds,\n workspaceDefaultMcpServerIds: context.workspaceDefaultToolIds,\n catalogReady: context.workspaceMcpCatalogReady,\n customizing: connectorCustomizing,\n explicit: toolSelectionExplicit,\n ...(!toolSelectionExplicit ? { excludedMcpServerIds: connectorExclusions } : {}),\n }),\n draft.agentCapabilities,\n ),\n [\n context.selectedCapabilityToolIds,\n context.workspaceMcpCatalogReady,\n context.workspaceDefaultToolIds,\n toolSelectionExplicit,\n connectorCustomizing,\n connectorExclusions,\n draft.agentCapabilities,\n ],\n );\n const persistedValue = useMemo(\n () => ({\n text: message,\n resources: [\n ...(draft.compute.kind === \"machine\" ? [] : context.currentResources),\n ...attachments.readyResources,\n ],\n tools: persistedToolPolicy.tools,\n toolsProvided: persistedToolPolicy.toolsProvided,\n model: context.model,\n reasoningEffort: context.reasoningEffort,\n latencyMode: context.latencyMode,\n ...(modelProvided !== undefined ? { modelProvided } : {}),\n ...(projectProvenancePresent ? { selectedProjectChannelId: selectedChannelId } : {}),\n options: {\n ...newSessionDraftOptionsFromSessionDraft(\n draft,\n defaultFirstPartyMcpTools,\n createVisibility,\n ),\n ...(persistedToolPolicy.excludedMcpServerIds !== undefined\n ? { excludedMcpServerIds: persistedToolPolicy.excludedMcpServerIds }\n : {}),\n },\n }),\n [\n attachments.readyResources,\n context.model,\n context.latencyMode,\n context.reasoningEffort,\n context.currentResources,\n draft,\n defaultFirstPartyMcpTools,\n message,\n modelProvided,\n createVisibility,\n persistedToolPolicy,\n projectProvenancePresent,\n selectedChannelId,\n ],\n );\n useEffect(() => {\n if (\n context.selectedPersonalGitHubRepoIds.size > 0 &&\n !context.personalGitHubAuthority &&\n context.personalGitHubCatalogReady\n ) {\n void context.ensurePersonalGitHubAuthority(workspaceId);\n }\n }, [\n context,\n context.ensurePersonalGitHubAuthority,\n context.personalGitHubAuthority,\n context.personalGitHubCatalogReady,\n context.selectedPersonalGitHubRepoIds.size,\n workspaceId,\n ]);\n const hydrateResources = useLatestCallback((resources: NewSessionDraftEditable[\"resources\"]) =>\n rehydrateRepositoryResources(resources, context.githubRepos, {\n catalogReady: context.githubCatalogReady,\n personalRepositories: context.personalGitHubRepositories,\n personalCatalogReady: context.personalGitHubCatalogReady,\n }),\n );\n const setModel = context.setModel;\n const setReasoningEffort = context.setReasoningEffort;\n const setLatencyMode = context.setLatencyMode;\n const setSelectedCapabilityToolIds = context.setSelectedCapabilityToolIds;\n const setManualRepos = context.setManualRepos;\n const setSelectedRepoIds = context.setSelectedRepoIds;\n const setSelectedRepoRefs = context.setSelectedRepoRefs;\n const setSelectedPersonalGitHubRepoIds = context.setSelectedPersonalGitHubRepoIds;\n const setSelectedPersonalGitHubRepoRefs = context.setSelectedPersonalGitHubRepoRefs;\n const githubRepos = context.githubRepos;\n const workspaceDefaultToolIdsForHydration = context.workspaceDefaultToolIds;\n const applyRemoteDraft = useCallback(\n (remote: NewSessionDraftEditable, history: NewSessionSelectionHistory) => {\n setMessage(remote.text);\n const restored = sessionDraftFromNewSessionDraftOptions(\n remote.options,\n defaultFirstPartyMcpTools,\n defaultSandboxBackend,\n );\n const projectSelection = resolveHydratedNewSessionProjectSelection({\n launchIntent: launchProjectIntentRef.current,\n remote,\n history,\n restoredCompute: restored.compute,\n defaultSandboxBackend,\n });\n // Fence the ambient Recents effect before installing history. That state\n // update changes recentChannelId, but must not replace this hydrated\n // explicit/persisted selection (or the legacy fallback resolved above).\n remoteDraftHydratedRef.current = true;\n setSelectionHistory(history);\n setProjectProvenancePresent(\n hydratedNewSessionProjectProvenancePresent(launchProjectIntentRef.current, remote),\n );\n setSelectedProjectChannelId(projectSelection.channelId);\n const compute = initialWorkspaceMachineCompute({\n settings: workspace?.settings,\n options: remote.options,\n fallback: projectSelection.compute,\n backend: defaultSandboxBackend,\n });\n setDraft({ ...restored, compute });\n setModel(remote.model);\n setReasoningEffort(remote.reasoningEffort);\n setLatencyMode(remote.latencyMode);\n setModelProvided(remote.modelProvided);\n const customize = newSessionConnectorCustomizeState({\n toolsProvided: remote.toolsProvided,\n tools: remote.tools,\n excludedMcpServerIds: remote.options.excludedMcpServerIds,\n });\n setConnectorCustomizing(customize.customizing);\n setToolSelectionExplicit(customize.explicit);\n setConnectorExclusions(remote.options.excludedMcpServerIds ?? []);\n const selected = new Set(\n customize.explicit\n ? remote.tools.map((tool) => tool.id)\n : defaultConnectorSelection(\n workspaceDefaultToolIdsForHydration,\n customize.customizing ? (remote.options.excludedMcpServerIds ?? []) : [],\n ),\n );\n setSelectedCapabilityToolIds(selectableSessionMcpServerIds(selected));\n const repositorySelection = repositorySelectionFromResources(remote.resources, githubRepos);\n setManualRepos(repositorySelection.manualRepos);\n setSelectedRepoIds(repositorySelection.selectedRepoIds);\n setSelectedRepoRefs(repositorySelection.selectedRepoRefs);\n setSelectedPersonalGitHubRepoIds(repositorySelection.selectedPersonalRepoIds);\n setSelectedPersonalGitHubRepoRefs(repositorySelection.selectedPersonalRepoRefs);\n },\n [\n setManualRepos,\n setModel,\n setLatencyMode,\n setReasoningEffort,\n setSelectedCapabilityToolIds,\n setSelectedRepoIds,\n setSelectedRepoRefs,\n setSelectedPersonalGitHubRepoIds,\n setSelectedPersonalGitHubRepoRefs,\n githubRepos,\n defaultFirstPartyMcpTools,\n defaultSandboxBackend,\n setSelectedProjectChannelId,\n workspaceDefaultToolIdsForHydration,\n workspace?.settings,\n ],\n );\n const newSessionDraft = useNewSessionDraft({\n workspaceId,\n client: context.client,\n value: persistedValue,\n onApplyRemote: applyRemoteDraft,\n restoreReadyFiles: attachments.restoreReadyFiles,\n hydrateResources,\n suspendAutosave: submitting,\n // Establish the passive baseline only after effective visibility settles.\n // Otherwise a late Personal-workspace capability response turns hydration\n // into an autosave, racing navigation and sibling drafts without a user edit.\n // Failed capability reads settle to the existing unavailable fallback too.\n // GitHub remains optional and must not keep the composer unsendable.\n resourceHydrationReady: context.workspaceMcpCatalogReady && tenancyCapabilities !== null,\n });\n useEffect(() => {\n if (newSessionDraft.loading || !context.workspaceMcpCatalogReady || toolSelectionExplicit)\n return;\n const next = defaultConnectorSelection(\n context.workspaceDefaultToolIds,\n connectorCustomizing ? connectorExclusions : [],\n );\n setSelectedCapabilityToolIds((current) =>\n current.size === next.size && [...next].every((id) => current.has(id)) ? current : next,\n );\n }, [\n newSessionDraft.loading,\n context.workspaceMcpCatalogReady,\n context.workspaceDefaultToolIds,\n setSelectedCapabilityToolIds,\n connectorCustomizing,\n connectorExclusions,\n toolSelectionExplicit,\n ]);\n const busy = context.busy || submitting;\n const privateCreateUnavailable =\n (personalWorkspace && tenancyCapabilities === null) ||\n (!personalWorkspace &&\n draft.visibility === \"private\" &&\n tenancyCapabilities?.canCreatePrivate !== true);\n const selectedPolicyRow = findPickerRow(modelCatalog.rows, context.model);\n const newSessionPolicyValid = Boolean(\n selectedPolicyRow?.selectable &&\n effortOptionsForModel(selectedPolicyRow.catalog).includes(context.reasoningEffort) &&\n (context.latencyMode === \"standard\" ||\n runnableLatencyModesForModel(selectedPolicyRow.catalog).includes(context.latencyMode)),\n );\n const noRunnableModel =\n !modelCatalog.loading &&\n modelCatalog.rows.length > 0 &&\n !modelCatalog.rows.some((row) => row.selectable);\n const newSessionPolicyError =\n !modelCatalog.loading &&\n !newSessionPolicyValid &&\n !noRunnableModel &&\n selectedPolicyRow?.selectable\n ? \"Choose a supported model, reasoning level, and speed.\"\n : null;\n useEffect(() => {\n if (modelCatalog.loading || newSessionDraft.loading) return;\n if (findPickerRow(modelCatalog.rows, context.model)?.selectable) return;\n // The server-resolved default comes first (saved workspace default, then a\n // connected subscription, then credits, then the deployment default); the\n // client ranking only covers a default that is itself unavailable.\n const resolvedDefault = modelCatalog.defaultSelection;\n const next = composerFallbackModel({\n models: modelCatalog.models,\n rows: modelCatalog.rows,\n defaultSelection: resolvedDefault,\n });\n if (!next || next.id === context.model) return;\n setModel(next.id);\n setReasoningEffort(next.effort);\n // An automatic replacement is not the person's choice.\n setModelProvided((current) => (current === undefined ? current : false));\n }, [\n context.model,\n modelCatalog.defaultSelection,\n modelCatalog.loading,\n modelCatalog.models,\n modelCatalog.rows,\n newSessionDraft.loading,\n setModel,\n setReasoningEffort,\n ]);\n const codexConnected = modelCatalog.models.some(\n (candidate) =>\n candidate.provider === \"codex-subscription\" &&\n candidate.credentialReadiness.status === \"ready\",\n );\n const startBlocker =\n modelCatalog.loading || newSessionDraft.loading\n ? null\n : modelCatalog.error\n ? \"model_catalog_unavailable\"\n : !newSessionPolicyValid\n ? !modelCatalog.rows.some((row) => row.selectable)\n ? \"no_model_connected\"\n : selectedPolicyRow &&\n selectedPolicyRow.billingClass !== \"opengeni_credits\" &&\n selectedPolicyRow.catalog.credentialReadiness.status !== \"ready\"\n ? \"selected_model_not_connected\"\n : \"model_policy_unavailable\"\n : privateCreateUnavailable\n ? \"private_session_unavailable\"\n : attachments.hasUnresolved\n ? \"attachments_pending\"\n : !computeReady\n ? \"compute_unavailable\"\n : null;\n useEffect(() => {\n const record = () => {\n if (startBlocker)\n captureAnalyticsEvent(\"session_start_blocker_viewed\", {\n workspace_id: workspaceId,\n reason: startBlocker,\n });\n };\n record();\n window.addEventListener(ANALYTICS_COLLECTION_ENABLED_EVENT, record);\n return () => window.removeEventListener(ANALYTICS_COLLECTION_ENABLED_EVENT, record);\n }, [startBlocker, workspaceId]);\n // Shared with the bar start control and the mobile “+ → Voice model” panel.\n const voiceSelection = useRealtimeModelSelection({\n client: context.client,\n workspaceId,\n codexConnected,\n });\n\n useEffect(() => {\n if (createComposerFocusGen === 0 || newSessionDraft.loading) return;\n const textarea = composerRegionRef.current?.querySelector(\"textarea\");\n if (!textarea || textarea.disabled) return;\n textarea.focus();\n }, [createComposerFocusGen, newSessionDraft.loading]);\n\n const submitNewSession = useLatestCallback(\n async (\n realtimeModel: SessionRealtimeModel | null,\n policy?: Pick<ComposerLaunchSearch, \"model\" | \"effort\" | \"latency\">,\n ): Promise<boolean> => {\n if (startBlocker)\n captureAnalyticsEvent(\"session_start_blocked\", {\n workspace_id: workspaceId,\n reason: startBlocker,\n });\n const hasTypedText = message.trim().length > 0;\n const text = hasTypedText\n ? message\n : attachments.readyResources.length > 0\n ? FILE_ONLY_MESSAGE_TEXT(t)\n : \"\";\n if (\n busy ||\n !context.workspaceMcpCatalogReady ||\n newSessionDraft.loading ||\n !newSessionPolicyValid ||\n privateCreateUnavailable ||\n personalResourceCatalogRefreshPending ||\n (!realtimeModel &&\n createdSessionAuthority === null &&\n (connectionAccounts.loading ||\n connectionAccounts.error !== null ||\n connectionAccounts.requiresAccountChoice)) ||\n (createdSessionAuthority === null && !fixedResourceSelection.selectionResolved)\n )\n return false;\n if (createdSessionAuthority === null) {\n const unavailable = unavailableSessionMcpServerIds(\n context.selectedCapabilityToolIds,\n context.toolMcpServers,\n context.workspaceMcpCatalogLoadedSuccessfully,\n );\n if (unavailable.length > 0) {\n const removed = new Set(unavailable);\n context.setSelectedCapabilityToolIds(\n (current) => new Set([...current].filter((id) => !removed.has(id))),\n );\n setConnectorExclusions((current) => [...new Set([...current, ...unavailable])]);\n toast.error(\"Some selected tools are no longer available\", {\n description:\n \"Removed them from this draft. Your message is still here; review the tools and send again.\",\n });\n return false;\n }\n }\n if (realtimeModel && personalMachineSelected) {\n toast.error(\"Voice can't start on a personal Connected Machine\", {\n description:\n \"Start the session with a message first so Opengeni can attach the machine to an accepted turn.\",\n });\n return false;\n }\n if (\n createdSessionAuthority === null &&\n ((!text && !realtimeModel) || attachments.hasUnresolved || !computeReady)\n ) {\n return false;\n }\n // A chosen limit must be a valid amount; an older server never gets one.\n const usageLimit =\n usageLimitCapability === \"enabled\" ? parseSessionUsageLimitDraft(usageLimitDraft) : null;\n if (createdSessionAuthority === null && usageLimit && !usageLimit.ok) {\n setUsageLimitSendBlocked(true);\n toast.error(\"Check the usage limit\", {\n description: `${usageLimit.error} Change it under + > Usage limit.`,\n });\n return false;\n }\n const usageLimitMicros = usageLimit?.ok ? usageLimit.limitMicros : null;\n const model = policy?.model ?? persistedValue.model;\n const reasoningEffort = policy?.effort ?? persistedValue.reasoningEffort;\n const latencyMode = policy?.latency ?? persistedValue.latencyMode;\n // One Send always refers to one visible snapshot, even if a sibling edit\n // forces a draft save or create retry while the user continues typing.\n const visibleSignature = stableJson(persistedValue);\n const submittedSnapshot = newSessionCreateSnapshot(\n persistedValue,\n realtimeModel ? persistedValue.text : text,\n {\n model,\n reasoningEffort,\n latencyMode,\n },\n );\n const preserveNewerLocalDraft = async () => {\n if (!newSessionDraft.isCurrentSignature(visibleSignature)) {\n // A definitive create failure must not leave text typed during the\n // attempt unsaved after a retry persisted the clicked snapshot.\n await (realtimeModel ? newSessionDraft.flush() : newSessionDraft.flushForSend());\n }\n };\n setSubmitting(true);\n try {\n return await runNewSessionRouteSubmission({\n authority: createdSessionAuthority,\n onAuthorityChange: setCreatedSessionAuthority,\n create: async () => {\n // Voice launch is realtime-only: never turn composer text/files into\n // an initial message. Persist the draft so a pending autosave is not\n // lost on navigate, but do not consume it — text stays for later.\n if (realtimeModel) {\n for (let attempt = 0; attempt < 3; attempt += 1) {\n // Voice launch does not consume the draft. Save local edits if\n // possible, but never rebase an old voice draft over a sibling's\n // newer unsent message merely to start a realtime session.\n const flushed = await newSessionDraft.flush();\n if (!flushed) {\n reportDraftSaveFailure(newSessionDraft);\n return null;\n }\n const submission = submissionFromSessionDraft(\n draft,\n defaultFirstPartyMcpTools,\n personalResourceAttachment.intent,\n );\n let draftConflict = false;\n let outcomeUnknown = false;\n const created = await context.startSession(\n workspaceId,\n {\n text: \"\",\n resources: [],\n tools: submittedSnapshot.tools,\n model,\n reasoningEffort,\n latencyMode,\n ...submission.extras,\n },\n {\n targetSandboxId: submission.options.targetSandboxId,\n workingDir: submission.options.workingDir,\n channelId: selectedChannelId,\n omitWorkspaceResources: submission.omitWorkspaceResources,\n installedSkillIds: launch.skillCapabilityId\n ? [launch.skillCapabilityId]\n : undefined,\n startMode: \"realtime\",\n expectedNewSessionDraftRevision: flushed.revision,\n newSessionDraftToolPolicy: persistedToolPolicy,\n agentLearning: draft.agentLearning,\n usageLimitMicros,\n visibility: newSessionCreateVisibility(\n personalWorkspace,\n submission.options.visibility ?? \"workspace\",\n tenancyCapabilities?.canCreatePrivate === true,\n ),\n onFailure: ({ error, request, outcomeUnknown: uncertain }) => {\n draftConflict = newSessionDraft.captureConflict(error);\n outcomeUnknown = uncertain;\n recoverPersonalResourceAttachment(error, request);\n // A brief outage shows the updating notice, not a toast.\n return draftConflict || newSessionDraft.reportUnavailable(error);\n },\n },\n );\n if (!created) {\n if (draftConflict) continue;\n if (!outcomeUnknown) await preserveNewerLocalDraft();\n return null;\n }\n setUsageLimitDraft(NO_SESSION_USAGE_LIMIT);\n setUsageLimitSendBlocked(false);\n return {\n sessionId: created.id,\n settleDraft: async () => true,\n };\n }\n await preserveNewerLocalDraft();\n newSessionDraft.clearError();\n toast.error(\"Couldn't start voice\", {\n description: DRAFT_CHANGED_DURING_SEND_TEXT,\n });\n return null;\n }\n\n const submittedResources = submittedSnapshot.resources;\n for (let attempt = 0; attempt < 3; attempt += 1) {\n const flushed = await newSessionDraft.flushForSend(submittedSnapshot);\n if (!flushed) {\n reportDraftSaveFailure(newSessionDraft);\n return null;\n }\n const submission = submissionFromSessionDraft(\n draft,\n defaultFirstPartyMcpTools,\n personalResourceAttachment.intent,\n );\n let draftConflict = false;\n let outcomeUnknown = false;\n const created = await context.startSession(\n workspaceId,\n {\n text,\n resources: submittedResources,\n tools: submittedSnapshot.tools,\n model,\n reasoningEffort,\n latencyMode,\n ...submission.extras,\n connectionAccounts: connectionAccounts.selections,\n },\n {\n targetSandboxId: submission.options.targetSandboxId,\n workingDir: submission.options.workingDir,\n channelId: selectedChannelId,\n omitWorkspaceResources: submission.omitWorkspaceResources,\n installedSkillIds: launch.skillCapabilityId\n ? [launch.skillCapabilityId]\n : undefined,\n expectedNewSessionDraftRevision: flushed.revision,\n newSessionDraftToolPolicy: persistedToolPolicy,\n agentLearning: draft.agentLearning,\n usageLimitMicros,\n visibility: newSessionCreateVisibility(\n personalWorkspace,\n submission.options.visibility ?? \"workspace\",\n tenancyCapabilities?.canCreatePrivate === true,\n ),\n onFailure: ({ error, request, outcomeUnknown: uncertain }) => {\n draftConflict = newSessionDraft.captureConflict(error);\n outcomeUnknown = uncertain;\n recoverPersonalResourceAttachment(error, request);\n // A brief outage shows the updating notice, not a toast.\n // An unconfirmed create keeps its idempotency key, so the\n // person's next Send cannot start a second session.\n return draftConflict || newSessionDraft.reportUnavailable(error);\n },\n },\n );\n if (!created) {\n if (draftConflict) continue;\n if (!outcomeUnknown) await preserveNewerLocalDraft();\n return null;\n }\n // The limit belongs to the chat just created; the next starts with none.\n setUsageLimitDraft(NO_SESSION_USAGE_LIMIT);\n setUsageLimitSendBlocked(false);\n return {\n sessionId: created.id,\n settleDraft: async () => {\n const acknowledged = await newSessionDraft.acknowledgeConsumed(\n flushed,\n visibleSignature,\n );\n if (\n acknowledged?.kind === \"consumed\" &&\n newSessionDraft.isCurrentSignature(visibleSignature)\n ) {\n setMessage(\"\");\n visibilityChosenRef.current = false;\n setDraft({\n ...emptySessionDraft(defaultFirstPartyMcpTools, defaultSandboxBackend),\n visibility:\n tenancyCapabilities?.canCreatePrivate === true &&\n tenancyCapabilities.defaultVisibility === \"private\"\n ? \"private\"\n : \"workspace\",\n });\n attachments.removeReadyFiles(\n submittedResources.flatMap((resource) =>\n resource.kind === \"file\" ? [resource.fileId] : [],\n ),\n );\n } else if (\n acknowledged?.kind !== \"preserved\" ||\n !newSessionDraft.isCurrentSignature(acknowledged.flushed.signature)\n ) {\n // The message was already accepted. If there is no newer\n // local edit, leave a sibling's later draft untouched.\n if (!acknowledged && newSessionDraft.isCurrentSignature(visibleSignature)) {\n return true;\n }\n const preserved = await newSessionDraft.flushForSend();\n if (!preserved || !newSessionDraft.isCurrentSignature(preserved.signature)) {\n return false;\n }\n }\n return true;\n },\n };\n }\n await preserveNewerLocalDraft();\n // Each attempt saved the draft before the create refused it, so the\n // draft is not unsaved: clear that notice and resume autosave.\n newSessionDraft.clearError();\n toast.error(\"Couldn't send\", {\n description: DRAFT_CHANGED_DURING_SEND_TEXT,\n });\n return null;\n },\n navigate: async (sessionId) => {\n // Voice connects while the session page loads; the page adopts\n // the running call (`?realtime=` still selects its model there).\n const sessionPath = `/workspaces/${workspaceId}/sessions/${sessionId}`;\n const abandonVoice = realtimeModel\n ? prestartSessionRealtime({\n client: api.voiceRealtimeClient(\n context.client,\n () => new URL(sessionPath, page.origin()).href,\n ),\n workspaceId,\n sessionId,\n model: realtimeModel,\n language: voiceSelection.languageFor(realtimeModel),\n voiceSettings: voiceSelection.voiceSettingsFor(realtimeModel),\n })\n : null;\n try {\n await navigate({\n to: \"/workspaces/$workspaceId/sessions/$sessionId\",\n params: { workspaceId, sessionId },\n search: realtimeModel ? { realtime: realtimeModel } : {},\n });\n } catch (error) {\n abandonVoice?.();\n throw error;\n }\n },\n });\n } finally {\n setSubmitting(false);\n }\n },\n );\n\n // URL launch: ?model=&effort=&latency= prefill the composer; +?realtime= also\n // creates a realtime-first session and autostarts voice on the session page.\n // Wait for the durable new-session draft so remote hydrate cannot stomp the\n // URL policy after we apply it.\n const launchModel = launch.model;\n const launchEffort = launch.effort;\n const launchLatency = launch.latency;\n const launchRealtime = launch.realtime;\n const launchFollowDefault = launch.followDefault === true;\n const launchSkillCapabilityId = launch.skillCapabilityId;\n const launchKey = composerLaunchSearchKey(launch);\n const handledLaunchKeyRef = useRef<string | null>(null);\n useEffect(() => {\n if (!launchKey || handledLaunchKeyRef.current === launchKey) return;\n if (newSessionDraft.loading) return;\n if (launchModel) setModel(launchModel);\n if (launchEffort) setReasoningEffort(launchEffort);\n if (launchLatency) setLatencyMode(launchLatency);\n // A checkout return carries the credits default and keeps following the\n // default; any other launch policy is the person's choice.\n setModelProvided((current) =>\n modelProvidedAfterLaunch(\n {\n ...(launchModel ? { model: launchModel } : {}),\n ...(launchEffort ? { effort: launchEffort } : {}),\n ...(launchLatency ? { latency: launchLatency } : {}),\n ...(launchFollowDefault ? { followDefault: true } : {}),\n },\n current,\n ),\n );\n if (!launchRealtime) {\n handledLaunchKeyRef.current = launchKey;\n void navigate({\n to: \"/workspaces/$workspaceId/sessions\",\n params: { workspaceId },\n search: {\n ...(launch.channelId ? { channelId: launch.channelId } : {}),\n ...(launchSkillCapabilityId ? { skillCapabilityId: launchSkillCapabilityId } : {}),\n },\n replace: true,\n });\n return;\n }\n if (\n busy ||\n !computeReady ||\n !newSessionPolicyValid ||\n !context.workspaceMcpCatalogReady ||\n attachments.hasUnresolved\n ) {\n return;\n }\n handledLaunchKeyRef.current = launchKey;\n void submitNewSession(launchRealtime, {\n model: launchModel,\n effort: launchEffort,\n latency: launchLatency,\n }).then((ok) => {\n if (!ok) handledLaunchKeyRef.current = null;\n });\n }, [\n attachments.hasUnresolved,\n busy,\n computeReady,\n context.workspaceMcpCatalogReady,\n launchEffort,\n launchFollowDefault,\n launchLatency,\n launchModel,\n launchRealtime,\n launchSkillCapabilityId,\n launchKey,\n launch.channelId,\n navigate,\n newSessionDraft.loading,\n newSessionPolicyValid,\n setLatencyMode,\n setModel,\n setReasoningEffort,\n submitNewSession,\n workspaceId,\n ]);\n\n // The session does not exist yet, so this surface cannot use `useComposer`\n // (that hook sends to a session). It still renders the package ChatComposer\n // by implementing the same `ComposerState` contract over session creation.\n const createComposer: ComposerState = {\n value: message,\n setValue: setMessage,\n hasDraftContent: () => message.length > 0 || attachments.attachments.length > 0,\n sending: busy,\n // Mirrors useComposer's gate: a ready attachment with no typed draft is a\n // sendable file-only message (the API requires non-empty text, so send()\n // substitutes FILE_ONLY_MESSAGE_TEXT).\n canSend:\n (createdSessionAuthority !== null ||\n message.trim().length > 0 ||\n attachments.readyResources.length > 0) &&\n !busy &&\n !newSessionDraft.loading &&\n newSessionPolicyValid &&\n !personalResourceCatalogRefreshPending &&\n (createdSessionAuthority !== null ||\n (!connectionAccounts.loading &&\n connectionAccounts.error === null &&\n !connectionAccounts.requiresAccountChoice)) &&\n (createdSessionAuthority !== null || fixedResourceSelection.selectionResolved) &&\n (createdSessionAuthority !== null || (!attachments.hasUnresolved && computeReady)),\n pause: async () => {},\n pausing: false,\n resume: async () => {},\n resumeScope: async () => {},\n resuming: false,\n draft: null,\n draftRevision: newSessionDraft.revision,\n draftLoading: newSessionDraft.loading,\n draftSaving: newSessionDraft.saving,\n // A stale autosaved draft must not block or distract from explicit Send.\n draftConflict: null,\n policy: {\n model: context.model,\n reasoningEffort: context.reasoningEffort,\n latencyMode: context.latencyMode,\n },\n setModel: (model) => {\n setModelProvided(true);\n context.setModel(model);\n },\n setReasoningEffort: (effort) => {\n setModelProvided(true);\n context.setReasoningEffort(effort);\n },\n setLatencyMode: (latencyMode) => {\n setModelProvided(true);\n context.setLatencyMode(latencyMode);\n },\n draftPersistence: \"disabled\",\n applyDraft: () => {},\n reloadDraft: newSessionDraft.reload,\n resolveDraftConflict: newSessionDraft.resolveConflict,\n restoredResources: [],\n removeRestoredResource: () => {},\n // A brief outage is explained once by the updating notice below the\n // composer, never as a red error with a request reference.\n error: newSessionDraft.unavailable || newSessionDraft.conflict ? null : newSessionDraft.error,\n clearError: newSessionDraft.clearError,\n send: async () => await submitNewSession(null),\n steer: async () => {\n const text =\n message.trim() || (attachments.readyResources.length > 0 ? FILE_ONLY_MESSAGE_TEXT(t) : \"\");\n if (!text || busy || attachments.hasUnresolved || !computeReady || !newSessionPolicyValid) {\n return false;\n }\n return await createComposer.send();\n },\n };\n useBrowserAccountBridgeBlocker(`new-session-composer:${workspaceId}`, () => {\n if (attachments.hasUnresolved) {\n return {\n id: \"ignored\",\n label: \"A file upload is not settled\",\n detail: \"Wait for the upload or remove it before changing accounts.\",\n };\n }\n if (busy || submitting || newSessionDraft.saving) {\n return {\n id: \"ignored\",\n label: \"A new-session mutation is still running\",\n detail: \"Wait for the current save or session creation to finish.\",\n };\n }\n return createComposer.hasDraftContent()\n ? {\n id: \"ignored\",\n label: \"The new-session composer has an unsent draft\",\n detail: \"Continuing clears the account-bound draft.\",\n }\n : null;\n });\n\n // A transient outage is covered by the updating notice instead.\n const accountsFailure = connectionAccounts.error !== null && !connectionAccounts.unavailable;\n\n return createElement(\n LightboxProvider,\n null,\n // The canvas parent is overflow-hidden, so this route owns its scrolling —\n // without it the page clips (recent sessions were unreachable below the fold).\n <div\n data-workspace-scroll-owner=\"self-managed\"\n data-window-top-page\n className=\"min-h-0 flex-1 overflow-y-auto\"\n >\n {githubAppConnect.element}\n <div className=\"mx-auto flex w-full max-w-3xl flex-col px-4 pt-10 pb-16 sm:px-6 sm:pt-16\">\n <section className=\"flex flex-col items-center gap-2 text-center\">\n <h1 className=\"text-balance text-2xl font-semibold tracking-tight sm:text-3xl\">\n What should the agent do?\n </h1>\n {context.clientConfig.billingMode === \"stripe\" &&\n workspace?.accountId &&\n hasAccountPermission(context.accessContext, workspace.accountId, \"billing:manage\") ? (\n <>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-2\"\n onClick={() => setCreditTopupOpen(true)}\n >\n <CreditCardIcon className=\"size-4\" />\n Add credits\n </Button>\n <Suspense fallback={null}>\n <CreditTopupPrompt\n purpose=\"topup\"\n open={creditTopupOpen}\n workspaceId={workspaceId}\n accountId={workspace.accountId}\n canBuyCredits\n onOpenChange={setCreditTopupOpen}\n />\n </Suspense>\n </>\n ) : null}\n </section>\n\n {launchSkillCapabilityId ? (\n <div className=\"mt-6\">\n <Notice tone=\"info\" title=\"Implementation guidance selected\">\n This installed Skill will be frozen onto this session only. Other workspace sessions\n will not receive it.\n </Notice>\n </div>\n ) : null}\n\n {modelUsesCredits(selectedPolicyRow?.catalog) &&\n hasAccountPermission(context.accessContext, workspace?.accountId ?? \"\", \"billing:read\") ? (\n <div className=\"mt-6\">\n <Suspense fallback={null}>\n <EmptyCreditsNotice\n creditFunding={selectedPolicyRow?.catalog.creditFunding}\n workspaceId={workspaceId}\n accountId={workspace?.accountId ?? null}\n canBuyCredits={hasAccountPermission(\n context.accessContext,\n workspace?.accountId ?? \"\",\n \"billing:manage\",\n )}\n canReadBilling\n />\n </Suspense>\n </div>\n ) : null}\n\n <div ref={composerRegionRef} className=\"mt-8 [&_textarea]:min-h-[calc(2lh+1rem)]\">\n <ConsoleComposer\n workspaceId={workspaceId}\n composer={createComposer}\n attachments={attachments}\n autoFocus\n disabled={newSessionDraft.loading || submitting}\n fileUploadsEnabled={context.clientConfig.fileUploads.enabled === true}\n placeholder=\"Describe a task for the agent…\"\n controlsLeading={\n <>\n <ComposerMobilePlus\n openRequest={capabilitiesOpenRequest}\n connectorActions={{\n accountControls: {\n groups: connectionAccounts.availableAccountGroups,\n choices: connectionAccounts.accountChoices,\n onChoose: connectionAccounts.selectAccount,\n loading: connectionAccounts.loading,\n error: connectionAccounts.error,\n accessDenied: connectionAccounts.accessDenied,\n onRefresh: () => void connectionAccounts.refresh(),\n disabled: busy || newSessionDraft.loading,\n },\n }}\n menuSide=\"bottom\"\n agentCapabilities={{\n ...composerAgentCapabilities,\n disabled: busy || newSessionDraft.loading,\n }}\n draftChatSettings={{\n workspaceId,\n scope:\n createVisibility === \"private\" || personalWorkspace\n ? \"personal\"\n : \"workspace\",\n value: draft.agentLearning ?? {},\n onChange: (agentLearning) =>\n setDraft((current) => ({ ...current, agentLearning })),\n }}\n workspaceId={workspaceId}\n disabled={busy || newSessionDraft.loading}\n fileUploadsEnabled={context.clientConfig.fileUploads.enabled === true}\n servers={context.toolMcpServers}\n firstPartyTools={firstPartyToolOptions}\n selection={{\n mcpServerIds: context.selectedCapabilityToolIds,\n firstPartyToolIds: draft.firstPartyMcpTools,\n }}\n toolsDisabled={busy || newSessionDraft.loading}\n connectorCustomizing={connectorCustomizing}\n onConnectorCustomizingChange={(next) => {\n if (next) setConnectorCustomizing(true);\n else followWorkspaceConnectors();\n }}\n onToolSelectionChange={(selection) => {\n changeConnectorSelection(selection);\n }}\n {...(hasRunsOnChoices(runsOnChoices)\n ? {\n runsOn: {\n summary: runsOnSummary(runsOnChoices),\n disabled: busy || newSessionDraft.loading,\n panel: (\n <RunsOnMenuBody\n {...runsOnChoices}\n disabled={busy || newSessionDraft.loading}\n onChange={setDraft}\n onComputeChange={setExplicitComputeDraft}\n onRetryMachines={() => void fleet.refresh()}\n />\n ),\n },\n }\n : {})}\n {...(hasVisibilityChoice({\n personalWorkspace,\n canCreatePrivate: tenancyCapabilities?.canCreatePrivate === true,\n })\n ? {\n visibility: {\n summary: visibilitySummary(draft.visibility),\n disabled: busy || newSessionDraft.loading,\n panel: (\n <VisibilityMenuBody\n value={draft.visibility}\n disabled={busy || newSessionDraft.loading}\n onChange={(visibility) => {\n visibilityChosenRef.current = true;\n setDraft((current) => ({\n ...current,\n visibility,\n }));\n }}\n />\n ),\n },\n }\n : {})}\n {...(usageLimitCapability === \"enabled\"\n ? {\n usageLimit: {\n summary: sessionUsageLimitDraftSummary(usageLimitDraft),\n disabled: busy || newSessionDraft.loading,\n panel: (\n <UsageLimitMenuBody\n value={usageLimitDraft}\n disabled={busy || newSessionDraft.loading}\n showRequiredError={usageLimitSendBlocked}\n onChange={setUsageLimitDraft}\n />\n ),\n },\n }\n : {})}\n {...(draft.compute.kind === \"sandbox\"\n ? {\n repositories: {\n selectedCount:\n context.selectedRepoIds.size +\n context.selectedPersonalGitHubRepoIds.size +\n context.manualRepos.filter((repo) => repo.url.trim().length > 0).length,\n disabled: busy || newSessionDraft.loading,\n panel: (\n <WorkspaceRepositoryMenuBody\n workspaceId={workspaceId}\n disabled={busy || newSessionDraft.loading}\n catalogRefresh={repositoryCatalogRefresh}\n onConnectWorkspaceApp={githubAppConnect.open}\n />\n ),\n },\n }\n : {})}\n {...(draftSecretsOn && canListSecrets\n ? {\n secrets: {\n summary: sessionSecretsSummary(draftVaultPolicy, draftVaultRows),\n disabled: busy || newSessionDraft.loading,\n panel: (\n <SessionSecretsMenuBody\n vaults={draftVaultRows}\n policy={draftVaultPolicy}\n narrowedByParent={false}\n canEdit\n disabled={busy || newSessionDraft.loading}\n loading={draftVaults.loading}\n error={draftVaults.error}\n onRetry={() => void draftVaults.refresh()}\n onPolicyChange={(policy) =>\n setDraft((current) => {\n const { vaultPolicy: _previous, ...rest } = current;\n return policy.mode === \"all\"\n ? rest\n : { ...rest, vaultPolicy: policy };\n })\n }\n onManage={() =>\n void navigate({\n to: \"/workspaces/$workspaceId/secrets\",\n params: { workspaceId },\n })\n }\n />\n ),\n },\n }\n : {})}\n />\n {composerAgentCapabilities.customized ? (\n <ComposerCapabilitiesChip\n summary={capabilitySummary(\n composerAgentCapabilities.draft.values,\n composerAgentCapabilities.availability,\n )}\n disabled={busy || newSessionDraft.loading}\n onOpen={() =>\n setCapabilitiesOpenRequest((current) => ({\n panel: \"capabilities\",\n nonce: (current?.nonce ?? 0) + 1,\n }))\n }\n />\n ) : null}\n </>\n }\n controls={\n <div className=\"@container/model-controls flex min-w-0 flex-1 items-center gap-1.5\">\n <SessionModelControl\n hasImageAttachments={attachments.attachments.some(\n (file) => file.status !== \"failed\" && file.contentType.startsWith(\"image/\"),\n )}\n modelCatalog={modelCatalog}\n policyError={newSessionPolicyError}\n disabled={busy || newSessionDraft.loading}\n workspaceId={workspaceId}\n onPolicyChosen={() => setModelProvided(true)}\n />\n </div>\n }\n actions={\n <>\n <NewSessionRealtimeControl\n client={context.client}\n workspaceId={workspaceId}\n codexConnected={codexConnected}\n models={voiceSelection.models}\n selectedModel={voiceSelection.selectedModel}\n onSelectModel={voiceSelection.selectModel}\n modelMenu=\"split\"\n disabled={\n busy ||\n newSessionDraft.loading ||\n attachments.hasUnresolved ||\n !newSessionPolicyValid ||\n !computeReady ||\n personalMachineSelected ||\n !context.workspaceMcpCatalogReady\n }\n disabledReason={\n attachments.hasUnresolved\n ? \"Wait for attachments to finish before starting voice.\"\n : !newSessionPolicyValid\n ? \"Choose supported model settings before starting voice.\"\n : !computeReady\n ? \"Choose where this session should run first.\"\n : personalMachineSelected\n ? \"Start with a message so personal machine access can attach to an accepted turn.\"\n : !context.workspaceMcpCatalogReady\n ? \"Wait for session tools to finish loading.\"\n : null\n }\n onStart={async (model) => await submitNewSession(model)}\n />\n </>\n }\n header={\n <SessionSetupStrip\n disabled={busy || newSessionDraft.loading}\n channels={channelsQuery.channels}\n selectedChannelId={selectedChannelId}\n onChannelChange={selectProject}\n onCreateProject={() => setProjectDialogOpen(true)}\n />\n }\n />\n\n {personalWorkspace ? <PrivateWorkspaceNote /> : null}\n {newSessionDraft.conflict ? <NewSessionDraftSyncNotice /> : null}\n\n {/* A deploy or restart makes Opengeni unreachable for a few seconds.\n Reads retry quietly first; if it lasts longer, this one calm line\n replaces every error, the message stays in the composer, and the\n hooks reconnect on their own so Send works again. */}\n {newSessionDraft.unavailable || connectionAccounts.unavailable ? (\n <div role=\"status\" className=\"mt-3\">\n <Notice tone=\"info\">{OPENGENI_UPDATING_NOTICE(t)}</Notice>\n </div>\n ) : null}\n\n {/* Accounts load quietly with the composer: only a problem shows here,\n never a loading line behind an open menu. */}\n {accountsFailure || connectionAccounts.accountChoiceMessage ? (\n <div role=\"alert\" className=\"mt-3\">\n <Notice\n tone=\"waiting\"\n action={\n accountsFailure && !connectionAccounts.accessDenied ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => void connectionAccounts.refresh()}\n >\n Retry\n </Button>\n ) : undefined\n }\n >\n {accountsFailure\n ? connectionAccounts.accessDenied\n ? connectionAccounts.error\n : \"Couldn't send your message. Try again.\"\n : connectionAccounts.accountChoiceMessage}\n </Notice>\n </div>\n ) : null}\n\n <ComputeTargetControl\n workspaceId={workspaceId}\n defaultSandboxBackend={defaultSandboxBackend}\n draft={draft}\n onChange={setDraft}\n onComputeChange={setExplicitComputeDraft}\n disabled={busy || newSessionDraft.loading}\n personalResourceAccess={{\n names: selectedPersonalResourceNames,\n visibility: createVisibility,\n }}\n fleet={fleet}\n machines={machines}\n rigs={selectableRigs}\n workspaceDefaultRigId={workspace?.defaultRigId ?? null}\n catalogRecovery={{\n error: fixedResourceCatalogError,\n refreshing: personalResourceCatalogRefreshPending,\n onRetry: () => void refreshPersonalResourceCatalogs(),\n }}\n selectedChannelId={selectedChannelId}\n selectionHistory={selectionHistory}\n />\n </div>\n\n <RecentSessions workspaceId={workspaceId} />\n <NewSessionStarters\n workspaceId={workspaceId}\n set={signupStarterSet(context.authSession?.user.email, workspace?.accountId)}\n disabled={busy || newSessionDraft.loading}\n onSelect={(prompt) => {\n setMessage(prompt);\n composerRegionRef.current?.querySelector(\"textarea\")?.focus({ preventScroll: true });\n }}\n />\n </div>\n <ChannelCreateDialog\n open={projectDialogOpen}\n name={projectNameDraft}\n busy={channelsQuery.mutating}\n onNameChange={setProjectNameDraft}\n onOpenChange={(open) => {\n setProjectDialogOpen(open);\n if (!open) setProjectNameDraft(\"\");\n }}\n onSubmit={() => void createProject()}\n />\n </div>,\n );\n}\n\n/** Send kept losing to a newer draft saved elsewhere (another tab or window). */\nconst DRAFT_CHANGED_DURING_SEND_TEXT =\n \"Your message is saved, but this draft kept changing in another tab or window. Check it and send again.\";\n\n/** A draft that didn't save: the message is kept, then what to do. */\nfunction draftSaveFailureText(draft: { conflict: Error | null; error: Error | null }): string {\n if (draft.conflict || !draft.error) return \"Your message is still here. Try again.\";\n return `Your message is still here. ${userErrorText(draft.error)}`;\n}\n\n/** A failed pre-send draft save: a brief outage shows the updating notice instead of a toast. */\nfunction reportDraftSaveFailure(draft: {\n conflict: Error | null;\n currentError: () => Error | null;\n}): void {\n const error = draft.currentError();\n if (isTransientServiceFailure(error)) return;\n toast.error(\"Couldn't save the draft\", {\n description: draftSaveFailureText({ conflict: draft.conflict, error }),\n });\n}\n\n// ── Recent sessions — the quiet main-canvas browser the rail can't be (D4.2) ──\n// A calm section below the composer: the most recent sessions as compact rows\n// (status, title, provider mark + catalog model label, relative time). Reuses\n// the rail's session list + the workspace model catalog so labels/marks match\n// the model picker — never raw wire ids as the primary display.\nfunction RecentSessions({ workspaceId }: { workspaceId: string }) {\n const { workspaceSessionListEvent } = useOpenGeni();\n const hintsAvailable =\n workspaceSessionListEvent?.workspaceId === workspaceId && workspaceSessionListEvent.available;\n const { sessions, pinned, refresh, error } = useWorkspaceSessions({\n limit: 12,\n // Top-level conversations: sub-agents open from their parent and would\n // otherwise fill this short page in a workspace that runs many of them.\n parentSessionId: null,\n pollIntervalMs: hintsAvailable ? undefined : 30_000,\n });\n useSessionListHintRefresh(refresh, error);\n const modelCatalog = useWorkspaceModelCatalog(workspaceId);\n // Pins are server-authoritative and sit above running and recency rows.\n const recent = useMemo(() => recentSessionsForHome(t, sessions, pinned, 6), [pinned, sessions]);\n\n if (recent.length === 0) {\n return null;\n }\n\n return (\n <section className=\"mt-12\">\n <h2 className=\"mb-1.5 px-0.5 text-2xs font-semibold uppercase tracking-wider text-fg\">\n Recent sessions\n </h2>\n {/* flex-col, not grid: a grid auto track grows to a nowrap row's full\n min-content width, defeating truncate and overflowing the page. */}\n <ul className=\"flex min-w-0 flex-col divide-y divide-border/60\">\n {recent.map((session) => (\n <RecentSessionRow\n key={session.id}\n workspaceId={workspaceId}\n session={session}\n catalogRows={modelCatalog.rows}\n />\n ))}\n </ul>\n </section>\n );\n}\n\nfunction RecentSessionRow({\n workspaceId,\n session,\n catalogRows,\n}: {\n workspaceId: string;\n session: Session;\n catalogRows: readonly PickerModelRow[];\n}) {\n const title = sessionDisplayTitle(session);\n const model = recentSessionModelPresentation(session.model, catalogRows);\n const repo = sessionRepoLabel(session);\n const metaBits = [model.label, repo].filter(Boolean);\n const status = recentSessionStatus(session);\n return (\n <li className=\"min-w-0\">\n <Link\n to=\"/workspaces/$workspaceId/sessions/$sessionId\"\n params={{ workspaceId, sessionId: session.id }}\n className=\"group flex items-center gap-3 rounded-md px-1 py-2.5 transition-colors hover:bg-hover\"\n >\n <StatusDot tone={status.tone} pulse={status.pulse} />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm text-fg group-hover:text-fg\">{title}</span>\n {metaBits.length > 0 ? (\n <span className=\"mt-0.5 flex min-w-0 items-center gap-1.5 text-2xs text-fg-subtle\">\n <ModelMark\n model={{ id: session.model, logoUrl: model.logoUrl }}\n className=\"size-3 text-fg-muted\"\n fallback={\n <BillingClassMark\n billingClass={model.billingClass}\n className=\"size-3\"\n aria-label=\"\"\n />\n }\n />\n <span className=\"truncate\">{metaBits.join(\" · \")}</span>\n </span>\n ) : null}\n </span>\n <span className=\"shrink-0 text-2xs tabular-nums text-fg-subtle\">\n {relativeTimeLabel(t, session.updatedAt)}\n </span>\n </Link>\n </li>\n );\n}\n\n// Setup selections sit above the prompt so the footer remains an action row.\n// Repo stays out of the compute band so that band only shows when rigs /\n// machines exist. Tools and repos live under “+” at every width.\nfunction SessionSetupStrip({\n disabled,\n channels,\n selectedChannelId,\n onChannelChange,\n onCreateProject,\n}: {\n disabled: boolean;\n channels: Channel[];\n selectedChannelId: string | null;\n onChannelChange: (channelId: string | null) => void;\n onCreateProject: () => void;\n}) {\n return (\n <div className=\"flex min-w-0 items-center gap-1.5 border-b border-border/70 px-3 py-2 sm:px-4\">\n <SessionFolderPicker\n channels={channels}\n selectedChannelId={selectedChannelId}\n disabled={disabled}\n onChange={onChannelChange}\n onCreateProject={onCreateProject}\n />\n </div>\n );\n}\n\n/** Keep model policy adjacent to voice/send in the bottom action row. */\nfunction SessionModelControl({\n hasImageAttachments,\n modelCatalog,\n policyError,\n disabled,\n workspaceId,\n onPolicyChosen,\n}: {\n hasImageAttachments: boolean;\n modelCatalog: WorkspaceModelCatalogState;\n policyError: string | null;\n disabled: boolean;\n workspaceId: string;\n /** The person picked a model, reasoning level, or speed. */\n onPolicyChosen: () => void;\n}) {\n const context = useAppContext();\n return (\n <ModelPicker\n hasImageAttachments={hasImageAttachments}\n onOpenChange={(open) => {\n if (open) void modelCatalog.refresh();\n }}\n rows={modelCatalog.rows}\n model={context.model}\n effort={context.reasoningEffort}\n latencyMode={context.latencyMode}\n disabled={disabled}\n loading={modelCatalog.loading}\n error={modelCatalog.error ?? policyError}\n menuSide=\"bottom\"\n connectModelsHref={`/workspaces/${encodeURIComponent(workspaceId)}/settings?section=models`}\n onModelChange={(model) => {\n onPolicyChosen();\n context.setModel(model);\n }}\n onEffortChange={(effort) => {\n onPolicyChosen();\n context.setReasoningEffort(effort);\n }}\n onLatencyModeChange={(latencyMode) => {\n onPolicyChosen();\n context.setLatencyMode(latencyMode);\n }}\n />\n );\n}\n\nfunction SessionFolderPicker({\n channels,\n selectedChannelId,\n disabled,\n onChange,\n onCreateProject,\n}: {\n channels: Channel[];\n selectedChannelId: string | null;\n disabled: boolean;\n onChange: (channelId: string | null) => void;\n onCreateProject: () => void;\n}) {\n const selected = channels.find((channel) => channel.id === selectedChannelId) ?? null;\n const label = selected?.name ?? \"Default\";\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={disabled}\n aria-label={`Project: ${label}`}\n title={label}\n className=\"h-8 min-w-0 max-w-[12rem] shrink gap-1.5 overflow-hidden rounded-full border border-transparent px-2.5 text-xs text-fg-muted hover:border-border hover:bg-surface-2 hover:text-fg sm:shrink-0\"\n >\n <FolderIcon className=\"size-3.5 shrink-0\" />\n <span className=\"min-w-0 truncate\">{label}</span>\n <ChevronDownIcon className=\"size-3 shrink-0\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" side=\"bottom\" sideOffset={8} className=\"w-60\">\n <DropdownMenuLabel>Save new session in</DropdownMenuLabel>\n <DropdownMenuItem onSelect={() => onChange(null)}>\n <FolderIcon />\n <span className=\"min-w-0 flex-1 truncate\">Default</span>\n <DropdownMenuCheck checked={selectedChannelId === null} />\n </DropdownMenuItem>\n {channels.map((channel) => (\n <DropdownMenuItem key={channel.id} onSelect={() => onChange(channel.id)}>\n <FolderIcon />\n <span className=\"min-w-0 flex-1 truncate\">{channel.name}</span>\n <DropdownMenuCheck checked={channel.id === selectedChannelId} />\n </DropdownMenuItem>\n ))}\n <DropdownMenuItem onSelect={onCreateProject}>\n <PlusIcon />\n New project\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\nfunction workspaceRepositoryPickerProps(\n context: ReturnType<typeof useAppContext>,\n workspaceId: string,\n disabled: boolean,\n onConnectWorkspaceApp: () => void,\n page: PageHost,\n): RepositoryContextPickerProps {\n return {\n setupMode:\n context.githubStatus?.setupMode ??\n (context.clientConfig.productAccessMode === \"managed\" ? \"platform\" : \"operator\"),\n configured: context.githubStatus?.configured === true,\n status: context.githubStatus?.status ?? (\"disabled\" as const),\n installUrl: context.githubStatus?.installUrl ?? null,\n linkUrl: context.githubStatus?.linkUrl ?? null,\n installations: context.githubStatus?.installations ?? [],\n repositories: context.githubRepos,\n personalGitHubStatus: context.personalGitHubStatus,\n personalGitHubRepositories: context.personalGitHubRepositories,\n selectedPersonalGitHubRepoIds: context.selectedPersonalGitHubRepoIds,\n selectedPersonalGitHubRepoRefs: context.selectedPersonalGitHubRepoRefs,\n personalGitHubBusy: context.personalGitHubBusy,\n groups: context.repositoryGroups,\n selectedRepoIds: context.selectedRepoIds,\n selectedRepoRefs: context.selectedRepoRefs,\n selectedInstallationId: context.selectedInstallationId,\n manualRepos: context.manualRepos,\n manualOpen: context.manualReposOpen,\n githubAppOpen: context.githubAppOpen,\n org: context.githubOrg,\n pending: context.busy || disabled,\n repoBusy: context.repoBusy,\n githubAppBusy: context.githubAppBusy,\n onRefresh: async () => {\n await Promise.all([\n context.refreshGitHub(workspaceId, undefined, { sync: true }),\n context.refreshPersonalGitHub(workspaceId),\n ]);\n },\n onConnectPersonalGitHub: () => void context.connectPersonalGitHub(workspaceId),\n onTogglePersonalGitHubRepo: (repository) =>\n void context.togglePersonalGitHubRepository(workspaceId, repository),\n onPersonalGitHubRefChange: (repositoryId: string, ref: string) =>\n context.setSelectedPersonalGitHubRepoRefs((current) => ({\n ...current,\n [repositoryId]: ref,\n })),\n onToggleRepo: context.toggleGitHubRepository,\n onRefChange: (repoId: number, ref: string) =>\n context.setSelectedRepoRefs((current) => ({ ...current, [repoId]: ref })),\n onLoadGitHubBranches: async (repository) => {\n const acceptedTransition = context.captureWorkspaceInvocation(workspaceId);\n if (!acceptedTransition) throw new Error(\"The workspace changed; refresh and try again.\");\n const { listGitHubRepositoryBranches } = await import(\"@opengeni/sdk/github-repositories\");\n const response = await listGitHubRepositoryBranches(\n context.client,\n workspaceId,\n repository.installationId,\n repository.id,\n { limit: 100 },\n );\n if (!context.ownsWorkspaceInvocation(workspaceId, acceptedTransition)) {\n throw new Error(\"The workspace changed; refresh and try again.\");\n }\n return response.branches;\n },\n onLoadPersonalGitHubBranches: async (repository) => {\n const acceptedTransition = context.captureWorkspaceInvocation(workspaceId);\n if (!acceptedTransition) throw new Error(\"The workspace changed; refresh and try again.\");\n const connectionId = context.personalGitHubStatus?.connection?.id;\n if (!connectionId) throw new Error(\"Connect your GitHub identity to load branches.\");\n const { listPersonalGitHubRepositoryBranches } =\n await import(\"@opengeni/sdk/github-repositories\");\n const response = await listPersonalGitHubRepositoryBranches(\n context.client,\n workspaceId,\n connectionId,\n repository.repositoryId,\n { limit: 100 },\n );\n if (!context.ownsWorkspaceInvocation(workspaceId, acceptedTransition)) {\n throw new Error(\"The workspace changed; refresh and try again.\");\n }\n return response.branches;\n },\n onManualOpenChange: context.setManualReposOpen,\n onManualAdd: context.addManualRepository,\n onManualUpdate: (id: number, patch: Partial<RepoDraft>) =>\n context.setManualRepos((current) =>\n current.map((repo) => (repo.id === id ? { ...repo, ...patch } : repo)),\n ),\n onManualRemove: (id: number) =>\n context.setManualRepos((current) => current.filter((repo) => repo.id !== id)),\n onManualAttach: async (repository) => {\n const acceptedTransition = context.captureWorkspaceInvocation(workspaceId);\n if (!acceptedTransition) throw new Error(\"The workspace changed; try again.\");\n const assertCurrent = () => {\n if (!context.ownsWorkspaceInvocation(workspaceId, acceptedTransition)) {\n throw new Error(\"The workspace changed; try again.\");\n }\n };\n assertCurrent();\n return await attachManualRepository({\n repository,\n workspaceRepositories: context.githubRepos,\n personalRepositories: context.personalGitHubRepositories,\n selectWorkspaceRepository: (matched, ref) => {\n assertCurrent();\n context.setSelectedRepoIds((current) => {\n const next =\n context.selectedInstallationId !== null &&\n context.selectedInstallationId !== matched.installationId\n ? new Set<number>()\n : new Set(current);\n next.add(matched.id);\n return next;\n });\n context.setSelectedRepoRefs((current) => ({\n ...current,\n [matched.id]: ref,\n }));\n context.setSelectedPersonalGitHubRepoIds(\n (current) =>\n new Set(\n [...current].filter(\n (id) =>\n context.personalGitHubRepositories\n .find((candidate) => candidate.repositoryId === id)\n ?.fullName.toLowerCase() !== matched.fullName.toLowerCase(),\n ),\n ),\n );\n },\n selectPersonalRepository: async (matched, ref) => {\n if (!(await context.ensurePersonalGitHubAuthority(workspaceId))) {\n throw new Error(\"Your GitHub identity could not be authorized for this workspace.\");\n }\n assertCurrent();\n context.setSelectedRepoIds(\n (current) =>\n new Set(\n [...current].filter(\n (id) =>\n context.githubRepos\n .find((candidate) => candidate.id === id)\n ?.fullName.toLowerCase() !== matched.fullName.toLowerCase(),\n ),\n ),\n );\n context.setSelectedPersonalGitHubRepoIds((current) =>\n new Set(current).add(matched.repositoryId),\n );\n context.setSelectedPersonalGitHubRepoRefs((current) => ({\n ...current,\n [matched.repositoryId]: ref,\n }));\n },\n verifyPublicGitHubRepository: async (request) => {\n const { verifyPublicGitHubRepositoryRef } =\n await import(\"@opengeni/sdk/github-repositories\");\n const verified = await verifyPublicGitHubRepositoryRef(\n context.client,\n workspaceId,\n request,\n );\n assertCurrent();\n return verified;\n },\n attach: (attached) => {\n assertCurrent();\n context.setManualRepos((current) =>\n current.map((candidate) => (candidate.id === attached.id ? attached : candidate)),\n );\n },\n remove: (id) => {\n assertCurrent();\n context.setManualRepos((current) => current.filter((candidate) => candidate.id !== id));\n },\n });\n },\n validationError: context.repositoryValidationError,\n onGitHubAppOpenChange: context.setGithubAppOpen,\n onOrgChange: context.setGithubOrg,\n onStartGitHubApp: () => void context.startGitHubAppManifestFlow(workspaceId),\n onConnectWorkspaceApp,\n onConfigureInstallation: (installationId: number) =>\n openGitHubInstallationSettings(context.client, workspaceId, installationId, page.assign),\n onDisconnectInstallation: async (installationId: number) => {\n await context.disconnectGitHubInstallation(workspaceId, installationId);\n },\n };\n}\n\nfunction WorkspaceRepositoryMenuBody({\n workspaceId,\n disabled,\n leading,\n catalogRefresh,\n onConnectWorkspaceApp,\n}: {\n workspaceId: string;\n disabled: boolean;\n leading?: ReactNode | undefined;\n catalogRefresh: ReturnType<typeof useRepositoryCatalogRefresh>;\n onConnectWorkspaceApp: () => void;\n}) {\n const page = usePage();\n const context = useAppContext();\n return (\n <RepositoryContextMenuBody\n {...workspaceRepositoryPickerProps(\n context,\n workspaceId,\n disabled,\n onConnectWorkspaceApp,\n page,\n )}\n {...catalogRefresh}\n {...(leading ? { leading } : {})}\n />\n );\n}\n\n// ── The promoted top-level compute target (the parent that gates the band) ────\n\ntype NewSessionPersonalResourceAccess = {\n names: string[];\n visibility: \"private\" | \"workspace\";\n};\n\ntype FixedResourceCatalogRecovery = {\n error: boolean;\n refreshing: boolean;\n onRetry: () => void;\n};\n\nfunction ComputeTargetControl(props: {\n workspaceId: string;\n defaultSandboxBackend?: SandboxBackend | undefined;\n draft: SessionDraft;\n onChange: (draft: SessionDraft) => void;\n onComputeChange: (draft: SessionDraft) => void;\n disabled: boolean;\n personalResourceAccess: NewSessionPersonalResourceAccess;\n fleet: ReturnType<typeof useWorkspaceMachines>;\n machines: MachineView[];\n rigs: Rig[];\n workspaceDefaultRigId: string | null;\n catalogRecovery: FixedResourceCatalogRecovery;\n selectedChannelId: string | null;\n selectionHistory: NewSessionSelectionHistory;\n}) {\n const { draft, onChange } = props;\n const { fleet, machines } = props;\n const selfhostedPrimary = props.defaultSandboxBackend === \"selfhosted\";\n // Managed-primary deployments keep Connected Machine opt-in and hide the\n // chooser when the fleet is empty. Selfhosted-primary deployments always show\n // the required machine path, including its honest unavailable state.\n const machineAvailabilityKey = machines\n .map((machine) => `${machine.sandboxId}:${machine.state}`)\n .join(\"\\u0000\");\n\n const selectedMachineSandboxId =\n draft.compute.kind === \"machine\" ? draft.compute.sandboxId : null;\n\n // A named machine stays selected when it disconnects or is removed. The\n // unavailable notice and submission gate require an explicit replacement.\n useEffect(() => {\n if (\n selfhostedPrimary &&\n draft.compute.kind === \"machine\" &&\n selectedMachineSandboxId === null &&\n !fleet.loading\n ) {\n const firstSelectableId = resolveSelectableMachineSandboxId(machines, null);\n if (firstSelectableId)\n onChange({\n ...draft,\n compute: {\n kind: \"machine\",\n sandboxId: firstSelectableId,\n folder: rememberedMachineFolder(\n props.selectionHistory,\n props.selectedChannelId,\n firstSelectableId,\n ),\n },\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selfhostedPrimary, fleet.loading, machineAvailabilityKey, selectedMachineSandboxId]);\n\n // A 404 means Connected Machines are off here, not a failure.\n const fleetLoadFailed =\n fleet.error != null && !(fleet.error instanceof OpenGeniApiError && fleet.error.status === 404);\n const attention = runsOnAttention({\n draft,\n machines,\n fleetLoadFailed,\n fleetLoading: fleet.loading,\n });\n\n // Where it runs is chosen under \"+\" > Runs on. Only what needs attention\n // shows under the composer: why Send waits on where it runs (with a retry\n // for a failed machine load), a catalog that couldn't be verified, and the\n // personal resources this chat will use.\n return (\n <>\n {attention ? (\n <div className=\"mt-3\">\n <RunsOnNotice\n attention={attention}\n machines={machines}\n disabled={props.disabled}\n onRetryMachines={() => void fleet.refresh()}\n connectAction={\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link\n to=\"/workspaces/$workspaceId/machines\"\n params={{ workspaceId: props.workspaceId }}\n >\n Connect a machine\n </Link>\n </Button>\n }\n />\n </div>\n ) : null}\n {props.catalogRecovery.error ? (\n <div role=\"alert\" className=\"mt-3\">\n <Notice\n tone=\"failed\"\n title=\"Couldn’t verify the selected Sandbox Environment\"\n action={\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={props.disabled || props.catalogRecovery.refreshing}\n onClick={props.catalogRecovery.onRetry}\n >\n Try again\n </Button>\n }\n >\n Try again to reload your available resources before starting this session.\n </Notice>\n </div>\n ) : null}\n <div className=\"mt-3\">\n <PersonalResourceAccessInline access={props.personalResourceAccess} />\n </div>\n </>\n );\n}\n\nfunction PersonalResourceAccessInline(props: {\n access: NewSessionPersonalResourceAccess;\n embedded?: boolean | undefined;\n}) {\n if (props.access.names.length === 0) return null;\n const content = (\n <p className=\"text-2xs text-fg-subtle\">\n {props.access.names.join(\", \")} will be available for your work in this session.\n {props.access.visibility === \"workspace\"\n ? \" Results are visible to people who can access this chat.\"\n : null}\n </p>\n );\n return props.embedded ? (\n <div className=\"border-t border-border/70 px-3 py-2.5\">{content}</div>\n ) : (\n <div className=\"px-0.5\">{content}</div>\n );\n}\n\n/** One quiet line on the new-chat page of a Personal workspace: its chats are private. */\nfunction PrivateWorkspaceNote() {\n return (\n <p className=\"mt-3 flex items-center gap-1.5 px-0.5 text-xs text-fg-muted\">\n <LockIcon aria-hidden=\"true\" className=\"size-3.5 shrink-0\" />\n Private: only you can see chats here.\n </p>\n );\n}\n"],"mappings":"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","names":[]}
|