@openhands/agent-canvas 1.17.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.windows.md +2 -2
- package/build/assets/{acp-providers-DrjNsPOH.js → acp-providers-DcY_mKYa.js} +1 -1
- package/build/assets/active-backend-context-BnH4-L8h.js +2 -0
- package/build/assets/{agent-context-settings-CJUrcBut.js → agent-context-settings-D3peZkjX.js} +1 -1
- package/build/assets/{agent-profiles-service.api-Biieml2L.js → agent-profiles-service.api-DkeZaqIl.js} +1 -1
- package/build/assets/agent-profiles-settings-7yMWYjGF.js +1 -0
- package/build/assets/agent-server-client-options-EHB23gyx.js +1 -0
- package/build/assets/agent-server-config-C_x8Otd9.js +1 -0
- package/build/assets/agent-server-conversation-service.api-jiCopc2E.js +88 -0
- package/build/assets/{agent-settings-CpY3zObk.js → agent-settings-BF8hM6wb.js} +1 -1
- package/build/assets/agent-settings-YPutBAeR.js +1 -0
- package/build/assets/alert-banner-eYyqvHL3.js +1 -0
- package/build/assets/{api-error-message-Ve79qDcN.js → api-error-message-BXo0lCI5.js} +1 -1
- package/build/assets/api-key-entry-screen-CCBvBD8u.js +1 -0
- package/build/assets/app-settings-BtYDs-Be.js +1 -0
- package/build/assets/automation-detail-BxXhb_m2.js +3 -0
- package/build/assets/{automation-export-DxY47m3T.js → automation-export-BJsfi7n2.js} +1 -1
- package/build/assets/automation-git-sync-B7o_Nbl-.js +1 -0
- package/build/assets/automation-setup-route-qaJ6lLCf.js +3 -0
- package/build/assets/{automation-templates-4C4PM8K7.js → automation-templates-Bb98r-kx.js} +1 -1
- package/build/assets/automations-list-DEPVNud3.js +1 -0
- package/build/assets/{back-nav-button-B8tH0BEp.js → back-nav-button-B2yBiVMB.js} +1 -1
- package/build/assets/backend-form-modal-DxisQV_6.js +1 -0
- package/build/assets/backend-synced-settings-badge-DLEp6cq7.js +1 -0
- package/build/assets/badge-ehL-kgeO.js +1 -0
- package/build/assets/{base-modal-DTULovNc.js → base-modal-C1a0TsSx.js} +1 -1
- package/build/assets/{bot-CLMxGFaq.js → bot-ByolqPEr.js} +1 -1
- package/build/assets/{brand-button-DxPO4Lf8.js → brand-button-CUMfjb99.js} +1 -1
- package/build/assets/{browser-C-_qBasq.js → browser-SE24Tk8g.js} +6 -6
- package/build/assets/browser-tab-HjJxHA0V.js +1 -0
- package/build/assets/canvas-extension-page-BsUGBb1T.js +1 -0
- package/build/assets/canvas-extensions-C9Tm6s_E.js +1 -0
- package/build/assets/{canvas-extensions-runtime-DdnkgJXV.js → canvas-extensions-runtime-B8kxM4rO.js} +1 -1
- package/build/assets/{chat-send-button-B3SFSIg5.js → chat-send-button-CGvc2wpE.js} +1 -1
- package/build/assets/check-Bo8s5Ylg.js +1 -0
- package/build/assets/chevron-down-Cr6Fn_wS.js +1 -0
- package/build/assets/chevron-right-CfdfRn-8.js +1 -0
- package/build/assets/circle-check-5pH3qCji.js +1 -0
- package/build/assets/circle-plus-check-toggle-BDX_ctNs.js +1 -0
- package/build/assets/{cloud-funnel-analytics-BQanUEEC.js → cloud-funnel-analytics-D5uJ_4JE.js} +1 -1
- package/build/assets/{cog-VBlRo6iw.js → cog-CAEugqtV.js} +1 -1
- package/build/assets/command-menu-CQxs4mtX.js +1 -0
- package/build/assets/commits-tab-D0xgjipP.js +1 -0
- package/build/assets/{condenser-settings-eVKFMvap.js → condenser-settings-D63NJRBT.js} +1 -1
- package/build/assets/confirmation-modal-78sd9Vny.js +1 -0
- package/build/assets/{context-menu-list-item-DDROe12Z.js → context-menu-list-item-Cm7-7Y-7.js} +1 -1
- package/build/assets/{conversation-BnjJSFf5.js → conversation-B_nweu5p.js} +8 -8
- package/build/assets/conversation-edjzrv5w.js +1 -0
- package/build/assets/conversation-panel-edjzrv5w.js +1 -0
- package/build/assets/conversation-state-store-9D_3P7q4.js +1 -0
- package/build/assets/conversation-store-DC-JlJuq.js +6 -0
- package/build/assets/{conversation-tab-empty-state-DKlzAz5c.js → conversation-tab-empty-state-B3dpJXX0.js} +1 -1
- package/build/assets/copy-to-clipboard-button-B1ljgNxO.js +1 -0
- package/build/assets/device-verify-D5QRIS_x.js +1 -0
- package/build/assets/{dropdown-classes-B9kJVDIk.js → dropdown-classes-BGvOvW2_.js} +1 -1
- package/build/assets/edit-automation-modal-D_JWSmxT.js +1 -0
- package/build/assets/empty-state-FK_s1B60.js +1 -0
- package/build/assets/{entry.client-Ds8LVp-E.js → entry.client-BMafTpjO.js} +2 -2
- package/build/assets/enum-filter-dropdown-UNaom12H.js +1 -0
- package/build/assets/environment-switch-overlay-COibRUA-.js +1 -0
- package/build/assets/error-state-Cf8LRuuY.js +1 -0
- package/build/assets/extensions-hub-C_6ahIua.js +1 -0
- package/build/assets/extensions-navigation-C5GfpzFe.js +1 -0
- package/build/assets/{external-link-DQtv7eTh.js → external-link-Bd7Tga-1.js} +1 -1
- package/build/assets/files-tab-D5PPIWI1.js +1 -0
- package/build/assets/{form-control-classes-B-z85REi.js → form-control-classes-Dbq-7YP_.js} +1 -1
- package/build/assets/format-model-name-Dfh9Udrx.js +1 -0
- package/build/assets/get-git-path-jU2zjqIB.js +1 -0
- package/build/assets/git-repo-dropdown-BoDDWXfX.js +1 -0
- package/build/assets/git-repo-dropdown-uxlFw2gn.js +1 -0
- package/build/assets/highlighted-source-view-C7pAXrT0.js +1 -0
- package/build/assets/home-BM5_Wz_R.js +1 -0
- package/build/assets/home-Ivfm7KC4.js +1 -0
- package/build/assets/home-automation-run-tooltip-B1N2uO9p.js +1 -0
- package/build/assets/home-store-DCbei3DX.js +1 -0
- package/build/assets/hooks-service-Dnmhqc0Z.js +1 -0
- package/build/assets/index-home-td9BN2T3.js +1 -0
- package/build/assets/info-BcajzHn1.js +1 -0
- package/build/assets/install-server-modal-B81I-5OE.js +1 -0
- package/build/assets/kebab-menu-item-content-SCJBwZnp.js +1 -0
- package/build/assets/{key-CfXbJa8w.js → key-O84CMFHb.js} +1 -1
- package/build/assets/launch-ZLxI4opd.js +1 -0
- package/build/assets/list-filter-B8PQk3RA.js +1 -0
- package/build/assets/{list-todo-ByXMdY4W.js → list-todo-Caa8E1X_.js} +1 -1
- package/build/assets/llm-not-configured-banner-Dh_ajcM8.js +27 -0
- package/build/assets/llm-settings-CODhjQzy.js +1 -0
- package/build/assets/llm-settings-CZaXYgtw.js +1 -0
- package/build/assets/{llm-subscription-service-aDNBQ7Gq.js → llm-subscription-service-CgIDc38n.js} +1 -1
- package/build/assets/loader-circle-BxJgk73D.js +1 -0
- package/build/assets/{loading-spinner-DfHI77BA.js → loading-spinner-BeLV0IXf.js} +1 -1
- package/build/assets/manage-backends-modal-cMXqCb-B.js +1 -0
- package/build/assets/manifest-bfeccb98.js +1 -0
- package/build/assets/manifest-subpage-layout-CVZgVKoY.js +1 -0
- package/build/assets/{map-provider-DXvssjw9.js → map-provider-iRs80q_6.js} +1 -1
- package/build/assets/markdown-renderer-DyFl9-mL.js +8 -0
- package/build/assets/mcp-CraxoXQv.js +1 -0
- package/build/assets/{mcp-marketplace-utils-Cn_NIMWM.js → mcp-marketplace-utils-C7PYr293.js} +1 -1
- package/build/assets/mcp-page-CteH_K0N.js +9 -0
- package/build/assets/messages-Bk1xhbU2.js +41 -0
- package/build/assets/{modal-body-DJw4xBki.js → modal-body-C24WsdFb.js} +1 -1
- package/build/assets/{modal-classes-Dg0ngBPO.js → modal-classes-B0b9eiL8.js} +1 -1
- package/build/assets/modal-close-button-DfqfB2Nj.js +1 -0
- package/build/assets/{mouse-pointer-click-DEhsSUpu.js → mouse-pointer-click-BXlRN92t.js} +1 -1
- package/build/assets/onboarding-DXFBRqEy.js +1 -0
- package/build/assets/onboarding-modal-BT3Gx_sZ.js +1 -0
- package/build/assets/{organization-service.api-Cyg1Tn03.js → organization-service.api-B5CvmnYQ.js} +1 -1
- package/build/assets/{pencil-D5c47kyN.js → pencil-q-ihqDYv.js} +1 -1
- package/build/assets/{pin-C7vMagvf.js → pin-BdroVQdN.js} +1 -1
- package/build/assets/planner-tab-CstoOlAB.js +1 -0
- package/build/assets/{plug-CeaqeF6u.js → plug-7ACOEbMs.js} +1 -1
- package/build/assets/{plugins-management-service-Bh_pBuf-.js → plugins-management-service-5rqVPEGN.js} +1 -1
- package/build/assets/plus-C2e21TFC.js +1 -0
- package/build/assets/{profiles-service.api-BbOK0EkF.js → profiles-service.api-D1XKMgr0.js} +1 -1
- package/build/assets/providers-XmZ9HM4Q.js +1 -0
- package/build/assets/proxy-XP6U1Dhv.js +1 -0
- package/build/assets/{puzzle-DdAqbUrb.js → puzzle-LJYnuxKe.js} +1 -1
- package/build/assets/react-BX7IV650.js +1 -0
- package/build/assets/recommended-automations-launcher-DEHRKIAg.js +1 -0
- package/build/assets/{refresh-cw-DEQdPCpH.js → refresh-cw-BtdC3T8P.js} +1 -1
- package/build/assets/root-CM6IZHlg.css +1 -0
- package/build/assets/root-DdFkodKW.js +2 -0
- package/build/assets/root-layout-DUquNZTU.js +2 -0
- package/build/assets/schema-field-Y3F8JvXd.js +1 -0
- package/build/assets/sdk-section-page-CNZTLwH9.js +1 -0
- package/build/assets/secret-form-9-BoGA40.js +1 -0
- package/build/assets/{secrets-service-Cr8g8xuv.js → secrets-service-BOIsfD9j.js} +1 -1
- package/build/assets/secrets-settings-CBJgFr42.js +1 -0
- package/build/assets/settings-D4hdToD4.js +1 -0
- package/build/assets/settings-dropdown-input-DBvsZ7-Q.js +1 -0
- package/build/assets/settings-index-DeQphyBK.js +1 -0
- package/build/assets/settings-input-dVuzapBA.js +1 -0
- package/build/assets/{settings-list-classes-Ds4jPBHK.js → settings-list-classes-DhAPuXm6.js} +1 -1
- package/build/assets/settings-modal-tHiJ8iYV.js +1 -0
- package/build/assets/settings-nav-GAQjW1a-.js +16 -0
- package/build/assets/{settings-service.api-9_xdv_mh.js → settings-service.api-C1vZH9Vh.js} +1 -1
- package/build/assets/settings-switch-DDd1cQ8t.js +1 -0
- package/build/assets/{settings-utils-8GIIgOQL.js → settings-utils-BTaaRhLZ.js} +1 -1
- package/build/assets/shared-conversation-Cyg7m7ns.js +1 -0
- package/build/assets/{shield-check-DO7wa_eu.js → shield-check-C3Rl0NF8.js} +1 -1
- package/build/assets/{sidebar-layout-EPfWxk11.js → sidebar-layout-DH0E-5KW.js} +1 -1
- package/build/assets/sidebar-mobile-menu-toggle-CQ4iky__.js +1 -0
- package/build/assets/{sidebar-nav-link-_t4_Ef-9.js → sidebar-nav-link-oLQiKUBu.js} +1 -1
- package/build/assets/{sidebar-onboarding-checklist-storage-DbDX-Wvj.js → sidebar-onboarding-checklist-storage-TfvNNnnr.js} +1 -1
- package/build/assets/sidebar-store-DAZVH-DR.js +1 -0
- package/build/assets/skill-card-pill-row-DfjIfj0K.js +1 -0
- package/build/assets/{skill-filter-BBeZ4JEP.js → skill-filter-DsNLmn76.js} +2 -2
- package/build/assets/{skill-icon-badge-BDhQ-tQ0.js → skill-icon-badge-0MK_68Nc.js} +1 -1
- package/build/assets/skill-scope-BE-H9TSZ.js +1 -0
- package/build/assets/skills-plugins-vzSdxSk_.js +1 -0
- package/build/assets/skills-settings-BiPOH9H9.js +1 -0
- package/build/assets/{styled-tooltip-Pd22BIvr.js → styled-tooltip-CejG0rqv.js} +1 -1
- package/build/assets/task-list-tab-OkZSqnTp.js +1 -0
- package/build/assets/{terminal-onXx0_Qz.js → terminal-Dph60VFZ.js} +1 -1
- package/build/assets/{toggle-switch-lwQtxDcm.js → toggle-switch-B2uXaAUS.js} +1 -1
- package/build/assets/{trash-2-ZhKuTLiz.js → trash-2-Bb40zQzs.js} +1 -1
- package/build/assets/trash-Ckh7yCaB.js +1 -0
- package/build/assets/{triangle-alert-BajLPpQg.js → triangle-alert-DEdu-b_L.js} +1 -1
- package/build/assets/{typography-HLLg_FAn.js → typography-DgcLGdHk.js} +1 -1
- package/build/assets/usage-tab-MCmNRAnR.js +1 -0
- package/build/assets/use-acp-credential-form-ychoGqjC.js +1 -0
- package/build/assets/{use-activate-agent-profile-BLKML6vQ.js → use-activate-agent-profile-8L8Xdghy.js} +1 -1
- package/build/assets/use-agent-profiles-Bi8hSkze.js +1 -0
- package/build/assets/{use-automation-health-BZkQNEA8.js → use-automation-health-U99vvHxx.js} +1 -1
- package/build/assets/{use-automation-permissions-B_RpvL-s.js → use-automation-permissions-Buus0R6h.js} +1 -1
- package/build/assets/{use-automations-Cg0PDIZr.js → use-automations-Bq5hVuv0.js} +1 -1
- package/build/assets/{use-can-manage-org-profiles-BbN6KfDr.js → use-can-manage-org-profiles-MzIeEV8F.js} +1 -1
- package/build/assets/{use-canvas-extensions-CFUpHat6.js → use-canvas-extensions-Ca9KoVEm.js} +1 -1
- package/build/assets/{use-cloud-current-user-id-Dk0rjr63.js → use-cloud-current-user-id-B4ZLUZSa.js} +1 -1
- package/build/assets/{use-config-DpafU_QP.js → use-config-l5tkDHyD.js} +1 -1
- package/build/assets/{use-create-conversation-1YgmAHt-.js → use-create-conversation-i_PdFdIs.js} +1 -1
- package/build/assets/use-create-secret-CjWq0J4O.js +1 -0
- package/build/assets/use-free-models-gCsJ5BV0.js +1 -0
- package/build/assets/{use-get-secrets-CQ4b0qK8.js → use-get-secrets-CMTuWEp_.js} +1 -1
- package/build/assets/use-is-authed-A2Yinlt0.js +1 -0
- package/build/assets/{use-launch-skill-in-chat-DeYa1tFM.js → use-launch-skill-in-chat-QbXDhiHr.js} +1 -1
- package/build/assets/use-llm-configured-Dl4zg8ht.js +1 -0
- package/build/assets/use-llm-profiles-SWsuFmFu.js +1 -0
- package/build/assets/{use-manifest-capabilities-AOWGcu0j.js → use-manifest-capabilities-CdqYfUAC.js} +1 -1
- package/build/assets/{use-onboarding-completion-CoINurkm.js → use-onboarding-completion-Xl63ZvzQ.js} +1 -1
- package/build/assets/{use-pinned-home-route-D6krwXjy.js → use-pinned-home-route-BXDIUaxQ.js} +1 -1
- package/build/assets/{use-plugins-marketplace-mLsIDhBv.js → use-plugins-marketplace-BIIaPiaB.js} +1 -1
- package/build/assets/use-save-agent-profile-D-ZHHE94.js +1 -0
- package/build/assets/{use-save-settings-3U5K9-8x.js → use-save-settings-Dapkf4cC.js} +1 -1
- package/build/assets/{use-settings-Dn00UISA.js → use-settings-C2KKQKVC.js} +1 -1
- package/build/assets/use-settings-nav-items-TOc0Rsfd.js +1 -0
- package/build/assets/{use-tracking-B9prBsrq.js → use-tracking-j4uo9VEW.js} +1 -1
- package/build/assets/{use-user-conversation-ZWlXtbZb.js → use-user-conversation-5UFqMoO4.js} +1 -1
- package/build/assets/{useInfiniteQuery-BzrRqjLg.js → useInfiniteQuery-CtSRG7uW.js} +1 -1
- package/build/assets/{useMutation-CJuK90oc.js → useMutation-Cszf8mKy.js} +1 -1
- package/build/assets/useQueries-pUohFMSP.js +1 -0
- package/build/assets/useQuery-DAAacS7O.js +1 -0
- package/build/assets/useTranslation-CCgUjPJF.js +1 -0
- package/build/assets/utils-BgLSZdyy.js +1 -0
- package/build/assets/{vendor~conversation-panel~conversation-4eJ0tml3.js → vendor~conversation-panel~conversation-C22sJuWZ.js} +1 -1
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~czjee3a3-BXXGJNDU.js +185 -0
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ew9ih1s8-40UR63Gt.js +1 -0
- package/build/assets/{vendor~index-home~home~conversation-panel~conversation-CSFLzmTN.js → vendor~index-home~home~conversation-panel~conversation-UTl7gUo9.js} +1 -1
- package/build/assets/{vendor~root-layout-n8XCEXG8.js → vendor~root-layout-CcdIqs-C.js} +1 -1
- package/build/assets/{vendor~root-layout~conversation-panel~conversation-3Idg1_U3.js → vendor~root-layout~conversation-panel~conversation-C3EBV3kp.js} +1 -1
- package/build/assets/vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-BCe0JJVy.js +1 -0
- package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation-DgQ564nC.js → vendor~root-layout~index-home~home~conversation-panel~conversation-BGGbPcYh.js} +1 -1
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-BPjI-atc.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-3eJ4ExtV.js} +1 -1
- package/build/assets/{verification-settings-u2POabjH.js → verification-settings-DdBpaVPz.js} +1 -1
- package/build/assets/{wrench-CkgI4rxA.js → wrench-B8Wg_nbp.js} +1 -1
- package/build/assets/{x-By6qCmtY.js → x-CX8lVGwm.js} +1 -1
- package/build/index.html +4 -4
- package/build/locales/ar/openhands.json +6 -2
- package/build/locales/ca/openhands.json +6 -2
- package/build/locales/de/openhands.json +6 -2
- package/build/locales/en/openhands.json +6 -2
- package/build/locales/es/openhands.json +6 -2
- package/build/locales/fr/openhands.json +6 -2
- package/build/locales/it/openhands.json +6 -2
- package/build/locales/ja/openhands.json +6 -2
- package/build/locales/ko-KR/openhands.json +6 -2
- package/build/locales/no/openhands.json +6 -2
- package/build/locales/pt/openhands.json +6 -2
- package/build/locales/tr/openhands.json +6 -2
- package/build/locales/uk/openhands.json +6 -2
- package/build/locales/zh-CN/openhands.json +6 -2
- package/build/locales/zh-TW/openhands.json +6 -2
- package/config/defaults.json +1 -1
- package/dist/api/cloud/organization-service.api.cjs.map +1 -1
- package/dist/api/cloud/organization-service.api.d.ts +9 -1
- package/dist/api/cloud/organization-service.api.js.map +1 -1
- package/dist/api/config-service/config-service.api.cjs +1 -1
- package/dist/api/config-service/config-service.api.cjs.map +1 -1
- package/dist/api/config-service/config-service.api.js +6 -2
- package/dist/api/config-service/config-service.api.js.map +1 -1
- package/dist/api/config-service/config-service.types.d.ts +13 -0
- package/dist/components/features/automations/automation-card.cjs +1 -1
- package/dist/components/features/automations/automation-card.cjs.map +1 -1
- package/dist/components/features/automations/automation-card.js +39 -38
- package/dist/components/features/automations/automation-card.js.map +1 -1
- package/dist/components/features/automations/automation-list-row.cjs +1 -1
- package/dist/components/features/automations/automation-list-row.cjs.map +1 -1
- package/dist/components/features/automations/automation-list-row.js +73 -72
- package/dist/components/features/automations/automation-list-row.js.map +1 -1
- package/dist/components/features/automations/build-automation-menu-items.cjs +1 -1
- package/dist/components/features/automations/build-automation-menu-items.cjs.map +1 -1
- package/dist/components/features/automations/build-automation-menu-items.d.ts +3 -1
- package/dist/components/features/automations/build-automation-menu-items.js +12 -11
- package/dist/components/features/automations/build-automation-menu-items.js.map +1 -1
- package/dist/components/features/automations/detail/configuration-section.d.ts +7 -1
- package/dist/components/features/automations/detail/detail-header.d.ts +8 -5
- package/dist/components/features/backends/backend-selector.cjs +1 -1
- package/dist/components/features/backends/backend-selector.cjs.map +1 -1
- package/dist/components/features/backends/backend-selector.js +112 -112
- package/dist/components/features/backends/backend-selector.js.map +1 -1
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.cjs +1 -1
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.cjs.map +1 -1
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.js +62 -61
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.js.map +1 -1
- package/dist/components/features/chat/model-messages.cjs +1 -1
- package/dist/components/features/chat/model-messages.cjs.map +1 -1
- package/dist/components/features/chat/model-messages.js +27 -26
- package/dist/components/features/chat/model-messages.js.map +1 -1
- package/dist/components/features/conversation-panel/budget-display.cjs +1 -1
- package/dist/components/features/conversation-panel/budget-display.cjs.map +1 -1
- package/dist/components/features/conversation-panel/budget-display.d.ts +1 -2
- package/dist/components/features/conversation-panel/budget-display.js +12 -19
- package/dist/components/features/conversation-panel/budget-display.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js +45 -44
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js.map +1 -1
- package/dist/components/features/home/featured-automations/build-home-automation-menu-items.d.ts +1 -2
- package/dist/components/features/home/featured-automations/build-pinned-automation-menu-items.d.ts +0 -1
- package/dist/components/features/images/image-lightbox.cjs +2 -0
- package/dist/components/features/images/image-lightbox.cjs.map +1 -0
- package/dist/components/features/images/image-lightbox.d.ts +11 -0
- package/dist/components/features/images/image-lightbox.js +37 -0
- package/dist/components/features/images/image-lightbox.js.map +1 -0
- package/dist/components/features/images/image-preview.cjs +1 -1
- package/dist/components/features/images/image-preview.cjs.map +1 -1
- package/dist/components/features/images/image-preview.d.ts +2 -1
- package/dist/components/features/images/image-preview.js +33 -13
- package/dist/components/features/images/image-preview.js.map +1 -1
- package/dist/components/features/onboarding/steps/setup-llm-step.d.ts +3 -4
- package/dist/components/features/settings/cloud-settings-link.cjs +1 -1
- package/dist/components/features/settings/cloud-settings-link.cjs.map +1 -1
- package/dist/components/features/settings/cloud-settings-link.d.ts +3 -1
- package/dist/components/features/settings/cloud-settings-link.js +22 -21
- package/dist/components/features/settings/cloud-settings-link.js.map +1 -1
- package/dist/components/features/settings/llm-profiles/llm-settings-local-view.cjs +1 -1
- package/dist/components/features/settings/llm-profiles/llm-settings-local-view.js +2 -1
- package/dist/components/features/settings/llm-profiles/profile-row.cjs +1 -1
- package/dist/components/features/settings/llm-profiles/profile-row.js +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.d.ts +2 -1
- package/dist/components/features/sidebar/sidebar-rail-body.js +143 -142
- package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
- package/dist/components/features/sidebar/sidebar.cjs +1 -1
- package/dist/components/features/sidebar/sidebar.cjs.map +1 -1
- package/dist/components/features/sidebar/sidebar.js +28 -27
- package/dist/components/features/sidebar/sidebar.js.map +1 -1
- package/dist/components/providers/agent-server-ui-providers.cjs +1 -1
- package/dist/components/providers/agent-server-ui-providers.cjs.map +1 -1
- package/dist/components/providers/agent-server-ui-providers.js +33 -29
- package/dist/components/providers/agent-server-ui-providers.js.map +1 -1
- package/dist/components/shared/buttons/remove-button.cjs +1 -1
- package/dist/components/shared/buttons/remove-button.cjs.map +1 -1
- package/dist/components/shared/buttons/remove-button.d.ts +2 -1
- package/dist/components/shared/buttons/remove-button.js +2 -1
- package/dist/components/shared/buttons/remove-button.js.map +1 -1
- package/dist/components/shared/free-models-note.cjs +2 -0
- package/dist/components/shared/free-models-note.cjs.map +1 -0
- package/dist/components/shared/free-models-note.d.ts +3 -0
- package/dist/components/shared/free-models-note.js +20 -0
- package/dist/components/shared/free-models-note.js.map +1 -0
- package/dist/components/shared/modals/settings/model-selector.cjs +1 -1
- package/dist/components/shared/modals/settings/model-selector.cjs.map +1 -1
- package/dist/components/shared/modals/settings/model-selector.js +102 -112
- package/dist/components/shared/modals/settings/model-selector.js.map +1 -1
- package/dist/config/defaults.cjs +1 -1
- package/dist/config/defaults.cjs.map +1 -1
- package/dist/config/defaults.js +1 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/constants/acp-providers.cjs.map +1 -1
- package/dist/constants/acp-providers.d.ts +12 -0
- package/dist/constants/acp-providers.js.map +1 -1
- package/dist/hooks/chat/use-slash-command.cjs +1 -1
- package/dist/hooks/chat/use-slash-command.cjs.map +1 -1
- package/dist/hooks/chat/use-slash-command.js +63 -62
- package/dist/hooks/chat/use-slash-command.js.map +1 -1
- package/dist/hooks/query/use-free-models.cjs +2 -0
- package/dist/hooks/query/use-free-models.cjs.map +1 -0
- package/dist/hooks/query/use-free-models.d.ts +23 -0
- package/dist/hooks/query/use-free-models.js +67 -0
- package/dist/hooks/query/use-free-models.js.map +1 -0
- package/dist/hooks/query/use-local-git-info.cjs.map +1 -1
- package/dist/hooks/query/use-local-git-info.js.map +1 -1
- package/dist/hooks/query/use-provider-models.cjs +1 -1
- package/dist/hooks/query/use-provider-models.cjs.map +1 -1
- package/dist/hooks/query/use-provider-models.js +34 -25
- package/dist/hooks/query/use-provider-models.js.map +1 -1
- package/dist/hooks/query/use-search-providers.cjs +1 -1
- package/dist/hooks/query/use-search-providers.cjs.map +1 -1
- package/dist/hooks/query/use-search-providers.js +31 -19
- package/dist/hooks/query/use-search-providers.js.map +1 -1
- package/dist/hooks/use-home-automation-actions.cjs +1 -1
- package/dist/hooks/use-home-automation-actions.cjs.map +1 -1
- package/dist/hooks/use-home-automation-actions.d.ts +1 -2
- package/dist/hooks/use-home-automation-actions.js +0 -1
- package/dist/hooks/use-home-automation-actions.js.map +1 -1
- package/dist/i18n/declaration.cjs +1 -1
- package/dist/i18n/declaration.cjs.map +1 -1
- package/dist/i18n/declaration.d.ts +6 -2
- package/dist/i18n/declaration.js +1 -1
- package/dist/i18n/declaration.js.map +1 -1
- package/dist/i18n/translation.cjs +2 -2
- package/dist/i18n/translation.cjs.map +1 -1
- package/dist/i18n/translation.js +85 -17
- package/dist/i18n/translation.js.map +1 -1
- package/dist/locales/ar/openhands.json +6 -2
- package/dist/locales/ca/openhands.json +6 -2
- package/dist/locales/de/openhands.json +6 -2
- package/dist/locales/en/openhands.json +6 -2
- package/dist/locales/es/openhands.json +6 -2
- package/dist/locales/fr/openhands.json +6 -2
- package/dist/locales/it/openhands.json +6 -2
- package/dist/locales/ja/openhands.json +6 -2
- package/dist/locales/ko-KR/openhands.json +6 -2
- package/dist/locales/no/openhands.json +6 -2
- package/dist/locales/pt/openhands.json +6 -2
- package/dist/locales/tr/openhands.json +6 -2
- package/dist/locales/uk/openhands.json +6 -2
- package/dist/locales/zh-CN/openhands.json +6 -2
- package/dist/locales/zh-TW/openhands.json +6 -2
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/dist/routes/app-settings.cjs +1 -1
- package/dist/routes/app-settings.cjs.map +1 -1
- package/dist/routes/app-settings.js +52 -47
- package/dist/routes/app-settings.js.map +1 -1
- package/dist/routes/llm-settings.cjs +1 -1
- package/dist/routes/llm-settings.cjs.map +1 -1
- package/dist/routes/llm-settings.js +137 -145
- package/dist/routes/llm-settings.js.map +1 -1
- package/dist/stores/free-models-store.cjs +2 -0
- package/dist/stores/free-models-store.cjs.map +1 -0
- package/dist/stores/free-models-store.d.ts +30 -0
- package/dist/stores/free-models-store.js +22 -0
- package/dist/stores/free-models-store.js.map +1 -0
- package/dist/utils/format-model-name.cjs +1 -1
- package/dist/utils/format-model-name.cjs.map +1 -1
- package/dist/utils/format-model-name.d.ts +27 -6
- package/dist/utils/format-model-name.js +14 -6
- package/dist/utils/format-model-name.js.map +1 -1
- package/package.json +1 -1
- package/build/assets/active-backend-context-rZiLJRUc.js +0 -2
- package/build/assets/agent-profiles-settings-x6RvPsq7.js +0 -1
- package/build/assets/agent-server-client-options-BikiNwTa.js +0 -1
- package/build/assets/agent-server-conversation-service.api-DYFsNHKf.js +0 -88
- package/build/assets/agent-settings-BJyovpJ_.js +0 -1
- package/build/assets/alert-banner-vARz1idS.js +0 -1
- package/build/assets/api-key-entry-screen-CsMuBhoP.js +0 -1
- package/build/assets/app-settings-BaJ7nfHt.js +0 -1
- package/build/assets/automation-detail-CVoGDrKq.js +0 -3
- package/build/assets/automation-git-sync-CRMP9Bbm.js +0 -1
- package/build/assets/automation-setup-route-072beLz1.js +0 -3
- package/build/assets/automations-list-xuqTSQL4.js +0 -1
- package/build/assets/backend-form-modal-0aJmWdsa.js +0 -1
- package/build/assets/backend-synced-settings-badge-B7rKWBir.js +0 -1
- package/build/assets/badge-CcGx2TaV.js +0 -1
- package/build/assets/browser-tab-DZanIw5m.js +0 -1
- package/build/assets/canvas-extension-page-o_cWgE9B.js +0 -1
- package/build/assets/canvas-extensions-DSgNlCha.js +0 -1
- package/build/assets/check-fDEfgSzj.js +0 -1
- package/build/assets/chevron-down-CFrWHqu8.js +0 -1
- package/build/assets/chevron-right-C5roOrJu.js +0 -1
- package/build/assets/circle-check-ClTzJTdb.js +0 -1
- package/build/assets/circle-plus-check-toggle-Fr-h-mbL.js +0 -1
- package/build/assets/command-menu-BT3Ia5Ru.js +0 -1
- package/build/assets/commits-tab-2jhtaohl.js +0 -1
- package/build/assets/confirmation-modal-gIFHeZt6.js +0 -1
- package/build/assets/conversation-DZ578rOX.js +0 -1
- package/build/assets/conversation-panel-DZ578rOX.js +0 -1
- package/build/assets/conversation-state-store-D1_G_9I-.js +0 -1
- package/build/assets/conversation-store-DVVfkCsk.js +0 -6
- package/build/assets/copy-to-clipboard-button-B3w0X7WH.js +0 -1
- package/build/assets/device-verify-BfkCzyFB.js +0 -1
- package/build/assets/edit-automation-modal-BwhJ39JT.js +0 -1
- package/build/assets/empty-state-RZz0OfnY.js +0 -1
- package/build/assets/enum-filter-dropdown-C4pW0ORd.js +0 -1
- package/build/assets/environment-switch-overlay-P2ZAuzov.js +0 -1
- package/build/assets/error-state-B_5cgNPJ.js +0 -1
- package/build/assets/extensions-hub-DsaUr4ca.js +0 -1
- package/build/assets/extensions-navigation-CRMZd-FE.js +0 -1
- package/build/assets/files-tab-CCgAcVdc.js +0 -1
- package/build/assets/format-model-name-CasAP3nd.js +0 -1
- package/build/assets/get-git-path-EHrSDxTM.js +0 -1
- package/build/assets/git-repo-dropdown-D2WEQ97X.js +0 -1
- package/build/assets/git-repo-dropdown-DVeCUUXG.js +0 -1
- package/build/assets/highlighted-source-view-DjHO3SdW.js +0 -1
- package/build/assets/home-BorS_vdS.js +0 -1
- package/build/assets/home-aIMbHw5M.js +0 -1
- package/build/assets/home-automation-run-tooltip-CpHNFiFl.js +0 -1
- package/build/assets/home-store-DyXz0w6d.js +0 -1
- package/build/assets/hooks-service-C6dpRtZM.js +0 -1
- package/build/assets/index-home-zKFuKK2B.js +0 -1
- package/build/assets/info-CTIdjttz.js +0 -1
- package/build/assets/install-server-modal-DUiZMc8u.js +0 -1
- package/build/assets/kebab-menu-item-content-mm04SBD3.js +0 -1
- package/build/assets/launch-BSIf9KEg.js +0 -1
- package/build/assets/list-filter-CNpqTWVY.js +0 -1
- package/build/assets/llm-not-configured-banner-z_QRSeV0.js +0 -27
- package/build/assets/llm-settings-B-5AHMiX.js +0 -1
- package/build/assets/llm-settings-B3SjHDmA.js +0 -1
- package/build/assets/loader-circle-Dex47vVW.js +0 -1
- package/build/assets/manage-backends-modal-q1NdFisr.js +0 -1
- package/build/assets/manifest-8920b615.js +0 -1
- package/build/assets/manifest-subpage-layout-BQQy5ipR.js +0 -1
- package/build/assets/markdown-renderer-rivLvYh-.js +0 -8
- package/build/assets/mcp-CEXDhQWn.js +0 -1
- package/build/assets/mcp-page-LGYIICMG.js +0 -9
- package/build/assets/messages-DUSeANAh.js +0 -41
- package/build/assets/modal-close-button-B9j4nasm.js +0 -1
- package/build/assets/onboarding-BjFebfs5.js +0 -1
- package/build/assets/onboarding-modal-DDTjOpyd.js +0 -1
- package/build/assets/planner-tab-D8f2Y3rn.js +0 -1
- package/build/assets/plus-B3wvU06-.js +0 -1
- package/build/assets/providers-2gIIkz2N.js +0 -1
- package/build/assets/proxy-CBgMd2zf.js +0 -1
- package/build/assets/recommended-automations-launcher-YLAQTp4s.js +0 -1
- package/build/assets/root-Bye_XmEL.js +0 -2
- package/build/assets/root-Cnwwzgo0.css +0 -1
- package/build/assets/root-layout-CSAwxBGM.js +0 -2
- package/build/assets/schema-field-CK0xYNbO.js +0 -1
- package/build/assets/sdk-section-page-Da73Rs_o.js +0 -1
- package/build/assets/secret-form-CB2VwYYg.js +0 -1
- package/build/assets/secrets-settings-Bh0udeKv.js +0 -1
- package/build/assets/settings-DmyIgRxO.js +0 -1
- package/build/assets/settings-dropdown-input-DVpyD87C.js +0 -1
- package/build/assets/settings-index-BSJUFmjE.js +0 -1
- package/build/assets/settings-input-C0dd8Utu.js +0 -1
- package/build/assets/settings-modal-yStgEh2o.js +0 -1
- package/build/assets/settings-switch-B78Khmyz.js +0 -1
- package/build/assets/shared-conversation-DM96X4KV.js +0 -1
- package/build/assets/sidebar-mobile-menu-toggle-D5GR5xT9.js +0 -1
- package/build/assets/sidebar-store-CSDFK0W5.js +0 -1
- package/build/assets/skill-card-pill-row-989y15jV.js +0 -1
- package/build/assets/skill-scope-Dz3kPH3P.js +0 -1
- package/build/assets/skills-plugins-e3CYGdUJ.js +0 -1
- package/build/assets/skills-settings-3e-FuHw_.js +0 -1
- package/build/assets/task-list-tab-3Jg8ywch.js +0 -1
- package/build/assets/trash-B6OIe4yX.js +0 -1
- package/build/assets/usage-tab-Cm-9j3UK.js +0 -1
- package/build/assets/use-acp-credential-form-BARcvjYE.js +0 -1
- package/build/assets/use-agent-profiles-1P91KSXz.js +0 -1
- package/build/assets/use-create-secret-D8p9ybQj.js +0 -1
- package/build/assets/use-is-authed-BRPjCRKM.js +0 -1
- package/build/assets/use-llm-configured-DGm8FiRR.js +0 -1
- package/build/assets/use-llm-profiles-BTTtpW4z.js +0 -1
- package/build/assets/use-save-agent-profile-CxyO9YG-.js +0 -1
- package/build/assets/use-settings-nav-items-vrjxTqcu.js +0 -16
- package/build/assets/useQueries-CykmpT-a.js +0 -1
- package/build/assets/useQuery-S6j94er1.js +0 -1
- package/build/assets/utils-BOco8mxR.js +0 -1
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~czjee3a3-BfkNGovw.js +0 -185
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ew9ih1s8-DnDoaYNi.js +0 -1
- package/build/assets/vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-DkPlXWl9.js +0 -1
- package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~iyia17eu-CV850oio.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-input-llm-profile-picker.cjs","names":[],"sources":["../../../../../src/components/features/chat/components/chat-input-llm-profile-picker.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useChatInputLlmProfileState } from \"#/hooks/use-chat-input-llm-profile-state\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport SettingsGearIcon from \"#/icons/settings-gear.svg?react\";\nimport CheckIcon from \"#/icons/checkmark.svg?react\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { ContextMenu } from \"#/ui/context-menu\";\nimport { ContextMenuListItem } from \"#/components/features/context-menu/context-menu-list-item\";\nimport { Divider } from \"#/ui/divider\";\nimport { Typography } from \"#/ui/typography\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\nimport { formatModelNameForDisplay } from \"#/utils/format-model-name\";\n\nconst PROFILE_LABEL_MAX_CHARS = 18;\n\nfunction truncateLabel(label: string): string {\n return label.length <= PROFILE_LABEL_MAX_CHARS\n ? label\n : `${label.slice(0, PROFILE_LABEL_MAX_CHARS)}…`;\n}\n\ninterface ChatInputLlmProfileMenuContentProps {\n onClose: () => void;\n dividerInset?: \"menu\";\n settingsLinkClassName?: string;\n settingsIconClassName?: string;\n}\n\n/**\n * The in-conversation OpenHands LLM-profile switcher list. Selecting a profile\n * live-swaps the running conversation's LLM via `/switch_profile` (the ACP\n * analog is {@link ChatInputModelMenuContent}). Shared by the inline pill and\n * the chat-input overflow submenu.\n */\nexport function ChatInputLlmProfileMenuContent({\n onClose,\n dividerInset,\n settingsLinkClassName,\n settingsIconClassName,\n}: ChatInputLlmProfileMenuContentProps) {\n const { t } = useTranslation(\"openhands\");\n const {\n profiles,\n currentProfileName,\n currentProfileModel,\n canSwitchProfile,\n selectProfile,\n } = useChatInputLlmProfileState();\n // Read-only surfaces (a cloud member on the home page, or a start-task route)\n // still name the active profile — the same shape ChatInputModelMenuContent\n // uses when the ACP picker is gated off.\n const showProfileList = canSwitchProfile && profiles.length > 0;\n const readOnlyProfileName = canSwitchProfile ? null : currentProfileName;\n\n const handleSelect = (profileName: string) => {\n selectProfile(profileName);\n onClose();\n };\n\n return (\n <>\n {showProfileList && (\n <>\n {/* role=\"presentation\" keeps this a valid <li> child of the\n ContextMenu <ul> without exposing the label as a menu item. */}\n <li role=\"presentation\" className=\"px-2 pt-1 pb-0.5\">\n <Typography.Text className=\"text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4\">\n {t(I18nKey.SETTINGS$AVAILABLE_PROFILES)}\n </Typography.Text>\n </li>\n {profiles.map((profile) => {\n const isCurrent = profile.name === currentProfileName;\n const displayModel = formatModelNameForDisplay(profile.model);\n return (\n <ContextMenuListItem\n key={profile.name}\n testId={`chat-input-llm-profile-option-${profile.name}`}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (isCurrent) {\n onClose();\n return;\n }\n handleSelect(profile.name);\n }}\n className={cn(\n \"flex flex-col items-stretch gap-0.5\",\n isCurrent && \"bg-[var(--oh-interactive-hover)]\",\n )}\n >\n <span className=\"flex items-center gap-2\">\n <span\n className=\"flex-1 truncate text-sm leading-5\"\n title={profile.model ?? profile.name}\n >\n {profile.name}\n </span>\n {isCurrent && (\n <CheckIcon\n width={14}\n height={14}\n className=\"shrink-0\"\n aria-hidden\n />\n )}\n </span>\n {displayModel && (\n <span className=\"block truncate text-xs leading-4 text-[var(--oh-muted)]\">\n {displayModel}\n </span>\n )}\n </ContextMenuListItem>\n );\n })}\n </>\n )}\n {readOnlyProfileName && (\n <li className=\"text-sm\" data-testid=\"chat-input-llm-profile-current\">\n <div className=\"flex flex-col gap-0.5 p-2 leading-5 text-[var(--oh-foreground)]\">\n <span className=\"truncate\" title={readOnlyProfileName}>\n {readOnlyProfileName}\n </span>\n {currentProfileModel && (\n <span className=\"truncate text-xs leading-4 text-[var(--oh-muted)]\">\n {formatModelNameForDisplay(currentProfileModel)}\n </span>\n )}\n </div>\n </li>\n )}\n {(showProfileList || readOnlyProfileName) && (\n <Divider inset={dividerInset} />\n )}\n <li className=\"text-sm\">\n <NavigationLink\n to=\"/settings/llm\"\n onClick={onClose}\n className={cn(\n \"flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)] transition-colors\",\n settingsLinkClassName,\n )}\n >\n <SettingsGearIcon\n width={16}\n height={16}\n className={cn(\"shrink-0\", settingsIconClassName)}\n aria-hidden\n />\n <span>{t(I18nKey.SETTINGS$LLM_PROFILES)}</span>\n </NavigationLink>\n </li>\n </>\n );\n}\n\nexport function ChatInputLlmProfilePicker() {\n const { t } = useTranslation(\"openhands\");\n const { profiles, currentProfileName, isLoading, isSwitching } =\n useChatInputLlmProfileState();\n const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const popoverRef = useClickOutsideElement<HTMLUListElement>(\n () => setIsPopoverOpen(false),\n triggerRef,\n );\n\n // No LLM profiles yet (or the agent-server lacks the surface): stay out of\n // the way, exactly like the ACP/AgentProfile pickers.\n if (isLoading || profiles.length === 0) {\n return null;\n }\n\n const label = currentProfileName ?? t(I18nKey.LLM$SELECT_MODEL_PLACEHOLDER);\n\n return (\n <div className=\"relative min-w-0\">\n <button\n ref={triggerRef}\n type=\"button\"\n className={cn(chatInputPillButtonClassName, \"max-w-[200px]\")}\n title={currentProfileName ?? undefined}\n data-testid=\"chat-input-llm-profile\"\n aria-expanded={isPopoverOpen}\n aria-haspopup=\"dialog\"\n // Disabled mid-switch so re-opening can't fire a second /switch_profile.\n disabled={isSwitching}\n aria-busy={isSwitching}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setIsPopoverOpen((open) => !open);\n }}\n >\n <span className=\"truncate\">{truncateLabel(label)}</span>\n <ComboboxCaretInline isOpen={isPopoverOpen} />\n </button>\n\n {isPopoverOpen && (\n <ContextMenu\n ref={popoverRef}\n testId=\"chat-input-llm-profile-popover\"\n position=\"top\"\n alignment=\"left\"\n spacing=\"none\"\n className=\"z-[60] mb-2 min-w-[200px] max-w-[320px] max-h-[60vh] overflow-y-auto\"\n >\n <ChatInputLlmProfileMenuContent\n onClose={() => setIsPopoverOpen(false)}\n />\n </ContextMenu>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chat-input-llm-profile-picker.cjs","names":[],"sources":["../../../../../src/components/features/chat/components/chat-input-llm-profile-picker.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useChatInputLlmProfileState } from \"#/hooks/use-chat-input-llm-profile-state\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport SettingsGearIcon from \"#/icons/settings-gear.svg?react\";\nimport CheckIcon from \"#/icons/checkmark.svg?react\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { ContextMenu } from \"#/ui/context-menu\";\nimport { ContextMenuListItem } from \"#/components/features/context-menu/context-menu-list-item\";\nimport { Divider } from \"#/ui/divider\";\nimport { Typography } from \"#/ui/typography\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\nimport { useFreeModels } from \"#/hooks/query/use-free-models\";\nimport { formatModelPillLabel } from \"#/utils/format-model-name\";\n\nconst PROFILE_LABEL_MAX_CHARS = 18;\n\nfunction truncateLabel(label: string): string {\n return label.length <= PROFILE_LABEL_MAX_CHARS\n ? label\n : `${label.slice(0, PROFILE_LABEL_MAX_CHARS)}…`;\n}\n\ninterface ChatInputLlmProfileMenuContentProps {\n onClose: () => void;\n dividerInset?: \"menu\";\n settingsLinkClassName?: string;\n settingsIconClassName?: string;\n}\n\n/**\n * The in-conversation OpenHands LLM-profile switcher list. Selecting a profile\n * live-swaps the running conversation's LLM via `/switch_profile` (the ACP\n * analog is {@link ChatInputModelMenuContent}). Shared by the inline pill and\n * the chat-input overflow submenu.\n */\nexport function ChatInputLlmProfileMenuContent({\n onClose,\n dividerInset,\n settingsLinkClassName,\n settingsIconClassName,\n}: ChatInputLlmProfileMenuContentProps) {\n const { t } = useTranslation(\"openhands\");\n const freeModels = useFreeModels();\n const {\n profiles,\n currentProfileName,\n currentProfileModel,\n canSwitchProfile,\n selectProfile,\n } = useChatInputLlmProfileState();\n // Read-only surfaces (a cloud member on the home page, or a start-task route)\n // still name the active profile — the same shape ChatInputModelMenuContent\n // uses when the ACP picker is gated off.\n const showProfileList = canSwitchProfile && profiles.length > 0;\n const readOnlyProfileName = canSwitchProfile ? null : currentProfileName;\n\n const handleSelect = (profileName: string) => {\n selectProfile(profileName);\n onClose();\n };\n\n return (\n <>\n {showProfileList && (\n <>\n {/* role=\"presentation\" keeps this a valid <li> child of the\n ContextMenu <ul> without exposing the label as a menu item. */}\n <li role=\"presentation\" className=\"px-2 pt-1 pb-0.5\">\n <Typography.Text className=\"text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4\">\n {t(I18nKey.SETTINGS$AVAILABLE_PROFILES)}\n </Typography.Text>\n </li>\n {profiles.map((profile) => {\n const isCurrent = profile.name === currentProfileName;\n const displayModel = formatModelPillLabel(\n profile.model,\n freeModels,\n );\n return (\n <ContextMenuListItem\n key={profile.name}\n testId={`chat-input-llm-profile-option-${profile.name}`}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (isCurrent) {\n onClose();\n return;\n }\n handleSelect(profile.name);\n }}\n className={cn(\n \"flex flex-col items-stretch gap-0.5\",\n isCurrent && \"bg-[var(--oh-interactive-hover)]\",\n )}\n >\n <span className=\"flex items-center gap-2\">\n <span\n className=\"flex-1 truncate text-sm leading-5\"\n title={profile.model ?? profile.name}\n >\n {profile.name}\n </span>\n {isCurrent && (\n <CheckIcon\n width={14}\n height={14}\n className=\"shrink-0\"\n aria-hidden\n />\n )}\n </span>\n {displayModel && (\n <span className=\"block truncate text-xs leading-4 text-[var(--oh-muted)]\">\n {displayModel}\n </span>\n )}\n </ContextMenuListItem>\n );\n })}\n </>\n )}\n {readOnlyProfileName && (\n <li className=\"text-sm\" data-testid=\"chat-input-llm-profile-current\">\n <div className=\"flex flex-col gap-0.5 p-2 leading-5 text-[var(--oh-foreground)]\">\n <span className=\"truncate\" title={readOnlyProfileName}>\n {readOnlyProfileName}\n </span>\n {currentProfileModel && (\n <span className=\"truncate text-xs leading-4 text-[var(--oh-muted)]\">\n {formatModelPillLabel(currentProfileModel, freeModels)}\n </span>\n )}\n </div>\n </li>\n )}\n {(showProfileList || readOnlyProfileName) && (\n <Divider inset={dividerInset} />\n )}\n <li className=\"text-sm\">\n <NavigationLink\n to=\"/settings/llm\"\n onClick={onClose}\n className={cn(\n \"flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)] transition-colors\",\n settingsLinkClassName,\n )}\n >\n <SettingsGearIcon\n width={16}\n height={16}\n className={cn(\"shrink-0\", settingsIconClassName)}\n aria-hidden\n />\n <span>{t(I18nKey.SETTINGS$LLM_PROFILES)}</span>\n </NavigationLink>\n </li>\n </>\n );\n}\n\nexport function ChatInputLlmProfilePicker() {\n const { t } = useTranslation(\"openhands\");\n const { profiles, currentProfileName, isLoading, isSwitching } =\n useChatInputLlmProfileState();\n const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const popoverRef = useClickOutsideElement<HTMLUListElement>(\n () => setIsPopoverOpen(false),\n triggerRef,\n );\n\n // No LLM profiles yet (or the agent-server lacks the surface): stay out of\n // the way, exactly like the ACP/AgentProfile pickers.\n if (isLoading || profiles.length === 0) {\n return null;\n }\n\n const label = currentProfileName ?? t(I18nKey.LLM$SELECT_MODEL_PLACEHOLDER);\n\n return (\n <div className=\"relative min-w-0\">\n <button\n ref={triggerRef}\n type=\"button\"\n className={cn(chatInputPillButtonClassName, \"max-w-[200px]\")}\n title={currentProfileName ?? undefined}\n data-testid=\"chat-input-llm-profile\"\n aria-expanded={isPopoverOpen}\n aria-haspopup=\"dialog\"\n // Disabled mid-switch so re-opening can't fire a second /switch_profile.\n disabled={isSwitching}\n aria-busy={isSwitching}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setIsPopoverOpen((open) => !open);\n }}\n >\n <span className=\"truncate\">{truncateLabel(label)}</span>\n <ComboboxCaretInline isOpen={isPopoverOpen} />\n </button>\n\n {isPopoverOpen && (\n <ContextMenu\n ref={popoverRef}\n testId=\"chat-input-llm-profile-popover\"\n position=\"top\"\n alignment=\"left\"\n spacing=\"none\"\n className=\"z-[60] mb-2 min-w-[200px] max-w-[320px] max-h-[60vh] overflow-y-auto\"\n >\n <ChatInputLlmProfileMenuContent\n onClose={() => setIsPopoverOpen(false)}\n />\n </ContextMenu>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -3,132 +3,133 @@ import { I18nKey as t } from "../../../../i18n/declaration.js";
|
|
|
3
3
|
import { cn as n } from "../../../../utils/utils.js";
|
|
4
4
|
import r from "../../../../icons/checkmark.js";
|
|
5
5
|
import { chatInputPillButtonClassName as i } from "../../../../utils/form-control-classes.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import d from "../../../../
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import h from "
|
|
17
|
-
import
|
|
6
|
+
import { useFreeModels as a } from "../../../../hooks/query/use-free-models.js";
|
|
7
|
+
import { formatModelPillLabel as o } from "../../../../utils/format-model-name.js";
|
|
8
|
+
import { Typography as s } from "../../../../ui/typography.js";
|
|
9
|
+
import { ComboboxCaretInline as c } from "../../../../ui/combobox-caret.js";
|
|
10
|
+
import { ContextMenu as l } from "../../../../ui/context-menu.js";
|
|
11
|
+
import { ContextMenuListItem as u } from "../../context-menu/context-menu-list-item.js";
|
|
12
|
+
import { useClickOutsideElement as d } from "../../../../hooks/use-click-outside-element.js";
|
|
13
|
+
import f from "../../../../icons/settings-gear.js";
|
|
14
|
+
import { NavigationLink as p } from "../../../shared/navigation-link.js";
|
|
15
|
+
import { Divider as m } from "../../../../ui/divider.js";
|
|
16
|
+
import { useChatInputLlmProfileState as h } from "../../../../hooks/use-chat-input-llm-profile-state.js";
|
|
17
|
+
import g from "react";
|
|
18
|
+
import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
18
19
|
//#region src/components/features/chat/components/chat-input-llm-profile-picker.tsx
|
|
19
|
-
var
|
|
20
|
-
function
|
|
21
|
-
return e.length <=
|
|
20
|
+
var b = 18;
|
|
21
|
+
function x(e) {
|
|
22
|
+
return e.length <= b ? e : `${e.slice(0, b)}…`;
|
|
22
23
|
}
|
|
23
|
-
function
|
|
24
|
-
let { t:
|
|
25
|
-
|
|
24
|
+
function S({ onClose: i, dividerInset: c, settingsLinkClassName: l, settingsIconClassName: d }) {
|
|
25
|
+
let { t: g } = e("openhands"), b = a(), { profiles: x, currentProfileName: S, currentProfileModel: C, canSwitchProfile: w, selectProfile: T } = h(), E = w && x.length > 0, D = w ? null : S, O = (e) => {
|
|
26
|
+
T(e), i();
|
|
26
27
|
};
|
|
27
|
-
return /* @__PURE__ */
|
|
28
|
-
|
|
28
|
+
return /* @__PURE__ */ y(_, { children: [
|
|
29
|
+
E && /* @__PURE__ */ y(_, { children: [/* @__PURE__ */ v("li", {
|
|
29
30
|
role: "presentation",
|
|
30
31
|
className: "px-2 pt-1 pb-0.5",
|
|
31
|
-
children: /* @__PURE__ */
|
|
32
|
+
children: /* @__PURE__ */ v(s.Text, {
|
|
32
33
|
className: "text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4",
|
|
33
|
-
children:
|
|
34
|
+
children: g(t.SETTINGS$AVAILABLE_PROFILES)
|
|
34
35
|
})
|
|
35
|
-
}),
|
|
36
|
-
let t = e.name ===
|
|
37
|
-
return /* @__PURE__ */
|
|
36
|
+
}), x.map((e) => {
|
|
37
|
+
let t = e.name === S, a = o(e.model, b);
|
|
38
|
+
return /* @__PURE__ */ y(u, {
|
|
38
39
|
testId: `chat-input-llm-profile-option-${e.name}`,
|
|
39
40
|
onClick: (n) => {
|
|
40
41
|
if (n.preventDefault(), n.stopPropagation(), t) {
|
|
41
42
|
i();
|
|
42
43
|
return;
|
|
43
44
|
}
|
|
44
|
-
|
|
45
|
+
O(e.name);
|
|
45
46
|
},
|
|
46
47
|
className: n("flex flex-col items-stretch gap-0.5", t && "bg-[var(--oh-interactive-hover)]"),
|
|
47
|
-
children: [/* @__PURE__ */
|
|
48
|
+
children: [/* @__PURE__ */ y("span", {
|
|
48
49
|
className: "flex items-center gap-2",
|
|
49
|
-
children: [/* @__PURE__ */
|
|
50
|
+
children: [/* @__PURE__ */ v("span", {
|
|
50
51
|
className: "flex-1 truncate text-sm leading-5",
|
|
51
52
|
title: e.model ?? e.name,
|
|
52
53
|
children: e.name
|
|
53
|
-
}), t && /* @__PURE__ */
|
|
54
|
+
}), t && /* @__PURE__ */ v(r, {
|
|
54
55
|
width: 14,
|
|
55
56
|
height: 14,
|
|
56
57
|
className: "shrink-0",
|
|
57
58
|
"aria-hidden": !0
|
|
58
59
|
})]
|
|
59
|
-
}),
|
|
60
|
+
}), a && /* @__PURE__ */ v("span", {
|
|
60
61
|
className: "block truncate text-xs leading-4 text-[var(--oh-muted)]",
|
|
61
|
-
children:
|
|
62
|
+
children: a
|
|
62
63
|
})]
|
|
63
64
|
}, e.name);
|
|
64
65
|
})] }),
|
|
65
|
-
|
|
66
|
+
D && /* @__PURE__ */ v("li", {
|
|
66
67
|
className: "text-sm",
|
|
67
68
|
"data-testid": "chat-input-llm-profile-current",
|
|
68
|
-
children: /* @__PURE__ */
|
|
69
|
+
children: /* @__PURE__ */ y("div", {
|
|
69
70
|
className: "flex flex-col gap-0.5 p-2 leading-5 text-[var(--oh-foreground)]",
|
|
70
|
-
children: [/* @__PURE__ */
|
|
71
|
+
children: [/* @__PURE__ */ v("span", {
|
|
71
72
|
className: "truncate",
|
|
72
|
-
title:
|
|
73
|
-
children:
|
|
74
|
-
}),
|
|
73
|
+
title: D,
|
|
74
|
+
children: D
|
|
75
|
+
}), C && /* @__PURE__ */ v("span", {
|
|
75
76
|
className: "truncate text-xs leading-4 text-[var(--oh-muted)]",
|
|
76
|
-
children:
|
|
77
|
+
children: o(C, b)
|
|
77
78
|
})]
|
|
78
79
|
})
|
|
79
80
|
}),
|
|
80
|
-
(
|
|
81
|
-
/* @__PURE__ */
|
|
81
|
+
(E || D) && /* @__PURE__ */ v(m, { inset: c }),
|
|
82
|
+
/* @__PURE__ */ v("li", {
|
|
82
83
|
className: "text-sm",
|
|
83
|
-
children: /* @__PURE__ */
|
|
84
|
+
children: /* @__PURE__ */ y(p, {
|
|
84
85
|
to: "/settings/llm",
|
|
85
86
|
onClick: i,
|
|
86
|
-
className: n("flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)] transition-colors",
|
|
87
|
-
children: [/* @__PURE__ */
|
|
87
|
+
className: n("flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)] transition-colors", l),
|
|
88
|
+
children: [/* @__PURE__ */ v(f, {
|
|
88
89
|
width: 16,
|
|
89
90
|
height: 16,
|
|
90
|
-
className: n("shrink-0",
|
|
91
|
+
className: n("shrink-0", d),
|
|
91
92
|
"aria-hidden": !0
|
|
92
|
-
}), /* @__PURE__ */
|
|
93
|
+
}), /* @__PURE__ */ v("span", { children: g(t.SETTINGS$LLM_PROFILES) })]
|
|
93
94
|
})
|
|
94
95
|
})
|
|
95
96
|
] });
|
|
96
97
|
}
|
|
97
|
-
function
|
|
98
|
-
let { t: r } = e("openhands"), { profiles: a, currentProfileName: o, isLoading:
|
|
99
|
-
if (
|
|
100
|
-
let
|
|
101
|
-
return /* @__PURE__ */
|
|
98
|
+
function C() {
|
|
99
|
+
let { t: r } = e("openhands"), { profiles: a, currentProfileName: o, isLoading: s, isSwitching: u } = h(), [f, p] = g.useState(!1), m = g.useRef(null), _ = d(() => p(!1), m);
|
|
100
|
+
if (s || a.length === 0) return null;
|
|
101
|
+
let b = o ?? r(t.LLM$SELECT_MODEL_PLACEHOLDER);
|
|
102
|
+
return /* @__PURE__ */ y("div", {
|
|
102
103
|
className: "relative min-w-0",
|
|
103
|
-
children: [/* @__PURE__ */
|
|
104
|
-
ref:
|
|
104
|
+
children: [/* @__PURE__ */ y("button", {
|
|
105
|
+
ref: m,
|
|
105
106
|
type: "button",
|
|
106
107
|
className: n(i, "max-w-[200px]"),
|
|
107
108
|
title: o ?? void 0,
|
|
108
109
|
"data-testid": "chat-input-llm-profile",
|
|
109
110
|
"aria-expanded": f,
|
|
110
111
|
"aria-haspopup": "dialog",
|
|
111
|
-
disabled:
|
|
112
|
-
"aria-busy":
|
|
112
|
+
disabled: u,
|
|
113
|
+
"aria-busy": u,
|
|
113
114
|
onClick: (e) => {
|
|
114
115
|
e.preventDefault(), e.stopPropagation(), p((e) => !e);
|
|
115
116
|
},
|
|
116
|
-
children: [/* @__PURE__ */
|
|
117
|
+
children: [/* @__PURE__ */ v("span", {
|
|
117
118
|
className: "truncate",
|
|
118
|
-
children: b
|
|
119
|
-
}), /* @__PURE__ */
|
|
120
|
-
}), f && /* @__PURE__ */
|
|
121
|
-
ref:
|
|
119
|
+
children: x(b)
|
|
120
|
+
}), /* @__PURE__ */ v(c, { isOpen: f })]
|
|
121
|
+
}), f && /* @__PURE__ */ v(l, {
|
|
122
|
+
ref: _,
|
|
122
123
|
testId: "chat-input-llm-profile-popover",
|
|
123
124
|
position: "top",
|
|
124
125
|
alignment: "left",
|
|
125
126
|
spacing: "none",
|
|
126
127
|
className: "z-[60] mb-2 min-w-[200px] max-w-[320px] max-h-[60vh] overflow-y-auto",
|
|
127
|
-
children: /* @__PURE__ */
|
|
128
|
+
children: /* @__PURE__ */ v(S, { onClose: () => p(!1) })
|
|
128
129
|
})]
|
|
129
130
|
});
|
|
130
131
|
}
|
|
131
132
|
//#endregion
|
|
132
|
-
export {
|
|
133
|
+
export { S as ChatInputLlmProfileMenuContent, C as ChatInputLlmProfilePicker };
|
|
133
134
|
|
|
134
135
|
//# sourceMappingURL=chat-input-llm-profile-picker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-input-llm-profile-picker.js","names":[],"sources":["../../../../../src/components/features/chat/components/chat-input-llm-profile-picker.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useChatInputLlmProfileState } from \"#/hooks/use-chat-input-llm-profile-state\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport SettingsGearIcon from \"#/icons/settings-gear.svg?react\";\nimport CheckIcon from \"#/icons/checkmark.svg?react\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { ContextMenu } from \"#/ui/context-menu\";\nimport { ContextMenuListItem } from \"#/components/features/context-menu/context-menu-list-item\";\nimport { Divider } from \"#/ui/divider\";\nimport { Typography } from \"#/ui/typography\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\nimport { formatModelNameForDisplay } from \"#/utils/format-model-name\";\n\nconst PROFILE_LABEL_MAX_CHARS = 18;\n\nfunction truncateLabel(label: string): string {\n return label.length <= PROFILE_LABEL_MAX_CHARS\n ? label\n : `${label.slice(0, PROFILE_LABEL_MAX_CHARS)}…`;\n}\n\ninterface ChatInputLlmProfileMenuContentProps {\n onClose: () => void;\n dividerInset?: \"menu\";\n settingsLinkClassName?: string;\n settingsIconClassName?: string;\n}\n\n/**\n * The in-conversation OpenHands LLM-profile switcher list. Selecting a profile\n * live-swaps the running conversation's LLM via `/switch_profile` (the ACP\n * analog is {@link ChatInputModelMenuContent}). Shared by the inline pill and\n * the chat-input overflow submenu.\n */\nexport function ChatInputLlmProfileMenuContent({\n onClose,\n dividerInset,\n settingsLinkClassName,\n settingsIconClassName,\n}: ChatInputLlmProfileMenuContentProps) {\n const { t } = useTranslation(\"openhands\");\n const {\n profiles,\n currentProfileName,\n currentProfileModel,\n canSwitchProfile,\n selectProfile,\n } = useChatInputLlmProfileState();\n // Read-only surfaces (a cloud member on the home page, or a start-task route)\n // still name the active profile — the same shape ChatInputModelMenuContent\n // uses when the ACP picker is gated off.\n const showProfileList = canSwitchProfile && profiles.length > 0;\n const readOnlyProfileName = canSwitchProfile ? null : currentProfileName;\n\n const handleSelect = (profileName: string) => {\n selectProfile(profileName);\n onClose();\n };\n\n return (\n <>\n {showProfileList && (\n <>\n {/* role=\"presentation\" keeps this a valid <li> child of the\n ContextMenu <ul> without exposing the label as a menu item. */}\n <li role=\"presentation\" className=\"px-2 pt-1 pb-0.5\">\n <Typography.Text className=\"text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4\">\n {t(I18nKey.SETTINGS$AVAILABLE_PROFILES)}\n </Typography.Text>\n </li>\n {profiles.map((profile) => {\n const isCurrent = profile.name === currentProfileName;\n const displayModel = formatModelNameForDisplay(profile.model);\n return (\n <ContextMenuListItem\n key={profile.name}\n testId={`chat-input-llm-profile-option-${profile.name}`}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (isCurrent) {\n onClose();\n return;\n }\n handleSelect(profile.name);\n }}\n className={cn(\n \"flex flex-col items-stretch gap-0.5\",\n isCurrent && \"bg-[var(--oh-interactive-hover)]\",\n )}\n >\n <span className=\"flex items-center gap-2\">\n <span\n className=\"flex-1 truncate text-sm leading-5\"\n title={profile.model ?? profile.name}\n >\n {profile.name}\n </span>\n {isCurrent && (\n <CheckIcon\n width={14}\n height={14}\n className=\"shrink-0\"\n aria-hidden\n />\n )}\n </span>\n {displayModel && (\n <span className=\"block truncate text-xs leading-4 text-[var(--oh-muted)]\">\n {displayModel}\n </span>\n )}\n </ContextMenuListItem>\n );\n })}\n </>\n )}\n {readOnlyProfileName && (\n <li className=\"text-sm\" data-testid=\"chat-input-llm-profile-current\">\n <div className=\"flex flex-col gap-0.5 p-2 leading-5 text-[var(--oh-foreground)]\">\n <span className=\"truncate\" title={readOnlyProfileName}>\n {readOnlyProfileName}\n </span>\n {currentProfileModel && (\n <span className=\"truncate text-xs leading-4 text-[var(--oh-muted)]\">\n {formatModelNameForDisplay(currentProfileModel)}\n </span>\n )}\n </div>\n </li>\n )}\n {(showProfileList || readOnlyProfileName) && (\n <Divider inset={dividerInset} />\n )}\n <li className=\"text-sm\">\n <NavigationLink\n to=\"/settings/llm\"\n onClick={onClose}\n className={cn(\n \"flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)] transition-colors\",\n settingsLinkClassName,\n )}\n >\n <SettingsGearIcon\n width={16}\n height={16}\n className={cn(\"shrink-0\", settingsIconClassName)}\n aria-hidden\n />\n <span>{t(I18nKey.SETTINGS$LLM_PROFILES)}</span>\n </NavigationLink>\n </li>\n </>\n );\n}\n\nexport function ChatInputLlmProfilePicker() {\n const { t } = useTranslation(\"openhands\");\n const { profiles, currentProfileName, isLoading, isSwitching } =\n useChatInputLlmProfileState();\n const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const popoverRef = useClickOutsideElement<HTMLUListElement>(\n () => setIsPopoverOpen(false),\n triggerRef,\n );\n\n // No LLM profiles yet (or the agent-server lacks the surface): stay out of\n // the way, exactly like the ACP/AgentProfile pickers.\n if (isLoading || profiles.length === 0) {\n return null;\n }\n\n const label = currentProfileName ?? t(I18nKey.LLM$SELECT_MODEL_PLACEHOLDER);\n\n return (\n <div className=\"relative min-w-0\">\n <button\n ref={triggerRef}\n type=\"button\"\n className={cn(chatInputPillButtonClassName, \"max-w-[200px]\")}\n title={currentProfileName ?? undefined}\n data-testid=\"chat-input-llm-profile\"\n aria-expanded={isPopoverOpen}\n aria-haspopup=\"dialog\"\n // Disabled mid-switch so re-opening can't fire a second /switch_profile.\n disabled={isSwitching}\n aria-busy={isSwitching}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setIsPopoverOpen((open) => !open);\n }}\n >\n <span className=\"truncate\">{truncateLabel(label)}</span>\n <ComboboxCaretInline isOpen={isPopoverOpen} />\n </button>\n\n {isPopoverOpen && (\n <ContextMenu\n ref={popoverRef}\n testId=\"chat-input-llm-profile-popover\"\n position=\"top\"\n alignment=\"left\"\n spacing=\"none\"\n className=\"z-[60] mb-2 min-w-[200px] max-w-[320px] max-h-[60vh] overflow-y-auto\"\n >\n <ChatInputLlmProfileMenuContent\n onClose={() => setIsPopoverOpen(false)}\n />\n </ContextMenu>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chat-input-llm-profile-picker.js","names":[],"sources":["../../../../../src/components/features/chat/components/chat-input-llm-profile-picker.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useChatInputLlmProfileState } from \"#/hooks/use-chat-input-llm-profile-state\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport SettingsGearIcon from \"#/icons/settings-gear.svg?react\";\nimport CheckIcon from \"#/icons/checkmark.svg?react\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { ContextMenu } from \"#/ui/context-menu\";\nimport { ContextMenuListItem } from \"#/components/features/context-menu/context-menu-list-item\";\nimport { Divider } from \"#/ui/divider\";\nimport { Typography } from \"#/ui/typography\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\nimport { useFreeModels } from \"#/hooks/query/use-free-models\";\nimport { formatModelPillLabel } from \"#/utils/format-model-name\";\n\nconst PROFILE_LABEL_MAX_CHARS = 18;\n\nfunction truncateLabel(label: string): string {\n return label.length <= PROFILE_LABEL_MAX_CHARS\n ? label\n : `${label.slice(0, PROFILE_LABEL_MAX_CHARS)}…`;\n}\n\ninterface ChatInputLlmProfileMenuContentProps {\n onClose: () => void;\n dividerInset?: \"menu\";\n settingsLinkClassName?: string;\n settingsIconClassName?: string;\n}\n\n/**\n * The in-conversation OpenHands LLM-profile switcher list. Selecting a profile\n * live-swaps the running conversation's LLM via `/switch_profile` (the ACP\n * analog is {@link ChatInputModelMenuContent}). Shared by the inline pill and\n * the chat-input overflow submenu.\n */\nexport function ChatInputLlmProfileMenuContent({\n onClose,\n dividerInset,\n settingsLinkClassName,\n settingsIconClassName,\n}: ChatInputLlmProfileMenuContentProps) {\n const { t } = useTranslation(\"openhands\");\n const freeModels = useFreeModels();\n const {\n profiles,\n currentProfileName,\n currentProfileModel,\n canSwitchProfile,\n selectProfile,\n } = useChatInputLlmProfileState();\n // Read-only surfaces (a cloud member on the home page, or a start-task route)\n // still name the active profile — the same shape ChatInputModelMenuContent\n // uses when the ACP picker is gated off.\n const showProfileList = canSwitchProfile && profiles.length > 0;\n const readOnlyProfileName = canSwitchProfile ? null : currentProfileName;\n\n const handleSelect = (profileName: string) => {\n selectProfile(profileName);\n onClose();\n };\n\n return (\n <>\n {showProfileList && (\n <>\n {/* role=\"presentation\" keeps this a valid <li> child of the\n ContextMenu <ul> without exposing the label as a menu item. */}\n <li role=\"presentation\" className=\"px-2 pt-1 pb-0.5\">\n <Typography.Text className=\"text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4\">\n {t(I18nKey.SETTINGS$AVAILABLE_PROFILES)}\n </Typography.Text>\n </li>\n {profiles.map((profile) => {\n const isCurrent = profile.name === currentProfileName;\n const displayModel = formatModelPillLabel(\n profile.model,\n freeModels,\n );\n return (\n <ContextMenuListItem\n key={profile.name}\n testId={`chat-input-llm-profile-option-${profile.name}`}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (isCurrent) {\n onClose();\n return;\n }\n handleSelect(profile.name);\n }}\n className={cn(\n \"flex flex-col items-stretch gap-0.5\",\n isCurrent && \"bg-[var(--oh-interactive-hover)]\",\n )}\n >\n <span className=\"flex items-center gap-2\">\n <span\n className=\"flex-1 truncate text-sm leading-5\"\n title={profile.model ?? profile.name}\n >\n {profile.name}\n </span>\n {isCurrent && (\n <CheckIcon\n width={14}\n height={14}\n className=\"shrink-0\"\n aria-hidden\n />\n )}\n </span>\n {displayModel && (\n <span className=\"block truncate text-xs leading-4 text-[var(--oh-muted)]\">\n {displayModel}\n </span>\n )}\n </ContextMenuListItem>\n );\n })}\n </>\n )}\n {readOnlyProfileName && (\n <li className=\"text-sm\" data-testid=\"chat-input-llm-profile-current\">\n <div className=\"flex flex-col gap-0.5 p-2 leading-5 text-[var(--oh-foreground)]\">\n <span className=\"truncate\" title={readOnlyProfileName}>\n {readOnlyProfileName}\n </span>\n {currentProfileModel && (\n <span className=\"truncate text-xs leading-4 text-[var(--oh-muted)]\">\n {formatModelPillLabel(currentProfileModel, freeModels)}\n </span>\n )}\n </div>\n </li>\n )}\n {(showProfileList || readOnlyProfileName) && (\n <Divider inset={dividerInset} />\n )}\n <li className=\"text-sm\">\n <NavigationLink\n to=\"/settings/llm\"\n onClick={onClose}\n className={cn(\n \"flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)] transition-colors\",\n settingsLinkClassName,\n )}\n >\n <SettingsGearIcon\n width={16}\n height={16}\n className={cn(\"shrink-0\", settingsIconClassName)}\n aria-hidden\n />\n <span>{t(I18nKey.SETTINGS$LLM_PROFILES)}</span>\n </NavigationLink>\n </li>\n </>\n );\n}\n\nexport function ChatInputLlmProfilePicker() {\n const { t } = useTranslation(\"openhands\");\n const { profiles, currentProfileName, isLoading, isSwitching } =\n useChatInputLlmProfileState();\n const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const popoverRef = useClickOutsideElement<HTMLUListElement>(\n () => setIsPopoverOpen(false),\n triggerRef,\n );\n\n // No LLM profiles yet (or the agent-server lacks the surface): stay out of\n // the way, exactly like the ACP/AgentProfile pickers.\n if (isLoading || profiles.length === 0) {\n return null;\n }\n\n const label = currentProfileName ?? t(I18nKey.LLM$SELECT_MODEL_PLACEHOLDER);\n\n return (\n <div className=\"relative min-w-0\">\n <button\n ref={triggerRef}\n type=\"button\"\n className={cn(chatInputPillButtonClassName, \"max-w-[200px]\")}\n title={currentProfileName ?? undefined}\n data-testid=\"chat-input-llm-profile\"\n aria-expanded={isPopoverOpen}\n aria-haspopup=\"dialog\"\n // Disabled mid-switch so re-opening can't fire a second /switch_profile.\n disabled={isSwitching}\n aria-busy={isSwitching}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setIsPopoverOpen((open) => !open);\n }}\n >\n <span className=\"truncate\">{truncateLabel(label)}</span>\n <ComboboxCaretInline isOpen={isPopoverOpen} />\n </button>\n\n {isPopoverOpen && (\n <ContextMenu\n ref={popoverRef}\n testId=\"chat-input-llm-profile-popover\"\n position=\"top\"\n alignment=\"left\"\n spacing=\"none\"\n className=\"z-[60] mb-2 min-w-[200px] max-w-[320px] max-h-[60vh] overflow-y-auto\"\n >\n <ChatInputLlmProfileMenuContent\n onClose={() => setIsPopoverOpen(false)}\n />\n </ContextMenu>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/react-i18next/dist/es/Trans.cjs"),n=require("../../../i18n/declaration.cjs"),r=require("../../../node_modules/lucide-react/dist/esm/icons/chevron-down.cjs"),i=require("../../../node_modules/lucide-react/dist/esm/icons/chevron-right.cjs"),a=require("../../../stores/model-store.cjs"),o=require("./generic-event-message.cjs"),s=require("../../../icons/info-circle.cjs"),c=require("../../../utils/format-model-name.cjs");let
|
|
1
|
+
const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/react-i18next/dist/es/Trans.cjs"),n=require("../../../i18n/declaration.cjs"),r=require("../../../node_modules/lucide-react/dist/esm/icons/chevron-down.cjs"),i=require("../../../node_modules/lucide-react/dist/esm/icons/chevron-right.cjs"),a=require("../../../stores/model-store.cjs"),o=require("./generic-event-message.cjs"),s=require("../../../icons/info-circle.cjs"),c=require("../../../hooks/query/use-free-models.cjs"),l=require("../../../utils/format-model-name.cjs");let u=require("react");u=e.__toESM(u,1);let d=require("react/jsx-runtime");function f({profile:e}){let[t,n]=u.default.useState(!1),a=c.useFreeModels(),o=l.formatModelNameForDisplay(e.model,a);return(0,d.jsxs)(`div`,{className:`border border-neutral-700 rounded-md overflow-hidden`,children:[(0,d.jsxs)(`button`,{type:`button`,onClick:()=>n(e=>!e),"aria-expanded":t,"aria-label":`Toggle details for ${e.name}`,className:`w-full py-1.5 px-2 text-left flex items-center gap-2 hover:bg-neutral-700 transition-colors cursor-pointer`,children:[(0,d.jsx)(`span`,{className:`text-neutral-300`,children:t?(0,d.jsx)(r.ChevronDown,{size:14}):(0,d.jsx)(i.ChevronRight,{size:14})}),(0,d.jsx)(`span`,{className:`font-normal text-neutral-200 text-sm`,children:e.name})]}),t&&(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(`hr`,{className:`border-neutral-700`}),(0,d.jsx)(`div`,{className:`px-3 py-2 text-xs text-neutral-300 font-mono whitespace-pre-wrap`,children:`model: ${o??`—`}\nbase_url: ${e.base_url??`—`}\napi_key: ${e.api_key_set?`set`:`not set`}`})]})]})}function p({conversationId:e,anchorEventId:r}){let i=a.useModelStore(e=>e.entriesByConversation),c=(e?i[e]??[]:[]).filter(e=>e.anchorEventId===r);return!e||c.length===0?null:(0,d.jsx)(`div`,{"data-testid":`model-messages`,className:`flex flex-col w-full`,children:c.map(e=>{if(e.switchedTo)return(0,d.jsx)(o.GenericEventMessage,{title:(0,d.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,d.jsx)(s.default,{width:14,height:14,className:`shrink-0 text-neutral-400`,"aria-hidden":!0}),(0,d.jsx)(t.Trans,{i18nKey:n.I18nKey.MODEL$SWITCHED_TO_PROFILE,values:{name:e.switchedTo},components:{cmd:(0,d.jsx)(`span`,{className:`font-mono text-neutral-200 bg-neutral-800 px-1 rounded`})}})]}),details:``},e.id);let r=e.profiles.length===0;return(0,d.jsx)(o.GenericEventMessage,{title:(0,d.jsx)(`span`,{children:r?(0,d.jsx)(t.Trans,{i18nKey:n.I18nKey.MODEL$NO_SAVED_PROFILES}):(0,d.jsx)(t.Trans,{i18nKey:n.I18nKey.MODEL$AVAILABLE_PROFILES,values:{count:e.profiles.length}})}),details:r?(0,d.jsx)(`span`,{className:`text-neutral-300 text-sm px-2 py-1 block`,children:(0,d.jsx)(t.Trans,{i18nKey:n.I18nKey.MODEL$NO_PROFILES_HINT})}):(0,d.jsx)(`div`,{className:`flex flex-col gap-1 mt-1`,children:e.profiles.map(e=>(0,d.jsx)(f,{profile:e},e.name))}),initiallyExpanded:r},e.id)})})}exports.ModelMessages=p;
|
|
2
2
|
//# sourceMappingURL=model-messages.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-messages.cjs","names":[],"sources":["../../../../src/components/features/chat/model-messages.tsx"],"sourcesContent":["import React from \"react\";\nimport { Trans } from \"react-i18next\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport InfoCircleIcon from \"#/icons/info-circle.svg?react\";\nimport type { ProfileInfo } from \"#/api/profiles-service/profiles-service.api\";\nimport { formatModelNameForDisplay } from \"#/utils/format-model-name\";\nimport { GenericEventMessage } from \"./generic-event-message\";\n\ninterface ProfileRowProps {\n profile: ProfileInfo;\n}\n\nfunction ProfileRow({ profile }: ProfileRowProps) {\n const [expanded, setExpanded] = React.useState(false);\n const displayModel = formatModelNameForDisplay(profile.model);\n\n return (\n <div className=\"border border-neutral-700 rounded-md overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n aria-expanded={expanded}\n aria-label={`Toggle details for ${profile.name}`}\n className=\"w-full py-1.5 px-2 text-left flex items-center gap-2 hover:bg-neutral-700 transition-colors cursor-pointer\"\n >\n <span className=\"text-neutral-300\">\n {expanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n </span>\n <span className=\"font-normal text-neutral-200 text-sm\">\n {profile.name}\n </span>\n </button>\n {expanded && (\n <>\n <hr className=\"border-neutral-700\" />\n <div className=\"px-3 py-2 text-xs text-neutral-300 font-mono whitespace-pre-wrap\">\n {`model: ${displayModel ?? \"—\"}\\n` +\n `base_url: ${profile.base_url ?? \"—\"}\\n` +\n // eslint-disable-next-line i18next/no-literal-string -- diagnostic readout; field labels are intentionally untranslated\n `api_key: ${profile.api_key_set ? \"set\" : \"not set\"}`}\n </div>\n </>\n )}\n </div>\n );\n}\n\nexport interface ModelMessagesProps {\n conversationId: string | null | undefined;\n /**\n * Render only entries anchored to this event id. Use `null` to render the\n * \"no events at the time of /model\" entries (top of the chat history).\n */\n anchorEventId: string | null;\n}\n\nexport function ModelMessages({\n conversationId,\n anchorEventId,\n}: ModelMessagesProps) {\n const entriesById = useModelStore((s) => s.entriesByConversation);\n const allEntries = conversationId ? (entriesById[conversationId] ?? []) : [];\n const entries = allEntries.filter((e) => e.anchorEventId === anchorEventId);\n\n if (!conversationId || entries.length === 0) return null;\n\n return (\n <div data-testid=\"model-messages\" className=\"flex flex-col w-full\">\n {entries.map((entry) => {\n if (entry.switchedTo) {\n return (\n <GenericEventMessage\n key={entry.id}\n title={\n <span className=\"inline-flex items-center gap-1.5\">\n <InfoCircleIcon\n width={14}\n height={14}\n className=\"shrink-0 text-neutral-400\"\n aria-hidden\n />\n <Trans\n i18nKey={I18nKey.MODEL$SWITCHED_TO_PROFILE}\n values={{ name: entry.switchedTo }}\n components={{\n cmd: (\n <span className=\"font-mono text-neutral-200 bg-neutral-800 px-1 rounded\" />\n ),\n }}\n />\n </span>\n }\n details=\"\"\n />\n );\n }\n\n const isEmpty = entry.profiles.length === 0;\n return (\n <GenericEventMessage\n key={entry.id}\n title={\n <span>\n {isEmpty ? (\n <Trans i18nKey={I18nKey.MODEL$NO_SAVED_PROFILES} />\n ) : (\n <Trans\n i18nKey={I18nKey.MODEL$AVAILABLE_PROFILES}\n values={{ count: entry.profiles.length }}\n />\n )}\n </span>\n }\n details={\n isEmpty ? (\n <span className=\"text-neutral-300 text-sm px-2 py-1 block\">\n <Trans i18nKey={I18nKey.MODEL$NO_PROFILES_HINT} />\n </span>\n ) : (\n <div className=\"flex flex-col gap-1 mt-1\">\n {entry.profiles.map((p) => (\n <ProfileRow key={p.name} profile={p} />\n ))}\n </div>\n )\n }\n initiallyExpanded={isEmpty}\n />\n );\n })}\n </div>\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"model-messages.cjs","names":[],"sources":["../../../../src/components/features/chat/model-messages.tsx"],"sourcesContent":["import React from \"react\";\nimport { Trans } from \"react-i18next\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport InfoCircleIcon from \"#/icons/info-circle.svg?react\";\nimport type { ProfileInfo } from \"#/api/profiles-service/profiles-service.api\";\nimport { useFreeModels } from \"#/hooks/query/use-free-models\";\nimport { formatModelNameForDisplay } from \"#/utils/format-model-name\";\nimport { GenericEventMessage } from \"./generic-event-message\";\n\ninterface ProfileRowProps {\n profile: ProfileInfo;\n}\n\nfunction ProfileRow({ profile }: ProfileRowProps) {\n const [expanded, setExpanded] = React.useState(false);\n const freeModels = useFreeModels();\n const displayModel = formatModelNameForDisplay(profile.model, freeModels);\n\n return (\n <div className=\"border border-neutral-700 rounded-md overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n aria-expanded={expanded}\n aria-label={`Toggle details for ${profile.name}`}\n className=\"w-full py-1.5 px-2 text-left flex items-center gap-2 hover:bg-neutral-700 transition-colors cursor-pointer\"\n >\n <span className=\"text-neutral-300\">\n {expanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n </span>\n <span className=\"font-normal text-neutral-200 text-sm\">\n {profile.name}\n </span>\n </button>\n {expanded && (\n <>\n <hr className=\"border-neutral-700\" />\n <div className=\"px-3 py-2 text-xs text-neutral-300 font-mono whitespace-pre-wrap\">\n {`model: ${displayModel ?? \"—\"}\\n` +\n `base_url: ${profile.base_url ?? \"—\"}\\n` +\n // eslint-disable-next-line i18next/no-literal-string -- diagnostic readout; field labels are intentionally untranslated\n `api_key: ${profile.api_key_set ? \"set\" : \"not set\"}`}\n </div>\n </>\n )}\n </div>\n );\n}\n\nexport interface ModelMessagesProps {\n conversationId: string | null | undefined;\n /**\n * Render only entries anchored to this event id. Use `null` to render the\n * \"no events at the time of /model\" entries (top of the chat history).\n */\n anchorEventId: string | null;\n}\n\nexport function ModelMessages({\n conversationId,\n anchorEventId,\n}: ModelMessagesProps) {\n const entriesById = useModelStore((s) => s.entriesByConversation);\n const allEntries = conversationId ? (entriesById[conversationId] ?? []) : [];\n const entries = allEntries.filter((e) => e.anchorEventId === anchorEventId);\n\n if (!conversationId || entries.length === 0) return null;\n\n return (\n <div data-testid=\"model-messages\" className=\"flex flex-col w-full\">\n {entries.map((entry) => {\n if (entry.switchedTo) {\n return (\n <GenericEventMessage\n key={entry.id}\n title={\n <span className=\"inline-flex items-center gap-1.5\">\n <InfoCircleIcon\n width={14}\n height={14}\n className=\"shrink-0 text-neutral-400\"\n aria-hidden\n />\n <Trans\n i18nKey={I18nKey.MODEL$SWITCHED_TO_PROFILE}\n values={{ name: entry.switchedTo }}\n components={{\n cmd: (\n <span className=\"font-mono text-neutral-200 bg-neutral-800 px-1 rounded\" />\n ),\n }}\n />\n </span>\n }\n details=\"\"\n />\n );\n }\n\n const isEmpty = entry.profiles.length === 0;\n return (\n <GenericEventMessage\n key={entry.id}\n title={\n <span>\n {isEmpty ? (\n <Trans i18nKey={I18nKey.MODEL$NO_SAVED_PROFILES} />\n ) : (\n <Trans\n i18nKey={I18nKey.MODEL$AVAILABLE_PROFILES}\n values={{ count: entry.profiles.length }}\n />\n )}\n </span>\n }\n details={\n isEmpty ? (\n <span className=\"text-neutral-300 text-sm px-2 py-1 block\">\n <Trans i18nKey={I18nKey.MODEL$NO_PROFILES_HINT} />\n </span>\n ) : (\n <div className=\"flex flex-col gap-1 mt-1\">\n {entry.profiles.map((p) => (\n <ProfileRow key={p.name} profile={p} />\n ))}\n </div>\n )\n }\n initiallyExpanded={isEmpty}\n />\n );\n })}\n </div>\n );\n}\n"],"mappings":"+nBAeA,SAAS,EAAW,CAAE,WAA4B,CAChD,GAAM,CAAC,EAAU,GAAe,EAAA,QAAM,SAAS,EAAK,EAC9C,EAAa,EAAA,cAAc,EAC3B,EAAe,EAAA,0BAA0B,EAAQ,MAAO,CAAU,EAExE,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,gEAAf,EACE,EAAA,EAAA,MAAC,SAAD,CACE,KAAK,SACL,YAAe,EAAa,GAAM,CAAC,CAAC,EACpC,gBAAe,EACf,aAAY,sBAAsB,EAAQ,OAC1C,UAAU,sHALZ,EAOE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,4BACb,GAAW,EAAA,EAAA,KAAC,EAAA,YAAD,CAAa,KAAM,EAAK,CAAA,GAAI,EAAA,EAAA,KAAC,EAAA,aAAD,CAAc,KAAM,EAAK,CAAA,CAC7D,CAAA,GACN,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,gDACb,EAAQ,IACL,CAAA,CACA,IACP,IACC,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,oBAAsB,CAAA,GACpC,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,4EACZ,aAAa,GAAgB,IAAI,cACnB,EAAQ,UAAY,IAAI,cAExB,EAAQ,YAAc,MAAQ,WAC1C,CAAA,CACL,CAAA,CAAA,CAED,GAET,CAWA,SAAgB,EAAc,CAC5B,iBACA,iBACqB,CACrB,IAAM,EAAc,EAAA,cAAe,GAAM,EAAE,qBAAqB,EAE1D,GADa,EAAkB,EAAY,IAAmB,CAAC,EAAK,CAAC,GAChD,OAAQ,GAAM,EAAE,gBAAkB,CAAa,EAI1E,MAFI,CAAC,GAAkB,EAAQ,SAAW,EAAU,MAGlD,EAAA,EAAA,KAAC,MAAD,CAAK,cAAY,iBAAiB,UAAU,gCACzC,EAAQ,IAAK,GAAU,CACtB,GAAI,EAAM,WACR,OACE,EAAA,EAAA,KAAC,EAAA,oBAAD,CAEE,OACE,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,4CAAhB,EACE,EAAA,EAAA,KAAC,EAAA,QAAD,CACE,MAAO,GACP,OAAQ,GACR,UAAU,4BACV,cAAA,EACD,CAAA,GACD,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,QAAS,EAAA,QAAQ,0BACjB,OAAQ,CAAE,KAAM,EAAM,UAAW,EACjC,WAAY,CACV,KACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,wDAA0D,CAAA,CAE9E,CACD,CAAA,CACG,IAER,QAAQ,EACT,EArBM,EAAM,EAqBZ,EAIL,IAAM,EAAU,EAAM,SAAS,SAAW,EAC1C,OACE,EAAA,EAAA,KAAC,EAAA,oBAAD,CAEE,OACE,EAAA,EAAA,KAAC,OAAD,CAAA,SACG,GACC,EAAA,EAAA,KAAC,EAAA,MAAD,CAAO,QAAS,EAAA,QAAQ,uBAA0B,CAAA,GAElD,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,QAAS,EAAA,QAAQ,yBACjB,OAAQ,CAAE,MAAO,EAAM,SAAS,MAAO,CACxC,CAAA,CAEC,CAAA,EAER,QACE,GACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qDACd,EAAA,EAAA,KAAC,EAAA,MAAD,CAAO,QAAS,EAAA,QAAQ,sBAAyB,CAAA,CAC7C,CAAA,GAEN,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,oCACZ,EAAM,SAAS,IAAK,IACnB,EAAA,EAAA,KAAC,EAAD,CAAyB,QAAS,CAAI,EAArB,EAAE,IAAmB,CACvC,CACE,CAAA,EAGT,kBAAmB,CACpB,EA3BM,EAAM,EA2BZ,CAEL,CAAC,CACE,CAAA,CAET"}
|
|
@@ -5,67 +5,68 @@ import { ChevronRight as r } from "../../../node_modules/lucide-react/dist/esm/i
|
|
|
5
5
|
import { useModelStore as i } from "../../../stores/model-store.js";
|
|
6
6
|
import { GenericEventMessage as a } from "./generic-event-message.js";
|
|
7
7
|
import o from "../../../icons/info-circle.js";
|
|
8
|
-
import {
|
|
9
|
-
import c from "
|
|
10
|
-
import
|
|
8
|
+
import { useFreeModels as s } from "../../../hooks/query/use-free-models.js";
|
|
9
|
+
import { formatModelNameForDisplay as c } from "../../../utils/format-model-name.js";
|
|
10
|
+
import l from "react";
|
|
11
|
+
import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
11
12
|
//#region src/components/features/chat/model-messages.tsx
|
|
12
|
-
function
|
|
13
|
-
let [t, i] =
|
|
14
|
-
return /* @__PURE__ */
|
|
13
|
+
function p({ profile: e }) {
|
|
14
|
+
let [t, i] = l.useState(!1), a = s(), o = c(e.model, a);
|
|
15
|
+
return /* @__PURE__ */ f("div", {
|
|
15
16
|
className: "border border-neutral-700 rounded-md overflow-hidden",
|
|
16
|
-
children: [/* @__PURE__ */
|
|
17
|
+
children: [/* @__PURE__ */ f("button", {
|
|
17
18
|
type: "button",
|
|
18
19
|
onClick: () => i((e) => !e),
|
|
19
20
|
"aria-expanded": t,
|
|
20
21
|
"aria-label": `Toggle details for ${e.name}`,
|
|
21
22
|
className: "w-full py-1.5 px-2 text-left flex items-center gap-2 hover:bg-neutral-700 transition-colors cursor-pointer",
|
|
22
|
-
children: [/* @__PURE__ */
|
|
23
|
+
children: [/* @__PURE__ */ d("span", {
|
|
23
24
|
className: "text-neutral-300",
|
|
24
|
-
children:
|
|
25
|
-
}), /* @__PURE__ */
|
|
25
|
+
children: d(t ? n : r, { size: 14 })
|
|
26
|
+
}), /* @__PURE__ */ d("span", {
|
|
26
27
|
className: "font-normal text-neutral-200 text-sm",
|
|
27
28
|
children: e.name
|
|
28
29
|
})]
|
|
29
|
-
}), t && /* @__PURE__ */
|
|
30
|
+
}), t && /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("hr", { className: "border-neutral-700" }), /* @__PURE__ */ d("div", {
|
|
30
31
|
className: "px-3 py-2 text-xs text-neutral-300 font-mono whitespace-pre-wrap",
|
|
31
|
-
children: `model: ${
|
|
32
|
+
children: `model: ${o ?? "—"}\nbase_url: ${e.base_url ?? "—"}\napi_key: ${e.api_key_set ? "set" : "not set"}`
|
|
32
33
|
})] })]
|
|
33
34
|
});
|
|
34
35
|
}
|
|
35
|
-
function
|
|
36
|
+
function m({ conversationId: n, anchorEventId: r }) {
|
|
36
37
|
let s = i((e) => e.entriesByConversation), c = (n ? s[n] ?? [] : []).filter((e) => e.anchorEventId === r);
|
|
37
|
-
return !n || c.length === 0 ? null : /* @__PURE__ */
|
|
38
|
+
return !n || c.length === 0 ? null : /* @__PURE__ */ d("div", {
|
|
38
39
|
"data-testid": "model-messages",
|
|
39
40
|
className: "flex flex-col w-full",
|
|
40
41
|
children: c.map((n) => {
|
|
41
|
-
if (n.switchedTo) return /* @__PURE__ */
|
|
42
|
-
title: /* @__PURE__ */
|
|
42
|
+
if (n.switchedTo) return /* @__PURE__ */ d(a, {
|
|
43
|
+
title: /* @__PURE__ */ f("span", {
|
|
43
44
|
className: "inline-flex items-center gap-1.5",
|
|
44
|
-
children: [/* @__PURE__ */
|
|
45
|
+
children: [/* @__PURE__ */ d(o, {
|
|
45
46
|
width: 14,
|
|
46
47
|
height: 14,
|
|
47
48
|
className: "shrink-0 text-neutral-400",
|
|
48
49
|
"aria-hidden": !0
|
|
49
|
-
}), /* @__PURE__ */
|
|
50
|
+
}), /* @__PURE__ */ d(e, {
|
|
50
51
|
i18nKey: t.MODEL$SWITCHED_TO_PROFILE,
|
|
51
52
|
values: { name: n.switchedTo },
|
|
52
|
-
components: { cmd: /* @__PURE__ */
|
|
53
|
+
components: { cmd: /* @__PURE__ */ d("span", { className: "font-mono text-neutral-200 bg-neutral-800 px-1 rounded" }) }
|
|
53
54
|
})]
|
|
54
55
|
}),
|
|
55
56
|
details: ""
|
|
56
57
|
}, n.id);
|
|
57
58
|
let r = n.profiles.length === 0;
|
|
58
|
-
return /* @__PURE__ */
|
|
59
|
-
title: /* @__PURE__ */
|
|
59
|
+
return /* @__PURE__ */ d(a, {
|
|
60
|
+
title: /* @__PURE__ */ d("span", { children: r ? /* @__PURE__ */ d(e, { i18nKey: t.MODEL$NO_SAVED_PROFILES }) : /* @__PURE__ */ d(e, {
|
|
60
61
|
i18nKey: t.MODEL$AVAILABLE_PROFILES,
|
|
61
62
|
values: { count: n.profiles.length }
|
|
62
63
|
}) }),
|
|
63
|
-
details: r ? /* @__PURE__ */
|
|
64
|
+
details: r ? /* @__PURE__ */ d("span", {
|
|
64
65
|
className: "text-neutral-300 text-sm px-2 py-1 block",
|
|
65
|
-
children: /* @__PURE__ */
|
|
66
|
-
}) : /* @__PURE__ */
|
|
66
|
+
children: /* @__PURE__ */ d(e, { i18nKey: t.MODEL$NO_PROFILES_HINT })
|
|
67
|
+
}) : /* @__PURE__ */ d("div", {
|
|
67
68
|
className: "flex flex-col gap-1 mt-1",
|
|
68
|
-
children: n.profiles.map((e) => /* @__PURE__ */
|
|
69
|
+
children: n.profiles.map((e) => /* @__PURE__ */ d(p, { profile: e }, e.name))
|
|
69
70
|
}),
|
|
70
71
|
initiallyExpanded: r
|
|
71
72
|
}, n.id);
|
|
@@ -73,6 +74,6 @@ function p({ conversationId: n, anchorEventId: r }) {
|
|
|
73
74
|
});
|
|
74
75
|
}
|
|
75
76
|
//#endregion
|
|
76
|
-
export {
|
|
77
|
+
export { m as ModelMessages };
|
|
77
78
|
|
|
78
79
|
//# sourceMappingURL=model-messages.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-messages.js","names":[],"sources":["../../../../src/components/features/chat/model-messages.tsx"],"sourcesContent":["import React from \"react\";\nimport { Trans } from \"react-i18next\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport InfoCircleIcon from \"#/icons/info-circle.svg?react\";\nimport type { ProfileInfo } from \"#/api/profiles-service/profiles-service.api\";\nimport { formatModelNameForDisplay } from \"#/utils/format-model-name\";\nimport { GenericEventMessage } from \"./generic-event-message\";\n\ninterface ProfileRowProps {\n profile: ProfileInfo;\n}\n\nfunction ProfileRow({ profile }: ProfileRowProps) {\n const [expanded, setExpanded] = React.useState(false);\n const displayModel = formatModelNameForDisplay(profile.model);\n\n return (\n <div className=\"border border-neutral-700 rounded-md overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n aria-expanded={expanded}\n aria-label={`Toggle details for ${profile.name}`}\n className=\"w-full py-1.5 px-2 text-left flex items-center gap-2 hover:bg-neutral-700 transition-colors cursor-pointer\"\n >\n <span className=\"text-neutral-300\">\n {expanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n </span>\n <span className=\"font-normal text-neutral-200 text-sm\">\n {profile.name}\n </span>\n </button>\n {expanded && (\n <>\n <hr className=\"border-neutral-700\" />\n <div className=\"px-3 py-2 text-xs text-neutral-300 font-mono whitespace-pre-wrap\">\n {`model: ${displayModel ?? \"—\"}\\n` +\n `base_url: ${profile.base_url ?? \"—\"}\\n` +\n // eslint-disable-next-line i18next/no-literal-string -- diagnostic readout; field labels are intentionally untranslated\n `api_key: ${profile.api_key_set ? \"set\" : \"not set\"}`}\n </div>\n </>\n )}\n </div>\n );\n}\n\nexport interface ModelMessagesProps {\n conversationId: string | null | undefined;\n /**\n * Render only entries anchored to this event id. Use `null` to render the\n * \"no events at the time of /model\" entries (top of the chat history).\n */\n anchorEventId: string | null;\n}\n\nexport function ModelMessages({\n conversationId,\n anchorEventId,\n}: ModelMessagesProps) {\n const entriesById = useModelStore((s) => s.entriesByConversation);\n const allEntries = conversationId ? (entriesById[conversationId] ?? []) : [];\n const entries = allEntries.filter((e) => e.anchorEventId === anchorEventId);\n\n if (!conversationId || entries.length === 0) return null;\n\n return (\n <div data-testid=\"model-messages\" className=\"flex flex-col w-full\">\n {entries.map((entry) => {\n if (entry.switchedTo) {\n return (\n <GenericEventMessage\n key={entry.id}\n title={\n <span className=\"inline-flex items-center gap-1.5\">\n <InfoCircleIcon\n width={14}\n height={14}\n className=\"shrink-0 text-neutral-400\"\n aria-hidden\n />\n <Trans\n i18nKey={I18nKey.MODEL$SWITCHED_TO_PROFILE}\n values={{ name: entry.switchedTo }}\n components={{\n cmd: (\n <span className=\"font-mono text-neutral-200 bg-neutral-800 px-1 rounded\" />\n ),\n }}\n />\n </span>\n }\n details=\"\"\n />\n );\n }\n\n const isEmpty = entry.profiles.length === 0;\n return (\n <GenericEventMessage\n key={entry.id}\n title={\n <span>\n {isEmpty ? (\n <Trans i18nKey={I18nKey.MODEL$NO_SAVED_PROFILES} />\n ) : (\n <Trans\n i18nKey={I18nKey.MODEL$AVAILABLE_PROFILES}\n values={{ count: entry.profiles.length }}\n />\n )}\n </span>\n }\n details={\n isEmpty ? (\n <span className=\"text-neutral-300 text-sm px-2 py-1 block\">\n <Trans i18nKey={I18nKey.MODEL$NO_PROFILES_HINT} />\n </span>\n ) : (\n <div className=\"flex flex-col gap-1 mt-1\">\n {entry.profiles.map((p) => (\n <ProfileRow key={p.name} profile={p} />\n ))}\n </div>\n )\n }\n initiallyExpanded={isEmpty}\n />\n );\n })}\n </div>\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"model-messages.js","names":[],"sources":["../../../../src/components/features/chat/model-messages.tsx"],"sourcesContent":["import React from \"react\";\nimport { Trans } from \"react-i18next\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport InfoCircleIcon from \"#/icons/info-circle.svg?react\";\nimport type { ProfileInfo } from \"#/api/profiles-service/profiles-service.api\";\nimport { useFreeModels } from \"#/hooks/query/use-free-models\";\nimport { formatModelNameForDisplay } from \"#/utils/format-model-name\";\nimport { GenericEventMessage } from \"./generic-event-message\";\n\ninterface ProfileRowProps {\n profile: ProfileInfo;\n}\n\nfunction ProfileRow({ profile }: ProfileRowProps) {\n const [expanded, setExpanded] = React.useState(false);\n const freeModels = useFreeModels();\n const displayModel = formatModelNameForDisplay(profile.model, freeModels);\n\n return (\n <div className=\"border border-neutral-700 rounded-md overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n aria-expanded={expanded}\n aria-label={`Toggle details for ${profile.name}`}\n className=\"w-full py-1.5 px-2 text-left flex items-center gap-2 hover:bg-neutral-700 transition-colors cursor-pointer\"\n >\n <span className=\"text-neutral-300\">\n {expanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n </span>\n <span className=\"font-normal text-neutral-200 text-sm\">\n {profile.name}\n </span>\n </button>\n {expanded && (\n <>\n <hr className=\"border-neutral-700\" />\n <div className=\"px-3 py-2 text-xs text-neutral-300 font-mono whitespace-pre-wrap\">\n {`model: ${displayModel ?? \"—\"}\\n` +\n `base_url: ${profile.base_url ?? \"—\"}\\n` +\n // eslint-disable-next-line i18next/no-literal-string -- diagnostic readout; field labels are intentionally untranslated\n `api_key: ${profile.api_key_set ? \"set\" : \"not set\"}`}\n </div>\n </>\n )}\n </div>\n );\n}\n\nexport interface ModelMessagesProps {\n conversationId: string | null | undefined;\n /**\n * Render only entries anchored to this event id. Use `null` to render the\n * \"no events at the time of /model\" entries (top of the chat history).\n */\n anchorEventId: string | null;\n}\n\nexport function ModelMessages({\n conversationId,\n anchorEventId,\n}: ModelMessagesProps) {\n const entriesById = useModelStore((s) => s.entriesByConversation);\n const allEntries = conversationId ? (entriesById[conversationId] ?? []) : [];\n const entries = allEntries.filter((e) => e.anchorEventId === anchorEventId);\n\n if (!conversationId || entries.length === 0) return null;\n\n return (\n <div data-testid=\"model-messages\" className=\"flex flex-col w-full\">\n {entries.map((entry) => {\n if (entry.switchedTo) {\n return (\n <GenericEventMessage\n key={entry.id}\n title={\n <span className=\"inline-flex items-center gap-1.5\">\n <InfoCircleIcon\n width={14}\n height={14}\n className=\"shrink-0 text-neutral-400\"\n aria-hidden\n />\n <Trans\n i18nKey={I18nKey.MODEL$SWITCHED_TO_PROFILE}\n values={{ name: entry.switchedTo }}\n components={{\n cmd: (\n <span className=\"font-mono text-neutral-200 bg-neutral-800 px-1 rounded\" />\n ),\n }}\n />\n </span>\n }\n details=\"\"\n />\n );\n }\n\n const isEmpty = entry.profiles.length === 0;\n return (\n <GenericEventMessage\n key={entry.id}\n title={\n <span>\n {isEmpty ? (\n <Trans i18nKey={I18nKey.MODEL$NO_SAVED_PROFILES} />\n ) : (\n <Trans\n i18nKey={I18nKey.MODEL$AVAILABLE_PROFILES}\n values={{ count: entry.profiles.length }}\n />\n )}\n </span>\n }\n details={\n isEmpty ? (\n <span className=\"text-neutral-300 text-sm px-2 py-1 block\">\n <Trans i18nKey={I18nKey.MODEL$NO_PROFILES_HINT} />\n </span>\n ) : (\n <div className=\"flex flex-col gap-1 mt-1\">\n {entry.profiles.map((p) => (\n <ProfileRow key={p.name} profile={p} />\n ))}\n </div>\n )\n }\n initiallyExpanded={isEmpty}\n />\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAeA,SAAS,EAAW,EAAE,cAA4B;CAChD,IAAM,CAAC,GAAU,KAAe,EAAM,SAAS,EAAK,GAC9C,IAAa,EAAc,GAC3B,IAAe,EAA0B,EAAQ,OAAO,CAAU;CAExE,OACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,GAAa,MAAM,CAAC,CAAC;GACpC,iBAAe;GACf,cAAY,sBAAsB,EAAQ;GAC1C,WAAU;aALZ,CAOE,kBAAC,QAAD;IAAM,WAAU;cACF,EAAX,IAAY,IAA4B,GAA7B,EAAa,MAAM,GAAK,CAA6B;GAC7D,CAAA,GACN,kBAAC,QAAD;IAAM,WAAU;cACb,EAAQ;GACL,CAAA,CACA;MACP,KACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,MAAD,EAAI,WAAU,qBAAsB,CAAA,GACpC,kBAAC,OAAD;GAAK,WAAU;aACZ,aAAa,KAAgB,IAAI,cACnB,EAAQ,YAAY,IAAI,cAExB,EAAQ,cAAc,QAAQ;EAC1C,CAAA,CACL,EAAA,CAAA,CAED;;AAET;AAWA,SAAgB,EAAc,EAC5B,mBACA,oBACqB;CACrB,IAAM,IAAc,GAAe,MAAM,EAAE,qBAAqB,GAE1D,KADa,IAAkB,EAAY,MAAmB,CAAC,IAAK,CAAC,GAChD,QAAQ,MAAM,EAAE,kBAAkB,CAAa;CAI1E,OAFI,CAAC,KAAkB,EAAQ,WAAW,IAAU,OAGlD,kBAAC,OAAD;EAAK,eAAY;EAAiB,WAAU;YACzC,EAAQ,KAAK,MAAU;GACtB,IAAI,EAAM,YACR,OACE,kBAAC,GAAD;IAEE,OACE,kBAAC,QAAD;KAAM,WAAU;eAAhB,CACE,kBAAC,GAAD;MACE,OAAO;MACP,QAAQ;MACR,WAAU;MACV,eAAA;KACD,CAAA,GACD,kBAAC,GAAD;MACE,SAAS,EAAQ;MACjB,QAAQ,EAAE,MAAM,EAAM,WAAW;MACjC,YAAY,EACV,KACE,kBAAC,QAAD,EAAM,WAAU,yDAA0D,CAAA,EAE9E;KACD,CAAA,CACG;;IAER,SAAQ;GACT,GArBM,EAAM,EAqBZ;GAIL,IAAM,IAAU,EAAM,SAAS,WAAW;GAC1C,OACE,kBAAC,GAAD;IAEE,OACE,kBAAC,QAAD,EAAA,UACG,IACC,kBAAC,GAAD,EAAO,SAAS,EAAQ,wBAA0B,CAAA,IAElD,kBAAC,GAAD;KACE,SAAS,EAAQ;KACjB,QAAQ,EAAE,OAAO,EAAM,SAAS,OAAO;IACxC,CAAA,EAEC,CAAA;IAER,SACE,IACE,kBAAC,QAAD;KAAM,WAAU;eACd,kBAAC,GAAD,EAAO,SAAS,EAAQ,uBAAyB,CAAA;IAC7C,CAAA,IAEN,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAM,SAAS,KAAK,MACnB,kBAAC,GAAD,EAAyB,SAAS,EAAI,GAArB,EAAE,IAAmB,CACvC;IACE,CAAA;IAGT,mBAAmB;GACpB,GA3BM,EAAM,EA2BZ;EAEL,CAAC;CACE,CAAA;AAET"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
require("../../../_virtual/_rolldown/runtime.cjs");const e=require("./budget-progress-bar.cjs"),t=require("./budget-usage-text.cjs");let n=require("react/jsx-runtime");function r({cost:r,maxBudgetPerTask:i}){return r===null||i===null||i<=0?null:(0,n.jsxs)(`div`,{children:[(0,n.jsx)(e.BudgetProgressBar,{currentCost:r,maxBudget:i}),(0,n.jsx)(t.BudgetUsageText,{currentCost:r,maxBudget:i})]})}exports.BudgetDisplay=r;
|
|
2
2
|
//# sourceMappingURL=budget-display.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"budget-display.cjs","names":[],"sources":["../../../../src/components/features/conversation-panel/budget-display.tsx"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"budget-display.cjs","names":[],"sources":["../../../../src/components/features/conversation-panel/budget-display.tsx"],"sourcesContent":["import { BudgetProgressBar } from \"./budget-progress-bar\";\nimport { BudgetUsageText } from \"./budget-usage-text\";\n\ninterface BudgetDisplayProps {\n cost: number | null;\n maxBudgetPerTask: number | null;\n}\n\nexport function BudgetDisplay({ cost, maxBudgetPerTask }: BudgetDisplayProps) {\n // Only render the cap/progress UI when a real per-conversation budget cap\n // exists. There is currently no way for a user to set max_budget_per_task,\n // so showing a \"No budget limit\" line is misleading — omit it entirely\n // and let the surrounding cost/usage rows speak for themselves.\n if (cost === null || maxBudgetPerTask === null || maxBudgetPerTask <= 0) {\n return null;\n }\n\n return (\n <div>\n <BudgetProgressBar currentCost={cost} maxBudget={maxBudgetPerTask} />\n <BudgetUsageText currentCost={cost} maxBudget={maxBudgetPerTask} />\n </div>\n );\n}\n"],"mappings":"wKAQA,SAAgB,EAAc,CAAE,OAAM,oBAAwC,CAS5E,OAJI,IAAS,MAAQ,IAAqB,MAAQ,GAAoB,EAC7D,MAIP,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,kBAAD,CAAmB,YAAa,EAAM,UAAW,CAAmB,CAAA,GACpE,EAAA,EAAA,KAAC,EAAA,gBAAD,CAAiB,YAAa,EAAM,UAAW,CAAmB,CAAA,CAC/D,CAAA,CAAA,CAET"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
interface BudgetDisplayProps {
|
|
3
2
|
cost: number | null;
|
|
4
3
|
maxBudgetPerTask: number | null;
|
|
5
4
|
}
|
|
6
|
-
export declare function BudgetDisplay({ cost, maxBudgetPerTask }: BudgetDisplayProps):
|
|
5
|
+
export declare function BudgetDisplay({ cost, maxBudgetPerTask }: BudgetDisplayProps): import("react").JSX.Element | null;
|
|
7
6
|
export {};
|
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { BudgetUsageText as r } from "./budget-usage-text.js";
|
|
5
|
-
import "react";
|
|
6
|
-
import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
1
|
+
import { BudgetProgressBar as e } from "./budget-progress-bar.js";
|
|
2
|
+
import { BudgetUsageText as t } from "./budget-usage-text.js";
|
|
3
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
7
4
|
//#region src/components/features/conversation-panel/budget-display.tsx
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
})] }) : /* @__PURE__ */ a("span", {
|
|
17
|
-
className: "text-xs text-[var(--oh-muted)]",
|
|
18
|
-
children: l(t.CONVERSATION$NO_BUDGET_LIMIT)
|
|
19
|
-
}) });
|
|
5
|
+
function i({ cost: i, maxBudgetPerTask: a }) {
|
|
6
|
+
return i === null || a === null || a <= 0 ? null : /* @__PURE__ */ r("div", { children: [/* @__PURE__ */ n(e, {
|
|
7
|
+
currentCost: i,
|
|
8
|
+
maxBudget: a
|
|
9
|
+
}), /* @__PURE__ */ n(t, {
|
|
10
|
+
currentCost: i,
|
|
11
|
+
maxBudget: a
|
|
12
|
+
})] });
|
|
20
13
|
}
|
|
21
14
|
//#endregion
|
|
22
|
-
export {
|
|
15
|
+
export { i as BudgetDisplay };
|
|
23
16
|
|
|
24
17
|
//# sourceMappingURL=budget-display.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"budget-display.js","names":[],"sources":["../../../../src/components/features/conversation-panel/budget-display.tsx"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"budget-display.js","names":[],"sources":["../../../../src/components/features/conversation-panel/budget-display.tsx"],"sourcesContent":["import { BudgetProgressBar } from \"./budget-progress-bar\";\nimport { BudgetUsageText } from \"./budget-usage-text\";\n\ninterface BudgetDisplayProps {\n cost: number | null;\n maxBudgetPerTask: number | null;\n}\n\nexport function BudgetDisplay({ cost, maxBudgetPerTask }: BudgetDisplayProps) {\n // Only render the cap/progress UI when a real per-conversation budget cap\n // exists. There is currently no way for a user to set max_budget_per_task,\n // so showing a \"No budget limit\" line is misleading — omit it entirely\n // and let the surrounding cost/usage rows speak for themselves.\n if (cost === null || maxBudgetPerTask === null || maxBudgetPerTask <= 0) {\n return null;\n }\n\n return (\n <div>\n <BudgetProgressBar currentCost={cost} maxBudget={maxBudgetPerTask} />\n <BudgetUsageText currentCost={cost} maxBudget={maxBudgetPerTask} />\n </div>\n );\n}\n"],"mappings":";;;;AAQA,SAAgB,EAAc,EAAE,SAAM,uBAAwC;CAS5E,OAJI,MAAS,QAAQ,MAAqB,QAAQ,KAAoB,IAC7D,OAIP,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EAAmB,aAAa;EAAM,WAAW;CAAmB,CAAA,GACpE,kBAAC,GAAD;EAAiB,aAAa;EAAM,WAAW;CAAmB,CAAA,CAC/D,EAAA,CAAA;AAET"}
|