@opengeni/react 4.6.1 → 4.6.2-canary.39853438886001
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 +13 -13
- package/dist/app/components/Composer.js +14 -14
- package/dist/app/components/artifacts/artifact-library.js +5 -5
- package/dist/app/components/artifacts/chat-interactive-block.js +10 -10
- package/dist/app/components/artifacts/inline-chat-image.js +14 -14
- package/dist/app/components/artifacts/retained-file-preview.js +16 -16
- package/dist/app/components/artifacts/retained-text-preview.js +2 -2
- package/dist/app/components/artifacts/site-conversations.js +5 -4
- package/dist/app/components/artifacts/site-data.js +2 -2
- package/dist/app/components/artifacts/site-publishing.js +11 -11
- package/dist/app/components/artifacts/site-settings.js +15 -15
- package/dist/app/components/billing-class-mark.js +3 -3
- package/dist/app/components/capabilities/capability-detail-sheet.js +2 -2
- package/dist/app/components/capabilities/capability-logo-source.js +7 -7
- package/dist/app/components/capabilities/native-connect-readiness.js +1 -0
- package/dist/app/components/capabilities/native-connect-readiness.js.map +1 -1
- package/dist/app/components/capabilities/native-connect-setup.js +6 -6
- package/dist/app/components/capabilities/perform-capability-action.js +2 -1
- package/dist/app/components/capabilities/prepared-mcp-setup-card.js +8 -8
- package/dist/app/components/capabilities/session-capability-card.js +32 -31
- package/dist/app/components/capabilities/session-capability-card.js.map +1 -1
- package/dist/app/components/capabilities/session-chrome-card.js +14 -14
- package/dist/app/components/capabilities/session-custom-mcp-card.js +9 -9
- package/dist/app/components/capabilities/session-github-card.js +9 -9
- package/dist/app/components/capabilities/session-machine-card.js +14 -14
- package/dist/app/components/command-menu/chat-status.js +6 -5
- package/dist/app/components/command-menu/chat-switcher.d.ts +2 -0
- package/dist/app/components/command-menu/chat-switcher.js +26 -9
- package/dist/app/components/command-menu/chat-switcher.js.map +1 -1
- package/dist/app/components/command-menu/command-menu.js +16 -15
- package/dist/app/components/command-menu/command-menu.js.map +1 -1
- package/dist/app/components/command-menu/shortcut-sheet.js +8 -8
- package/dist/app/components/composer-mobile-plus-panel.js +5 -5
- package/dist/app/components/composer-mobile-plus.js +1 -1
- package/dist/app/components/credit-required-gate.js +1 -1
- package/dist/app/components/credit-required-prompt.js +4 -4
- package/dist/app/components/desktop/app-shots.js +5 -5
- package/dist/app/components/desktop/this-computer.js +4 -4
- package/dist/app/components/feedback.js +3 -3
- package/dist/app/components/github-app-connect-launcher.js +1 -1
- package/dist/app/components/machines/connect-machine-dialog.js +3 -3
- package/dist/app/components/markdown.js +4 -4
- package/dist/app/components/models/models-ui.js +2 -2
- package/dist/app/components/pickers.js +5 -5
- package/dist/app/components/rail/rail-context.js +3 -3
- package/dist/app/components/rail/rail-sections.js +28 -27
- package/dist/app/components/rail/session-header.d.ts +6 -5
- package/dist/app/components/rail/session-header.js +20 -19
- package/dist/app/components/rail/session-list.js +27 -26
- package/dist/app/components/rail/session-row-hover-details.js +7 -6
- package/dist/app/components/rail/session-shell.js +51 -53
- package/dist/app/components/rail/site-session-group-heading.js +2 -1
- package/dist/app/components/session/agent-configuration-panel.js +6 -6
- package/dist/app/components/session/banners.js +6 -6
- package/dist/app/components/session/conversation-find.js +3 -3
- package/dist/app/components/session/editable-artifacts-workspace.js +17 -17
- package/dist/app/components/session/failed-session-banner.js +5 -5
- package/dist/app/components/session/human-input.js +26 -26
- package/dist/app/components/session/inspector.js +37 -37
- package/dist/app/components/session/message-actions.js +3 -3
- package/dist/app/components/session/message-resource-attachments.js +5 -5
- package/dist/app/components/session/model-recovery-notice.js +3 -3
- package/dist/app/components/session/new-session-settings-menu.js +4 -4
- package/dist/app/components/session/sandbox-switcher.js +8 -8
- package/dist/app/components/session/sandbox-workspace.js +36 -36
- package/dist/app/components/session/search-markdown-highlight.js +5 -5
- package/dist/app/components/session/search-results-view.js +6 -6
- package/dist/app/components/session/session-admission-notice.js +4 -4
- package/dist/app/components/session/session-machine-access-notice.js +4 -4
- package/dist/app/components/session/session-search-dialog.js +6 -6
- package/dist/app/components/session/session-tenancy-control.js +4 -4
- package/dist/app/components/session/session-usage-limit-section.js +3 -3
- package/dist/app/components/session/session-wait-status.js +2 -1
- package/dist/app/components/session/session-wait-status.js.map +1 -1
- package/dist/app/components/session/subagents.js +6 -5
- package/dist/app/components/session/subscription-account-indicator.d.ts +35 -0
- package/dist/app/components/session/{codex-account-indicator.js → subscription-account-indicator.js} +23 -10
- package/dist/app/components/session/subscription-account-menu.d.ts +11 -12
- package/dist/app/components/session/subscription-account-menu.js +1 -1
- package/dist/app/components/session/subscription-account.d.ts +105 -0
- package/dist/app/components/usage/usage-entry.js +3 -3
- package/dist/app/components/workspace-composer-plus.js +10 -10
- package/dist/app/embed/session-app.js +154 -156
- package/dist/app/lib/actions/actions-provider.js +8 -8
- package/dist/app/lib/actions/chat-switcher.d.ts +19 -7
- package/dist/app/lib/codex-usage-query.js +2 -2
- package/dist/app/lib/composer-connectors.js +8 -8
- package/dist/app/lib/console-text.js +2 -2
- package/dist/app/lib/drive-connect-return.d.ts +26 -0
- package/dist/app/lib/drive-connect-return.js +16 -0
- package/dist/app/lib/events.js +7 -7
- package/dist/app/lib/failed-session-copy.js +3 -3
- package/dist/app/lib/model-access-onboarding.js +3 -3
- package/dist/app/lib/move-chat-to-machine.js +3 -3
- package/dist/app/lib/session-branch-cache.js +6 -5
- package/dist/app/lib/session-group-pagination.js +6 -5
- package/dist/app/lib/session-hover-facts.js +6 -5
- package/dist/app/lib/session-rail.js +2 -1
- package/dist/app/lib/sessions-group.js +5 -4
- package/dist/app/lib/turn-failure-analytics.js +5 -5
- package/dist/app/lib/use-workspace-machines.js +4 -4
- package/dist/app/lib/use-workspace-model-catalog.js +3 -3
- package/dist/app/lib/use-workspace-rigs.js +2 -2
- package/dist/app/lib/workspace-navigation-preference.js +4 -4
- package/dist/app/lib/workspace-scope-context.js +3 -3
- package/dist/app/routes/artifacts.js +50 -49
- package/dist/app/routes/artifacts.js.map +1 -1
- package/dist/app/routes/retained-artifact.js +23 -23
- package/dist/app/routes/session.js +92 -91
- package/dist/app/routes/sessions-index.js +52 -52
- package/dist/app/routes/site-view.js +35 -34
- package/dist/app/routes/site-view.js.map +1 -1
- 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 +10 -10
- package/dist/{browser-viewer-YQC6BFMS.js → browser-viewer-VKIAULG7.js} +4 -4
- package/dist/{chat-interactive-block-Z22YHDRU.js → chat-interactive-block-JGYSW4KB.js} +5 -5
- package/dist/{chunk-WN2MIB4Q.js → chunk-22V2QCEM.js} +2 -2
- package/dist/{chunk-SJPAKWWP.js → chunk-2BISI664.js} +2 -2
- package/dist/{chunk-O5UOCMH4.js → chunk-2LPJVEWY.js} +3 -3
- package/dist/{chunk-NPDL4W4Y.js → chunk-2MLJHNKJ.js} +108 -109
- package/dist/chunk-2MLJHNKJ.js.map +1 -0
- package/dist/{chunk-JI6WPLZB.js → chunk-2SBCOGQN.js} +4 -4
- package/dist/{chunk-6JF7C3U3.js → chunk-2WERWWSS.js} +2 -2
- package/dist/{chunk-4XKT4ENZ.js → chunk-2Y3QL3DA.js} +4 -4
- package/dist/{chunk-KVMFT6FN.js → chunk-3FL3F4WF.js} +2 -2
- package/dist/{chunk-4VJOZJDV.js → chunk-3JPQAIYJ.js} +2 -2
- package/dist/{chunk-27EORKJ4.js → chunk-3N4LNBJF.js} +2 -2
- package/dist/{chunk-7JZSFJHB.js → chunk-3OJU3RUR.js} +2 -2
- package/dist/{chunk-NV5OYV3G.js → chunk-3U6K36QA.js} +5 -5
- package/dist/{chunk-MDRLP5DO.js → chunk-3W7ROHN4.js} +3 -3
- package/dist/{chunk-3MQM4ZOC.js → chunk-3Y6ZR2VN.js} +3 -3
- package/dist/{chunk-HXZIX7MR.js → chunk-47AB65IO.js} +4 -4
- package/dist/{chunk-DNYD7AUG.js → chunk-4BOLIZ7Y.js} +3 -3
- package/dist/{chunk-4XO346BW.js → chunk-4FBJFQFU.js} +2 -2
- package/dist/{chunk-BWKZEW6K.js → chunk-4T3E56NT.js} +3 -3
- package/dist/{chunk-4PC7LIQK.js → chunk-4ZMUWRFF.js} +3 -3
- package/dist/{chunk-TM2ZLY3Q.js → chunk-5OLFYSVG.js} +13 -13
- package/dist/{chunk-D4QOZXPM.js → chunk-5WBRM7V4.js} +5 -5
- package/dist/{chunk-GXK4CUAB.js → chunk-5WQKTT5Z.js} +2 -2
- package/dist/{chunk-6N7W3TOV.js → chunk-63BPMTBM.js} +2 -2
- package/dist/{chunk-R5YZ3ROM.js → chunk-63PQKTTT.js} +2 -2
- package/dist/{chunk-WLZVXCPZ.js → chunk-6GO6WN22.js} +3 -3
- package/dist/{chunk-6PQBKMUL.js → chunk-6IIA63VD.js} +11 -7
- package/dist/chunk-6IIA63VD.js.map +1 -0
- package/dist/{chunk-XDCZBOEY.js → chunk-6LGBGPBU.js} +1 -1
- package/dist/{chunk-FMATVQFW.js → chunk-6XXMG5YP.js} +9 -9
- package/dist/{chunk-M5E3CKSE.js → chunk-7QWWE5XL.js} +2 -2
- package/dist/{chunk-RABKQFTA.js → chunk-A2HCAMRH.js} +2 -2
- package/dist/{chunk-6K3WNTRI.js → chunk-AODISQO6.js} +2 -2
- package/dist/{chunk-C6JL6PBL.js → chunk-AQDRH6VF.js} +3 -3
- package/dist/{chunk-72XEFLMD.js → chunk-ASWINLSW.js} +2 -2
- package/dist/{chunk-ZPZYYSHW.js → chunk-BVMDON5T.js} +8 -8
- package/dist/{chunk-EURDMOXZ.js → chunk-BYJZUCOQ.js} +2 -2
- package/dist/{chunk-BQWUXC55.js → chunk-CAVAVT5S.js} +9 -9
- package/dist/{chunk-ZWACUOU5.js → chunk-CDBGAAJY.js} +3 -3
- package/dist/chunk-CDBGAAJY.js.map +1 -0
- package/dist/{chunk-BPD4IJBG.js → chunk-CG6CJMIS.js} +2 -2
- package/dist/{chunk-B254JG72.js → chunk-CQX24PT7.js} +2 -2
- package/dist/{chunk-65K5LV4L.js → chunk-CTCOVPZU.js} +51 -50
- package/dist/{chunk-65K5LV4L.js.map → chunk-CTCOVPZU.js.map} +1 -1
- package/dist/{chunk-HJTTDLF6.js → chunk-CY3NO4JN.js} +4 -4
- package/dist/{chunk-OLUG4IFF.js → chunk-D2RLPRSG.js} +2 -2
- package/dist/{chunk-74NIHMAT.js → chunk-D653JH6D.js} +3 -3
- package/dist/{chunk-2LUO22FR.js → chunk-DAI5CTQF.js} +4 -4
- package/dist/{chunk-HTKVYEVB.js → chunk-DBM4ZXDN.js} +2 -2
- package/dist/{chunk-MB2DTUEG.js → chunk-DNYKLU3K.js} +4 -4
- package/dist/{chunk-26P7B46A.js → chunk-DXYARXK3.js} +3 -3
- package/dist/{chunk-JQKURO3S.js → chunk-E4MQRQ6Z.js} +2 -2
- package/dist/{chunk-KW53DBY7.js → chunk-EBW2E32G.js} +2 -2
- package/dist/{chunk-O73DRA77.js → chunk-ENKBO7FC.js} +4 -4
- package/dist/{chunk-FVCLVASD.js → chunk-FI3KRVOF.js} +24 -24
- package/dist/{chunk-WWM7WVD2.js → chunk-GABFKHQE.js} +2 -2
- package/dist/chunk-GLCOKWLH.js +42 -0
- package/dist/chunk-GLCOKWLH.js.map +1 -0
- package/dist/{chunk-32HA7DXJ.js → chunk-GNBRB3DH.js} +25 -25
- package/dist/{chunk-CEQUNJJY.js → chunk-HPALK6LD.js} +2 -2
- package/dist/{chunk-LR7U3HCD.js → chunk-HPSATFLQ.js} +4 -4
- package/dist/{chunk-O4AWXTZQ.js → chunk-HUYLQW75.js} +6 -6
- package/dist/{chunk-PQCFW2KT.js → chunk-IDDHH5AQ.js} +29 -24
- package/dist/chunk-IDDHH5AQ.js.map +1 -0
- package/dist/{chunk-ZZUKJ5HQ.js → chunk-IG2ERMSB.js} +2 -2
- package/dist/{chunk-2SZ3KC5S.js → chunk-IMKIIS4Y.js} +2 -2
- package/dist/{chunk-CA64OZLZ.js → chunk-IRXPXDY5.js} +4 -4
- package/dist/{chunk-I57HZMMA.js → chunk-IXIE3H43.js} +2 -2
- package/dist/{chunk-OWJD3V4V.js → chunk-J3YQ3554.js} +2 -2
- package/dist/{chunk-BCFHMBMK.js → chunk-J5HZBHU4.js} +7 -7
- package/dist/{chunk-UHMMRQGU.js → chunk-KD7GNHOP.js} +3 -3
- package/dist/{chunk-X7Z4B5GK.js → chunk-KPL7EXS6.js} +2 -2
- package/dist/{chunk-GTR2WUBA.js → chunk-KX6M5CJI.js} +1 -1
- package/dist/{chunk-CYO5HL4C.js → chunk-KYL2BPS2.js} +2 -2
- package/dist/{chunk-QLDMF7MH.js → chunk-LC5HE7PZ.js} +2 -2
- package/dist/{chunk-3SMJ2BIQ.js → chunk-LGD5RESZ.js} +7 -33
- package/dist/chunk-LGD5RESZ.js.map +1 -0
- package/dist/{chunk-4ICPJZAB.js → chunk-LMYSYG6U.js} +2 -2
- package/dist/{chunk-3ZZOE4SN.js → chunk-LOCDYMD6.js} +4 -4
- package/dist/{chunk-DNWBLT4U.js → chunk-MASBMJ2M.js} +2 -2
- package/dist/{chunk-NZMQDUOD.js → chunk-MU6HYDNF.js} +5 -5
- package/dist/{chunk-GMVKCEBG.js → chunk-MY6QEDZ2.js} +2 -2
- package/dist/{chunk-SK57RWSA.js → chunk-MZGKQ5WV.js} +2 -2
- package/dist/{chunk-HSQRYJ4P.js → chunk-N52SFH2K.js} +2 -2
- package/dist/{chunk-MY6VZVCP.js → chunk-OAJX5CEL.js} +4 -4
- package/dist/{chunk-IWIMIRV3.js → chunk-OSJTLQXA.js} +9 -4
- package/dist/chunk-OSJTLQXA.js.map +1 -0
- package/dist/{chunk-FH75NNLB.js → chunk-OZ5NAXCP.js} +2 -2
- package/dist/{chunk-PEGNFZ3F.js → chunk-P5S777YI.js} +2 -2
- package/dist/{chunk-LY6727IF.js → chunk-PPSVFNEA.js} +1 -1
- package/dist/{chunk-K4FDZVMQ.js → chunk-PR42VIVY.js} +2 -2
- package/dist/{chunk-I74J2UZ2.js → chunk-PWMZCW4H.js} +8 -8
- package/dist/{chunk-6YDXUE5H.js → chunk-PYA2O3WS.js} +2 -2
- package/dist/{chunk-GUIZDI5T.js → chunk-Q2PA4KZS.js} +2 -2
- package/dist/{chunk-JJ7VMIEQ.js → chunk-QCANSTLU.js} +64 -64
- package/dist/{chunk-DZH2HTTB.js → chunk-R27GW5WV.js} +1 -1
- package/dist/chunk-R4U4EWZG.js +414 -0
- package/dist/chunk-R4U4EWZG.js.map +1 -0
- package/dist/{chunk-DAQG3C4W.js → chunk-R6JY22SG.js} +29 -29
- package/dist/{chunk-7OIBLMDP.js → chunk-RAQISW42.js} +2 -2
- package/dist/{chunk-DNLXQUBX.js → chunk-RLS6PTL4.js} +32 -44
- package/dist/chunk-RLS6PTL4.js.map +1 -0
- package/dist/{chunk-CPKD2YGK.js → chunk-RNU5CUPI.js} +2 -2
- package/dist/{chunk-467VRP4E.js → chunk-RO5YZQHZ.js} +3 -3
- package/dist/{chunk-SSZROOOI.js → chunk-ROLXYGT5.js} +2 -2
- package/dist/{chunk-6VITVQ23.js → chunk-SHJ5SQOW.js} +7 -7
- package/dist/{chunk-F4B2YYCN.js → chunk-TAWFXRXB.js} +3 -3
- package/dist/{chunk-G3FU2IF7.js → chunk-TB7UW5BB.js} +3 -3
- package/dist/{chunk-NF6Q4XTN.js → chunk-TQF2I5SY.js} +3 -3
- package/dist/{chunk-MM7OKOTE.js → chunk-UBXHP224.js} +43 -18
- package/dist/chunk-UBXHP224.js.map +1 -0
- package/dist/{chunk-M7A226EQ.js → chunk-UL44R3W2.js} +2 -2
- package/dist/{chunk-GTR5NLVP.js → chunk-VCRQPLKS.js} +2 -2
- package/dist/{chunk-MHIYYHCL.js → chunk-VJU3ET7N.js} +12 -12
- package/dist/{chunk-RXMIXKB3.js → chunk-WGJUARF3.js} +13 -13
- package/dist/{chunk-NWSAF6P5.js → chunk-WJDH7CH5.js} +22 -1
- package/dist/chunk-WJDH7CH5.js.map +1 -0
- package/dist/{chunk-LG67ZNRU.js → chunk-WK2ZCTUF.js} +2 -2
- package/dist/{chunk-XGE75VPK.js → chunk-WNARM3LY.js} +3 -3
- package/dist/{chunk-RNBH5TSM.js → chunk-WQ2RTQYO.js} +2 -2
- package/dist/chunk-X5XEYQ4B.js +84 -0
- package/dist/chunk-X5XEYQ4B.js.map +1 -0
- package/dist/{chunk-W57QFLQD.js → chunk-X6JIGNLI.js} +4 -4
- package/dist/{chunk-CKA4SJRK.js → chunk-XIQDCQX7.js} +2 -2
- package/dist/{chunk-AJ7PY4FJ.js → chunk-Y3GCG6CA.js} +2 -2
- package/dist/{chunk-2K27S6LK.js → chunk-Y565N5ZJ.js} +24 -7
- package/dist/chunk-Y565N5ZJ.js.map +1 -0
- package/dist/{chunk-ZRB4M3GG.js → chunk-YC5KH7ZB.js} +3 -3
- package/dist/{chunk-4RY64KQY.js → chunk-YJUKLLNP.js} +2 -2
- package/dist/{chunk-OHG2UQ2O.js → chunk-YWP2H7SX.js} +60 -22
- package/dist/chunk-YWP2H7SX.js.map +1 -0
- package/dist/{chunk-24POWVUY.js → chunk-ZDJNRRVS.js} +4 -4
- package/dist/{chunk-S6WJ6TUT.js → chunk-ZEVJGMNB.js} +2 -2
- package/dist/chunk-ZEVJGMNB.js.map +1 -0
- package/dist/{chunk-M7YEZR6X.js → chunk-ZITMDA4C.js} +2 -2
- package/dist/components/model-policy-picker.d.ts +2 -0
- package/dist/composer.js +6 -6
- package/dist/{computer-viewer-BWVNDFTO.js → computer-viewer-6CRLWQHP.js} +5 -5
- package/dist/connect.js +6 -6
- package/dist/connection-service-presentation.d.ts +1 -4
- package/dist/desktop.js +2 -2
- package/dist/editor.js +2 -2
- package/dist/{embedded-new-voice-GBXSZ3TO.js → embedded-new-voice-KILV3RYM.js} +5 -5
- package/dist/{embedded-voice-MGI7EK7C.js → embedded-voice-GHDRLCFX.js} +5 -5
- package/dist/{fleet-decision-row-35S3GAUN.js → fleet-decision-row-DQXRRBT7.js} +2 -2
- package/dist/index.js +44 -44
- package/dist/interaction.js +5 -5
- package/dist/machines.js +3 -3
- package/dist/messages/en.d.ts +1 -1
- package/dist/messages.js +1 -1
- package/dist/{model-policy-picker-menu-KP53N6UJ.js → model-policy-picker-menu-5ALKUJMR.js} +4 -4
- package/dist/{platform-activity-row-ISMXR7NJ.js → platform-activity-row-227C764Z.js} +2 -2
- package/dist/{queue-surface-implementation-ULW7DDJA.js → queue-surface-implementation-H3NOBXU5.js} +5 -5
- package/dist/realtime.js +4 -4
- package/dist/{sandbox-files-QYSD4XCZ.js → sandbox-files-5FEOHUMD.js} +6 -6
- package/dist/session-app.js +155 -157
- package/dist/{session-realtime-JXRLPNUH.js → session-realtime-OHBMODNX.js} +3 -3
- package/dist/session-realtime.js +2 -2
- package/dist/session-ui.js +26 -26
- package/dist/session.js +6 -6
- package/dist/sites.js +2 -2
- package/dist/terminal.js +2 -2
- package/dist/this-computer.js +3 -3
- package/dist/timeline/connector-logo-index.d.ts +19 -0
- package/dist/{timeline-annotation-markers-OJYKHBEO.js → timeline-annotation-markers-NDHS7MCK.js} +2 -2
- package/dist/{timeline-annotation-selection-6OAZLXFU.js → timeline-annotation-selection-DRQSTJOV.js} +2 -2
- package/dist/{timeline-annotations-dialog-5M6DP5FX.js → timeline-annotations-dialog-G6J5ZJKN.js} +3 -3
- package/dist/timeline-model.d.ts +2 -0
- package/dist/timeline-model.js +9 -1
- package/dist/ui/list-row.js +1 -1
- package/dist/usage.js +2 -2
- package/dist/workbench.js +4 -4
- package/package.json +4 -4
- package/src/app/components/capabilities/native-connect-readiness.tsx +1 -0
- package/src/app/components/capabilities/perform-capability-action.test.ts +67 -0
- package/src/app/components/capabilities/perform-capability-action.tsx +28 -0
- package/src/app/components/command-menu/chat-switcher.tsx +25 -4
- package/src/app/components/rail/session-header.test.tsx +73 -2
- package/src/app/components/rail/session-header.tsx +20 -12
- package/src/app/components/rail/session-shell.tsx +10 -18
- package/src/app/components/session/subscription-account-indicator.test.ts +239 -0
- package/src/app/components/session/subscription-account-indicator.tsx +361 -0
- package/src/app/components/session/subscription-account-menu.tsx +21 -43
- package/src/app/components/session/subscription-account.test.ts +314 -0
- package/src/app/components/session/subscription-account.ts +354 -0
- package/src/app/lib/actions/actions-provider.tsx +11 -0
- package/src/app/lib/actions/actions.test.ts +59 -4
- package/src/app/lib/actions/chat-switcher.ts +73 -20
- package/src/app/lib/drive-connect-return.test.ts +183 -0
- package/src/app/lib/drive-connect-return.tsx +116 -0
- package/src/app/routes/session.tsx +12 -14
- package/src/app/routes/sessions-index.tsx +1 -0
- package/src/components/model-policy-picker-menu.tsx +25 -4
- package/src/components/model-policy-picker.tsx +2 -0
- package/src/components/session-mcp-capability-card.tsx +13 -4
- package/src/connection-service-presentation.ts +6 -1
- package/src/messages/en.ts +1 -1
- package/src/timeline/connector-logo-index.test.ts +46 -0
- package/src/timeline/connector-logo-index.ts +68 -0
- package/src/timeline-model.ts +6 -0
- package/src/ui/list-row.tsx +38 -10
- package/styles/compiled.css +13 -0
- package/dist/app/components/session/codex-account-indicator.d.ts +0 -9
- package/dist/app/components/session/model-account-indicator.d.ts +0 -10
- package/dist/app/components/session/model-account-indicator.js +0 -34
- package/dist/app/components/session/model-account-usage.d.ts +0 -8
- package/dist/app/components/session/model-account-usage.js +0 -8
- package/dist/chunk-2K27S6LK.js.map +0 -1
- package/dist/chunk-3SMJ2BIQ.js.map +0 -1
- package/dist/chunk-6PQBKMUL.js.map +0 -1
- package/dist/chunk-7H2D4VNU.js +0 -150
- package/dist/chunk-7H2D4VNU.js.map +0 -1
- package/dist/chunk-DNLXQUBX.js.map +0 -1
- package/dist/chunk-HCCSAECI.js +0 -132
- package/dist/chunk-HCCSAECI.js.map +0 -1
- package/dist/chunk-IWIMIRV3.js.map +0 -1
- package/dist/chunk-M77ZQE5T.js +0 -58
- package/dist/chunk-M77ZQE5T.js.map +0 -1
- package/dist/chunk-MM7OKOTE.js.map +0 -1
- package/dist/chunk-NPDL4W4Y.js.map +0 -1
- package/dist/chunk-NWSAF6P5.js.map +0 -1
- package/dist/chunk-OHG2UQ2O.js.map +0 -1
- package/dist/chunk-PQCFW2KT.js.map +0 -1
- package/dist/chunk-S6WJ6TUT.js.map +0 -1
- package/dist/chunk-ZWACUOU5.js.map +0 -1
- package/dist/session-realtime-JXRLPNUH.js.map +0 -1
- package/src/app/components/session/codex-account-indicator.tsx +0 -207
- package/src/app/components/session/model-account-indicator.tsx +0 -189
- package/src/app/components/session/model-account-usage.test.ts +0 -59
- package/src/app/components/session/model-account-usage.tsx +0 -89
- /package/dist/app/components/session/{codex-account-indicator.js.map → subscription-account-indicator.js.map} +0 -0
- /package/dist/app/{components/session/model-account-indicator.js.map → lib/drive-connect-return.js.map} +0 -0
- /package/dist/{app/components/session/model-account-usage.js.map → browser-viewer-VKIAULG7.js.map} +0 -0
- /package/dist/{browser-viewer-YQC6BFMS.js.map → chat-interactive-block-JGYSW4KB.js.map} +0 -0
- /package/dist/{chunk-WN2MIB4Q.js.map → chunk-22V2QCEM.js.map} +0 -0
- /package/dist/{chunk-SJPAKWWP.js.map → chunk-2BISI664.js.map} +0 -0
- /package/dist/{chunk-O5UOCMH4.js.map → chunk-2LPJVEWY.js.map} +0 -0
- /package/dist/{chunk-JI6WPLZB.js.map → chunk-2SBCOGQN.js.map} +0 -0
- /package/dist/{chunk-6JF7C3U3.js.map → chunk-2WERWWSS.js.map} +0 -0
- /package/dist/{chunk-4XKT4ENZ.js.map → chunk-2Y3QL3DA.js.map} +0 -0
- /package/dist/{chunk-KVMFT6FN.js.map → chunk-3FL3F4WF.js.map} +0 -0
- /package/dist/{chunk-4VJOZJDV.js.map → chunk-3JPQAIYJ.js.map} +0 -0
- /package/dist/{chunk-27EORKJ4.js.map → chunk-3N4LNBJF.js.map} +0 -0
- /package/dist/{chunk-7JZSFJHB.js.map → chunk-3OJU3RUR.js.map} +0 -0
- /package/dist/{chunk-NV5OYV3G.js.map → chunk-3U6K36QA.js.map} +0 -0
- /package/dist/{chunk-MDRLP5DO.js.map → chunk-3W7ROHN4.js.map} +0 -0
- /package/dist/{chunk-3MQM4ZOC.js.map → chunk-3Y6ZR2VN.js.map} +0 -0
- /package/dist/{chunk-HXZIX7MR.js.map → chunk-47AB65IO.js.map} +0 -0
- /package/dist/{chunk-DNYD7AUG.js.map → chunk-4BOLIZ7Y.js.map} +0 -0
- /package/dist/{chunk-4XO346BW.js.map → chunk-4FBJFQFU.js.map} +0 -0
- /package/dist/{chunk-BWKZEW6K.js.map → chunk-4T3E56NT.js.map} +0 -0
- /package/dist/{chunk-4PC7LIQK.js.map → chunk-4ZMUWRFF.js.map} +0 -0
- /package/dist/{chunk-TM2ZLY3Q.js.map → chunk-5OLFYSVG.js.map} +0 -0
- /package/dist/{chunk-D4QOZXPM.js.map → chunk-5WBRM7V4.js.map} +0 -0
- /package/dist/{chunk-GXK4CUAB.js.map → chunk-5WQKTT5Z.js.map} +0 -0
- /package/dist/{chunk-6N7W3TOV.js.map → chunk-63BPMTBM.js.map} +0 -0
- /package/dist/{chunk-R5YZ3ROM.js.map → chunk-63PQKTTT.js.map} +0 -0
- /package/dist/{chunk-WLZVXCPZ.js.map → chunk-6GO6WN22.js.map} +0 -0
- /package/dist/{chunk-XDCZBOEY.js.map → chunk-6LGBGPBU.js.map} +0 -0
- /package/dist/{chunk-FMATVQFW.js.map → chunk-6XXMG5YP.js.map} +0 -0
- /package/dist/{chunk-M5E3CKSE.js.map → chunk-7QWWE5XL.js.map} +0 -0
- /package/dist/{chunk-RABKQFTA.js.map → chunk-A2HCAMRH.js.map} +0 -0
- /package/dist/{chunk-6K3WNTRI.js.map → chunk-AODISQO6.js.map} +0 -0
- /package/dist/{chunk-C6JL6PBL.js.map → chunk-AQDRH6VF.js.map} +0 -0
- /package/dist/{chunk-72XEFLMD.js.map → chunk-ASWINLSW.js.map} +0 -0
- /package/dist/{chunk-ZPZYYSHW.js.map → chunk-BVMDON5T.js.map} +0 -0
- /package/dist/{chunk-EURDMOXZ.js.map → chunk-BYJZUCOQ.js.map} +0 -0
- /package/dist/{chunk-BQWUXC55.js.map → chunk-CAVAVT5S.js.map} +0 -0
- /package/dist/{chunk-BPD4IJBG.js.map → chunk-CG6CJMIS.js.map} +0 -0
- /package/dist/{chunk-B254JG72.js.map → chunk-CQX24PT7.js.map} +0 -0
- /package/dist/{chunk-HJTTDLF6.js.map → chunk-CY3NO4JN.js.map} +0 -0
- /package/dist/{chunk-OLUG4IFF.js.map → chunk-D2RLPRSG.js.map} +0 -0
- /package/dist/{chunk-74NIHMAT.js.map → chunk-D653JH6D.js.map} +0 -0
- /package/dist/{chunk-2LUO22FR.js.map → chunk-DAI5CTQF.js.map} +0 -0
- /package/dist/{chunk-HTKVYEVB.js.map → chunk-DBM4ZXDN.js.map} +0 -0
- /package/dist/{chunk-MB2DTUEG.js.map → chunk-DNYKLU3K.js.map} +0 -0
- /package/dist/{chunk-26P7B46A.js.map → chunk-DXYARXK3.js.map} +0 -0
- /package/dist/{chunk-JQKURO3S.js.map → chunk-E4MQRQ6Z.js.map} +0 -0
- /package/dist/{chunk-KW53DBY7.js.map → chunk-EBW2E32G.js.map} +0 -0
- /package/dist/{chunk-O73DRA77.js.map → chunk-ENKBO7FC.js.map} +0 -0
- /package/dist/{chunk-FVCLVASD.js.map → chunk-FI3KRVOF.js.map} +0 -0
- /package/dist/{chunk-WWM7WVD2.js.map → chunk-GABFKHQE.js.map} +0 -0
- /package/dist/{chunk-32HA7DXJ.js.map → chunk-GNBRB3DH.js.map} +0 -0
- /package/dist/{chunk-CEQUNJJY.js.map → chunk-HPALK6LD.js.map} +0 -0
- /package/dist/{chunk-LR7U3HCD.js.map → chunk-HPSATFLQ.js.map} +0 -0
- /package/dist/{chunk-O4AWXTZQ.js.map → chunk-HUYLQW75.js.map} +0 -0
- /package/dist/{chunk-ZZUKJ5HQ.js.map → chunk-IG2ERMSB.js.map} +0 -0
- /package/dist/{chunk-2SZ3KC5S.js.map → chunk-IMKIIS4Y.js.map} +0 -0
- /package/dist/{chunk-CA64OZLZ.js.map → chunk-IRXPXDY5.js.map} +0 -0
- /package/dist/{chunk-I57HZMMA.js.map → chunk-IXIE3H43.js.map} +0 -0
- /package/dist/{chunk-OWJD3V4V.js.map → chunk-J3YQ3554.js.map} +0 -0
- /package/dist/{chunk-BCFHMBMK.js.map → chunk-J5HZBHU4.js.map} +0 -0
- /package/dist/{chunk-UHMMRQGU.js.map → chunk-KD7GNHOP.js.map} +0 -0
- /package/dist/{chunk-X7Z4B5GK.js.map → chunk-KPL7EXS6.js.map} +0 -0
- /package/dist/{chunk-GTR2WUBA.js.map → chunk-KX6M5CJI.js.map} +0 -0
- /package/dist/{chunk-CYO5HL4C.js.map → chunk-KYL2BPS2.js.map} +0 -0
- /package/dist/{chunk-QLDMF7MH.js.map → chunk-LC5HE7PZ.js.map} +0 -0
- /package/dist/{chunk-4ICPJZAB.js.map → chunk-LMYSYG6U.js.map} +0 -0
- /package/dist/{chunk-3ZZOE4SN.js.map → chunk-LOCDYMD6.js.map} +0 -0
- /package/dist/{chunk-DNWBLT4U.js.map → chunk-MASBMJ2M.js.map} +0 -0
- /package/dist/{chunk-NZMQDUOD.js.map → chunk-MU6HYDNF.js.map} +0 -0
- /package/dist/{chunk-GMVKCEBG.js.map → chunk-MY6QEDZ2.js.map} +0 -0
- /package/dist/{chunk-SK57RWSA.js.map → chunk-MZGKQ5WV.js.map} +0 -0
- /package/dist/{chunk-HSQRYJ4P.js.map → chunk-N52SFH2K.js.map} +0 -0
- /package/dist/{chunk-MY6VZVCP.js.map → chunk-OAJX5CEL.js.map} +0 -0
- /package/dist/{chunk-FH75NNLB.js.map → chunk-OZ5NAXCP.js.map} +0 -0
- /package/dist/{chunk-PEGNFZ3F.js.map → chunk-P5S777YI.js.map} +0 -0
- /package/dist/{chunk-LY6727IF.js.map → chunk-PPSVFNEA.js.map} +0 -0
- /package/dist/{chunk-K4FDZVMQ.js.map → chunk-PR42VIVY.js.map} +0 -0
- /package/dist/{chunk-I74J2UZ2.js.map → chunk-PWMZCW4H.js.map} +0 -0
- /package/dist/{chunk-6YDXUE5H.js.map → chunk-PYA2O3WS.js.map} +0 -0
- /package/dist/{chunk-GUIZDI5T.js.map → chunk-Q2PA4KZS.js.map} +0 -0
- /package/dist/{chunk-JJ7VMIEQ.js.map → chunk-QCANSTLU.js.map} +0 -0
- /package/dist/{chunk-DZH2HTTB.js.map → chunk-R27GW5WV.js.map} +0 -0
- /package/dist/{chunk-DAQG3C4W.js.map → chunk-R6JY22SG.js.map} +0 -0
- /package/dist/{chunk-7OIBLMDP.js.map → chunk-RAQISW42.js.map} +0 -0
- /package/dist/{chunk-CPKD2YGK.js.map → chunk-RNU5CUPI.js.map} +0 -0
- /package/dist/{chunk-467VRP4E.js.map → chunk-RO5YZQHZ.js.map} +0 -0
- /package/dist/{chunk-SSZROOOI.js.map → chunk-ROLXYGT5.js.map} +0 -0
- /package/dist/{chunk-6VITVQ23.js.map → chunk-SHJ5SQOW.js.map} +0 -0
- /package/dist/{chunk-F4B2YYCN.js.map → chunk-TAWFXRXB.js.map} +0 -0
- /package/dist/{chunk-G3FU2IF7.js.map → chunk-TB7UW5BB.js.map} +0 -0
- /package/dist/{chunk-NF6Q4XTN.js.map → chunk-TQF2I5SY.js.map} +0 -0
- /package/dist/{chunk-M7A226EQ.js.map → chunk-UL44R3W2.js.map} +0 -0
- /package/dist/{chunk-GTR5NLVP.js.map → chunk-VCRQPLKS.js.map} +0 -0
- /package/dist/{chunk-MHIYYHCL.js.map → chunk-VJU3ET7N.js.map} +0 -0
- /package/dist/{chunk-RXMIXKB3.js.map → chunk-WGJUARF3.js.map} +0 -0
- /package/dist/{chunk-LG67ZNRU.js.map → chunk-WK2ZCTUF.js.map} +0 -0
- /package/dist/{chunk-XGE75VPK.js.map → chunk-WNARM3LY.js.map} +0 -0
- /package/dist/{chunk-RNBH5TSM.js.map → chunk-WQ2RTQYO.js.map} +0 -0
- /package/dist/{chunk-W57QFLQD.js.map → chunk-X6JIGNLI.js.map} +0 -0
- /package/dist/{chunk-CKA4SJRK.js.map → chunk-XIQDCQX7.js.map} +0 -0
- /package/dist/{chunk-AJ7PY4FJ.js.map → chunk-Y3GCG6CA.js.map} +0 -0
- /package/dist/{chunk-ZRB4M3GG.js.map → chunk-YC5KH7ZB.js.map} +0 -0
- /package/dist/{chunk-4RY64KQY.js.map → chunk-YJUKLLNP.js.map} +0 -0
- /package/dist/{chunk-24POWVUY.js.map → chunk-ZDJNRRVS.js.map} +0 -0
- /package/dist/{chunk-M7YEZR6X.js.map → chunk-ZITMDA4C.js.map} +0 -0
- /package/dist/{chat-interactive-block-Z22YHDRU.js.map → computer-viewer-6CRLWQHP.js.map} +0 -0
- /package/dist/{computer-viewer-BWVNDFTO.js.map → embedded-new-voice-KILV3RYM.js.map} +0 -0
- /package/dist/{embedded-new-voice-GBXSZ3TO.js.map → embedded-voice-GHDRLCFX.js.map} +0 -0
- /package/dist/{fleet-decision-row-35S3GAUN.js.map → fleet-decision-row-DQXRRBT7.js.map} +0 -0
- /package/dist/{embedded-voice-MGI7EK7C.js.map → model-policy-picker-menu-5ALKUJMR.js.map} +0 -0
- /package/dist/{platform-activity-row-ISMXR7NJ.js.map → platform-activity-row-227C764Z.js.map} +0 -0
- /package/dist/{queue-surface-implementation-ULW7DDJA.js.map → queue-surface-implementation-H3NOBXU5.js.map} +0 -0
- /package/dist/{model-policy-picker-menu-KP53N6UJ.js.map → sandbox-files-5FEOHUMD.js.map} +0 -0
- /package/dist/{sandbox-files-QYSD4XCZ.js.map → session-realtime-OHBMODNX.js.map} +0 -0
- /package/dist/{timeline-annotation-markers-OJYKHBEO.js.map → timeline-annotation-markers-NDHS7MCK.js.map} +0 -0
- /package/dist/{timeline-annotation-selection-6OAZLXFU.js.map → timeline-annotation-selection-DRQSTJOV.js.map} +0 -0
- /package/dist/{timeline-annotations-dialog-5M6DP5FX.js.map → timeline-annotations-dialog-G6J5ZJKN.js.map} +0 -0
|
@@ -83,7 +83,7 @@ function ScopedCard({
|
|
|
83
83
|
onConfigured,
|
|
84
84
|
dialogOnly = false,
|
|
85
85
|
onClose,
|
|
86
|
-
personalOnly = false,
|
|
86
|
+
personalOnly: configuredPersonalOnly = false,
|
|
87
87
|
connectLabel,
|
|
88
88
|
dialogSubtitle,
|
|
89
89
|
description: hostDescription,
|
|
@@ -96,6 +96,9 @@ function ScopedCard({
|
|
|
96
96
|
);
|
|
97
97
|
const view = useConnect(controller);
|
|
98
98
|
const [item, setItem] = useState<CapabilityCatalogItem | null>(null);
|
|
99
|
+
const personalOnly =
|
|
100
|
+
configuredPersonalOnly ||
|
|
101
|
+
(item?.mcpUrl ?? item?.endpointUrl) === "https://drivemcp.googleapis.com/mcp/v1";
|
|
99
102
|
const [logo, setLogo] = useState<string | null>(null);
|
|
100
103
|
const [expanded, setExpanded] = useState(dialogOnly);
|
|
101
104
|
const [complete, setComplete] = useState(false);
|
|
@@ -151,7 +154,9 @@ function ScopedCard({
|
|
|
151
154
|
setOwnership(resolved.connectionRef.subjectScope === "subject" ? "personal" : "workspace");
|
|
152
155
|
else if (
|
|
153
156
|
!item &&
|
|
154
|
-
(personalOnly ||
|
|
157
|
+
(personalOnly ||
|
|
158
|
+
(resolved.mcpUrl ?? resolved.endpointUrl) === "https://drivemcp.googleapis.com/mcp/v1" ||
|
|
159
|
+
resolved.metadata?.defaultConnectionOwnership === "personal")
|
|
155
160
|
)
|
|
156
161
|
setOwnership("personal");
|
|
157
162
|
let accountReady = false;
|
|
@@ -399,7 +404,8 @@ function ScopedCard({
|
|
|
399
404
|
}
|
|
400
405
|
startInput.current = input;
|
|
401
406
|
let attempt = await controller.begin({
|
|
402
|
-
providerId:
|
|
407
|
+
providerId:
|
|
408
|
+
mcpUrl === "https://drivemcp.googleapis.com/mcp/v1" ? "google-drive" : "mcp-oauth",
|
|
403
409
|
ownership,
|
|
404
410
|
returnUrl,
|
|
405
411
|
idempotencyKey: startKey.current,
|
|
@@ -409,7 +415,10 @@ function ScopedCard({
|
|
|
409
415
|
remember(attempt.id);
|
|
410
416
|
if (attempt.state === "credential_input")
|
|
411
417
|
attempt = await controller.advance(
|
|
412
|
-
{
|
|
418
|
+
{
|
|
419
|
+
type: "credentials",
|
|
420
|
+
values: mcpUrl === "https://drivemcp.googleapis.com/mcp/v1" ? {} : { mcpUrl },
|
|
421
|
+
},
|
|
413
422
|
advanceKey.current,
|
|
414
423
|
);
|
|
415
424
|
if (!active()) return;
|
|
@@ -4,7 +4,12 @@ import gmailLogo from "./assets/gmail.ico";
|
|
|
4
4
|
import outlookLogo from "./assets/outlook.ico";
|
|
5
5
|
|
|
6
6
|
/** Passive service identity only. Never selects an account or grants tool access. */
|
|
7
|
-
const services: Record<string, { name: string; logo: string; mcpUrl?: string }> = {
|
|
7
|
+
const services: Record<string, { name: string; logo: string | null; mcpUrl?: string }> = {
|
|
8
|
+
"google-drive": {
|
|
9
|
+
name: "Google Drive",
|
|
10
|
+
logo: null,
|
|
11
|
+
mcpUrl: "https://drivemcp.googleapis.com/mcp/v1",
|
|
12
|
+
},
|
|
8
13
|
gmail: { name: "Gmail", logo: gmailLogo, mcpUrl: "https://gmailmcp.googleapis.com/mcp/v1" },
|
|
9
14
|
"microsoft-outlook-mail": { name: "Outlook Mail", logo: outlookLogo },
|
|
10
15
|
"microsoft-outlook-calendar": { name: "Outlook Calendar", logo: outlookLogo },
|
package/src/messages/en.ts
CHANGED
|
@@ -1817,7 +1817,7 @@ export const englishMessages = {
|
|
|
1817
1817
|
"modelPolicy.billedToTheWorkspaceProvider": "Billed to the workspace provider account",
|
|
1818
1818
|
"modelPolicy.billedToTheWorkspaceVercel": "Billed to the workspace Vercel account",
|
|
1819
1819
|
"modelPolicy.blockedByWorkspacePolicy": "Blocked by workspace policy",
|
|
1820
|
-
"modelPolicy.claudeSubscription": "Claude
|
|
1820
|
+
"modelPolicy.claudeSubscription": "Claude",
|
|
1821
1821
|
"modelPolicy.claudeSubscriptionExternalBilling": "Claude subscription · external billing",
|
|
1822
1822
|
"modelPolicy.codex": "Codex",
|
|
1823
1823
|
"modelPolicy.codexSubscriptionExternalBilling": "Codex subscription · external billing",
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { connectorLogo, connectorLogoIndex } from "./connector-logo-index";
|
|
4
|
+
|
|
5
|
+
const url = (path: string | null | undefined) => (path ? `/v1/${path}` : null);
|
|
6
|
+
|
|
7
|
+
describe("connectorLogoIndex", () => {
|
|
8
|
+
test("a connector's server host finds the provider's logo", () => {
|
|
9
|
+
const index = connectorLogoIndex(
|
|
10
|
+
[
|
|
11
|
+
{
|
|
12
|
+
providerDomain: "linear.app",
|
|
13
|
+
mcpUrl: "https://mcp.linear.app/mcp",
|
|
14
|
+
logoAssetPath: "logos/linear.png",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
providerDomain: "notion.com",
|
|
18
|
+
connectionRef: { providerDomain: "mcp.notion.com" },
|
|
19
|
+
logoAssetPath: "logos/notion.png",
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
url,
|
|
23
|
+
);
|
|
24
|
+
expect(connectorLogo(index, "mcp.linear.app")).toBe("/v1/logos/linear.png");
|
|
25
|
+
expect(connectorLogo(index, "Linear.app")).toBe("/v1/logos/linear.png");
|
|
26
|
+
expect(connectorLogo(index, "mcp.notion.com")).toBe("/v1/logos/notion.png");
|
|
27
|
+
expect(connectorLogo(index, "example.com")).toBeNull();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("a provider's own domain wins over another entry's server host", () => {
|
|
31
|
+
const index = connectorLogoIndex(
|
|
32
|
+
[
|
|
33
|
+
{
|
|
34
|
+
providerDomain: "relay.example",
|
|
35
|
+
mcpUrl: "https://github.com/mcp",
|
|
36
|
+
logoAssetPath: "logos/relay.png",
|
|
37
|
+
},
|
|
38
|
+
{ providerDomain: "github.com", logoAssetPath: "logos/github.png" },
|
|
39
|
+
{ providerDomain: "nologo.app", logoAssetPath: null },
|
|
40
|
+
],
|
|
41
|
+
url,
|
|
42
|
+
);
|
|
43
|
+
expect(connectorLogo(index, "github.com")).toBe("/v1/logos/github.png");
|
|
44
|
+
expect(connectorLogo(index, "nologo.app")).toBeNull();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Which logo belongs to a connector domain. Tool steps and sign-in cards name
|
|
3
|
+
* their connector by the domain of the connection or MCP server they used
|
|
4
|
+
* (Linear's is mcp.linear.app), while the catalog files the logo under the
|
|
5
|
+
* provider's own domain (linear.app). Indexing every domain a catalog entry is
|
|
6
|
+
* known by lets any of them find the logo. Framework-neutral, so web, native
|
|
7
|
+
* and embedded surfaces resolve logos the same way.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** The catalog fields that name a connector's domains and logo. */
|
|
11
|
+
export type ConnectorLogoSource = {
|
|
12
|
+
providerDomain?: string | null | undefined;
|
|
13
|
+
mcpUrl?: string | null | undefined;
|
|
14
|
+
connectionRef?: { providerDomain?: string | null | undefined } | null | undefined;
|
|
15
|
+
logoAssetPath?: string | null | undefined;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/** "WWW.Linear.app " → "linear.app". */
|
|
19
|
+
export function normalizeConnectorDomain(domain: string): string {
|
|
20
|
+
return domain
|
|
21
|
+
.trim()
|
|
22
|
+
.toLowerCase()
|
|
23
|
+
.replace(/^www\./, "");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function urlHost(url: string | null | undefined): string | null {
|
|
27
|
+
if (!url) return null;
|
|
28
|
+
try {
|
|
29
|
+
return new URL(url).hostname || null;
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Every domain each catalog entry is known by, mapped to its logo URL. The
|
|
37
|
+
* provider's own domain is claimed first across the whole catalog, so another
|
|
38
|
+
* entry's server host never takes over a provider's logo.
|
|
39
|
+
*/
|
|
40
|
+
export function connectorLogoIndex(
|
|
41
|
+
catalog: readonly ConnectorLogoSource[],
|
|
42
|
+
logoUrl: (logoAssetPath: string | null | undefined) => string | null | undefined,
|
|
43
|
+
): ReadonlyMap<string, string> {
|
|
44
|
+
const logos = new Map<string, string>();
|
|
45
|
+
const entries = catalog.flatMap((item) => {
|
|
46
|
+
const url = logoUrl(item.logoAssetPath);
|
|
47
|
+
return url ? [{ item, url }] : [];
|
|
48
|
+
});
|
|
49
|
+
const claim = (domain: string | null | undefined, url: string) => {
|
|
50
|
+
if (!domain) return;
|
|
51
|
+
const key = normalizeConnectorDomain(domain);
|
|
52
|
+
if (key && !logos.has(key)) logos.set(key, url);
|
|
53
|
+
};
|
|
54
|
+
for (const { item, url } of entries) claim(item.providerDomain, url);
|
|
55
|
+
for (const { item, url } of entries) {
|
|
56
|
+
claim(item.connectionRef?.providerDomain, url);
|
|
57
|
+
claim(urlHost(item.mcpUrl), url);
|
|
58
|
+
}
|
|
59
|
+
return logos;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The logo for a connector domain from an index built by `connectorLogoIndex`. */
|
|
63
|
+
export function connectorLogo(
|
|
64
|
+
index: ReadonlyMap<string, string>,
|
|
65
|
+
domain: string | null | undefined,
|
|
66
|
+
): string | null {
|
|
67
|
+
return domain ? (index.get(normalizeConnectorDomain(domain)) ?? null) : null;
|
|
68
|
+
}
|
package/src/timeline-model.ts
CHANGED
|
@@ -32,6 +32,12 @@ export {
|
|
|
32
32
|
export type { ActivityGroup, ReadableWorkOptions, TurnGroup } from "./timeline/work-presentation";
|
|
33
33
|
export { timelineGroupContainsPresentedImage } from "./timeline/presented-image";
|
|
34
34
|
export { mcpToolLeaf, toolDisplayName } from "./timeline/tool-display-name";
|
|
35
|
+
export {
|
|
36
|
+
connectorLogo,
|
|
37
|
+
connectorLogoIndex,
|
|
38
|
+
normalizeConnectorDomain,
|
|
39
|
+
} from "./timeline/connector-logo-index";
|
|
40
|
+
export type { ConnectorLogoSource } from "./timeline/connector-logo-index";
|
|
35
41
|
export {
|
|
36
42
|
BUILT_IN_TOOL_STEP_NAMES,
|
|
37
43
|
builtInToolStep,
|
package/src/ui/list-row.tsx
CHANGED
|
@@ -550,6 +550,11 @@ export function ListRow({
|
|
|
550
550
|
const hasColumns = gridded && columns.length > 0;
|
|
551
551
|
const expandable = !table && expanded !== undefined;
|
|
552
552
|
|
|
553
|
+
// Resource and table rows keep one fixed height: the description, the meta
|
|
554
|
+
// facts and (on narrow lists) the status and indicator words share ONE
|
|
555
|
+
// secondary line that truncates. Catalog rows keep a two-line description
|
|
556
|
+
// with the facts under it.
|
|
557
|
+
const singleLine = !catalog;
|
|
553
558
|
/* The meta line: quiet facts, then the fact columns folded in on narrow lists. */
|
|
554
559
|
const presentFacts = columns.filter((column) => cells[column.id] != null);
|
|
555
560
|
const facts = [
|
|
@@ -568,6 +573,7 @@ export function ListRow({
|
|
|
568
573
|
key={column.id}
|
|
569
574
|
order={order}
|
|
570
575
|
keep={leads}
|
|
576
|
+
oneLine={singleLine}
|
|
571
577
|
className={cn(
|
|
572
578
|
hasColumns && "@[640px]/list:hidden",
|
|
573
579
|
// A phone-width line has room for one folded fact (none next to a
|
|
@@ -586,8 +592,13 @@ export function ListRow({
|
|
|
586
592
|
...metaItems.map((item, index) => {
|
|
587
593
|
const last = index === metaItems.length - 1;
|
|
588
594
|
return (
|
|
589
|
-
|
|
590
|
-
|
|
595
|
+
<MetaPart
|
|
596
|
+
// oxlint-disable-next-line react/no-array-index-key -- meta items are positional
|
|
597
|
+
key={`meta-${index}`}
|
|
598
|
+
order={leadingFacts + index}
|
|
599
|
+
keep={!last}
|
|
600
|
+
oneLine={singleLine}
|
|
601
|
+
>
|
|
591
602
|
{item}
|
|
592
603
|
</MetaPart>
|
|
593
604
|
);
|
|
@@ -598,11 +609,6 @@ export function ListRow({
|
|
|
598
609
|
foldedFact(column, leadingFacts + index, leadingFacts + metaItems.length + index, false),
|
|
599
610
|
),
|
|
600
611
|
];
|
|
601
|
-
// Resource and table rows keep one fixed height: the description, the meta
|
|
602
|
-
// facts and (on narrow lists) the status and indicator words share ONE
|
|
603
|
-
// secondary line that truncates. Catalog rows keep a two-line description
|
|
604
|
-
// with the facts under it.
|
|
605
|
-
const singleLine = !catalog;
|
|
606
612
|
const statusPart = status ? (
|
|
607
613
|
<MetaPart key="status" keep className="@[480px]/list:hidden">
|
|
608
614
|
{status}
|
|
@@ -840,13 +846,18 @@ export function ListRow({
|
|
|
840
846
|
<span className="flex shrink-0 items-center">{keptLeadParts}</span>
|
|
841
847
|
) : null}
|
|
842
848
|
{restLineParts.length > 0 ? (
|
|
849
|
+
// One line tall and wrapping: a part with no room for a few
|
|
850
|
+
// letters wraps onto the clipped second line and disappears
|
|
851
|
+
// whole, instead of staying behind as a lone dot. The empty
|
|
852
|
+
// first item lets even the first part wrap away.
|
|
843
853
|
<span
|
|
844
854
|
className={cn(
|
|
845
|
-
"flex min-w-0 shrink-[2] items-center overflow-hidden",
|
|
855
|
+
"flex h-4.5 min-w-0 shrink-[2] flex-wrap content-start items-center overflow-hidden",
|
|
846
856
|
// No description: drop the first part's leading dot.
|
|
847
857
|
!(secondary && !(disabled && disabledReason)) && "-ml-4",
|
|
848
858
|
)}
|
|
849
859
|
>
|
|
860
|
+
<span aria-hidden="true" className="h-4.5 w-0 shrink-0" />
|
|
850
861
|
{restLineParts}
|
|
851
862
|
</span>
|
|
852
863
|
) : null}
|
|
@@ -1018,6 +1029,7 @@ function MetaPart({
|
|
|
1018
1029
|
hidden = false,
|
|
1019
1030
|
order = 0,
|
|
1020
1031
|
keep = false,
|
|
1032
|
+
oneLine = false,
|
|
1021
1033
|
}: {
|
|
1022
1034
|
className?: string | undefined;
|
|
1023
1035
|
children: ReactNode;
|
|
@@ -1027,13 +1039,29 @@ function MetaPart({
|
|
|
1027
1039
|
order?: number | undefined;
|
|
1028
1040
|
/** Never shrinks (a status): it stays whole while the facts before it give way. */
|
|
1029
1041
|
keep?: boolean | undefined;
|
|
1042
|
+
/**
|
|
1043
|
+
* On a one-line meta line (which wraps into a clipped second line): the part
|
|
1044
|
+
* claims room for its dot and a few letters, then takes what is left in
|
|
1045
|
+
* order. One without even that much wraps away whole.
|
|
1046
|
+
*/
|
|
1047
|
+
oneLine?: boolean | undefined;
|
|
1030
1048
|
}) {
|
|
1049
|
+
const sizing: CSSProperties = keep
|
|
1050
|
+
? { flexShrink: 0 }
|
|
1051
|
+
: oneLine
|
|
1052
|
+
? // Earlier parts fill to their full width before later ones grow past
|
|
1053
|
+
// their few letters, so the line still gives way from the end.
|
|
1054
|
+
{ flexBasis: "3.5rem", flexGrow: 64 ** (4 - Math.min(order, 4)), flexShrink: 0 }
|
|
1055
|
+
: { flexShrink: 64 ** Math.min(order, 4) };
|
|
1031
1056
|
return (
|
|
1032
1057
|
<span
|
|
1033
1058
|
aria-hidden={hidden || undefined}
|
|
1034
|
-
style={
|
|
1059
|
+
style={sizing}
|
|
1035
1060
|
className={cn(
|
|
1036
|
-
"flex
|
|
1061
|
+
"flex min-w-0 items-center overflow-hidden whitespace-nowrap",
|
|
1062
|
+
// max-content caps the growth; the 3.5rem basis is the most a part
|
|
1063
|
+
// asks for before it fits, so a short fact never gains empty space.
|
|
1064
|
+
oneLine && !keep ? "max-w-max" : "max-w-full",
|
|
1037
1065
|
className,
|
|
1038
1066
|
)}
|
|
1039
1067
|
>
|
package/styles/compiled.css
CHANGED
|
@@ -2177,6 +2177,9 @@
|
|
|
2177
2177
|
:where(.og-root).max-w-lg,:where(.og-root) .max-w-lg {
|
|
2178
2178
|
max-width: var(--container-lg);
|
|
2179
2179
|
}
|
|
2180
|
+
:where(.og-root).max-w-max,:where(.og-root) .max-w-max {
|
|
2181
|
+
max-width: max-content;
|
|
2182
|
+
}
|
|
2180
2183
|
:where(.og-root).max-w-md,:where(.og-root) .max-w-md {
|
|
2181
2184
|
max-width: var(--container-md);
|
|
2182
2185
|
}
|
|
@@ -2581,6 +2584,9 @@
|
|
|
2581
2584
|
:where(.og-root).content-center,:where(.og-root) .content-center {
|
|
2582
2585
|
align-content: center;
|
|
2583
2586
|
}
|
|
2587
|
+
:where(.og-root).content-start,:where(.og-root) .content-start {
|
|
2588
|
+
align-content: flex-start;
|
|
2589
|
+
}
|
|
2584
2590
|
:where(.og-root).items-baseline,:where(.og-root) .items-baseline {
|
|
2585
2591
|
align-items: baseline;
|
|
2586
2592
|
}
|
|
@@ -6589,6 +6595,13 @@
|
|
|
6589
6595
|
padding-bottom: calc(var(--spacing) * 0);
|
|
6590
6596
|
}
|
|
6591
6597
|
}
|
|
6598
|
+
:where(.og-root).odd\:last\:col-span-2,:where(.og-root) .odd\:last\:col-span-2 {
|
|
6599
|
+
&:nth-child(odd) {
|
|
6600
|
+
&:last-child {
|
|
6601
|
+
grid-column: span 2 / span 2;
|
|
6602
|
+
}
|
|
6603
|
+
}
|
|
6604
|
+
}
|
|
6592
6605
|
:where(.og-root).open\:basis-full,:where(.og-root) .open\:basis-full {
|
|
6593
6606
|
&:is([open], :popover-open, :open) {
|
|
6594
6607
|
flex-basis: 100%;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { SessionEvent } from "@opengeni/sdk";
|
|
2
|
-
export declare function CodexAccountIndicator({ workspaceId: _workspaceId, sessionId, model, modelReady, events, }: {
|
|
3
|
-
workspaceId: string;
|
|
4
|
-
sessionId: string;
|
|
5
|
-
model: string;
|
|
6
|
-
/** False while the session's admitted model identity is still loading. */
|
|
7
|
-
modelReady?: boolean;
|
|
8
|
-
events?: SessionEvent[];
|
|
9
|
-
}): import("react").JSX.Element | null;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { SessionEvent } from "@opengeni/sdk";
|
|
2
|
-
export declare function ModelAccountIndicator({ workspaceId, sessionId, organizationId, provider, servingTurnId, events, }: {
|
|
3
|
-
workspaceId: string;
|
|
4
|
-
sessionId: string;
|
|
5
|
-
organizationId: string | null;
|
|
6
|
-
/** The session model's subscription provider; only its accounts are offered. */
|
|
7
|
-
provider: string;
|
|
8
|
-
servingTurnId?: string | undefined;
|
|
9
|
-
events?: SessionEvent[];
|
|
10
|
-
}): import("react").JSX.Element | null;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import {
|
|
3
|
-
ModelAccountIndicator
|
|
4
|
-
} from "../../../chunk-HCCSAECI.js";
|
|
5
|
-
import "../../../chunk-M77ZQE5T.js";
|
|
6
|
-
import "../../../chunk-3SMJ2BIQ.js";
|
|
7
|
-
import "../../../chunk-M7YEZR6X.js";
|
|
8
|
-
import "../../../chunk-Z63GB7JI.js";
|
|
9
|
-
import "../../../chunk-A3MTTRCX.js";
|
|
10
|
-
import "../../../chunk-TREHTIBD.js";
|
|
11
|
-
import "../../../chunk-5OTQA7CM.js";
|
|
12
|
-
import "../../../chunk-BMJTNPWK.js";
|
|
13
|
-
import "../../../chunk-CKA4SJRK.js";
|
|
14
|
-
import "../../../chunk-NLAFNMPK.js";
|
|
15
|
-
import "../../../chunk-RZLBICR5.js";
|
|
16
|
-
import "../../../chunk-IGVL3ELX.js";
|
|
17
|
-
import "../../../chunk-ZWACUOU5.js";
|
|
18
|
-
import "../../../chunk-PNNTR6KP.js";
|
|
19
|
-
import "../../../chunk-WJPMYXKZ.js";
|
|
20
|
-
import "../../../chunk-VYT4POBH.js";
|
|
21
|
-
import "../../../chunk-IQ64BNAG.js";
|
|
22
|
-
import "../../../chunk-J3BHDXQQ.js";
|
|
23
|
-
import "../../../chunk-CFEFYPNR.js";
|
|
24
|
-
import "../../../chunk-N7S72EXK.js";
|
|
25
|
-
import "../../../chunk-XEA5BCMA.js";
|
|
26
|
-
import "../../../chunk-2KO2G3RI.js";
|
|
27
|
-
import "../../../chunk-CM7LVUKC.js";
|
|
28
|
-
import "../../../chunk-TVQCDDSZ.js";
|
|
29
|
-
import "../../../chunk-TXS65BB2.js";
|
|
30
|
-
import "../../../chunk-S6WJ6TUT.js";
|
|
31
|
-
export {
|
|
32
|
-
ModelAccountIndicator
|
|
33
|
-
};
|
|
34
|
-
//# sourceMappingURL=model-account-indicator.js.map
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ModelAccountUsageSnapshot } from "@opengeni/sdk";
|
|
2
|
-
import type { SubscriptionAccountUsageWindow } from "./subscription-account-menu.js";
|
|
3
|
-
export declare function modelAccountUsage(usage: ModelAccountUsageSnapshot | null | undefined, now?: number): {
|
|
4
|
-
windows?: SubscriptionAccountUsageWindow[];
|
|
5
|
-
message?: string;
|
|
6
|
-
note?: string;
|
|
7
|
-
summary?: string;
|
|
8
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/model-policy-picker-menu.tsx"],"sourcesContent":["import type { ClientModel, LatencyMode, ReasoningEffort } from \"@opengeni/sdk\";\nimport { ArrowRightIcon, CheckIcon, SearchIcon, ZapIcon } from \"lucide-react\";\nimport { useRef, useState, type RefObject, type CSSProperties } from \"react\";\nimport { Popover, RadioGroup } from \"radix-ui\";\nimport { containedPortal } from \"../ui/portal-container\";\nimport { cn } from \"../lib/cn\";\nimport {\n MENU_CHECK_CLASS,\n MENU_LABEL_CLASS,\n MENU_NOTE_CLASS,\n MENU_SURFACE_CLASS,\n} from \"../lib/menu-styles\";\nimport { labelReasoningEffort, type PickerModelRow } from \"../model-policy\";\nimport {\n compactEffortLabel,\n groupPresentationFor,\n modelPickerChoice,\n modelPickerMenuView,\n} from \"../model-picker-model\";\nimport {\n BillingClassMark,\n defaultModelPolicyPickerMessages,\n PickerNavRow,\n type ModelPolicyPickerProps,\n} from \"./model-policy-picker\";\nimport { ModelMark } from \"./model-mark\";\nimport { useOpenGeniText, type OpenGeniText } from \"../messages/runtime\";\n\nconst PopoverContainedPortal = containedPortal(Popover.Portal);\ntype ClientPickerModelRow = PickerModelRow<ClientModel>;\n\n/** Model selection stays flat; reasoning never becomes a navigation destination. */\nexport function ModelPolicyPickerMenu(props: ModelPolicyPickerProps) {\n const t = useOpenGeniText();\n const [query, setQuery] = useState(\"\");\n const view = modelPickerMenuView(t, props, query);\n const { messages, rows, groups } = view;\n const selected = view.selected;\n const choose = (row: ClientPickerModelRow) => {\n if (props.disabled) return;\n const choice = modelPickerChoice(props, row);\n if (!choice) return;\n if (choice.model !== null) props.onModelChange(choice.model);\n // Hosts may commit the combined model/effort draft through this callback.\n props.onEffortChange(choice.effort);\n if (choice.latencyMode !== null) props.onLatencyModeChange(choice.latencyMode);\n };\n const modelRow = (row: ClientPickerModelRow) => (\n <PickerNavRow\n key={row.id}\n icon={\n props.collapseScopes === false ? undefined : (\n <ModelMark model={row.catalog} className=\"size-4 text-og-fg-muted\" />\n )\n }\n label={row.label}\n hint={row.unavailableReason ?? row.fundingHint}\n disabled={props.disabled || !row.selectable}\n title={[row.label, row.unavailableReason ?? row.fundingHint].filter(Boolean).join(\" · \")}\n active={row.selectable && row.id === props.model}\n showChevron={false}\n trailing={\n row.catalog.cost === \"free\" || row.id === props.model ? (\n <span className=\"flex items-center gap-2\">\n {row.catalog.cost === \"free\" ? (\n <span className=\"rounded-full bg-og-surface-2 px-1.5 py-0.5 text-og-control text-og-fg-muted\">\n {messages.free}\n </span>\n ) : null}\n {row.id === props.model ? (\n <CheckIcon className={MENU_CHECK_CLASS} aria-label={messages.selected} />\n ) : null}\n </span>\n ) : null\n }\n testId={`model-picker-choice-${row.id}`}\n onClick={() => choose(row)}\n />\n );\n return (\n <div\n data-testid=\"model-picker-menu\"\n className=\"flex min-h-0 flex-col\"\n onKeyDown={(event) => {\n if (\n !(event.target instanceof HTMLButtonElement) ||\n ![\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"].includes(event.key)\n )\n return;\n const buttons = Array.from(\n event.currentTarget.querySelectorAll<HTMLButtonElement>(\n '[data-testid^=\"model-picker-choice-\"]:not(:disabled)',\n ),\n );\n const index = buttons.indexOf(event.target);\n if (index < 0) return;\n event.preventDefault();\n const next =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? buttons.length - 1\n : (index + (event.key === \"ArrowDown\" ? 1 : -1) + buttons.length) % buttons.length;\n buttons[next]?.focus();\n }}\n >\n {rows.some((row) => row.selectable) ? (\n <div className=\"border-b border-og-border py-1\">\n <label className=\"og-model-policy-search flex items-center gap-2 px-2.5 py-0.5\">\n <SearchIcon className=\"size-4 shrink-0 text-og-fg-subtle\" aria-hidden />\n <input\n aria-label={messages.searchLabel}\n placeholder={messages.searchPlaceholder}\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={(event) => {\n if (event.key !== \"Escape\" && event.key !== \"Tab\") event.stopPropagation();\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n event.currentTarget\n .closest('[data-testid=\"model-picker-menu\"]')\n ?.querySelector<HTMLButtonElement>(\"button:not(:disabled)\")\n ?.focus();\n }\n }}\n className=\"og-model-policy-search-input h-8 min-w-0 flex-1 bg-transparent text-og-menu text-og-fg outline-hidden placeholder:text-og-fg-subtle\"\n />\n </label>\n </div>\n ) : null}\n {props.error ? (\n <p className={cn(MENU_NOTE_CLASS, \"text-og-sm text-og-status-failed\")} role=\"alert\">\n {props.error}\n </p>\n ) : null}\n <div\n className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain py-1\"\n data-testid=\"model-picker-models\"\n >\n {props.loading ? (\n // Rows at the menu's row height, never a sentence, so nothing jumps.\n <div role=\"status\" aria-label={messages.loading}>\n {[58, 44, 66, 50].map((width) => (\n <div key={width} aria-hidden=\"true\" className=\"flex h-8 items-center gap-3 px-2.5\">\n <span className=\"size-4 shrink-0 animate-pulse rounded bg-og-surface-2\" />\n <span\n className=\"h-2.5 animate-pulse rounded bg-og-surface-2\"\n style={{ width: `${width}%` }}\n />\n </div>\n ))}\n </div>\n ) : rows.some((row) => row.selectable) ? (\n <>\n {groups.map((group) => (\n <section\n key={group.billingClass}\n aria-label={group.label}\n className=\"[&+section]:mt-1.5 [&+section]:border-t [&+section]:border-og-border [&+section]:pt-1.5\"\n >\n <div className={cn(MENU_LABEL_CLASS, \"flex items-center gap-2\")}>\n <BillingClassMark\n billingClass={group.billingClass}\n presentation={groupPresentationFor(props, group.billingClass)}\n aria-label=\"\"\n />\n <span className=\"min-w-0 break-words\">{group.label}</span>\n </div>\n {group.description ? (\n <p className=\"break-words px-2.5 pb-1 text-og-sm text-og-fg-muted\">\n {group.description}\n </p>\n ) : null}\n {group.rows.map(modelRow)}\n </section>\n ))}\n {view.matchCount === 0 ? (\n <p className={MENU_NOTE_CLASS}>\n {view.searching ? messages.noMatches : messages.noModels}\n </p>\n ) : null}\n </>\n ) : props.connectModelsHref || rows.length > 0 ? (\n <ConnectModelsPanel href={props.connectModelsHref} messages={messages} />\n ) : (\n <p className={MENU_NOTE_CLASS}>{messages.noModels}</p>\n )}\n </div>\n {view.anySelectable &&\n selected &&\n (view.unsupportedAttachments || (props.allowModelOptions !== false && view.thinking)) ? (\n <div className=\"border-t border-og-border px-2.5 py-2.5\">\n {view.unsupportedAttachments ? (\n <p className=\"pb-1.5 text-og-control leading-relaxed text-og-fg-subtle\">\n {messages.unsupportedAttachments}\n </p>\n ) : null}\n {props.allowModelOptions !== false ? <ModelThinkingControls {...props} /> : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nconst CONNECT_MODEL_OPTIONS = (\n t: OpenGeniText,\n): Array<{\n billingClass: \"codex_subscription\" | \"supergrok_subscription\" | \"byok\" | \"external\";\n title: string;\n detail: string;\n}> => [\n {\n billingClass: \"codex_subscription\",\n title: t(\"modelPolicyPickerMenu.codex\"),\n detail: \"ChatGPT\",\n },\n { billingClass: \"supergrok_subscription\", title: \"SuperGrok\", detail: \"xAI\" },\n {\n billingClass: \"byok\",\n title: t(\"modelPolicyPickerMenu.aiGateway\"),\n detail: t(\"modelPolicyPickerMenu.vercel\"),\n },\n { billingClass: \"external\", title: \"OpenRouter\", detail: t(\"modelPolicyPickerMenu.apiKey\") },\n];\n\nfunction ConnectModelsPanel(props: {\n href: string | undefined;\n messages: ReturnType<typeof defaultModelPolicyPickerMessages>;\n}) {\n const t = useOpenGeniText();\n return (\n <div className=\"px-1.5 pb-1.5 pt-2\" data-testid=\"model-picker-connect\">\n <div className=\"px-1.5 pb-3\">\n <p className=\"text-og-menu font-medium tracking-tight text-og-fg\">\n {props.messages.connectTitle}\n </p>\n <p className=\"mt-1 text-og-control leading-snug text-og-fg-subtle\">\n {props.messages.connectBody}\n </p>\n </div>\n <div className=\"grid grid-cols-2 gap-1\">\n {CONNECT_MODEL_OPTIONS(t).map((option) => {\n const content = (\n <>\n <span className=\"flex size-8 shrink-0 items-center justify-center rounded-og-md bg-og-surface-2 text-og-fg\">\n <BillingClassMark\n billingClass={option.billingClass}\n aria-label=\"\"\n className=\"size-4 text-og-fg\"\n />\n </span>\n <span className=\"min-w-0\">\n <span className=\"block truncate text-og-control font-medium text-og-fg\">\n {option.title}\n </span>\n <span className=\"block truncate text-og-control text-og-fg-subtle\">\n {option.detail}\n </span>\n </span>\n </>\n );\n const className =\n \"flex min-w-0 items-center gap-2 rounded-og-md px-1.5 py-1.5 outline-hidden transition-colors hover:bg-og-hover focus-visible:ring-2 focus-visible:ring-og-accent/40\";\n return props.href ? (\n <a key={option.title} href={props.href} className={className}>\n {content}\n </a>\n ) : (\n <div key={option.title} className={className}>\n {content}\n </div>\n );\n })}\n </div>\n {props.href ? (\n <a\n href={props.href}\n className=\"mt-2 flex h-9 w-full items-center justify-center gap-1.5 rounded-og-md border border-og-primary-border bg-og-primary text-og-primary-fg hover:bg-og-primary-hover text-og-control font-medium outline-hidden transition-colors focus-visible:ring-2 focus-visible:ring-og-accent/40\"\n >\n {props.messages.connectAction}\n <ArrowRightIcon className=\"size-3.5\" aria-hidden />\n </a>\n ) : (\n <p className=\"px-1.5 pt-3 text-og-control text-og-fg-subtle\">{props.messages.noModels}</p>\n )}\n </div>\n );\n}\n\nfunction ModelThinkingControls(props: ModelPolicyPickerProps) {\n const t = useOpenGeniText();\n const view = modelPickerMenuView(t, props, \"\");\n const thinking = view.thinking;\n if (!view.selected || !thinking) return null;\n const messages = view.messages;\n const efforts = thinking.efforts;\n const showThinking = thinking.showThinking;\n const showFast = thinking.showFast;\n const speeds = thinking.speeds;\n const selectedSpeed = speeds?.find((speed) => speed.id === props.latencyMode) ?? speeds?.[0];\n return (\n <div className=\"space-y-2 text-og-control\" data-testid=\"model-picker-reasoning\">\n {showThinking || showFast ? (\n <div className=\"flex min-h-7 items-center justify-between gap-3\">\n {showThinking ? <span className=\"text-og-fg-subtle\">{messages.thinking}</span> : <span />}\n {showFast ? (\n <button\n type=\"button\"\n data-testid=\"model-picker-fast\"\n disabled={props.disabled || thinking.disabled}\n aria-pressed={props.latencyMode === \"fast\"}\n title={messages.fast + \" · \" + messages.fastRateHint}\n onClick={() =>\n props.onLatencyModeChange(props.latencyMode === \"fast\" ? \"standard\" : \"fast\")\n }\n className=\"flex min-h-8 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-og-sm px-2 text-og-fg-muted hover:bg-og-hover focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:opacity-50\"\n >\n <ZapIcon className={cn(\"size-3.5\", props.latencyMode === \"fast\" && \"fill-current\")} />\n {messages.fast}\n <span className=\"text-og-fg-subtle\">{messages.fastRateHint}</span>\n </button>\n ) : null}\n </div>\n ) : null}\n {showThinking ? (\n <RadioGroup.Root\n aria-label={messages.thinkingEffort}\n value={thinking.value}\n disabled={props.disabled || thinking.disabled}\n onValueChange={(value) => props.onEffortChange(value as ReasoningEffort)}\n orientation=\"horizontal\"\n className=\"flex flex-wrap gap-0.5 rounded-og-md bg-og-surface-2 p-0.5\"\n >\n {efforts.map((effort) => (\n <RadioGroup.Item\n key={effort}\n value={effort}\n aria-label={labelReasoningEffort(t, effort)}\n title={labelReasoningEffort(t, effort)}\n className=\"min-h-8 min-w-10 flex-1 cursor-pointer whitespace-nowrap rounded-og-sm px-1.5 text-og-control text-og-fg-muted outline-hidden transition-colors hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent/40 data-[state=checked]:bg-og-surface-1 data-[state=checked]:text-og-fg data-[state=checked]:shadow-sm disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {compactEffortLabel(t, effort, labelReasoningEffort(t, effort))}\n </RadioGroup.Item>\n ))}\n </RadioGroup.Root>\n ) : null}\n {speeds && selectedSpeed ? (\n <div className=\"space-y-2 pt-1\" data-testid=\"model-picker-speed\">\n <div className=\"flex min-h-7 items-center justify-between gap-3\">\n <span className=\"text-og-fg-subtle\">{messages.speed}</span>\n {selectedSpeed.hint ? (\n <span className=\"text-og-fg-subtle\">{selectedSpeed.hint}</span>\n ) : null}\n </div>\n <RadioGroup.Root\n aria-label={messages.speed}\n value={selectedSpeed.id}\n disabled={props.disabled || thinking.disabled}\n onValueChange={(value) => props.onLatencyModeChange(value as LatencyMode)}\n orientation=\"horizontal\"\n className=\"flex flex-wrap gap-0.5 rounded-og-md bg-og-surface-2 p-0.5\"\n >\n {speeds.map((speed) => (\n <RadioGroup.Item\n key={speed.id}\n value={speed.id}\n aria-label={speed.hint ? `${speed.label} · ${speed.hint}` : speed.label}\n title={speed.hint ? `${speed.label} · ${speed.hint}` : speed.label}\n className=\"flex min-h-8 min-w-10 flex-1 cursor-pointer items-center justify-center gap-1 whitespace-nowrap rounded-og-sm px-1.5 text-og-control text-og-fg-muted outline-hidden transition-colors hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent/40 data-[state=checked]:bg-og-surface-1 data-[state=checked]:text-og-fg data-[state=checked]:shadow-sm disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {speed.id === \"standard\" ? null : (\n <ZapIcon\n aria-hidden\n className={cn(\n \"size-3.5 shrink-0\",\n speed.id === selectedSpeed.id && \"fill-current\",\n )}\n />\n )}\n {speed.label}\n </RadioGroup.Item>\n ))}\n </RadioGroup.Root>\n </div>\n ) : null}\n </div>\n );\n}\n\nexport function ModelPolicyPickerPopover(\n props: ModelPolicyPickerProps & {\n anchor: RefObject<HTMLButtonElement | null>;\n contentId: string;\n portalStyle: CSSProperties;\n },\n) {\n const t = useOpenGeniText();\n const outside = useRef(false);\n const messages = { ...defaultModelPolicyPickerMessages(t), ...props.messages };\n return (\n <Popover.Root open onOpenChange={(open) => props.onOpenChange?.(open)}>\n <Popover.Anchor virtualRef={props.anchor} />\n <PopoverContainedPortal>\n <Popover.Content\n id={props.contentId}\n aria-label={messages.label}\n align=\"start\"\n side={props.menuSide ?? \"bottom\"}\n sideOffset={8}\n collisionPadding={12}\n onInteractOutside={(event) => {\n if (props.anchor.current?.contains(event.target as Node)) event.preventDefault();\n else outside.current = true;\n }}\n onCloseAutoFocus={(event) => {\n event.preventDefault();\n if (!outside.current) props.anchor.current?.focus();\n }}\n className={cn(\n MENU_SURFACE_CLASS,\n \"og-root og-model-policy-menu z-50 flex max-h-[min(32rem,var(--radix-popover-content-available-height))] w-[22rem] max-w-[calc(100vw-16px)] flex-col overflow-hidden p-[var(--og-model-picker-menu-padding)]\",\n props.contentClassName,\n )}\n style={{ ...props.portalStyle, ...props.contentStyle }}\n data-testid=\"model-picker-content\"\n >\n <ModelPolicyPickerMenu {...props} />\n </Popover.Content>\n </PopoverContainedPortal>\n </Popover.Root>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/app/components/session/subscription-account-menu.tsx"],"sourcesContent":["// Shared presentation extracted from the Codex subscription-account dropdown.\n// Adapters own loading, authorization, usage freshness, and selection semantics.\nimport { ChevronDownIcon, Loader2Icon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport {\n DropdownMenu,\n DropdownMenuCheck,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuMeta,\n DropdownMenuNote,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../../../ui/dropdown-menu\";\nimport { cn } from \"../../lib/utils\";\n\nexport type SubscriptionAccountMenuRow = {\n id: string;\n label: string;\n plan?: string | null | undefined;\n status?: string | null;\n detail?: string;\n personal?: boolean;\n disabled?: boolean;\n /** Only supplied when the adapter has a trustworthy quota reading. */\n remaining?: number | null;\n /** Cached window readings, not an aggregate capacity/eligibility estimate. */\n usageSummary?: string | undefined;\n};\n\nexport type SubscriptionAccountUsageWindow = {\n label: string;\n remaining?: number;\n usedPercent?: number | null;\n detail?: string;\n};\n\nfunction UsageRow({ label, remaining, usedPercent, detail }: SubscriptionAccountUsageWindow) {\n const value = remaining ?? usedPercent;\n const known = typeof value === \"number\" && Number.isFinite(value);\n const pct = known ? Math.min(100, Math.max(0, value)) : 0;\n const measure = remaining !== undefined ? \"remaining\" : \"used\";\n const text = known ? `${Math.round(value)}% ${measure}` : \"Unknown\";\n return (\n <div className=\"space-y-0.5 text-2xs text-fg-subtle\">\n <div className=\"flex items-center gap-2\">\n <span className=\"max-w-28 min-w-10 shrink-0 truncate\" title={label}>\n {label}\n </span>\n {known ? (\n <span\n className=\"h-1 min-w-0 flex-1 overflow-hidden rounded-full bg-surface-2\"\n role=\"progressbar\"\n aria-label={`${label} ${measure}`}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={pct}\n aria-valuetext={text}\n >\n <span\n className={cn(\n \"block h-full rounded-full\",\n (measure === \"remaining\" ? pct <= 10 : pct >= 90)\n ? \"bg-status-waiting\"\n : \"bg-brand\",\n )}\n style={{ width: `${pct}%` }}\n />\n </span>\n ) : (\n <span className=\"flex-1\" />\n )}\n <span className=\"shrink-0 whitespace-nowrap text-right tabular-nums\">{text}</span>\n </div>\n {detail ? <p>{detail}</p> : null}\n </div>\n );\n}\n\nfunction MiniBar({ remaining }: { remaining: number }) {\n const pct = Math.min(100, Math.max(0, remaining));\n return (\n <span\n className=\"inline-flex shrink-0 items-center gap-1.5 text-2xs text-fg-subtle\"\n title={`${Math.round(pct)}% remaining in the tighter usage window`}\n >\n <span className=\"h-1 w-8 overflow-hidden rounded-full bg-surface-2\" aria-hidden=\"true\">\n <span\n className={cn(\"block h-full rounded-full\", pct <= 10 ? \"bg-status-waiting\" : \"bg-brand\")}\n style={{ width: `${pct}%` }}\n />\n </span>\n <span className=\"whitespace-nowrap tabular-nums\">{Math.round(pct)}% remaining</span>\n </span>\n );\n}\n\nexport function SubscriptionAccountMenu({\n ariaLabel,\n triggerMark,\n headerMark,\n selectionLabel,\n displayName,\n metadata,\n identity,\n tone = \"ok\",\n usage,\n accounts,\n selectedId,\n automaticSelected,\n choosing,\n choosingTarget,\n actionLabel = \"Use for next turn\",\n automaticLabel = \"Automatic\",\n emptyMessage,\n error,\n note,\n onOpenChange,\n onChoose,\n}: {\n ariaLabel: string;\n triggerMark: ReactNode;\n headerMark: ReactNode;\n selectionLabel: string;\n displayName: string;\n metadata: string;\n identity?: string | null | undefined;\n tone?: \"ok\" | \"warn\" | \"bad\" | undefined;\n usage: {\n checking?: boolean | undefined;\n unavailable?: boolean | undefined;\n message?: string | undefined;\n note?: string | undefined;\n windows?: SubscriptionAccountUsageWindow[] | undefined;\n };\n accounts: SubscriptionAccountMenuRow[];\n selectedId: string | null;\n automaticSelected: boolean;\n choosing: boolean;\n choosingTarget: string | null | undefined;\n actionLabel?: string | undefined;\n automaticLabel?: string | undefined;\n emptyMessage?: string | undefined;\n error?: string | null | undefined;\n note: string;\n onOpenChange?: ((open: boolean) => void) | undefined;\n onChoose: (connectionId: string | null) => void;\n}) {\n const row = (account: SubscriptionAccountMenuRow) => (\n <DropdownMenuItem\n key={account.id}\n disabled={choosing || account.disabled}\n title={account.detail}\n onSelect={(event) => {\n event.preventDefault();\n onChoose(account.id);\n }}\n className=\"cursor-pointer\"\n >\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate\">{account.label}</span>\n {account.usageSummary ? (\n <span className=\"block truncate text-2xs text-fg-subtle\" title={account.usageSummary}>\n {account.usageSummary}\n </span>\n ) : null}\n </span>\n {account.plan ? <DropdownMenuMeta>{account.plan}</DropdownMenuMeta> : null}\n {account.remaining != null ? <MiniBar remaining={account.remaining} /> : null}\n {account.status ? (\n <span className=\"shrink-0 text-xs text-status-waiting\">{account.status}</span>\n ) : null}\n {choosingTarget === account.id ? (\n <Loader2Icon className=\"size-4 shrink-0 animate-spin\" />\n ) : (\n <DropdownMenuCheck checked={account.id === selectedId} className=\"ml-0\" />\n )}\n </DropdownMenuItem>\n );\n const personal = accounts.filter((account) => account.personal);\n return (\n <DropdownMenu {...(onOpenChange ? { onOpenChange } : {})}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n aria-label={ariaLabel}\n title={ariaLabel}\n className={cn(\n \"group/account relative inline-flex h-6 shrink-0 cursor-pointer items-center gap-0.5 rounded-full border border-border/70 bg-surface-2/50 px-1.5 text-fg-muted outline-hidden transition-[background-color,border-color,color] hover:border-border hover:bg-surface-2 hover:text-fg focus-visible:ring-1 focus-visible:ring-ring/40 data-[state=open]:border-border data-[state=open]:bg-surface-2 data-[state=open]:text-fg\",\n choosing && \"opacity-60\",\n )}\n >\n {triggerMark}\n {choosing ? (\n <Loader2Icon className=\"size-2.5 animate-spin text-current\" aria-hidden />\n ) : (\n <ChevronDownIcon\n className=\"size-2.5 shrink-0 opacity-70 transition-opacity group-hover/account:opacity-100\"\n aria-hidden\n />\n )}\n {tone !== \"ok\" ? (\n <span\n className={cn(\n \"absolute -top-0.5 -right-0.5 size-1.5 rounded-full ring-1 ring-surface\",\n tone === \"bad\" ? \"bg-destructive\" : \"bg-status-waiting\",\n )}\n aria-hidden\n />\n ) : null}\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"start\"\n side=\"bottom\"\n sideOffset={8}\n collisionPadding={12}\n className=\"flex max-h-[min(32rem,var(--radix-dropdown-menu-content-available-height))] w-72 flex-col overflow-hidden\"\n >\n <div className=\"shrink-0 space-y-2 px-2.5 pt-1.5 pb-2\">\n <div className=\"flex items-start gap-2\">\n <span className=\"mt-0.5 inline-flex size-7 shrink-0 items-center justify-center overflow-hidden rounded-md bg-surface-2 text-fg\">\n {headerMark}\n </span>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-2xs text-fg-subtle\">{selectionLabel}</p>\n <p className=\"truncate text-sm font-medium text-fg\">{displayName}</p>\n {identity ? (\n <p className=\"truncate text-2xs text-fg-subtle\" title={identity}>\n {identity}\n </p>\n ) : null}\n <p className=\"truncate text-2xs text-fg-subtle\" title={metadata}>\n {metadata}\n </p>\n </div>\n </div>\n {usage.checking ? (\n <p className=\"text-2xs text-fg-subtle\">Checking usage…</p>\n ) : usage.unavailable ? (\n <p className=\"text-2xs text-fg-subtle\">Usage unavailable</p>\n ) : usage.message ? (\n <p className=\"text-2xs text-fg-subtle\">{usage.message}</p>\n ) : (\n <div className=\"max-h-36 space-y-1.5 overflow-y-auto overscroll-contain\">\n {usage.windows?.map((window) => (\n <UsageRow key={window.label} {...window} />\n ))}\n </div>\n )}\n {usage.note ? <p className=\"text-2xs text-fg-subtle\">{usage.note}</p> : null}\n </div>\n <DropdownMenuSeparator className=\"shrink-0\" />\n <DropdownMenuLabel className=\"shrink-0\">{actionLabel}</DropdownMenuLabel>\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain\">\n <DropdownMenuItem\n disabled={choosing}\n onSelect={(event) => {\n event.preventDefault();\n onChoose(null);\n }}\n className=\"cursor-pointer\"\n >\n <span className=\"min-w-0 flex-1 truncate\">{automaticLabel}</span>\n {choosingTarget === null ? (\n <Loader2Icon className=\"size-4 shrink-0 animate-spin\" />\n ) : (\n <DropdownMenuCheck checked={automaticSelected} className=\"ml-0\" />\n )}\n </DropdownMenuItem>\n {accounts.filter((account) => !account.personal).map(row)}\n {personal.length > 0 ? (\n <>\n <DropdownMenuLabel className=\"pt-2\">Your accounts</DropdownMenuLabel>\n {personal.map(row)}\n </>\n ) : null}\n {accounts.length === 0 && emptyMessage ? (\n <DropdownMenuNote>{emptyMessage}</DropdownMenuNote>\n ) : null}\n {error ? (\n <DropdownMenuNote role=\"alert\" className=\"text-xs text-danger\">\n {error}\n </DropdownMenuNote>\n ) : (\n <p className=\"px-2.5 pt-1.5 pb-1 text-xs text-fg-muted\">{note}</p>\n )}\n </div>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":"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","names":[]}
|