@openhands/agent-canvas 1.17.0 → 1.19.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-BQ4o4vqy.js +1 -0
- package/build/assets/active-backend-context-BsLfwrXB.js +2 -0
- package/build/assets/{agent-context-settings-CJUrcBut.js → agent-context-settings-D9i6ezoJ.js} +1 -1
- package/build/assets/{agent-profiles-service.api-Biieml2L.js → agent-profiles-service.api-U-9YzDFU.js} +1 -1
- package/build/assets/agent-profiles-settings-D-bUV2PX.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-BaVQ6NpE.js +88 -0
- package/build/assets/agent-settings-BZJHtaIK.js +2 -0
- package/build/assets/agent-settings-D4snDd6u.js +1 -0
- package/build/assets/alert-banner-BkVt_8Or.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-fAIld-n7.js +1 -0
- package/build/assets/app-settings-DITbrM2u.js +1 -0
- package/build/assets/automation-detail-DawHmaOl.js +3 -0
- package/build/assets/automation-disabled-reason-DtgC8Ppt.js +1 -0
- package/build/assets/{automation-export-DxY47m3T.js → automation-export-Kv6e0bHx.js} +1 -1
- package/build/assets/automation-git-sync-Dd98G_Oz.js +1 -0
- package/build/assets/automation-setup-route-Cdc109ZD.js +3 -0
- package/build/assets/{automation-templates-4C4PM8K7.js → automation-templates-Xhr-FDAB.js} +1 -1
- package/build/assets/automations-list-BeP1LuzQ.js +1 -0
- package/build/assets/{back-nav-button-B8tH0BEp.js → back-nav-button-DWNiN277.js} +1 -1
- package/build/assets/backend-form-modal-DeaUJIik.js +1 -0
- package/build/assets/backend-synced-settings-badge-Br85iWIY.js +1 -0
- package/build/assets/badge-Cdnei7Ly.js +1 -0
- package/build/assets/{base-modal-DTULovNc.js → base-modal-Ds7grR67.js} +1 -1
- package/build/assets/{bot-CLMxGFaq.js → bot-ByolqPEr.js} +1 -1
- package/build/assets/{brand-button-DxPO4Lf8.js → brand-button-mQq2Ld1I.js} +1 -1
- package/build/assets/browser-Bfum8fkE.js +46 -0
- package/build/assets/browser-tab-CmYT4j_r.js +1 -0
- package/build/assets/canvas-extension-page-CokKSVRG.js +1 -0
- package/build/assets/canvas-extensions-BoQEYG-2.js +1 -0
- package/build/assets/{canvas-extensions-runtime-DdnkgJXV.js → canvas-extensions-runtime-Du2M5iEX.js} +1 -1
- package/build/assets/{chat-send-button-B3SFSIg5.js → chat-send-button-DM3JgMc2.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-BbYBiUwv.js +1 -0
- package/build/assets/{cloud-funnel-analytics-BQanUEEC.js → cloud-funnel-analytics-D02kgq1s.js} +1 -1
- package/build/assets/{cog-VBlRo6iw.js → cog-Dy1eWbSZ.js} +1 -1
- package/build/assets/command-menu-mehU3Evb.js +1 -0
- package/build/assets/commits-tab-DhQW8CXi.js +1 -0
- package/build/assets/{condenser-settings-eVKFMvap.js → condenser-settings-eRk6Fkx6.js} +1 -1
- package/build/assets/confirmation-modal-BmVt_c0I.js +1 -0
- package/build/assets/{context-menu-list-item-DDROe12Z.js → context-menu-list-item-lx2zk9G7.js} +1 -1
- package/build/assets/{conversation-BnjJSFf5.js → conversation-BOj0ENI6.js} +8 -8
- package/build/assets/conversation-SouWlGvs.js +1 -0
- package/build/assets/conversation-panel-SouWlGvs.js +1 -0
- package/build/assets/conversation-state-store-C6YncQNo.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-DIhwCC2J.js} +1 -1
- package/build/assets/copy-to-clipboard-button-DVNXLylP.js +1 -0
- package/build/assets/device-verify-LP-x7nra.js +1 -0
- package/build/assets/{dropdown-classes-B9kJVDIk.js → dropdown-classes-goDldkiu.js} +1 -1
- package/build/assets/edit-automation-modal-BJJR9wSW.js +1 -0
- package/build/assets/empty-state-Cd-TFe7i.js +1 -0
- package/build/assets/{entry.client-Ds8LVp-E.js → entry.client-CJdjIvMZ.js} +2 -2
- package/build/assets/enum-filter-dropdown-pocrz9AL.js +1 -0
- package/build/assets/environment-switch-overlay-Dwe78wRl.js +1 -0
- package/build/assets/error-state-SuWwztxV.js +1 -0
- package/build/assets/extensions-hub-O0esK3Er.js +1 -0
- package/build/assets/extensions-navigation-CgCVSXje.js +1 -0
- package/build/assets/{external-link-DQtv7eTh.js → external-link-Bd7Tga-1.js} +1 -1
- package/build/assets/files-tab-B_6t8ljw.js +1 -0
- package/build/assets/{form-control-classes-B-z85REi.js → form-control-classes-lQfLxzH4.js} +1 -1
- package/build/assets/format-model-name-Dfh9Udrx.js +1 -0
- package/build/assets/get-git-path-Bp5rsUkl.js +1 -0
- package/build/assets/git-repo-dropdown-CbD0_LPN.js +1 -0
- package/build/assets/git-repo-dropdown-DPQVumZg.js +1 -0
- package/build/assets/highlighted-source-view-Bp0sgK-f.js +1 -0
- package/build/assets/home-BghzJd-D.js +1 -0
- package/build/assets/home-CXZ8zawS.js +1 -0
- package/build/assets/home-automation-run-tooltip-BdpCckKO.js +1 -0
- package/build/assets/home-store-DNQpfIEO.js +1 -0
- package/build/assets/hooks-service-DkxnQa4N.js +1 -0
- package/build/assets/index-home-Ca6Q5CtT.js +1 -0
- package/build/assets/info-BcajzHn1.js +1 -0
- package/build/assets/install-server-modal-DvxxYKia.js +1 -0
- package/build/assets/{key-CfXbJa8w.js → key-CwTE6XJj.js} +1 -1
- package/build/assets/launch-jsRGPRBx.js +1 -0
- package/build/assets/link-external-B4gx3EeM.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-DMdL1vaX.js +27 -0
- package/build/assets/llm-settings-dkQ5Oq7W.js +1 -0
- package/build/assets/llm-settings-lNDerSlu.js +1 -0
- package/build/assets/{llm-subscription-service-aDNBQ7Gq.js → llm-subscription-service-BiQaZbvv.js} +1 -1
- package/build/assets/loader-circle-BxJgk73D.js +1 -0
- package/build/assets/{loading-spinner-DfHI77BA.js → loading-spinner-DK1sAwVg.js} +1 -1
- package/build/assets/manage-backends-modal-DqCJohsX.js +1 -0
- package/build/assets/manifest-ff93dc8c.js +1 -0
- package/build/assets/manifest-subpage-layout-sxuPqfUr.js +1 -0
- package/build/assets/{map-provider-DXvssjw9.js → map-provider-iRs80q_6.js} +1 -1
- package/build/assets/markdown-renderer-BH5pqDuJ.js +8 -0
- package/build/assets/mcp-BtaJDXnP.js +1 -0
- package/build/assets/mcp-installed-servers-Br4ZLsjr.js +1 -0
- package/build/assets/mcp-marketplace-utils-BwEnDYqm.js +1 -0
- package/build/assets/mcp-page-DwbnQpVs.js +9 -0
- package/build/assets/messages-DmFJlW6c.js +41 -0
- package/build/assets/{modal-body-DJw4xBki.js → modal-body-DBweM2EN.js} +1 -1
- package/build/assets/{modal-classes-Dg0ngBPO.js → modal-classes-jvG85nkU.js} +1 -1
- package/build/assets/modal-close-button-BrM5fNnn.js +1 -0
- package/build/assets/{mouse-pointer-click-DEhsSUpu.js → mouse-pointer-click-BXlRN92t.js} +1 -1
- package/build/assets/onboarding-CQ8T6T0U.js +1 -0
- package/build/assets/onboarding-modal-CnliiaSN.js +1 -0
- package/build/assets/{organization-service.api-Cyg1Tn03.js → organization-service.api-DmFUEmu5.js} +1 -1
- package/build/assets/parse-git-remote-url-BG8pcKL8.js +1 -0
- 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-CXph_C9F.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-CcEpfNKz.js} +1 -1
- package/build/assets/plus-C2e21TFC.js +1 -0
- package/build/assets/{profiles-service.api-BbOK0EkF.js → profiles-service.api-DdF_4Zhe.js} +1 -1
- package/build/assets/providers-BWRnl31s.js +1 -0
- package/build/assets/proxy-DbEf3Nqr.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-r0oI91HN.js +1 -0
- package/build/assets/{refresh-cw-DEQdPCpH.js → refresh-cw-BtdC3T8P.js} +1 -1
- package/build/assets/root-j2fFRlWS.js +2 -0
- package/build/assets/root-layout-CfGgm2lo.js +2 -0
- package/build/assets/root-sEWn3ha1.css +1 -0
- package/build/assets/schema-field-c3Ncgm4x.js +1 -0
- package/build/assets/sdk-section-page-DFEiuiFQ.js +1 -0
- package/build/assets/secret-form-WXXNFqTM.js +1 -0
- package/build/assets/{secrets-service-Cr8g8xuv.js → secrets-service-DU6wh3wX.js} +1 -1
- package/build/assets/secrets-settings-BEqbPvjy.js +1 -0
- package/build/assets/settings-DjaSQwFh.js +1 -0
- package/build/assets/settings-dropdown-input-BRR2OZwi.js +1 -0
- package/build/assets/settings-index-DHv4XFcM.js +1 -0
- package/build/assets/settings-input-Cm4VxUon.js +1 -0
- package/build/assets/{settings-list-classes-Ds4jPBHK.js → settings-list-classes-CaUfKZ33.js} +1 -1
- package/build/assets/settings-modal-djXuAnBO.js +1 -0
- package/build/assets/settings-nav-DFb3hBMr.js +16 -0
- package/build/assets/{settings-service.api-9_xdv_mh.js → settings-service.api-Q9lKW1TX.js} +1 -1
- package/build/assets/settings-switch-seaSJc7t.js +1 -0
- package/build/assets/{settings-utils-8GIIgOQL.js → settings-utils-BTaaRhLZ.js} +1 -1
- package/build/assets/shared-conversation-x3rxVCon.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-B6mcvvdV.js} +1 -1
- package/build/assets/sidebar-mobile-menu-toggle-CEqS8KnA.js +1 -0
- package/build/assets/{sidebar-nav-link-_t4_Ef-9.js → sidebar-nav-link-BTHX11LG.js} +1 -1
- package/build/assets/{sidebar-onboarding-checklist-storage-DbDX-Wvj.js → sidebar-onboarding-checklist-storage-BP1kzn6p.js} +1 -1
- package/build/assets/sidebar-store-DAZVH-DR.js +1 -0
- package/build/assets/skill-card-pill-row-TD39nfP3.js +1 -0
- package/build/assets/{skill-filter-BBeZ4JEP.js → skill-filter-CdBbbwjm.js} +2 -2
- package/build/assets/{skill-icon-badge-BDhQ-tQ0.js → skill-icon-badge-vUEp7gsC.js} +1 -1
- package/build/assets/skill-scope-BTRBQt0-.js +1 -0
- package/build/assets/skills-plugins-k1tUNAw4.js +1 -0
- package/build/assets/skills-settings-CENviPT7.js +1 -0
- package/build/assets/{styled-tooltip-Pd22BIvr.js → styled-tooltip-DVAlWYnL.js} +1 -1
- package/build/assets/task-list-tab-BLKF_x9f.js +1 -0
- package/build/assets/{terminal-onXx0_Qz.js → terminal-Ckbnqb23.js} +1 -1
- package/build/assets/{toggle-switch-lwQtxDcm.js → toggle-switch-DeiG9Mf6.js} +1 -1
- package/build/assets/{trash-2-ZhKuTLiz.js → trash-2-Bb40zQzs.js} +1 -1
- package/build/assets/trash-CXN2R54L.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-NarNyelM.js} +1 -1
- package/build/assets/usage-tab-Drd3O006.js +1 -0
- package/build/assets/use-acp-credential-form-CJ5wPsQm.js +1 -0
- package/build/assets/{use-activate-agent-profile-BLKML6vQ.js → use-activate-agent-profile-iQZ0U3qV.js} +1 -1
- package/build/assets/use-agent-profiles-LCvb5OXT.js +1 -0
- package/build/assets/{use-automation-health-BZkQNEA8.js → use-automation-health-DdgSa8sA.js} +1 -1
- package/build/assets/{use-automation-permissions-B_RpvL-s.js → use-automation-permissions-D3kEeieu.js} +1 -1
- package/build/assets/{use-automations-Cg0PDIZr.js → use-automations-CEubcYTD.js} +1 -1
- package/build/assets/{use-can-manage-org-profiles-BbN6KfDr.js → use-can-manage-org-profiles-CB8ybxFK.js} +1 -1
- package/build/assets/{use-canvas-extensions-CFUpHat6.js → use-canvas-extensions-BMacwi2v.js} +1 -1
- package/build/assets/{use-cloud-current-user-id-Dk0rjr63.js → use-cloud-current-user-id-BEKRd6XZ.js} +1 -1
- package/build/assets/{use-config-DpafU_QP.js → use-config-3WYcJsgC.js} +1 -1
- package/build/assets/{use-create-conversation-1YgmAHt-.js → use-create-conversation-Be-eVpFp.js} +1 -1
- package/build/assets/use-create-secret-Bk9ZxTjl.js +1 -0
- package/build/assets/use-free-models-Ci3FkKEm.js +1 -0
- package/build/assets/{use-get-secrets-CQ4b0qK8.js → use-get-secrets-fqS0kxt6.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-B71ZEVg2.js +1 -0
- package/build/assets/use-llm-profiles-xtCBMbef.js +1 -0
- package/build/assets/{use-manifest-capabilities-AOWGcu0j.js → use-manifest-capabilities-Bso6A_-A.js} +1 -1
- package/build/assets/{use-onboarding-completion-CoINurkm.js → use-onboarding-completion-CEgjL02y.js} +1 -1
- package/build/assets/{use-pinned-home-route-D6krwXjy.js → use-pinned-home-route-pK4IlJ-p.js} +1 -1
- package/build/assets/{use-plugins-marketplace-mLsIDhBv.js → use-plugins-marketplace-B8-ZEB34.js} +1 -1
- package/build/assets/use-save-agent-profile-D7hJuW_u.js +1 -0
- package/build/assets/{use-save-settings-3U5K9-8x.js → use-save-settings-CikTu5xV.js} +1 -1
- package/build/assets/{use-settings-Dn00UISA.js → use-settings-BWIH5EuN.js} +1 -1
- package/build/assets/use-settings-nav-items-DSKwLDnd.js +1 -0
- package/build/assets/use-tracking-ChnSFChv.js +3 -0
- package/build/assets/{use-user-conversation-ZWlXtbZb.js → use-user-conversation-C_l65DqW.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-D-gOfhmN.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~b0x1wrp2-D6owle9R.js +2 -0
- 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~extensions-h~inibp4qe-BFRW8wt-.js +48 -0
- 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-PKtoIUUY.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 +16 -2
- package/build/locales/ca/openhands.json +16 -2
- package/build/locales/de/openhands.json +16 -2
- package/build/locales/en/openhands.json +16 -2
- package/build/locales/es/openhands.json +16 -2
- package/build/locales/fr/openhands.json +16 -2
- package/build/locales/it/openhands.json +16 -2
- package/build/locales/ja/openhands.json +16 -2
- package/build/locales/ko-KR/openhands.json +16 -2
- package/build/locales/no/openhands.json +16 -2
- package/build/locales/pt/openhands.json +16 -2
- package/build/locales/tr/openhands.json +16 -2
- package/build/locales/uk/openhands.json +16 -2
- package/build/locales/zh-CN/openhands.json +16 -2
- package/build/locales/zh-TW/openhands.json +16 -2
- package/config/defaults.json +3 -3
- 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/conversation-events/chat/event-content-helpers/get-skill-ready-content.cjs +3 -3
- package/dist/components/conversation-events/chat/event-content-helpers/get-skill-ready-content.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-skill-ready-content.js +12 -16
- package/dist/components/conversation-events/chat/event-content-helpers/get-skill-ready-content.js.map +1 -1
- 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/automations/detail/disabled-reason-banner.d.ts +16 -0
- 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/home/featured-automations/home-automation-run-tooltip.cjs +1 -1
- package/dist/components/features/home/featured-automations/home-automation-run-tooltip.cjs.map +1 -1
- package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js +38 -29
- package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js.map +1 -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/agent-profiles/profile-scope-list.d.ts +20 -0
- 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 +3 -3
- package/dist/config/defaults.js.map +1 -1
- package/dist/constants/acp-providers.cjs +1 -1
- package/dist/constants/acp-providers.cjs.map +1 -1
- package/dist/constants/acp-providers.d.ts +7 -0
- package/dist/constants/acp-providers.js +20 -16
- package/dist/constants/acp-providers.js.map +1 -1
- package/dist/constants/profile-scope.d.ts +21 -0
- 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-automation-sdk-version.cjs +1 -1
- package/dist/hooks/query/use-automation-sdk-version.cjs.map +1 -1
- package/dist/hooks/query/use-automation-sdk-version.js +3 -1
- package/dist/hooks/query/use-automation-sdk-version.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-drag-resize.cjs +1 -1
- package/dist/hooks/use-drag-resize.cjs.map +1 -1
- package/dist/hooks/use-drag-resize.js +8 -9
- package/dist/hooks/use-drag-resize.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 +16 -2
- package/dist/i18n/declaration.js +1 -1
- package/dist/i18n/declaration.js.map +1 -1
- package/dist/i18n/translation.cjs +3 -3
- package/dist/i18n/translation.cjs.map +1 -1
- package/dist/i18n/translation.js +255 -17
- package/dist/i18n/translation.js.map +1 -1
- package/dist/locales/ar/openhands.json +16 -2
- package/dist/locales/ca/openhands.json +16 -2
- package/dist/locales/de/openhands.json +16 -2
- package/dist/locales/en/openhands.json +16 -2
- package/dist/locales/es/openhands.json +16 -2
- package/dist/locales/fr/openhands.json +16 -2
- package/dist/locales/it/openhands.json +16 -2
- package/dist/locales/ja/openhands.json +16 -2
- package/dist/locales/ko-KR/openhands.json +16 -2
- package/dist/locales/no/openhands.json +16 -2
- package/dist/locales/pt/openhands.json +16 -2
- package/dist/locales/tr/openhands.json +16 -2
- package/dist/locales/uk/openhands.json +16 -2
- package/dist/locales/zh-CN/openhands.json +16 -2
- package/dist/locales/zh-TW/openhands.json +16 -2
- package/dist/manifests/manifest-validation.cjs +1 -1
- package/dist/manifests/manifest-validation.cjs.map +1 -1
- package/dist/manifests/manifest-validation.js +2 -2
- package/dist/manifests/manifest-validation.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.js +15 -8
- package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.js +11 -13
- package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.js +6 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.js +3 -6
- package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/file-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/file-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/file-client.js +9 -12
- package/dist/node_modules/@openhands/typescript-client/dist/client/file-client.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/runtime-transport.cjs +2 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/runtime-transport.cjs.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/runtime-transport.js +41 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/runtime-transport.js.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/vscode-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/vscode-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/vscode-client.js +3 -6
- package/dist/node_modules/@openhands/typescript-client/dist/client/vscode-client.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/clients.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/clients.js +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js +199 -61
- package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/workspace/remote-workspace.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/workspace/remote-workspace.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/workspace/remote-workspace.js +9 -8
- package/dist/node_modules/@openhands/typescript-client/dist/workspace/remote-workspace.js.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +2 -2
- package/dist/package.js.map +1 -1
- package/dist/routes/agent-settings.d.ts +5 -0
- 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/types/automation.cjs.map +1 -1
- package/dist/types/automation.d.ts +23 -1
- package/dist/types/automation.js.map +1 -1
- package/dist/utils/automation-disabled-reason.cjs +2 -0
- package/dist/utils/automation-disabled-reason.cjs.map +1 -0
- package/dist/utils/automation-disabled-reason.d.ts +32 -0
- package/dist/utils/automation-disabled-reason.js +19 -0
- package/dist/utils/automation-disabled-reason.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/dist/utils/parse-git-remote-url.cjs +1 -1
- package/dist/utils/parse-git-remote-url.cjs.map +1 -1
- package/dist/utils/parse-git-remote-url.d.ts +5 -1
- package/dist/utils/parse-git-remote-url.js +20 -13
- package/dist/utils/parse-git-remote-url.js.map +1 -1
- package/package.json +2 -2
- package/scripts/check-sdk-version-sync.mjs +79 -8
- package/scripts/dev-safe.mjs +1 -1
- package/scripts/static-server.mjs +24 -7
- package/build/assets/acp-providers-DrjNsPOH.js +0 -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/agent-settings-CpY3zObk.js +0 -2
- 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-C-_qBasq.js +0 -46
- 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/link-external-BNZzCM1I.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-marketplace-utils-Cn_NIMWM.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/parse-git-remote-url-DpDM9bK6.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/use-tracking-B9prBsrq.js +0 -3
- 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~b0x1wrp2-Z0lly3FE.js +0 -2
- 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~inibp4qe-CnsDDzeE.js +0 -48
- 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":"+8BAkBA,IAAM,EAA0B,GAEhC,SAAS,EAAc,EAAuB,CAC5C,OAAO,EAAM,QAAU,EACnB,EACA,GAAG,EAAM,MAAM,EAAG,CAAuB,EAAE,EACjD,CAeA,SAAgB,EAA+B,CAC7C,UACA,eACA,wBACA,yBACsC,CACtC,GAAM,CAAE,KAAM,EAAA,eAAe,WAAW,EAClC,EAAa,EAAA,cAAc,EAC3B,CACJ,WACA,qBACA,sBACA,mBACA,iBACE,EAAA,4BAA4B,EAI1B,EAAkB,GAAoB,EAAS,OAAS,EACxD,EAAsB,EAAmB,KAAO,EAEhD,EAAgB,GAAwB,CAC5C,EAAc,CAAW,EACzB,EAAQ,CACV,EAEA,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,CACG,IACC,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EAGE,EAAA,EAAA,KAAC,KAAD,CAAI,KAAK,eAAe,UAAU,6BAChC,EAAA,EAAA,KAAC,EAAA,WAAW,KAAZ,CAAiB,UAAU,+FACxB,EAAE,EAAA,QAAQ,2BAA2B,CACvB,CAAA,CACf,CAAA,EACH,EAAS,IAAK,GAAY,CACzB,IAAM,EAAY,EAAQ,OAAS,EAC7B,EAAe,EAAA,qBACnB,EAAQ,MACR,CACF,EACA,OACE,EAAA,EAAA,MAAC,EAAA,oBAAD,CAEE,OAAQ,iCAAiC,EAAQ,OACjD,QAAU,GAAU,CAGlB,GAFA,EAAM,eAAe,EACrB,EAAM,gBAAgB,EAClB,EAAW,CACb,EAAQ,EACR,MACF,CACA,EAAa,EAAQ,IAAI,CAC3B,EACA,UAAW,EAAA,GACT,sCACA,GAAa,kCACf,WAfF,EAiBE,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,mCAAhB,EACE,EAAA,EAAA,KAAC,OAAD,CACE,UAAU,oCACV,MAAO,EAAQ,OAAS,EAAQ,cAE/B,EAAQ,IACL,CAAA,EACL,IACC,EAAA,EAAA,KAAC,EAAA,QAAD,CACE,MAAO,GACP,OAAQ,GACR,UAAU,WACV,cAAA,EACD,CAAA,CAEC,IACL,IACC,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,mEACb,CACG,CAAA,CAEW,GArCd,EAAQ,IAqCM,CAEzB,CAAC,CACD,CAAA,CAAA,EAEH,IACC,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,UAAU,cAAY,2CAClC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,2EAAf,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,WAAW,MAAO,WAC/B,CACG,CAAA,EACL,IACC,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,6DACb,EAAA,qBAAqB,EAAqB,CAAU,CACjD,CAAA,CAEL,GACH,CAAA,GAEJ,GAAmB,KACnB,EAAA,EAAA,KAAC,EAAA,QAAD,CAAS,MAAO,CAAe,CAAA,GAEjC,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,oBACZ,EAAA,EAAA,MAAC,EAAA,eAAD,CACE,GAAG,gBACH,QAAS,EACT,UAAW,EAAA,GACT,8IACA,CACF,WANF,EAQE,EAAA,EAAA,KAAC,EAAA,QAAD,CACE,MAAO,GACP,OAAQ,GACR,UAAW,EAAA,GAAG,WAAY,CAAqB,EAC/C,cAAA,EACD,CAAA,GACD,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAE,EAAA,QAAQ,qBAAqB,CAAQ,CAAA,CAChC,GACd,CAAA,CACJ,CAAA,CAAA,CAEN,CAEA,SAAgB,GAA4B,CAC1C,GAAM,CAAE,KAAM,EAAA,eAAe,WAAW,EAClC,CAAE,WAAU,qBAAoB,YAAW,eAC/C,EAAA,4BAA4B,EACxB,CAAC,EAAe,GAAoB,EAAA,QAAM,SAAS,EAAK,EACxD,EAAa,EAAA,QAAM,OAA0B,IAAI,EACjD,EAAa,EAAA,2BACX,EAAiB,EAAK,EAC5B,CACF,EAIA,GAAI,GAAa,EAAS,SAAW,EACnC,OAAO,KAGT,IAAM,EAAQ,GAAsB,EAAE,EAAA,QAAQ,4BAA4B,EAE1E,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,4BAAf,EACE,EAAA,EAAA,MAAC,SAAD,CACE,IAAK,EACL,KAAK,SACL,UAAW,EAAA,GAAG,EAAA,6BAA8B,eAAe,EAC3D,MAAO,GAAsB,IAAA,GAC7B,cAAY,yBACZ,gBAAe,EACf,gBAAc,SAEd,SAAU,EACV,YAAW,EACX,QAAU,GAAU,CAClB,EAAM,eAAe,EACrB,EAAM,gBAAgB,EACtB,EAAkB,GAAS,CAAC,CAAI,CAClC,WAfF,EAiBE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oBAAY,EAAc,CAAK,CAAQ,CAAA,GACvD,EAAA,EAAA,KAAC,EAAA,oBAAD,CAAqB,OAAQ,CAAgB,CAAA,CACvC,IAEP,IACC,EAAA,EAAA,KAAC,EAAA,YAAD,CACE,IAAK,EACL,OAAO,iCACP,SAAS,MACT,UAAU,OACV,QAAQ,OACR,UAAU,iFAEV,EAAA,EAAA,KAAC,EAAD,CACE,YAAe,EAAiB,EAAK,CACtC,CAAA,CACU,CAAA,CAEZ,GAET"}
|
|
@@ -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"}
|