@openhands/agent-canvas 1.16.0 → 1.17.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-CX3Lh9gj.js → acp-providers-DrjNsPOH.js} +1 -1
- package/build/assets/active-backend-context-rZiLJRUc.js +2 -0
- package/build/assets/{agent-context-settings-DSZlXrLj.js → agent-context-settings-CJUrcBut.js} +1 -1
- package/build/assets/agent-profiles-service.api-Biieml2L.js +1 -0
- package/build/assets/agent-profiles-settings-x6RvPsq7.js +1 -0
- package/build/assets/agent-server-client-options-BikiNwTa.js +1 -0
- package/build/assets/agent-server-conversation-service.api-DYFsNHKf.js +88 -0
- package/build/assets/agent-settings-BJyovpJ_.js +1 -0
- package/build/assets/agent-settings-CpY3zObk.js +2 -0
- package/build/assets/{alert-banner-HP6mX-Vr.js → alert-banner-vARz1idS.js} +1 -1
- package/build/assets/{api-error-message-B-XdSk3b.js → api-error-message-Ve79qDcN.js} +1 -1
- package/build/assets/api-key-entry-screen-CsMuBhoP.js +1 -0
- package/build/assets/{app-settings-dbnneVaV.js → app-settings-BaJ7nfHt.js} +1 -1
- package/build/assets/automation-detail-CVoGDrKq.js +3 -0
- package/build/assets/{automation-export-D3a3of4G.js → automation-export-DxY47m3T.js} +1 -1
- package/build/assets/automation-git-sync-CRMP9Bbm.js +1 -0
- package/build/assets/automation-setup-route-072beLz1.js +3 -0
- package/build/assets/{automation-templates-BRppNh99.js → automation-templates-4C4PM8K7.js} +1 -1
- package/build/assets/automations-list-xuqTSQL4.js +1 -0
- package/build/assets/{back-nav-button-Cjl_hoxq.js → back-nav-button-B8tH0BEp.js} +1 -1
- package/build/assets/backend-form-modal-0aJmWdsa.js +1 -0
- package/build/assets/{backend-synced-settings-badge-DPkz30BE.js → backend-synced-settings-badge-B7rKWBir.js} +1 -1
- package/build/assets/{badge-BU3S0VtE.js → badge-CcGx2TaV.js} +1 -1
- package/build/assets/{base-modal-D_L0oEbG.js → base-modal-DTULovNc.js} +1 -1
- package/build/assets/bot-CLMxGFaq.js +1 -0
- package/build/assets/{brand-button-BAfk4wGP.js → brand-button-DxPO4Lf8.js} +1 -1
- package/build/assets/{browser-DSAo0tz1.js → browser-C-_qBasq.js} +2 -2
- package/build/assets/{browser-tab-C9vy56R5.js → browser-tab-DZanIw5m.js} +1 -1
- package/build/assets/{canvas-extension-page-dx1gFrfW.js → canvas-extension-page-o_cWgE9B.js} +1 -1
- package/build/assets/canvas-extensions-DSgNlCha.js +1 -0
- package/build/assets/{canvas-extensions-runtime-2_x5Ezmi.js → canvas-extensions-runtime-DdnkgJXV.js} +1 -1
- package/build/assets/{chat-send-button-MUQqCZCS.js → chat-send-button-B3SFSIg5.js} +1 -1
- package/build/assets/check-fDEfgSzj.js +1 -0
- package/build/assets/chevron-down-CFrWHqu8.js +1 -0
- package/build/assets/chevron-right-C5roOrJu.js +1 -0
- package/build/assets/circle-check-ClTzJTdb.js +1 -0
- package/build/assets/{circle-plus-check-toggle-BO_kFZt3.js → circle-plus-check-toggle-Fr-h-mbL.js} +1 -1
- package/build/assets/{cloud-funnel-analytics-CztBCCPp.js → cloud-funnel-analytics-BQanUEEC.js} +1 -1
- package/build/assets/{cog-D-MPQW6G.js → cog-VBlRo6iw.js} +1 -1
- package/build/assets/command-menu-BT3Ia5Ru.js +1 -0
- package/build/assets/commits-tab-2jhtaohl.js +1 -0
- package/build/assets/{condenser-settings-DmEOje-7.js → condenser-settings-eVKFMvap.js} +1 -1
- package/build/assets/confirmation-modal-gIFHeZt6.js +1 -0
- package/build/assets/{context-menu-list-item-I86vKcmM.js → context-menu-list-item-DDROe12Z.js} +1 -1
- package/build/assets/conversation-BnjJSFf5.js +93 -0
- package/build/assets/conversation-DZ578rOX.js +1 -0
- package/build/assets/conversation-panel-DZ578rOX.js +1 -0
- package/build/assets/{conversation-state-store-B0ImPLHO.js → conversation-state-store-D1_G_9I-.js} +1 -1
- package/build/assets/{conversation-store-Ca3ghXap.js → conversation-store-DVVfkCsk.js} +1 -1
- package/build/assets/{conversation-tab-empty-state-FIbh_lc8.js → conversation-tab-empty-state-DKlzAz5c.js} +1 -1
- package/build/assets/{copy-to-clipboard-button-Ca8iSkkA.js → copy-to-clipboard-button-B3w0X7WH.js} +1 -1
- package/build/assets/{device-verify-Bhn2e_Ye.js → device-verify-BfkCzyFB.js} +1 -1
- package/build/assets/{dropdown-classes-Bc1djN0-.js → dropdown-classes-B9kJVDIk.js} +1 -1
- package/build/assets/edit-automation-modal-BwhJ39JT.js +1 -0
- package/build/assets/empty-state-RZz0OfnY.js +1 -0
- package/build/assets/{entry.client-CqyPPjOq.js → entry.client-Ds8LVp-E.js} +2 -2
- package/build/assets/enum-filter-dropdown-C4pW0ORd.js +1 -0
- package/build/assets/{environment-switch-overlay-BmBRT7gv.js → environment-switch-overlay-P2ZAuzov.js} +1 -1
- package/build/assets/{error-state-Body8Ngd.js → error-state-B_5cgNPJ.js} +1 -1
- package/build/assets/extensions-hub-DsaUr4ca.js +1 -0
- package/build/assets/extensions-navigation-CRMZd-FE.js +1 -0
- package/build/assets/external-link-DQtv7eTh.js +1 -0
- package/build/assets/files-tab-CCgAcVdc.js +1 -0
- package/build/assets/{form-control-classes-Bkh5FGrD.js → form-control-classes-B-z85REi.js} +1 -1
- package/build/assets/get-git-path-EHrSDxTM.js +1 -0
- package/build/assets/git-repo-dropdown-D2WEQ97X.js +1 -0
- package/build/assets/{git-repo-dropdown-4ROKl2cB.js → git-repo-dropdown-DVeCUUXG.js} +1 -1
- package/build/assets/{highlighted-source-view-BFRxGT_Q.js → highlighted-source-view-DjHO3SdW.js} +1 -1
- package/build/assets/home-BorS_vdS.js +1 -0
- package/build/assets/home-aIMbHw5M.js +1 -0
- package/build/assets/home-automation-run-tooltip-CpHNFiFl.js +1 -0
- package/build/assets/home-store-DyXz0w6d.js +1 -0
- package/build/assets/hooks-service-C6dpRtZM.js +1 -0
- package/build/assets/index-home-zKFuKK2B.js +1 -0
- package/build/assets/info-CTIdjttz.js +1 -0
- package/build/assets/install-server-modal-DUiZMc8u.js +1 -0
- package/build/assets/kebab-menu-item-content-mm04SBD3.js +1 -0
- package/build/assets/{key-BmVyxs-2.js → key-CfXbJa8w.js} +1 -1
- package/build/assets/{launch-IrTDEFCs.js → launch-BSIf9KEg.js} +1 -1
- package/build/assets/list-filter-CNpqTWVY.js +1 -0
- package/build/assets/{list-todo-apgLVjMw.js → list-todo-ByXMdY4W.js} +1 -1
- package/build/assets/llm-not-configured-banner-z_QRSeV0.js +27 -0
- package/build/assets/llm-settings-B-5AHMiX.js +1 -0
- package/build/assets/llm-settings-B3SjHDmA.js +1 -0
- package/build/assets/llm-subscription-service-aDNBQ7Gq.js +1 -0
- package/build/assets/loader-circle-Dex47vVW.js +1 -0
- package/build/assets/{loading-spinner-BY9N3pOe.js → loading-spinner-DfHI77BA.js} +1 -1
- package/build/assets/manage-backends-modal-q1NdFisr.js +1 -0
- package/build/assets/manifest-8920b615.js +1 -0
- package/build/assets/{manifest-subpage-layout-CAOYzrYp.js → manifest-subpage-layout-BQQy5ipR.js} +1 -1
- package/build/assets/{map-provider-Cu3Zgumb.js → map-provider-DXvssjw9.js} +1 -1
- package/build/assets/markdown-renderer-rivLvYh-.js +8 -0
- package/build/assets/{mcp-BTs_SXfZ.js → mcp-CEXDhQWn.js} +1 -1
- package/build/assets/{mcp-marketplace-utils-AIBzzHTO.js → mcp-marketplace-utils-Cn_NIMWM.js} +1 -1
- package/build/assets/mcp-page-LGYIICMG.js +9 -0
- package/build/assets/messages-DUSeANAh.js +41 -0
- package/build/assets/{modal-body-BxZjsju9.js → modal-body-DJw4xBki.js} +1 -1
- package/build/assets/{modal-classes-C8eycCwG.js → modal-classes-Dg0ngBPO.js} +1 -1
- package/build/assets/{modal-close-button-DDzdRvCs.js → modal-close-button-B9j4nasm.js} +1 -1
- package/build/assets/{mouse-pointer-click-Co2uyaPA.js → mouse-pointer-click-DEhsSUpu.js} +1 -1
- package/build/assets/onboarding-BjFebfs5.js +1 -0
- package/build/assets/onboarding-modal-DDTjOpyd.js +1 -0
- package/build/assets/organization-service.api-Cyg1Tn03.js +1 -0
- package/build/assets/pencil-D5c47kyN.js +1 -0
- package/build/assets/pin-C7vMagvf.js +1 -0
- package/build/assets/planner-tab-D8f2Y3rn.js +1 -0
- package/build/assets/plug-CeaqeF6u.js +1 -0
- package/build/assets/plugins-management-service-Bh_pBuf-.js +1 -0
- package/build/assets/plus-B3wvU06-.js +1 -0
- package/build/assets/profiles-service.api-BbOK0EkF.js +1 -0
- package/build/assets/{providers-BhMcY5nv.js → providers-2gIIkz2N.js} +1 -1
- package/build/assets/proxy-CBgMd2zf.js +1 -0
- package/build/assets/{puzzle-JM_QaRm0.js → puzzle-DdAqbUrb.js} +1 -1
- package/build/assets/recommended-automations-launcher-YLAQTp4s.js +1 -0
- package/build/assets/refresh-cw-DEQdPCpH.js +1 -0
- package/build/assets/root-Bye_XmEL.js +2 -0
- package/build/assets/root-Cnwwzgo0.css +1 -0
- package/build/assets/root-layout-CSAwxBGM.js +2 -0
- package/build/assets/schema-field-CK0xYNbO.js +1 -0
- package/build/assets/scroll-fade-state-Dt_fx2kf.js +1 -0
- package/build/assets/sdk-section-page-Da73Rs_o.js +1 -0
- package/build/assets/secret-form-CB2VwYYg.js +1 -0
- package/build/assets/secrets-service-Cr8g8xuv.js +1 -0
- package/build/assets/{secrets-settings-B_GpxKW2.js → secrets-settings-Bh0udeKv.js} +1 -1
- package/build/assets/settings-DmyIgRxO.js +1 -0
- package/build/assets/{settings-dropdown-input-BcwylHs2.js → settings-dropdown-input-DVpyD87C.js} +1 -1
- package/build/assets/settings-index-BSJUFmjE.js +1 -0
- package/build/assets/{settings-input-Db-1g8Ql.js → settings-input-C0dd8Utu.js} +1 -1
- package/build/assets/{settings-list-classes-BzeSZbF2.js → settings-list-classes-Ds4jPBHK.js} +1 -1
- package/build/assets/{settings-modal-DfJ3tcJQ.js → settings-modal-yStgEh2o.js} +1 -1
- package/build/assets/settings-service.api-9_xdv_mh.js +1 -0
- package/build/assets/{settings-switch-CS-dJDmA.js → settings-switch-B78Khmyz.js} +1 -1
- package/build/assets/{settings-utils-UYpEdPuD.js → settings-utils-8GIIgOQL.js} +1 -1
- package/build/assets/shared-conversation-DM96X4KV.js +1 -0
- package/build/assets/shield-check-DO7wa_eu.js +1 -0
- package/build/assets/{sidebar-layout-D6fS8-Gl.js → sidebar-layout-EPfWxk11.js} +1 -1
- package/build/assets/sidebar-mobile-menu-toggle-D5GR5xT9.js +1 -0
- package/build/assets/{sidebar-nav-link-DQQcMf1A.js → sidebar-nav-link-_t4_Ef-9.js} +1 -1
- package/build/assets/{sidebar-onboarding-checklist-storage-BBkeI6Bp.js → sidebar-onboarding-checklist-storage-DbDX-Wvj.js} +1 -1
- package/build/assets/{sidebar-store-DGqHkVLw.js → sidebar-store-CSDFK0W5.js} +1 -1
- package/build/assets/{skill-card-pill-row-B27-xyig.js → skill-card-pill-row-989y15jV.js} +1 -1
- package/build/assets/{skill-filter-w__3UCEE.js → skill-filter-BBeZ4JEP.js} +1 -1
- package/build/assets/{skill-icon-badge-RQkq8wvl.js → skill-icon-badge-BDhQ-tQ0.js} +1 -1
- package/build/assets/skill-scope-Dz3kPH3P.js +1 -0
- package/build/assets/skills-plugins-e3CYGdUJ.js +1 -0
- package/build/assets/skills-settings-3e-FuHw_.js +1 -0
- package/build/assets/styled-tooltip-Pd22BIvr.js +1 -0
- package/build/assets/{task-list-tab-C5zcaktH.js → task-list-tab-3Jg8ywch.js} +1 -1
- package/build/assets/{terminal-CNElN42a.js → terminal-onXx0_Qz.js} +2 -2
- package/build/assets/toggle-switch-lwQtxDcm.js +1 -0
- package/build/assets/trash-2-ZhKuTLiz.js +1 -0
- package/build/assets/trash-B6OIe4yX.js +1 -0
- package/build/assets/triangle-alert-BajLPpQg.js +1 -0
- package/build/assets/{typography-v1KN0tzi.js → typography-HLLg_FAn.js} +1 -1
- package/build/assets/usage-tab-Cm-9j3UK.js +1 -0
- package/build/assets/use-acp-credential-form-BARcvjYE.js +1 -0
- package/build/assets/use-activate-agent-profile-BLKML6vQ.js +1 -0
- package/build/assets/use-agent-profiles-1P91KSXz.js +1 -0
- package/build/assets/{use-automation-health-E6NZi9rb.js → use-automation-health-BZkQNEA8.js} +1 -1
- package/build/assets/use-automation-permissions-B_RpvL-s.js +1 -0
- package/build/assets/{use-automations-xijQKIl9.js → use-automations-Cg0PDIZr.js} +1 -1
- package/build/assets/{use-can-manage-org-profiles-CrJP5262.js → use-can-manage-org-profiles-BbN6KfDr.js} +1 -1
- package/build/assets/use-canvas-extensions-CFUpHat6.js +1 -0
- package/build/assets/{use-cloud-current-user-id-CDfAHpPX.js → use-cloud-current-user-id-Dk0rjr63.js} +1 -1
- package/build/assets/use-config-DpafU_QP.js +1 -0
- package/build/assets/use-create-conversation-1YgmAHt-.js +1 -0
- package/build/assets/use-create-secret-D8p9ybQj.js +1 -0
- package/build/assets/{use-get-secrets-K3jmk-LH.js → use-get-secrets-CQ4b0qK8.js} +1 -1
- package/build/assets/use-is-authed-BRPjCRKM.js +1 -0
- package/build/assets/{use-launch-skill-in-chat-BYjYihBP.js → use-launch-skill-in-chat-DeYa1tFM.js} +1 -1
- package/build/assets/use-llm-configured-DGm8FiRR.js +1 -0
- package/build/assets/use-llm-profiles-BTTtpW4z.js +1 -0
- package/build/assets/use-manifest-capabilities-AOWGcu0j.js +1 -0
- package/build/assets/use-onboarding-completion-CoINurkm.js +1 -0
- package/build/assets/use-pinned-home-route-D6krwXjy.js +1 -0
- package/build/assets/use-plugins-marketplace-mLsIDhBv.js +1 -0
- package/build/assets/use-save-agent-profile-CxyO9YG-.js +1 -0
- package/build/assets/{use-save-settings-DYqkKv7T.js → use-save-settings-3U5K9-8x.js} +1 -1
- package/build/assets/use-settings-Dn00UISA.js +1 -0
- package/build/assets/use-settings-nav-items-vrjxTqcu.js +16 -0
- package/build/assets/use-tracking-B9prBsrq.js +3 -0
- package/build/assets/{use-user-conversation-B9Gebw_g.js → use-user-conversation-ZWlXtbZb.js} +1 -1
- package/build/assets/{useInfiniteQuery-C926xzY4.js → useInfiniteQuery-BzrRqjLg.js} +1 -1
- package/build/assets/{useMutation-B-qc391N.js → useMutation-CJuK90oc.js} +1 -1
- package/build/assets/{useQueries-DlbhlH9I.js → useQueries-CykmpT-a.js} +1 -1
- package/build/assets/{useQuery-BSTgq1rl.js → useQuery-S6j94er1.js} +1 -1
- package/build/assets/utils-BOco8mxR.js +1 -0
- package/build/assets/{vendor~conversation-panel~conversation-C8Fn4XOf.js → vendor~conversation-panel~conversation-4eJ0tml3.js} +1 -1
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~b0x1wrp2-Z0lly3FE.js +2 -0
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~czjee3a3-BfkNGovw.js +185 -0
- package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ew9ih1s8-rfV8mQ9m.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ew9ih1s8-DnDoaYNi.js} +1 -1
- package/build/assets/{vendor~index-home~home~conversation-panel~conversation-hWywRBaR.js → vendor~index-home~home~conversation-panel~conversation-CSFLzmTN.js} +1 -1
- package/build/assets/vendor~root-layout-n8XCEXG8.js +1 -0
- package/build/assets/{vendor~root-layout~conversation-panel~conversation-BMbMgaGu.js → vendor~root-layout~conversation-panel~conversation-3Idg1_U3.js} +1 -1
- package/build/assets/{vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-BWir3rJs.js → vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-DkPlXWl9.js} +1 -1
- package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation-j5MFqfSy.js → vendor~root-layout~index-home~home~conversation-panel~conversation-DgQ564nC.js} +1 -1
- package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~mcp~automations-list~aut~ibfbmr9f-CxhwKuAd.js +1 -0
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~nj1hli3r-DP9wmsjo.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~inibp4qe-CnsDDzeE.js} +1 -1
- package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~iyia17eu-CV850oio.js +1 -0
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-CUmIwQCN.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-BPjI-atc.js} +12 -6
- package/build/assets/{verification-settings-gw_q6vkL.js → verification-settings-u2POabjH.js} +1 -1
- package/build/assets/{wrench-CUEI1krB.js → wrench-CkgI4rxA.js} +1 -1
- package/build/assets/x-By6qCmtY.js +1 -0
- package/build/index.html +4 -4
- package/build/locales/ar/openhands.json +73 -20
- package/build/locales/ca/openhands.json +73 -20
- package/build/locales/de/openhands.json +73 -20
- package/build/locales/en/openhands.json +73 -20
- package/build/locales/es/openhands.json +73 -20
- package/build/locales/fr/openhands.json +73 -20
- package/build/locales/it/openhands.json +73 -20
- package/build/locales/ja/openhands.json +73 -20
- package/build/locales/ko-KR/openhands.json +73 -20
- package/build/locales/no/openhands.json +73 -20
- package/build/locales/pt/openhands.json +73 -20
- package/build/locales/tr/openhands.json +73 -20
- package/build/locales/uk/openhands.json +73 -20
- package/build/locales/zh-CN/openhands.json +73 -20
- package/build/locales/zh-TW/openhands.json +73 -20
- package/config/defaults.json +3 -3
- package/dist/api/agent-server-adapter.cjs +3 -3
- package/dist/api/agent-server-adapter.cjs.map +1 -1
- package/dist/api/agent-server-adapter.d.ts +72 -12
- package/dist/api/agent-server-adapter.js +234 -132
- package/dist/api/agent-server-adapter.js.map +1 -1
- package/dist/api/agent-server-config.cjs +1 -1
- package/dist/api/agent-server-config.cjs.map +1 -1
- package/dist/api/agent-server-config.d.ts +6 -0
- package/dist/api/agent-server-config.js +6 -3
- package/dist/api/agent-server-config.js.map +1 -1
- package/dist/api/automation-service/automation-service.api.cjs +1 -1
- package/dist/api/automation-service/automation-service.api.cjs.map +1 -1
- package/dist/api/automation-service/automation-service.api.d.ts +2 -2
- package/dist/api/automation-service/automation-service.api.js +7 -7
- package/dist/api/automation-service/automation-service.api.js.map +1 -1
- package/dist/api/cloud/provider-connections-service.api.cjs +2 -0
- package/dist/api/cloud/provider-connections-service.api.cjs.map +1 -0
- package/dist/api/cloud/provider-connections-service.api.d.ts +5 -0
- package/dist/api/cloud/provider-connections-service.api.js +50 -0
- package/dist/api/cloud/provider-connections-service.api.js.map +1 -0
- package/dist/api/cloud/skills-service.api.cjs +1 -1
- package/dist/api/cloud/skills-service.api.cjs.map +1 -1
- package/dist/api/cloud/skills-service.api.d.ts +10 -0
- package/dist/api/cloud/skills-service.api.js +11 -1
- package/dist/api/cloud/skills-service.api.js.map +1 -1
- package/dist/api/conversation-metadata-store.cjs +1 -1
- package/dist/api/conversation-metadata-store.cjs.map +1 -1
- package/dist/api/conversation-metadata-store.d.ts +24 -0
- package/dist/api/conversation-metadata-store.js +10 -2
- package/dist/api/conversation-metadata-store.js.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +20 -0
- package/dist/api/conversation-service/agent-server-conversation-service.api.js +126 -77
- package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
- package/dist/api/hooks-service.cjs +2 -0
- package/dist/api/hooks-service.cjs.map +1 -0
- package/dist/api/hooks-service.d.ts +13 -0
- package/dist/api/hooks-service.js +20 -0
- package/dist/api/hooks-service.js.map +1 -0
- package/dist/api/provider-connections-service/provider-connections-service.api.cjs +1 -1
- package/dist/api/provider-connections-service/provider-connections-service.api.cjs.map +1 -1
- package/dist/api/provider-connections-service/provider-connections-service.api.js +25 -16
- package/dist/api/provider-connections-service/provider-connections-service.api.js.map +1 -1
- package/dist/api/settings-service/settings-service.api.cjs +1 -1
- package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
- package/dist/api/settings-service/settings-service.api.d.ts +2 -0
- package/dist/api/settings-service/settings-service.api.js +18 -10
- package/dist/api/settings-service/settings-service.api.js.map +1 -1
- package/dist/api/skills-service.cjs +1 -1
- package/dist/api/skills-service.cjs.map +1 -1
- package/dist/api/skills-service.d.ts +7 -0
- package/dist/api/skills-service.js +11 -8
- package/dist/api/skills-service.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/critic-result-display.cjs +1 -1
- package/dist/components/conversation-events/chat/event-message-components/critic-result-display.js +5 -5
- package/dist/components/conversation-events/chat/event-message-components/finish-event-message.cjs +1 -1
- package/dist/components/conversation-events/chat/event-message-components/finish-event-message.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/finish-event-message.js +2 -1
- package/dist/components/conversation-events/chat/event-message-components/finish-event-message.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.cjs +1 -1
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.d.ts +1 -1
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.js +28 -28
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/thought-event-message.cjs +1 -1
- package/dist/components/conversation-events/chat/event-message-components/thought-event-message.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/thought-event-message.js +2 -1
- package/dist/components/conversation-events/chat/event-message-components/thought-event-message.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.cjs +1 -1
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.d.ts +1 -1
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.js +37 -37
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message.cjs +2 -2
- package/dist/components/conversation-events/chat/event-message.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message.js +79 -70
- package/dist/components/conversation-events/chat/event-message.js.map +1 -1
- package/dist/components/conversation-events/chat/messages.cjs +1 -1
- package/dist/components/conversation-events/chat/messages.cjs.map +1 -1
- package/dist/components/conversation-events/chat/messages.js +28 -27
- package/dist/components/conversation-events/chat/messages.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 +100 -94
- 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 +88 -77
- package/dist/components/features/automations/automation-list-row.js.map +1 -1
- package/dist/components/features/automations/detail/detail-header.d.ts +3 -1
- package/dist/components/features/automations/detail/run-status-badge.cjs +1 -1
- package/dist/components/features/automations/detail/run-status-badge.cjs.map +1 -1
- package/dist/components/features/automations/detail/run-status-badge.d.ts +2 -2
- package/dist/components/features/automations/detail/run-status-badge.js +82 -53
- package/dist/components/features/automations/detail/run-status-badge.js.map +1 -1
- package/dist/components/features/automations/kebab-menu.cjs +1 -1
- package/dist/components/features/automations/kebab-menu.cjs.map +1 -1
- package/dist/components/features/automations/kebab-menu.js +9 -5
- package/dist/components/features/automations/kebab-menu.js.map +1 -1
- package/dist/components/features/automations/recommended-automations-launcher.cjs +1 -1
- package/dist/components/features/automations/recommended-automations-launcher.cjs.map +1 -1
- package/dist/components/features/automations/recommended-automations-launcher.js +12 -12
- package/dist/components/features/automations/recommended-automations-launcher.js.map +1 -1
- package/dist/components/features/automations/recommended-automations-section.cjs +1 -1
- package/dist/components/features/automations/recommended-automations-section.js +9 -9
- 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 +133 -122
- package/dist/components/features/backends/backend-selector.js.map +1 -1
- package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
- package/dist/components/features/backends/manage-backends-modal.cjs.map +1 -1
- package/dist/components/features/backends/manage-backends-modal.js +29 -29
- package/dist/components/features/backends/manage-backends-modal.js.map +1 -1
- package/dist/components/features/chat/change-agent-button.cjs +1 -1
- package/dist/components/features/chat/change-agent-button.js +4 -4
- package/dist/components/features/chat/chat-interface.cjs +2 -2
- package/dist/components/features/chat/chat-interface.cjs.map +1 -1
- package/dist/components/features/chat/chat-interface.js +137 -137
- package/dist/components/features/chat/chat-interface.js.map +1 -1
- package/dist/components/features/chat/chat-message.cjs +1 -1
- package/dist/components/features/chat/chat-message.cjs.map +1 -1
- package/dist/components/features/chat/chat-message.d.ts +2 -1
- package/dist/components/features/chat/chat-message.js +88 -79
- package/dist/components/features/chat/chat-message.js.map +1 -1
- package/dist/components/features/chat/components/context-window-meter.cjs +1 -1
- package/dist/components/features/chat/components/context-window-meter.js +4 -4
- package/dist/components/features/chat/confirmation-mode-enabled.cjs +1 -1
- package/dist/components/features/chat/confirmation-mode-enabled.js +4 -4
- package/dist/components/features/chat/generic-event-message.cjs +1 -1
- package/dist/components/features/chat/generic-event-message.cjs.map +1 -1
- package/dist/components/features/chat/generic-event-message.d.ts +2 -1
- package/dist/components/features/chat/generic-event-message.js +41 -22
- package/dist/components/features/chat/generic-event-message.js.map +1 -1
- package/dist/components/features/chat/interactive-chat-box.cjs +1 -1
- package/dist/components/features/chat/interactive-chat-box.cjs.map +1 -1
- package/dist/components/features/chat/interactive-chat-box.js +20 -19
- package/dist/components/features/chat/interactive-chat-box.js.map +1 -1
- package/dist/components/features/conversation/conversation-overview-git-section.cjs +1 -1
- package/dist/components/features/conversation/conversation-overview-git-section.js +4 -4
- package/dist/components/features/conversation/conversation-overview-skills-panel.cjs +1 -1
- package/dist/components/features/conversation/conversation-overview-skills-panel.js +4 -4
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs.map +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js +77 -78
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js.map +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs.map +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js +88 -88
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js.map +1 -1
- package/dist/components/features/conversation-panel/advanced-conversation-options-modal.cjs +2 -0
- package/dist/components/features/conversation-panel/advanced-conversation-options-modal.cjs.map +1 -0
- package/dist/components/features/conversation-panel/advanced-conversation-options-modal.d.ts +21 -0
- package/dist/components/features/conversation-panel/advanced-conversation-options-modal.js +239 -0
- package/dist/components/features/conversation-panel/advanced-conversation-options-modal.js.map +1 -0
- package/dist/components/features/conversation-panel/conversation-active-tag-filters.cjs +2 -0
- package/dist/components/features/conversation-panel/conversation-active-tag-filters.cjs.map +1 -0
- package/dist/components/features/conversation-panel/conversation-active-tag-filters.d.ts +28 -0
- package/dist/components/features/conversation-panel/conversation-active-tag-filters.js +69 -0
- package/dist/components/features/conversation-panel/conversation-active-tag-filters.js.map +1 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.d.ts +2 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.js +19 -18
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.d.ts +2 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.js +91 -80
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.js +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.d.ts +7 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.js +87 -81
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.d.ts +2 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.js +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.d.ts +2 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.js +2 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-layouts-menu.cjs +2 -0
- package/dist/components/features/conversation-panel/conversation-layouts-menu.cjs.map +1 -0
- package/dist/components/features/conversation-panel/conversation-layouts-menu.d.ts +29 -0
- package/dist/components/features/conversation-panel/conversation-layouts-menu.js +177 -0
- package/dist/components/features/conversation-panel/conversation-layouts-menu.js.map +1 -0
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.d.ts +37 -0
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js +85 -45
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.js +296 -290
- package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
- package/dist/components/features/conversation-panel/edit-conversation-tags-modal.cjs +2 -0
- package/dist/components/features/conversation-panel/edit-conversation-tags-modal.cjs.map +1 -0
- package/dist/components/features/conversation-panel/edit-conversation-tags-modal.d.ts +22 -0
- package/dist/components/features/conversation-panel/edit-conversation-tags-modal.js +153 -0
- package/dist/components/features/conversation-panel/edit-conversation-tags-modal.js.map +1 -0
- package/dist/components/features/conversation-panel/hide-older-conversations-row.cjs +2 -0
- package/dist/components/features/conversation-panel/hide-older-conversations-row.cjs.map +1 -0
- package/dist/components/features/conversation-panel/hide-older-conversations-row.d.ts +6 -0
- package/dist/components/features/conversation-panel/hide-older-conversations-row.js +65 -0
- package/dist/components/features/conversation-panel/hide-older-conversations-row.js.map +1 -0
- package/dist/components/features/conversation-panel/menu-row.cjs +1 -1
- package/dist/components/features/conversation-panel/menu-row.cjs.map +1 -1
- package/dist/components/features/conversation-panel/menu-row.d.ts +11 -1
- package/dist/components/features/conversation-panel/menu-row.js +27 -16
- package/dist/components/features/conversation-panel/menu-row.js.map +1 -1
- package/dist/components/features/home/featured-automations/automation-health-indicator.cjs +1 -1
- package/dist/components/features/home/featured-automations/automation-health-indicator.cjs.map +1 -1
- package/dist/components/features/home/featured-automations/automation-health-indicator.js +1 -1
- package/dist/components/features/home/featured-automations/automation-health-indicator.js.map +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-metrics.cjs +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-metrics.cjs.map +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-metrics.d.ts +4 -3
- package/dist/components/features/home/featured-automations/automation-run-activity-metrics.js +22 -25
- package/dist/components/features/home/featured-automations/automation-run-activity-metrics.js.map +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.cjs +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.cjs.map +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.d.ts +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.js +15 -15
- package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.js.map +1 -1
- package/dist/components/features/home/featured-automations/automation-run-health.cjs +1 -1
- package/dist/components/features/home/featured-automations/automation-run-health.cjs.map +1 -1
- package/dist/components/features/home/featured-automations/automation-run-health.d.ts +5 -3
- package/dist/components/features/home/featured-automations/automation-run-health.js +30 -23
- package/dist/components/features/home/featured-automations/automation-run-health.js.map +1 -1
- package/dist/components/features/home/featured-automations/home-automation-activity.d.ts +3 -2
- 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.d.ts +1 -1
- package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js +42 -42
- package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js.map +1 -1
- package/dist/components/features/manifest/manifest-form-field.d.ts +3 -1
- package/dist/components/features/manifest/manifest-review-step.d.ts +3 -1
- 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.js +5 -3
- package/dist/components/features/settings/cloud-settings-link.js.map +1 -1
- package/dist/components/features/settings/integrations-settings-link.cjs +1 -1
- package/dist/components/features/settings/integrations-settings-link.cjs.map +1 -1
- package/dist/components/features/settings/integrations-settings-link.d.ts +3 -1
- package/dist/components/features/settings/integrations-settings-link.js +20 -17
- package/dist/components/features/settings/integrations-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 +1 -1
- package/dist/components/features/settings/llm-profiles/profiles-body.d.ts +2 -2
- package/dist/components/features/settings/sdk-settings/sdk-section-page.cjs +1 -1
- package/dist/components/features/settings/sdk-settings/sdk-section-page.cjs.map +1 -1
- package/dist/components/features/settings/sdk-settings/sdk-section-page.d.ts +8 -7
- package/dist/components/features/settings/sdk-settings/sdk-section-page.js +172 -142
- package/dist/components/features/settings/sdk-settings/sdk-section-page.js.map +1 -1
- package/dist/components/features/settings/secrets-settings/secret-form.cjs +1 -1
- package/dist/components/features/settings/secrets-settings/secret-form.cjs.map +1 -1
- package/dist/components/features/settings/secrets-settings/secret-form.js +38 -25
- package/dist/components/features/settings/secrets-settings/secret-form.js.map +1 -1
- package/dist/components/features/settings/settings-dropdown-input.cjs +1 -1
- package/dist/components/features/settings/settings-dropdown-input.js +6 -6
- 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 +3 -1
- package/dist/components/features/sidebar/sidebar-rail-body.js +156 -139
- 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 +44 -43
- package/dist/components/features/sidebar/sidebar.js.map +1 -1
- package/dist/components/features/sidebar/use-sidebar-onboarding-checklist.cjs +1 -1
- package/dist/components/features/sidebar/use-sidebar-onboarding-checklist.js +3 -3
- package/dist/components/features/skills/extensions-navigation.cjs +1 -1
- package/dist/components/features/skills/extensions-navigation.cjs.map +1 -1
- package/dist/components/features/skills/extensions-navigation.js +3 -3
- package/dist/components/features/skills/extensions-navigation.js.map +1 -1
- package/dist/components/shared/buttons/styled-tooltip.cjs +1 -1
- package/dist/components/shared/buttons/styled-tooltip.cjs.map +1 -1
- package/dist/components/shared/buttons/styled-tooltip.d.ts +2 -1
- package/dist/components/shared/buttons/styled-tooltip.js +2 -1
- package/dist/components/shared/buttons/styled-tooltip.js.map +1 -1
- package/dist/components/shared/filters/enum-filter-dropdown.cjs +1 -1
- package/dist/components/shared/filters/enum-filter-dropdown.cjs.map +1 -1
- package/dist/components/shared/filters/enum-filter-dropdown.d.ts +5 -1
- package/dist/components/shared/filters/enum-filter-dropdown.js +14 -14
- package/dist/components/shared/filters/enum-filter-dropdown.js.map +1 -1
- package/dist/components/shared/modals/confirmation-modal.cjs +1 -1
- package/dist/components/shared/modals/confirmation-modal.cjs.map +1 -1
- package/dist/components/shared/modals/confirmation-modal.d.ts +2 -1
- package/dist/components/shared/modals/confirmation-modal.js +8 -8
- package/dist/components/shared/modals/confirmation-modal.js.map +1 -1
- package/dist/components/shared/modals/settings/model-selector.cjs +1 -1
- package/dist/components/shared/modals/settings/model-selector.js +27 -27
- 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/settings-nav.d.ts +8 -0
- package/dist/contexts/conversation-websocket-context.cjs +3 -3
- package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
- package/dist/contexts/conversation-websocket-context.d.ts +5 -0
- package/dist/contexts/conversation-websocket-context.js +194 -198
- package/dist/contexts/conversation-websocket-context.js.map +1 -1
- package/dist/contexts/websocket-provider-wrapper.cjs +1 -1
- package/dist/contexts/websocket-provider-wrapper.cjs.map +1 -1
- package/dist/contexts/websocket-provider-wrapper.js +31 -15
- package/dist/contexts/websocket-provider-wrapper.js.map +1 -1
- package/dist/hooks/chat/record-model-switch-message.cjs +1 -1
- package/dist/hooks/chat/record-model-switch-message.cjs.map +1 -1
- package/dist/hooks/chat/record-model-switch-message.d.ts +31 -0
- package/dist/hooks/chat/record-model-switch-message.js +25 -12
- package/dist/hooks/chat/record-model-switch-message.js.map +1 -1
- package/dist/hooks/chat/use-plan-mode-interceptor.cjs +2 -0
- package/dist/hooks/chat/use-plan-mode-interceptor.cjs.map +1 -0
- package/dist/hooks/chat/use-plan-mode-interceptor.d.ts +16 -0
- package/dist/hooks/chat/use-plan-mode-interceptor.js +43 -0
- package/dist/hooks/chat/use-plan-mode-interceptor.js.map +1 -0
- package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
- package/dist/hooks/mutation/use-create-conversation.cjs.map +1 -1
- package/dist/hooks/mutation/use-create-conversation.js +5 -1
- package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
- package/dist/hooks/mutation/use-read-conversation-file.cjs +1 -1
- package/dist/hooks/mutation/use-read-conversation-file.cjs.map +1 -1
- package/dist/hooks/mutation/use-read-conversation-file.js +11 -4
- package/dist/hooks/mutation/use-read-conversation-file.js.map +1 -1
- package/dist/hooks/mutation/use-save-settings.cjs +1 -1
- package/dist/hooks/mutation/use-save-settings.js +3 -3
- package/dist/hooks/mutation/use-switch-llm-profile.cjs +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile.cjs.map +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile.js +13 -25
- package/dist/hooks/mutation/use-switch-llm-profile.js.map +1 -1
- package/dist/hooks/mutation/use-update-conversation-tags.cjs +2 -0
- package/dist/hooks/mutation/use-update-conversation-tags.cjs.map +1 -0
- package/dist/hooks/mutation/use-update-conversation-tags.d.ts +8 -0
- package/dist/hooks/mutation/use-update-conversation-tags.js +45 -0
- package/dist/hooks/mutation/use-update-conversation-tags.js.map +1 -0
- package/dist/hooks/query/query-keys.cjs +1 -1
- package/dist/hooks/query/query-keys.cjs.map +1 -1
- package/dist/hooks/query/query-keys.d.ts +6 -0
- package/dist/hooks/query/query-keys.js +2 -2
- package/dist/hooks/query/query-keys.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.d.ts +0 -1
- package/dist/hooks/query/use-automation-sdk-version.js +30 -55
- package/dist/hooks/query/use-automation-sdk-version.js.map +1 -1
- package/dist/hooks/query/use-conversation-skills.cjs +1 -1
- package/dist/hooks/query/use-conversation-skills.cjs.map +1 -1
- package/dist/hooks/query/use-conversation-skills.d.ts +14 -5
- package/dist/hooks/query/use-conversation-skills.js +20 -4
- package/dist/hooks/query/use-conversation-skills.js.map +1 -1
- package/dist/hooks/query/use-provider-connections.cjs +1 -1
- package/dist/hooks/query/use-provider-connections.cjs.map +1 -1
- package/dist/hooks/query/use-provider-connections.d.ts +6 -3
- package/dist/hooks/query/use-provider-connections.js +7 -3
- package/dist/hooks/query/use-provider-connections.js.map +1 -1
- package/dist/hooks/query/use-sub-conversations.cjs +1 -1
- package/dist/hooks/query/use-sub-conversations.cjs.map +1 -1
- package/dist/hooks/query/use-sub-conversations.js +16 -16
- package/dist/hooks/query/use-sub-conversations.js.map +1 -1
- package/dist/hooks/use-acp-model-context.cjs +1 -1
- package/dist/hooks/use-acp-model-context.js +3 -3
- package/dist/hooks/use-agent-state.cjs +1 -1
- package/dist/hooks/use-agent-state.cjs.map +1 -1
- package/dist/hooks/use-agent-state.d.ts +17 -1
- package/dist/hooks/use-agent-state.js +19 -9
- package/dist/hooks/use-agent-state.js.map +1 -1
- package/dist/hooks/use-automation-permissions.cjs +2 -0
- package/dist/hooks/use-automation-permissions.cjs.map +1 -0
- package/dist/hooks/use-automation-permissions.d.ts +43 -0
- package/dist/hooks/use-automation-permissions.js +52 -0
- package/dist/hooks/use-automation-permissions.js.map +1 -0
- package/dist/hooks/use-chat-input-model-state.cjs +1 -1
- package/dist/hooks/use-chat-input-model-state.js +3 -3
- package/dist/hooks/use-handle-plan-click.cjs +1 -1
- package/dist/hooks/use-handle-plan-click.cjs.map +1 -1
- package/dist/hooks/use-handle-plan-click.d.ts +3 -1
- package/dist/hooks/use-handle-plan-click.js +85 -26
- package/dist/hooks/use-handle-plan-click.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.js +1 -0
- package/dist/hooks/use-home-automation-actions.js.map +1 -1
- package/dist/hooks/use-llm-configured.cjs +1 -1
- package/dist/hooks/use-llm-configured.js +3 -3
- package/dist/hooks/use-manifest-preflight.d.ts +1 -1
- package/dist/hooks/use-unified-websocket-status.cjs +1 -1
- package/dist/hooks/use-unified-websocket-status.cjs.map +1 -1
- package/dist/hooks/use-unified-websocket-status.d.ts +7 -0
- package/dist/hooks/use-unified-websocket-status.js +5 -1
- package/dist/hooks/use-unified-websocket-status.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 +65 -12
- package/dist/i18n/declaration.js +1 -1
- package/dist/i18n/declaration.js.map +1 -1
- package/dist/i18n/translation.cjs +2 -2
- package/dist/i18n/translation.cjs.map +1 -1
- package/dist/i18n/translation.js +1196 -295
- package/dist/i18n/translation.js.map +1 -1
- package/dist/locales/ar/openhands.json +73 -20
- package/dist/locales/ca/openhands.json +73 -20
- package/dist/locales/de/openhands.json +73 -20
- package/dist/locales/en/openhands.json +73 -20
- package/dist/locales/es/openhands.json +73 -20
- package/dist/locales/fr/openhands.json +73 -20
- package/dist/locales/it/openhands.json +73 -20
- package/dist/locales/ja/openhands.json +73 -20
- package/dist/locales/ko-KR/openhands.json +73 -20
- package/dist/locales/no/openhands.json +73 -20
- package/dist/locales/pt/openhands.json +73 -20
- package/dist/locales/tr/openhands.json +73 -20
- package/dist/locales/uk/openhands.json +73 -20
- package/dist/locales/zh-CN/openhands.json +73 -20
- package/dist/locales/zh-TW/openhands.json +73 -20
- package/dist/manifests/automation-insights.cjs.map +1 -1
- package/dist/manifests/automation-insights.d.ts +10 -2
- package/dist/manifests/automation-insights.js.map +1 -1
- package/dist/manifests/automation-setup.cjs +1 -1
- package/dist/manifests/automation-setup.cjs.map +1 -1
- package/dist/manifests/automation-setup.d.ts +9 -16
- package/dist/manifests/automation-setup.js +17 -7
- package/dist/manifests/automation-setup.js.map +1 -1
- package/dist/manifests/manifest-actions.d.ts +1 -1
- package/dist/manifests/manifest-capabilities.d.ts +3 -1
- package/dist/manifests/manifest-local-validation.cjs +2 -0
- package/dist/manifests/manifest-local-validation.cjs.map +1 -0
- package/dist/manifests/manifest-local-validation.d.ts +15 -11
- package/dist/manifests/manifest-local-validation.js +8 -0
- package/dist/manifests/manifest-local-validation.js.map +1 -0
- package/dist/manifests/manifest-template.cjs +2 -0
- package/dist/manifests/manifest-template.cjs.map +1 -0
- package/dist/manifests/manifest-template.d.ts +4 -4
- package/dist/manifests/manifest-template.js +12 -0
- package/dist/manifests/manifest-template.js.map +1 -0
- package/dist/manifests/manifest-validation.cjs +1 -1
- package/dist/manifests/manifest-validation.cjs.map +1 -1
- package/dist/manifests/manifest-validation.js +106 -28
- package/dist/manifests/manifest-validation.js.map +1 -1
- package/dist/manifests/types.cjs.map +1 -1
- package/dist/manifests/types.d.ts +39 -4
- package/dist/manifests/types.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/custom-automation/manifest.cjs +8 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/custom-automation/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/custom-automation/manifest.js +221 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/custom-automation/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.js +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.js +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.js +22 -20
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/interface.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/automations/interface.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/interface.js +2 -1
- package/dist/node_modules/@openhands/extensions/automations/interface.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.js +24 -5
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.js.map +1 -1
- package/dist/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs +1 -1
- package/dist/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js +1 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-question-mark.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-question-mark.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-question-mark.js +21 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-question-mark.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/shrink.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/shrink.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/shrink.js +23 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/shrink.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.js +43 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/tags.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/tags.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/tags.js +22 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/tags.js.map +1 -0
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +4 -4
- package/dist/package.js.map +1 -1
- package/dist/routes/agent-settings.d.ts +2 -0
- package/dist/routes/app-settings.cjs +1 -1
- package/dist/routes/app-settings.js +5 -5
- package/dist/routes/llm-settings.cjs +1 -1
- package/dist/routes/llm-settings.cjs.map +1 -1
- package/dist/routes/llm-settings.d.ts +3 -1
- package/dist/routes/llm-settings.js +88 -87
- package/dist/routes/llm-settings.js.map +1 -1
- package/dist/routes/planner-tab.cjs +1 -1
- package/dist/routes/planner-tab.cjs.map +1 -1
- package/dist/routes/planner-tab.js +44 -28
- package/dist/routes/planner-tab.js.map +1 -1
- package/dist/services/telemetry.cjs +1 -1
- package/dist/services/telemetry.cjs.map +1 -1
- package/dist/services/telemetry.d.ts +5 -0
- package/dist/services/telemetry.js +122 -115
- package/dist/services/telemetry.js.map +1 -1
- package/dist/stores/conversation-panel-preferences-store.cjs +1 -1
- package/dist/stores/conversation-panel-preferences-store.cjs.map +1 -1
- package/dist/stores/conversation-panel-preferences-store.d.ts +32 -5
- package/dist/stores/conversation-panel-preferences-store.js +29 -12
- package/dist/stores/conversation-panel-preferences-store.js.map +1 -1
- package/dist/stores/conversation-state-store.cjs +1 -1
- package/dist/stores/conversation-state-store.cjs.map +1 -1
- package/dist/stores/conversation-state-store.d.ts +9 -3
- package/dist/stores/conversation-state-store.js +6 -3
- package/dist/stores/conversation-state-store.js.map +1 -1
- package/dist/stores/conversation-store.cjs +1 -1
- package/dist/stores/conversation-store.cjs.map +1 -1
- package/dist/stores/conversation-store.d.ts +2 -0
- package/dist/stores/conversation-store.js +3 -0
- package/dist/stores/conversation-store.js.map +1 -1
- package/dist/stores/model-store.cjs +1 -1
- package/dist/stores/model-store.cjs.map +1 -1
- package/dist/stores/model-store.d.ts +7 -0
- package/dist/stores/model-store.js +4 -0
- package/dist/stores/model-store.js.map +1 -1
- package/dist/types/automation.cjs.map +1 -1
- package/dist/types/automation.d.ts +46 -1
- package/dist/types/automation.js.map +1 -1
- package/dist/ui/context-menu.d.ts +1 -1
- package/dist/ui/toggle-switch.cjs +1 -1
- package/dist/ui/toggle-switch.cjs.map +1 -1
- package/dist/ui/toggle-switch.d.ts +4 -1
- package/dist/ui/toggle-switch.js +4 -3
- package/dist/ui/toggle-switch.js.map +1 -1
- package/dist/utils/automation-catalog.cjs +1 -1
- package/dist/utils/automation-catalog.cjs.map +1 -1
- package/dist/utils/automation-catalog.d.ts +12 -1
- package/dist/utils/automation-catalog.js +42 -12
- package/dist/utils/automation-catalog.js.map +1 -1
- package/dist/utils/automation-run-display.cjs +2 -0
- package/dist/utils/automation-run-display.cjs.map +1 -0
- package/dist/utils/automation-run-display.d.ts +20 -0
- package/dist/utils/automation-run-display.js +85 -0
- package/dist/utils/automation-run-display.js.map +1 -0
- package/dist/utils/automation-schedule.cjs +1 -1
- package/dist/utils/automation-schedule.cjs.map +1 -1
- package/dist/utils/automation-schedule.d.ts +16 -0
- package/dist/utils/automation-schedule.js +2 -0
- package/dist/utils/automation-schedule.js.map +1 -1
- package/dist/utils/constants.cjs +1 -1
- package/dist/utils/constants.cjs.map +1 -1
- package/dist/utils/constants.d.ts +4 -0
- package/dist/utils/constants.js +23 -3
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/format-event-timestamp.cjs +2 -0
- package/dist/utils/format-event-timestamp.cjs.map +1 -0
- package/dist/utils/format-event-timestamp.d.ts +1 -0
- package/dist/utils/format-event-timestamp.js +13 -0
- package/dist/utils/format-event-timestamp.js.map +1 -0
- package/dist/utils/git-diff-stats.cjs +2 -2
- package/dist/utils/git-diff-stats.cjs.map +1 -1
- package/dist/utils/git-diff-stats.d.ts +4 -0
- package/dist/utils/git-diff-stats.js +12 -2
- package/dist/utils/git-diff-stats.js.map +1 -1
- package/dist/utils/plan-file.cjs +4 -0
- package/dist/utils/plan-file.cjs.map +1 -0
- package/dist/utils/plan-file.d.ts +18 -0
- package/dist/utils/plan-file.js +58 -0
- package/dist/utils/plan-file.js.map +1 -0
- package/dist/utils/recommended-automation-rail.cjs +1 -1
- package/dist/utils/recommended-automation-rail.cjs.map +1 -1
- package/dist/utils/recommended-automation-rail.js +1 -0
- package/dist/utils/recommended-automation-rail.js.map +1 -1
- package/dist/utils/scroll-fade-state.cjs +1 -1
- package/dist/utils/scroll-fade-state.cjs.map +1 -1
- package/dist/utils/scroll-fade-state.d.ts +6 -0
- package/dist/utils/scroll-fade-state.js +8 -1
- package/dist/utils/scroll-fade-state.js.map +1 -1
- package/dist/utils/sdk-settings-schema.cjs +1 -1
- package/dist/utils/sdk-settings-schema.cjs.map +1 -1
- package/dist/utils/sdk-settings-schema.d.ts +1 -0
- package/dist/utils/sdk-settings-schema.js +25 -22
- package/dist/utils/sdk-settings-schema.js.map +1 -1
- package/dist/utils/utils.cjs +1 -1
- package/dist/utils/utils.cjs.map +1 -1
- package/dist/utils/utils.js +11 -11
- package/dist/utils/utils.js.map +1 -1
- package/package.json +4 -4
- package/scripts/check-sdk-version-sync.mjs +6 -6
- package/scripts/dev-safe.mjs +1 -1
- package/scripts/dev-with-automation.mjs +1 -1
- package/scripts/static-server.mjs +33 -1
- package/build/assets/active-backend-context-CrHTlgvN.js +0 -2
- package/build/assets/agent-profiles-settings-Dzgb7G9z.js +0 -1
- package/build/assets/agent-server-conversation-service.api-tnqNjbpE.js +0 -86
- package/build/assets/agent-settings-DLtsqaOs.js +0 -2
- package/build/assets/agent-settings-fFvR-XC2.js +0 -1
- package/build/assets/api-key-entry-screen-qTzrmJcr.js +0 -1
- package/build/assets/automation-detail-BmwlCUAB.js +0 -3
- package/build/assets/automation-git-sync-CprN5DcU.js +0 -1
- package/build/assets/automation-setup-route-C40kXjMY.js +0 -1
- package/build/assets/automations-list-DuNcRawl.js +0 -1
- package/build/assets/backend-form-modal-lhGwzXFI.js +0 -1
- package/build/assets/bot-dMYHVfYM.js +0 -1
- package/build/assets/canvas-extensions-8A-XhpgP.js +0 -1
- package/build/assets/check-CS0vmpQQ.js +0 -1
- package/build/assets/chevron-down-e1QBpjVy.js +0 -1
- package/build/assets/chevron-right-ZG4R5G4Q.js +0 -1
- package/build/assets/circle-check-DzWLNsbE.js +0 -1
- package/build/assets/command-menu--UIlGL72.js +0 -1
- package/build/assets/commits-tab-AnZwLvh-.js +0 -1
- package/build/assets/confirmation-modal-Dv1ktp8K.js +0 -1
- package/build/assets/conversation-BbGrAO4Z.js +0 -93
- package/build/assets/conversation-mYT6NAoj.js +0 -1
- package/build/assets/conversation-panel-mYT6NAoj.js +0 -1
- package/build/assets/edit-automation-modal-DadGbJ2u.js +0 -1
- package/build/assets/empty-state-BoGVDecT.js +0 -1
- package/build/assets/enum-filter-dropdown-Bgca129f.js +0 -1
- package/build/assets/extensions-hub-CcDqq_vR.js +0 -1
- package/build/assets/extensions-navigation-Cr4yzYk4.js +0 -1
- package/build/assets/external-link-DKUlnCQV.js +0 -1
- package/build/assets/files-tab-D4o2VyE_.js +0 -1
- package/build/assets/get-git-path-ChKDVHZp.js +0 -1
- package/build/assets/git-repo-dropdown-BkqzkMmM.js +0 -1
- package/build/assets/home-ChpSuepX.js +0 -1
- package/build/assets/home-DIsB440S.js +0 -1
- package/build/assets/home-automation-run-tooltip-BVNDWjAH.js +0 -1
- package/build/assets/home-store-CY9Ej0ux.js +0 -1
- package/build/assets/index-home-BdlrFIif.js +0 -1
- package/build/assets/info-B6RQawoW.js +0 -1
- package/build/assets/install-server-modal-Dpy89p4g.js +0 -1
- package/build/assets/kebab-menu-item-content-D8hSNGmm.js +0 -1
- package/build/assets/list-filter-DsEK7NFC.js +0 -1
- package/build/assets/llm-not-configured-banner-CIFABh3K.js +0 -27
- package/build/assets/llm-settings-B9juXhIa.js +0 -1
- package/build/assets/llm-settings-De1d5dfr.js +0 -1
- package/build/assets/llm-subscription-service-BpJ0ouQo.js +0 -1
- package/build/assets/loader-circle-CC1au6hc.js +0 -1
- package/build/assets/manage-backends-modal-BrPV3oB-.js +0 -1
- package/build/assets/manifest-80fb1c29.js +0 -1
- package/build/assets/markdown-renderer-BzTlxI8x.js +0 -8
- package/build/assets/mcp-page-BEBYqH_K.js +0 -9
- package/build/assets/messages-DKV9cRc2.js +0 -41
- package/build/assets/onboarding-DV_OXoeP.js +0 -1
- package/build/assets/onboarding-modal-rkyBYkeQ.js +0 -1
- package/build/assets/organization-service.api-DrYNkEN_.js +0 -1
- package/build/assets/pencil-47jAZH_V.js +0 -1
- package/build/assets/pin-By41Vl5J.js +0 -1
- package/build/assets/planner-tab-C9uZmhme.js +0 -1
- package/build/assets/plug-CG5HFcNG.js +0 -1
- package/build/assets/plugins-management-service-BMJgC3Ga.js +0 -1
- package/build/assets/plus-C7Slq-0I.js +0 -1
- package/build/assets/profiles-service.api-ChoKrL0l.js +0 -1
- package/build/assets/proxy-9Fe1v5na.js +0 -1
- package/build/assets/recommended-automations-launcher-6ABrI9Cy.js +0 -1
- package/build/assets/refresh-cw-3q3Frrii.js +0 -1
- package/build/assets/root-Dc8YmC9F.js +0 -2
- package/build/assets/root-VDaypvK4.css +0 -1
- package/build/assets/root-layout-CXkhSPYh.js +0 -2
- package/build/assets/schema-field-D-y9-LDb.js +0 -1
- package/build/assets/scroll-fade-state-Dw-i4SGq.js +0 -1
- package/build/assets/sdk-section-page-BlFiizlG.js +0 -1
- package/build/assets/secret-form-BB7the8W.js +0 -1
- package/build/assets/secrets-service-ByZVENbp.js +0 -1
- package/build/assets/settings-C0EWuBtA.js +0 -1
- package/build/assets/settings-index-5w5UW2K3.js +0 -1
- package/build/assets/settings-service.api-DJ1r62Zr.js +0 -1
- package/build/assets/shared-conversation-CA5ISEDy.js +0 -1
- package/build/assets/shield-check-D2aCRd16.js +0 -1
- package/build/assets/sidebar-mobile-menu-toggle-C_fb0Jki.js +0 -1
- package/build/assets/skill-scope-B42H-XOc.js +0 -1
- package/build/assets/skills-plugins-tgF8EiXC.js +0 -1
- package/build/assets/skills-settings-BgJ9PaOe.js +0 -1
- package/build/assets/styled-tooltip-C4jf5Fv9.js +0 -1
- package/build/assets/toggle-switch-ChOLXv2n.js +0 -1
- package/build/assets/trash-2-D7K26eDO.js +0 -1
- package/build/assets/trash-D-HYiVYM.js +0 -1
- package/build/assets/triangle-alert-CtdXWHUI.js +0 -1
- package/build/assets/usage-tab-CVDffLPt.js +0 -1
- package/build/assets/use-acp-credential-form-XIQmpX6M.js +0 -1
- package/build/assets/use-activate-agent-profile-BLfmvDiG.js +0 -1
- package/build/assets/use-agent-profiles-Bd9Bvvp1.js +0 -1
- package/build/assets/use-canvas-extensions-Bi693ujJ.js +0 -1
- package/build/assets/use-config-A9QovgXO.js +0 -1
- package/build/assets/use-create-conversation-Dx3l7mFZ.js +0 -1
- package/build/assets/use-create-secret-B9cUFWRG.js +0 -1
- package/build/assets/use-has-permission-B3C8rQmR.js +0 -1
- package/build/assets/use-is-authed-nTBcM7dE.js +0 -1
- package/build/assets/use-llm-configured-BV9nZ1_j.js +0 -1
- package/build/assets/use-llm-profiles-BO-P4Oyo.js +0 -1
- package/build/assets/use-manifest-capabilities-Cw_flwEz.js +0 -1
- package/build/assets/use-onboarding-completion-D8U7k4Qb.js +0 -1
- package/build/assets/use-pinned-home-route-CckOZrmb.js +0 -1
- package/build/assets/use-plugins-marketplace-7i94Zu3Z.js +0 -1
- package/build/assets/use-save-agent-profile-BUjSsDXK.js +0 -1
- package/build/assets/use-settings-DSXLbvBl.js +0 -1
- package/build/assets/use-settings-nav-items-CwRw-CmX.js +0 -16
- package/build/assets/use-tracking-D53y3TH9.js +0 -3
- package/build/assets/utils-CN5ZfZy1.js +0 -1
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~czjee3a3-DqZDXfg2.js +0 -186
- package/build/assets/vendor~root-layout-C9Ju9DQg.js +0 -1
- package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~mcp~automations-list~aut~ibfbmr9f-cDuKr-WD.js +0 -1
- package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~iyia17eu-Chf7vmKB.js +0 -1
- package/build/assets/x-DJdhbdmt.js +0 -1
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs +0 -2
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs.map +0 -1
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.d.ts +0 -35
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js +0 -247
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js.map +0 -1
- package/dist/hooks/query/use-skills.cjs +0 -2
- package/dist/hooks/query/use-skills.cjs.map +0 -1
- package/dist/hooks/query/use-skills.d.ts +0 -7
- package/dist/hooks/query/use-skills.js +0 -13
- package/dist/hooks/query/use-skills.js.map +0 -1
- package/dist/hooks/use-has-permission.cjs +0 -2
- package/dist/hooks/use-has-permission.cjs.map +0 -1
- package/dist/hooks/use-has-permission.d.ts +0 -1
- package/dist/hooks/use-has-permission.js +0 -8
- package/dist/hooks/use-has-permission.js.map +0 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/eye.cjs +0 -2
- package/dist/node_modules/lucide-react/dist/esm/icons/eye.cjs.map +0 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/eye.js +0 -14
- package/dist/node_modules/lucide-react/dist/esm/icons/eye.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-selector.cjs","names":[],"sources":["../../../../src/components/features/backends/backend-selector.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useMatch, useNavigate } from \"react-router\";\nimport { Plus, Settings } from \"lucide-react\";\nimport { Dropdown } from \"#/ui/dropdown/dropdown\";\nimport { DropdownOption } from \"#/ui/dropdown/types\";\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\nimport { isNoBackend } from \"#/api/backend-registry/active-store\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { useAllCloudOrganizations } from \"#/hooks/query/use-cloud-organizations\";\nimport { useCloudCurrentUserId } from \"#/hooks/query/use-cloud-current-user-id\";\nimport {\n useBackendsHealth,\n type BackendHealth,\n} from \"#/hooks/query/use-backends-health\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport type { Backend } from \"#/api/backend-registry/types\";\n// Import the trigger helpers from the lightweight store, not the overlay\n// component, so the eagerly-mounted sidebar/backend-selector graph does not\n// pull in the overlay's render code (the overlay is lazy-loaded from\n// `routes/root-layout.tsx`).\nimport {\n ENVIRONMENT_SWITCH_SETACTIVE_DELAY_MS,\n triggerEnvironmentSwitch,\n} from \"#/components/features/backends/environment-switch-store\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { AddBackendModal } from \"./add-backend-modal\";\nimport { BackendStatusDot } from \"./backend-status-dot\";\nimport { ManageBackendsModal } from \"./manage-backends-modal\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlTransitionClassName } from \"#/utils/form-control-classes\";\nimport {\n dropdownFooterActionClassName,\n dropdownMenuListClassName,\n dropdownMenuRowIconWrapperClassName,\n} from \"#/utils/dropdown-classes\";\n\nconst VALUE_SEPARATOR = \"::\";\n\nfunction makeOptionValue(backendId: string, orgId: string | null): string {\n return orgId ? `${backendId}${VALUE_SEPARATOR}${orgId}` : backendId;\n}\n\nfunction parseOptionValue(value: string): {\n backendId: string;\n orgId: string | null;\n} {\n const [backendId, orgId] = value.split(VALUE_SEPARATOR);\n return { backendId, orgId: orgId ?? null };\n}\n\nfunction buildStatusPrefix(health: BackendHealth | undefined) {\n return <BackendStatusDot isConnected={health?.isConnected ?? null} />;\n}\n\nfunction buildNoBackendPrefix() {\n return <BackendStatusDot isConnected=\"unavailable\" />;\n}\n\nfunction buildOptions(\n registered: Backend[],\n personalWorkspaceLabel: string,\n cloudOrgs: ReturnType<typeof useAllCloudOrganizations>,\n currentUserIds: ReturnType<typeof useCloudCurrentUserId>,\n healthByBackendId: Record<string, BackendHealth>,\n): DropdownOption[] {\n const options: DropdownOption[] = [];\n\n const locals = registered.filter((b) => b.kind === \"local\");\n const clouds = registered.filter((b) => b.kind === \"cloud\");\n\n for (const b of locals) {\n options.push({\n value: makeOptionValue(b.id, null),\n label: b.name,\n prefix: buildStatusPrefix(healthByBackendId[b.id]),\n });\n }\n\n for (const b of clouds) {\n const entry = cloudOrgs[b.id];\n const prefix = buildStatusPrefix(healthByBackendId[b.id]);\n if (!entry || entry.orgs.length === 0) {\n options.push({\n value: makeOptionValue(b.id, null),\n label: b.name,\n prefix,\n });\n } else {\n // Personal-workspace rule (per the cloud contract): the org whose\n // id matches the calling user's id is the user's personal\n // workspace. We resolve `user_id` once per backend (via /me on any\n // one org) and apply it across all orgs of that backend.\n const userIdForBackend = currentUserIds[b.id]?.userId ?? null;\n\n for (const org of entry.orgs) {\n const isPersonal = !!userIdForBackend && userIdForBackend === org.id;\n const orgLabel = isPersonal ? personalWorkspaceLabel : org.name;\n options.push({\n value: makeOptionValue(b.id, org.id),\n label: `${b.name} – ${orgLabel}`,\n // All org rows for the same cloud backend share that backend's\n // single connectivity verdict — there is no per-org probe.\n prefix,\n });\n }\n }\n }\n\n return options;\n}\n\ninterface BackendSelectorProps {\n /** Render the menu above the trigger (e.g. when pinned to bottom of sidebar). */\n openUpward?: boolean;\n /** Hide the selector input trigger and only render the dropdown menu. */\n hideTrigger?: boolean;\n /** Whether the dropdown menu should start open on mount. */\n defaultOpen?: boolean;\n /** Callback fired after selecting a backend/org option. */\n onSelectOption?: () => void;\n /**\n * Override the internal Add Backend modal handling. When provided,\n * clicking \"Add Backend\" calls this instead of opening BackendSelector's\n * own modal. Useful when the selector is mounted inside an ephemeral\n * container (e.g. the collapsed-sidebar popover) and the modal must\n * survive the parent unmounting.\n */\n onOpenAddBackend?: () => void;\n /** Same as onOpenAddBackend but for the Manage Backends modal. */\n onOpenManageBackends?: () => void;\n /**\n * Whether the surrounding sidebar rail is in its collapsed variant. Passed\n * down from `SidebarRailBody` so the mobile drawer (which always renders\n * the expanded rail) can override the persisted desktop value.\n */\n sidebarCollapsed?: boolean;\n}\n\nexport function BackendSelector({\n openUpward = false,\n hideTrigger = false,\n defaultOpen = false,\n onSelectOption,\n onOpenAddBackend,\n onOpenManageBackends,\n sidebarCollapsed = false,\n}: BackendSelectorProps = {}) {\n const { t } = useTranslation(\"openhands\");\n const { backends, active, setActive } = useActiveBackendContext();\n const cloudOrgs = useAllCloudOrganizations();\n const currentUserIds = useCloudCurrentUserId();\n // Probe each registered backend every 10s.\n const healthByBackendId = useBackendsHealth(backends);\n const navigate = useNavigate();\n const settingsMatch = useMatch(\"/settings\");\n const settingsSubrouteMatch = useMatch(\"/settings/*\");\n const conversationMatch = useMatch(\"/conversations/:conversationId\");\n const automationDetailMatch = useMatch(\"/automations/:automationId\");\n const [addBackendModalOpen, setAddBackendModalOpen] = React.useState(false);\n const [manageBackendsModalOpen, setManageBackendsModalOpen] =\n React.useState(false);\n\n const personalWorkspaceLabel = t(I18nKey.BACKEND$PERSONAL_WORKSPACE);\n\n const options = React.useMemo(\n () =>\n buildOptions(\n backends,\n personalWorkspaceLabel,\n cloudOrgs,\n currentUserIds,\n healthByBackendId,\n ),\n [\n backends,\n personalWorkspaceLabel,\n cloudOrgs,\n currentUserIds,\n healthByBackendId,\n ],\n );\n\n const noBackendSelected = isNoBackend(active.backend);\n const noBackendLabel = t(I18nKey.BACKEND$NO_BACKEND_AVAILABLE);\n const activeValue = makeOptionValue(active.backend.id, active.orgId);\n const activeOption = noBackendSelected\n ? undefined\n : options.find((o) => o.value === activeValue);\n const isSettingsActive = Boolean(settingsMatch || settingsSubrouteMatch);\n const settingsLabel = t(I18nKey.SIDEBAR$SETTINGS);\n const isRightPanelShown = useConversationStore(\n (state) => state.isRightPanelShown,\n );\n // When the sidebar rail is expanded, `placement=\"left\"` hugs the main\n // canvas and reads awkwardly; prefer above the control. When the rail is\n // collapsed, keep left except on active conversation + open right drawer.\n const settingsTooltipPlacement =\n !sidebarCollapsed || (conversationMatch && isRightPanelShown)\n ? \"top\"\n : \"left\";\n\n const someCloudLoading = Object.values(cloudOrgs).some((c) => c.isLoading);\n\n // Self-heal a malformed `(cloudBackendId, null)` selection.\n //\n // Once a cloud backend's orgs resolve, the dropdown only renders\n // per-org rows for it — the `(backendId, null)` row disappears, so\n // selecting that shape would drift from what the dropdown can render\n // (UI says \"Local\", APIs hit cloud). When we detect the drift, snap\n // the selection onto Cloud's current org first, then fall back to the\n // personal workspace (or, lacking a /me result, the first org). The\n // selection is recorded locally only; the cloud request scope follows\n // from the X-Org-Id header sent by `callCloudProxy`, so the cloud UI's\n // org choice is never mutated as a side effect.\n React.useEffect(() => {\n if (noBackendSelected || active.backend.kind !== \"cloud\" || active.orgId)\n return;\n const { backend } = active;\n const entry = cloudOrgs[backend.id];\n if (!entry || entry.orgs.length === 0) return;\n\n const currentOrg = entry.currentOrgId\n ? entry.orgs.find((o) => o.id === entry.currentOrgId)\n : undefined;\n const userId = currentUserIds[backend.id]?.userId ?? null;\n const personal = userId\n ? entry.orgs.find((o) => o.id === userId)\n : undefined;\n const target = currentOrg ?? personal ?? entry.orgs[0];\n if (target) {\n setActive(backend.id, target.id);\n }\n }, [active, cloudOrgs, currentUserIds, setActive, noBackendSelected]);\n\n const openAddBackendModal = React.useCallback(() => {\n if (onOpenAddBackend) {\n onOpenAddBackend();\n onSelectOption?.();\n return;\n }\n setAddBackendModalOpen(true);\n }, [onOpenAddBackend, onSelectOption]);\n\n const openManageBackendsModal = React.useCallback(() => {\n if (onOpenManageBackends) {\n onOpenManageBackends();\n onSelectOption?.();\n return;\n }\n setManageBackendsModalOpen(true);\n }, [onOpenManageBackends, onSelectOption]);\n\n const isLockedToCloud = getLockedCloudHost() !== null;\n\n const preventDropdownMenuClose = React.useCallback(\n (event: React.SyntheticEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n },\n [],\n );\n\n const handleAddBackendClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openAddBackendModal();\n },\n [openAddBackendModal, preventDropdownMenuClose],\n );\n\n const handleAddBackendTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openAddBackendModal();\n },\n [openAddBackendModal, preventDropdownMenuClose],\n );\n\n const handleManageBackendsClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openManageBackendsModal();\n },\n [openManageBackendsModal, preventDropdownMenuClose],\n );\n\n const handleManageBackendsTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openManageBackendsModal();\n },\n [openManageBackendsModal, preventDropdownMenuClose],\n );\n\n const addBackendFooter = (\n <div className={dropdownMenuListClassName}>\n {isLockedToCloud ? null : (\n <button\n type=\"button\"\n data-testid=\"add-backend-menu-item\"\n onMouseDown={preventDropdownMenuClose}\n onTouchStart={preventDropdownMenuClose}\n onTouchEnd={handleAddBackendTouchEnd}\n onClick={handleAddBackendClick}\n className={cn(\n dropdownFooterActionClassName,\n \"cursor-pointer rounded-md\",\n )}\n >\n <span className={dropdownMenuRowIconWrapperClassName} aria-hidden>\n <Plus width={16} height={16} />\n </span>\n {t(I18nKey.BACKEND$ADD)}\n </button>\n )}\n <button\n type=\"button\"\n data-testid=\"manage-backends-menu-item\"\n onMouseDown={preventDropdownMenuClose}\n onTouchStart={preventDropdownMenuClose}\n onTouchEnd={handleManageBackendsTouchEnd}\n onClick={handleManageBackendsClick}\n className={cn(\n dropdownFooterActionClassName,\n \"cursor-pointer rounded-md\",\n )}\n >\n <span className={dropdownMenuRowIconWrapperClassName} aria-hidden>\n <Settings width={16} height={16} />\n </span>\n {t(\n isLockedToCloud\n ? I18nKey.BACKEND$RECONNECT_CLOUD\n : I18nKey.BACKEND$MANAGE,\n )}\n </button>\n </div>\n );\n\n const handleSelectBackend = React.useCallback(\n async (value: string) => {\n if (value === activeValue) return;\n\n const { backendId, orgId } = parseOptionValue(value);\n const target = backends.find((b) => b.id === backendId);\n if (!target) return;\n\n triggerEnvironmentSwitch(\n options.find((option) => option.value === value)?.label ?? target.name,\n );\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ENVIRONMENT_SWITCH_SETACTIVE_DELAY_MS);\n });\n\n // @spec BM-002 — Switching backends keeps the user on the same page\n if (conversationMatch) navigate(\"/conversations\");\n else if (automationDetailMatch) navigate(\"/automations\");\n\n setActive(target.id, orgId);\n onSelectOption?.();\n },\n [\n activeValue,\n backends,\n conversationMatch,\n automationDetailMatch,\n navigate,\n options,\n setActive,\n t,\n onSelectOption,\n ],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-2 w-full\">\n <div className=\"flex-1 min-w-0\">\n <Dropdown\n testId=\"backend-selector\"\n key={`${activeValue}-${activeOption?.label ?? \"\"}`}\n defaultValue={\n activeOption ?? {\n value: activeValue,\n label: noBackendSelected ? noBackendLabel : active.backend.name,\n prefix: noBackendSelected\n ? buildNoBackendPrefix()\n : buildStatusPrefix(healthByBackendId[active.backend.id]),\n }\n }\n footer={addBackendFooter}\n openUpward={openUpward}\n hideTrigger={hideTrigger}\n defaultOpen={defaultOpen}\n openOnHover={!hideTrigger}\n onChange={(item) => {\n if (!item) return;\n void handleSelectBackend(item.value);\n }}\n placeholder={\n noBackendSelected ? noBackendLabel : active.backend.name\n }\n loading={someCloudLoading}\n options={options}\n className=\"h-10 px-2 py-0 bg-transparent border-transparent hover:bg-[var(--oh-surface-raised)] focus-within:bg-[var(--oh-surface-raised)] focus-within:border-transparent focus-within:ring-0\"\n />\n </div>\n {!hideTrigger ? (\n <StyledTooltip\n content={settingsLabel}\n placement={settingsTooltipPlacement}\n offset={10}\n >\n <NavigationLink\n to=\"/settings\"\n data-testid=\"backend-selector-settings-link\"\n data-active={isSettingsActive}\n aria-label={settingsLabel}\n className={\n isSettingsActive\n ? cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md bg-tertiary text-white font-normal cursor-pointer\",\n formControlTransitionClassName,\n )\n : cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)] cursor-pointer\",\n formControlTransitionClassName,\n )\n }\n >\n <Settings width={16} height={16} />\n </NavigationLink>\n </StyledTooltip>\n ) : null}\n </div>\n {addBackendModalOpen ? (\n <AddBackendModal onClose={() => setAddBackendModalOpen(false)} />\n ) : null}\n {manageBackendsModalOpen ? (\n <ManageBackendsModal\n onClose={() => setManageBackendsModalOpen(false)}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"backend-selector.cjs","names":[],"sources":["../../../../src/components/features/backends/backend-selector.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useMatch, useNavigate } from \"react-router\";\nimport { Plus, Settings } from \"lucide-react\";\nimport { Dropdown } from \"#/ui/dropdown/dropdown\";\nimport { DropdownOption } from \"#/ui/dropdown/types\";\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\nimport { isNoBackend } from \"#/api/backend-registry/active-store\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { useAllCloudOrganizations } from \"#/hooks/query/use-cloud-organizations\";\nimport { useCloudCurrentUserId } from \"#/hooks/query/use-cloud-current-user-id\";\nimport {\n useBackendsHealth,\n type BackendHealth,\n} from \"#/hooks/query/use-backends-health\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport type { Backend } from \"#/api/backend-registry/types\";\n// Import the trigger helpers from the lightweight store, not the overlay\n// component, so the eagerly-mounted sidebar/backend-selector graph does not\n// pull in the overlay's render code (the overlay is lazy-loaded from\n// `routes/root-layout.tsx`).\nimport {\n ENVIRONMENT_SWITCH_SETACTIVE_DELAY_MS,\n triggerEnvironmentSwitch,\n} from \"#/components/features/backends/environment-switch-store\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { AddBackendModal } from \"./add-backend-modal\";\nimport { BackendStatusDot } from \"./backend-status-dot\";\nimport { ManageBackendsModal } from \"./manage-backends-modal\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlTransitionClassName } from \"#/utils/form-control-classes\";\nimport {\n dropdownFooterActionClassName,\n dropdownMenuListClassName,\n dropdownMenuRowIconWrapperClassName,\n} from \"#/utils/dropdown-classes\";\n\nconst VALUE_SEPARATOR = \"::\";\n\nfunction makeOptionValue(backendId: string, orgId: string | null): string {\n return orgId ? `${backendId}${VALUE_SEPARATOR}${orgId}` : backendId;\n}\n\nfunction parseOptionValue(value: string): {\n backendId: string;\n orgId: string | null;\n} {\n const [backendId, orgId] = value.split(VALUE_SEPARATOR);\n return { backendId, orgId: orgId ?? null };\n}\n\nfunction buildStatusPrefix(health: BackendHealth | undefined) {\n return <BackendStatusDot isConnected={health?.isConnected ?? null} />;\n}\n\nfunction buildNoBackendPrefix() {\n return <BackendStatusDot isConnected=\"unavailable\" />;\n}\n\nfunction buildOptions(\n registered: Backend[],\n personalWorkspaceLabel: string,\n cloudOrgs: ReturnType<typeof useAllCloudOrganizations>,\n currentUserIds: ReturnType<typeof useCloudCurrentUserId>,\n healthByBackendId: Record<string, BackendHealth>,\n): DropdownOption[] {\n const options: DropdownOption[] = [];\n\n const locals = registered.filter((b) => b.kind === \"local\");\n const clouds = registered.filter((b) => b.kind === \"cloud\");\n\n for (const b of locals) {\n options.push({\n value: makeOptionValue(b.id, null),\n label: b.name,\n prefix: buildStatusPrefix(healthByBackendId[b.id]),\n });\n }\n\n for (const b of clouds) {\n const entry = cloudOrgs[b.id];\n const prefix = buildStatusPrefix(healthByBackendId[b.id]);\n if (!entry || entry.orgs.length === 0) {\n options.push({\n value: makeOptionValue(b.id, null),\n label: b.name,\n prefix,\n });\n } else {\n // Personal-workspace rule (per the cloud contract): the org whose\n // id matches the calling user's id is the user's personal\n // workspace. We resolve `user_id` once per backend (via /me on any\n // one org) and apply it across all orgs of that backend.\n const userIdForBackend = currentUserIds[b.id]?.userId ?? null;\n\n for (const org of entry.orgs) {\n const isPersonal = !!userIdForBackend && userIdForBackend === org.id;\n const orgLabel = isPersonal ? personalWorkspaceLabel : org.name;\n options.push({\n value: makeOptionValue(b.id, org.id),\n label: `${b.name} – ${orgLabel}`,\n // All org rows for the same cloud backend share that backend's\n // single connectivity verdict — there is no per-org probe.\n prefix,\n });\n }\n }\n }\n\n return options;\n}\n\ninterface BackendSelectorProps {\n /** Render the menu above the trigger (e.g. when pinned to bottom of sidebar). */\n openUpward?: boolean;\n /** Hide the selector input trigger and only render the dropdown menu. */\n hideTrigger?: boolean;\n /** Whether the dropdown menu should start open on mount. */\n defaultOpen?: boolean;\n /** Callback fired after selecting a backend/org option. */\n onSelectOption?: () => void;\n /**\n * Override the internal Add Backend modal handling. When provided,\n * clicking \"Add Backend\" calls this instead of opening BackendSelector's\n * own modal. Useful when the selector is mounted inside an ephemeral\n * container (e.g. the collapsed-sidebar popover) and the modal must\n * survive the parent unmounting.\n */\n onOpenAddBackend?: () => void;\n /** Same as onOpenAddBackend but for the Manage Backends modal. */\n onOpenManageBackends?: () => void;\n /**\n * Whether the surrounding sidebar rail is in its collapsed variant. Passed\n * down from `SidebarRailBody` so the mobile drawer (which always renders\n * the expanded rail) can override the persisted desktop value.\n */\n sidebarCollapsed?: boolean;\n}\n\nexport function BackendSelector({\n openUpward = false,\n hideTrigger = false,\n defaultOpen = false,\n onSelectOption,\n onOpenAddBackend,\n onOpenManageBackends,\n sidebarCollapsed = false,\n}: BackendSelectorProps = {}) {\n const { t } = useTranslation(\"openhands\");\n const { backends, active, setActive } = useActiveBackendContext();\n const cloudOrgs = useAllCloudOrganizations();\n const currentUserIds = useCloudCurrentUserId();\n // Probe each registered backend every 10s.\n const healthByBackendId = useBackendsHealth(backends);\n const navigate = useNavigate();\n const settingsMatch = useMatch(\"/settings\");\n const settingsSubrouteMatch = useMatch(\"/settings/*\");\n const conversationMatch = useMatch(\"/conversations/:conversationId\");\n const automationDetailMatch = useMatch(\"/automations/:automationId\");\n const [addBackendModalOpen, setAddBackendModalOpen] = React.useState(false);\n const [manageBackendsModalOpen, setManageBackendsModalOpen] =\n React.useState(false);\n\n const personalWorkspaceLabel = t(I18nKey.BACKEND$PERSONAL_WORKSPACE);\n\n const options = React.useMemo(\n () =>\n buildOptions(\n backends,\n personalWorkspaceLabel,\n cloudOrgs,\n currentUserIds,\n healthByBackendId,\n ),\n [\n backends,\n personalWorkspaceLabel,\n cloudOrgs,\n currentUserIds,\n healthByBackendId,\n ],\n );\n\n const noBackendSelected = isNoBackend(active.backend);\n const noBackendLabel = t(I18nKey.BACKEND$NO_BACKEND_AVAILABLE);\n const activeValue = makeOptionValue(active.backend.id, active.orgId);\n const activeOption = noBackendSelected\n ? undefined\n : options.find((o) => o.value === activeValue);\n const isSettingsActive = Boolean(settingsMatch || settingsSubrouteMatch);\n const settingsLabel = t(I18nKey.SIDEBAR$SETTINGS);\n const isRightPanelShown = useConversationStore(\n (state) => state.isRightPanelShown,\n );\n // When the sidebar rail is expanded, `placement=\"left\"` hugs the main\n // canvas and reads awkwardly; prefer above the control. When the rail is\n // collapsed, keep left except on active conversation + open right drawer.\n const settingsTooltipPlacement =\n !sidebarCollapsed || (conversationMatch && isRightPanelShown)\n ? \"top\"\n : \"left\";\n\n const someCloudLoading = Object.values(cloudOrgs).some((c) => c.isLoading);\n\n // Self-heal a malformed `(cloudBackendId, null)` selection.\n //\n // Once a cloud backend's orgs resolve, the dropdown only renders\n // per-org rows for it — the `(backendId, null)` row disappears, so\n // selecting that shape would drift from what the dropdown can render\n // (UI says \"Local\", APIs hit cloud). When we detect the drift, snap\n // the selection onto Cloud's current org first, then fall back to the\n // personal workspace (or, lacking a /me result, the first org). The\n // selection is recorded locally only; the cloud request scope follows\n // from the X-Org-Id header sent by `callCloudProxy`, so the cloud UI's\n // org choice is never mutated as a side effect.\n React.useEffect(() => {\n if (noBackendSelected || active.backend.kind !== \"cloud\" || active.orgId)\n return;\n const { backend } = active;\n const entry = cloudOrgs[backend.id];\n if (!entry || entry.orgs.length === 0) return;\n\n const currentOrg = entry.currentOrgId\n ? entry.orgs.find((o) => o.id === entry.currentOrgId)\n : undefined;\n const userId = currentUserIds[backend.id]?.userId ?? null;\n const personal = userId\n ? entry.orgs.find((o) => o.id === userId)\n : undefined;\n const target = currentOrg ?? personal ?? entry.orgs[0];\n if (target) {\n setActive(backend.id, target.id);\n }\n }, [active, cloudOrgs, currentUserIds, setActive, noBackendSelected]);\n\n const openAddBackendModal = React.useCallback(() => {\n if (onOpenAddBackend) {\n onOpenAddBackend();\n onSelectOption?.();\n return;\n }\n setAddBackendModalOpen(true);\n }, [onOpenAddBackend, onSelectOption]);\n\n const openManageBackendsModal = React.useCallback(() => {\n if (onOpenManageBackends) {\n onOpenManageBackends();\n onSelectOption?.();\n return;\n }\n setManageBackendsModalOpen(true);\n }, [onOpenManageBackends, onSelectOption]);\n\n const isLockedToCloud = getLockedCloudHost() !== null;\n // A cookie-auth (OHE-hosted) Canvas has nothing to add, manage, or\n // reconnect — its single locked backend is owned by the main-app session.\n const hideBackendFooter =\n isLockedToCloud && active.backend.authMode === \"cookie\";\n\n const preventDropdownMenuClose = React.useCallback(\n (event: React.SyntheticEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n },\n [],\n );\n\n const handleAddBackendClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openAddBackendModal();\n },\n [openAddBackendModal, preventDropdownMenuClose],\n );\n\n const handleAddBackendTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openAddBackendModal();\n },\n [openAddBackendModal, preventDropdownMenuClose],\n );\n\n const handleManageBackendsClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openManageBackendsModal();\n },\n [openManageBackendsModal, preventDropdownMenuClose],\n );\n\n const handleManageBackendsTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openManageBackendsModal();\n },\n [openManageBackendsModal, preventDropdownMenuClose],\n );\n\n const addBackendFooter = hideBackendFooter ? undefined : (\n <div className={dropdownMenuListClassName}>\n {isLockedToCloud ? null : (\n <button\n type=\"button\"\n data-testid=\"add-backend-menu-item\"\n onMouseDown={preventDropdownMenuClose}\n onTouchStart={preventDropdownMenuClose}\n onTouchEnd={handleAddBackendTouchEnd}\n onClick={handleAddBackendClick}\n className={cn(\n dropdownFooterActionClassName,\n \"cursor-pointer rounded-md\",\n )}\n >\n <span className={dropdownMenuRowIconWrapperClassName} aria-hidden>\n <Plus width={16} height={16} />\n </span>\n {t(I18nKey.BACKEND$ADD)}\n </button>\n )}\n <button\n type=\"button\"\n data-testid=\"manage-backends-menu-item\"\n onMouseDown={preventDropdownMenuClose}\n onTouchStart={preventDropdownMenuClose}\n onTouchEnd={handleManageBackendsTouchEnd}\n onClick={handleManageBackendsClick}\n className={cn(\n dropdownFooterActionClassName,\n \"cursor-pointer rounded-md\",\n )}\n >\n <span className={dropdownMenuRowIconWrapperClassName} aria-hidden>\n <Settings width={16} height={16} />\n </span>\n {t(\n isLockedToCloud\n ? I18nKey.BACKEND$RECONNECT_CLOUD\n : I18nKey.BACKEND$MANAGE,\n )}\n </button>\n </div>\n );\n\n const handleSelectBackend = React.useCallback(\n async (value: string) => {\n if (value === activeValue) return;\n\n const { backendId, orgId } = parseOptionValue(value);\n const target = backends.find((b) => b.id === backendId);\n if (!target) return;\n\n triggerEnvironmentSwitch(\n options.find((option) => option.value === value)?.label ?? target.name,\n );\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ENVIRONMENT_SWITCH_SETACTIVE_DELAY_MS);\n });\n\n // @spec BM-002 — Switching backends keeps the user on the same page\n if (conversationMatch) navigate(\"/conversations\");\n else if (automationDetailMatch) navigate(\"/automations\");\n\n setActive(target.id, orgId);\n onSelectOption?.();\n },\n [\n activeValue,\n backends,\n conversationMatch,\n automationDetailMatch,\n navigate,\n options,\n setActive,\n t,\n onSelectOption,\n ],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-2 w-full\">\n <div className=\"flex-1 min-w-0\">\n <Dropdown\n testId=\"backend-selector\"\n key={`${activeValue}-${activeOption?.label ?? \"\"}`}\n defaultValue={\n activeOption ?? {\n value: activeValue,\n label: noBackendSelected ? noBackendLabel : active.backend.name,\n prefix: noBackendSelected\n ? buildNoBackendPrefix()\n : buildStatusPrefix(healthByBackendId[active.backend.id]),\n }\n }\n footer={addBackendFooter}\n openUpward={openUpward}\n hideTrigger={hideTrigger}\n defaultOpen={defaultOpen}\n openOnHover={!hideTrigger}\n onChange={(item) => {\n if (!item) return;\n void handleSelectBackend(item.value);\n }}\n placeholder={\n noBackendSelected ? noBackendLabel : active.backend.name\n }\n loading={someCloudLoading}\n options={options}\n className=\"h-10 px-2 py-0 bg-transparent border-transparent hover:bg-[var(--oh-surface-raised)] focus-within:bg-[var(--oh-surface-raised)] focus-within:border-transparent focus-within:ring-0\"\n />\n </div>\n {!hideTrigger ? (\n <StyledTooltip\n content={settingsLabel}\n placement={settingsTooltipPlacement}\n offset={10}\n >\n {active.backend.kind === \"cloud\" ? (\n <a\n href={`${active.backend.host.replace(/\\/+$/, \"\")}/settings`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-testid=\"backend-selector-settings-link\"\n aria-label={settingsLabel}\n className={cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)] cursor-pointer\",\n formControlTransitionClassName,\n )}\n >\n <Settings width={16} height={16} />\n </a>\n ) : (\n <NavigationLink\n to=\"/settings\"\n data-testid=\"backend-selector-settings-link\"\n data-active={isSettingsActive}\n aria-label={settingsLabel}\n className={\n isSettingsActive\n ? cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md bg-tertiary text-white font-normal cursor-pointer\",\n formControlTransitionClassName,\n )\n : cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)] cursor-pointer\",\n formControlTransitionClassName,\n )\n }\n >\n <Settings width={16} height={16} />\n </NavigationLink>\n )}\n </StyledTooltip>\n ) : null}\n </div>\n {addBackendModalOpen ? (\n <AddBackendModal onClose={() => setAddBackendModalOpen(false)} />\n ) : null}\n {manageBackendsModalOpen ? (\n <ManageBackendsModal\n onClose={() => setManageBackendsModalOpen(false)}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":"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"}
|
|
@@ -7,50 +7,50 @@ import { useConversationStore as a } from "../../../stores/conversation-store.js
|
|
|
7
7
|
import { getLockedCloudHost as o } from "../../../api/agent-server-config.js";
|
|
8
8
|
import { isNoBackend as s } from "../../../api/backend-registry/active-store.js";
|
|
9
9
|
import { useActiveBackendContext as ee } from "../../../contexts/active-backend-context.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { dropdownFooterActionClassName as
|
|
13
|
-
import { NavigationLink as
|
|
14
|
-
import { useAllCloudOrganizations as
|
|
15
|
-
import { useCloudCurrentUserId as
|
|
16
|
-
import { Dropdown as
|
|
17
|
-
import { useBackendsHealth as
|
|
18
|
-
import { triggerEnvironmentSwitch as
|
|
19
|
-
import { BackendStatusDot as
|
|
20
|
-
import { AddBackendModal as
|
|
21
|
-
import { ManageBackendsModal as
|
|
22
|
-
import
|
|
23
|
-
import { Fragment as
|
|
24
|
-
import { useMatch as
|
|
10
|
+
import { StyledTooltip as te } from "../../shared/buttons/styled-tooltip.js";
|
|
11
|
+
import { formControlTransitionClassName as c } from "../../../utils/form-control-classes.js";
|
|
12
|
+
import { dropdownFooterActionClassName as l, dropdownMenuListClassName as ne, dropdownMenuRowIconWrapperClassName as u } from "../../../utils/dropdown-classes.js";
|
|
13
|
+
import { NavigationLink as d } from "../../shared/navigation-link.js";
|
|
14
|
+
import { useAllCloudOrganizations as re } from "../../../hooks/query/use-cloud-organizations.js";
|
|
15
|
+
import { useCloudCurrentUserId as ie } from "../../../hooks/query/use-cloud-current-user-id.js";
|
|
16
|
+
import { Dropdown as ae } from "../../../ui/dropdown/dropdown.js";
|
|
17
|
+
import { useBackendsHealth as oe } from "../../../hooks/query/use-backends-health.js";
|
|
18
|
+
import { triggerEnvironmentSwitch as f } from "./environment-switch-store.js";
|
|
19
|
+
import { BackendStatusDot as p } from "./backend-status-dot.js";
|
|
20
|
+
import { AddBackendModal as se } from "./add-backend-modal.js";
|
|
21
|
+
import { ManageBackendsModal as m } from "./manage-backends-modal.js";
|
|
22
|
+
import h from "react";
|
|
23
|
+
import { Fragment as ce, jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
24
|
+
import { useMatch as v, useNavigate as le } from "react-router";
|
|
25
25
|
//#region src/components/features/backends/backend-selector.tsx
|
|
26
|
-
var
|
|
27
|
-
function
|
|
28
|
-
return t ? `${e}${
|
|
26
|
+
var y = "::";
|
|
27
|
+
function b(e, t) {
|
|
28
|
+
return t ? `${e}${y}${t}` : e;
|
|
29
29
|
}
|
|
30
|
-
function
|
|
31
|
-
let [t, n] = e.split(
|
|
30
|
+
function x(e) {
|
|
31
|
+
let [t, n] = e.split(y);
|
|
32
32
|
return {
|
|
33
33
|
backendId: t,
|
|
34
34
|
orgId: n ?? null
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
-
function
|
|
38
|
-
return /* @__PURE__ */
|
|
37
|
+
function S(e) {
|
|
38
|
+
return /* @__PURE__ */ g(p, { isConnected: e?.isConnected ?? null });
|
|
39
39
|
}
|
|
40
|
-
function
|
|
41
|
-
return /* @__PURE__ */
|
|
40
|
+
function ue() {
|
|
41
|
+
return /* @__PURE__ */ g(p, { isConnected: "unavailable" });
|
|
42
42
|
}
|
|
43
|
-
function
|
|
43
|
+
function de(e, t, n, r, i) {
|
|
44
44
|
let a = [], o = e.filter((e) => e.kind === "local"), s = e.filter((e) => e.kind === "cloud");
|
|
45
45
|
for (let e of o) a.push({
|
|
46
|
-
value:
|
|
46
|
+
value: b(e.id, null),
|
|
47
47
|
label: e.name,
|
|
48
|
-
prefix:
|
|
48
|
+
prefix: S(i[e.id])
|
|
49
49
|
});
|
|
50
50
|
for (let e of s) {
|
|
51
|
-
let o = n[e.id], s =
|
|
51
|
+
let o = n[e.id], s = S(i[e.id]);
|
|
52
52
|
if (!o || o.orgs.length === 0) a.push({
|
|
53
|
-
value:
|
|
53
|
+
value: b(e.id, null),
|
|
54
54
|
label: e.name,
|
|
55
55
|
prefix: s
|
|
56
56
|
});
|
|
@@ -59,7 +59,7 @@ function x(e, t, n, r, i) {
|
|
|
59
59
|
for (let r of o.orgs) {
|
|
60
60
|
let i = n && n === r.id ? t : r.name;
|
|
61
61
|
a.push({
|
|
62
|
-
value:
|
|
62
|
+
value: b(e.id, r.id),
|
|
63
63
|
label: `${e.name} – ${i}`,
|
|
64
64
|
prefix: s
|
|
65
65
|
});
|
|
@@ -68,148 +68,159 @@ function x(e, t, n, r, i) {
|
|
|
68
68
|
}
|
|
69
69
|
return a;
|
|
70
70
|
}
|
|
71
|
-
function
|
|
72
|
-
let { t:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
]),
|
|
79
|
-
|
|
80
|
-
if (
|
|
81
|
-
let { backend: e } =
|
|
71
|
+
function C({ openUpward: p = !1, hideTrigger: y = !1, defaultOpen: C = !1, onSelectOption: w, onOpenAddBackend: T, onOpenManageBackends: E, sidebarCollapsed: D = !1 } = {}) {
|
|
72
|
+
let { t: O } = e("openhands"), { backends: k, active: A, setActive: j } = ee(), M = re(), N = ie(), P = oe(k), F = le(), fe = v("/settings"), I = v("/settings/*"), L = v("/conversations/:conversationId"), R = v("/automations/:automationId"), [z, B] = h.useState(!1), [pe, V] = h.useState(!1), H = O(t.BACKEND$PERSONAL_WORKSPACE), U = h.useMemo(() => de(k, H, M, N, P), [
|
|
73
|
+
k,
|
|
74
|
+
H,
|
|
75
|
+
M,
|
|
76
|
+
N,
|
|
77
|
+
P
|
|
78
|
+
]), W = s(A.backend), G = O(t.BACKEND$NO_BACKEND_AVAILABLE), K = b(A.backend.id, A.orgId), q = W ? void 0 : U.find((e) => e.value === K), J = !!(fe || I), Y = O(t.SIDEBAR$SETTINGS), me = a((e) => e.isRightPanelShown), he = !D || L && me ? "top" : "left", ge = Object.values(M).some((e) => e.isLoading);
|
|
79
|
+
h.useEffect(() => {
|
|
80
|
+
if (W || A.backend.kind !== "cloud" || A.orgId) return;
|
|
81
|
+
let { backend: e } = A, t = M[e.id];
|
|
82
82
|
if (!t || t.orgs.length === 0) return;
|
|
83
|
-
let n = t.currentOrgId ? t.orgs.find((e) => e.id === t.currentOrgId) : void 0, r =
|
|
84
|
-
a &&
|
|
83
|
+
let n = t.currentOrgId ? t.orgs.find((e) => e.id === t.currentOrgId) : void 0, r = N[e.id]?.userId ?? null, i = r ? t.orgs.find((e) => e.id === r) : void 0, a = n ?? i ?? t.orgs[0];
|
|
84
|
+
a && j(e.id, a.id);
|
|
85
85
|
}, [
|
|
86
|
-
O,
|
|
87
86
|
A,
|
|
87
|
+
M,
|
|
88
|
+
N,
|
|
88
89
|
j,
|
|
89
|
-
|
|
90
|
-
U
|
|
90
|
+
W
|
|
91
91
|
]);
|
|
92
|
-
let
|
|
93
|
-
if (w) {
|
|
94
|
-
w(), C?.();
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
z(!0);
|
|
98
|
-
}, [w, C]), X = p.useCallback(() => {
|
|
92
|
+
let X = h.useCallback(() => {
|
|
99
93
|
if (T) {
|
|
100
|
-
T(),
|
|
94
|
+
T(), w?.();
|
|
101
95
|
return;
|
|
102
96
|
}
|
|
103
97
|
B(!0);
|
|
104
|
-
}, [T,
|
|
98
|
+
}, [T, w]), Z = h.useCallback(() => {
|
|
99
|
+
if (E) {
|
|
100
|
+
E(), w?.();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
V(!0);
|
|
104
|
+
}, [E, w]), Q = o() !== null, _e = Q && A.backend.authMode === "cookie", $ = h.useCallback((e) => {
|
|
105
105
|
e.preventDefault(), e.stopPropagation();
|
|
106
|
-
}, []), ve =
|
|
107
|
-
|
|
108
|
-
}, [
|
|
109
|
-
|
|
110
|
-
}, [
|
|
111
|
-
|
|
112
|
-
}, [
|
|
113
|
-
|
|
114
|
-
}, [
|
|
115
|
-
className:
|
|
116
|
-
children: [
|
|
106
|
+
}, []), ve = h.useCallback((e) => {
|
|
107
|
+
$(e), X();
|
|
108
|
+
}, [X, $]), ye = h.useCallback((e) => {
|
|
109
|
+
$(e), X();
|
|
110
|
+
}, [X, $]), be = h.useCallback((e) => {
|
|
111
|
+
$(e), Z();
|
|
112
|
+
}, [Z, $]), xe = h.useCallback((e) => {
|
|
113
|
+
$(e), Z();
|
|
114
|
+
}, [Z, $]), Se = _e ? void 0 : /* @__PURE__ */ _("div", {
|
|
115
|
+
className: ne,
|
|
116
|
+
children: [Q ? null : /* @__PURE__ */ _("button", {
|
|
117
117
|
type: "button",
|
|
118
118
|
"data-testid": "add-backend-menu-item",
|
|
119
|
-
onMouseDown:
|
|
120
|
-
onTouchStart:
|
|
119
|
+
onMouseDown: $,
|
|
120
|
+
onTouchStart: $,
|
|
121
121
|
onTouchEnd: ye,
|
|
122
122
|
onClick: ve,
|
|
123
|
-
className: i(
|
|
124
|
-
children: [/* @__PURE__ */
|
|
123
|
+
className: i(l, "cursor-pointer rounded-md"),
|
|
124
|
+
children: [/* @__PURE__ */ g("span", {
|
|
125
125
|
className: u,
|
|
126
126
|
"aria-hidden": !0,
|
|
127
|
-
children: /* @__PURE__ */
|
|
127
|
+
children: /* @__PURE__ */ g(n, {
|
|
128
128
|
width: 16,
|
|
129
129
|
height: 16
|
|
130
130
|
})
|
|
131
|
-
}),
|
|
132
|
-
}), /* @__PURE__ */
|
|
131
|
+
}), O(t.BACKEND$ADD)]
|
|
132
|
+
}), /* @__PURE__ */ _("button", {
|
|
133
133
|
type: "button",
|
|
134
134
|
"data-testid": "manage-backends-menu-item",
|
|
135
|
-
onMouseDown:
|
|
136
|
-
onTouchStart:
|
|
137
|
-
onTouchEnd:
|
|
135
|
+
onMouseDown: $,
|
|
136
|
+
onTouchStart: $,
|
|
137
|
+
onTouchEnd: xe,
|
|
138
138
|
onClick: be,
|
|
139
|
-
className: i(
|
|
140
|
-
children: [/* @__PURE__ */
|
|
139
|
+
className: i(l, "cursor-pointer rounded-md"),
|
|
140
|
+
children: [/* @__PURE__ */ g("span", {
|
|
141
141
|
className: u,
|
|
142
142
|
"aria-hidden": !0,
|
|
143
|
-
children: /* @__PURE__ */
|
|
143
|
+
children: /* @__PURE__ */ g(r, {
|
|
144
144
|
width: 16,
|
|
145
145
|
height: 16
|
|
146
146
|
})
|
|
147
|
-
}),
|
|
147
|
+
}), O(Q ? t.BACKEND$RECONNECT_CLOUD : t.BACKEND$MANAGE)]
|
|
148
148
|
})]
|
|
149
|
-
}),
|
|
150
|
-
if (e ===
|
|
151
|
-
let { backendId: t, orgId: n } =
|
|
152
|
-
r && (
|
|
149
|
+
}), Ce = h.useCallback(async (e) => {
|
|
150
|
+
if (e === K) return;
|
|
151
|
+
let { backendId: t, orgId: n } = x(e), r = k.find((e) => e.id === t);
|
|
152
|
+
r && (f(U.find((t) => t.value === e)?.label ?? r.name), await new Promise((e) => {
|
|
153
153
|
setTimeout(e, 400);
|
|
154
|
-
}),
|
|
154
|
+
}), L ? F("/conversations") : R && F("/automations"), j(r.id, n), w?.());
|
|
155
155
|
}, [
|
|
156
|
-
|
|
157
|
-
D,
|
|
158
|
-
I,
|
|
159
|
-
L,
|
|
160
|
-
N,
|
|
161
|
-
H,
|
|
156
|
+
K,
|
|
162
157
|
k,
|
|
163
|
-
|
|
164
|
-
|
|
158
|
+
L,
|
|
159
|
+
R,
|
|
160
|
+
F,
|
|
161
|
+
U,
|
|
162
|
+
j,
|
|
163
|
+
O,
|
|
164
|
+
w
|
|
165
165
|
]);
|
|
166
|
-
return /* @__PURE__ */
|
|
167
|
-
/* @__PURE__ */
|
|
166
|
+
return /* @__PURE__ */ _(ce, { children: [
|
|
167
|
+
/* @__PURE__ */ _("div", {
|
|
168
168
|
className: "flex items-center gap-2 w-full",
|
|
169
|
-
children: [/* @__PURE__ */
|
|
169
|
+
children: [/* @__PURE__ */ g("div", {
|
|
170
170
|
className: "flex-1 min-w-0",
|
|
171
|
-
children: /* @__PURE__ */
|
|
171
|
+
children: /* @__PURE__ */ g(ae, {
|
|
172
172
|
testId: "backend-selector",
|
|
173
|
-
defaultValue:
|
|
174
|
-
value:
|
|
175
|
-
label:
|
|
176
|
-
prefix:
|
|
173
|
+
defaultValue: q ?? {
|
|
174
|
+
value: K,
|
|
175
|
+
label: W ? G : A.backend.name,
|
|
176
|
+
prefix: W ? ue() : S(P[A.backend.id])
|
|
177
177
|
},
|
|
178
|
-
footer:
|
|
179
|
-
openUpward:
|
|
180
|
-
hideTrigger:
|
|
181
|
-
defaultOpen:
|
|
182
|
-
openOnHover: !
|
|
178
|
+
footer: Se,
|
|
179
|
+
openUpward: p,
|
|
180
|
+
hideTrigger: y,
|
|
181
|
+
defaultOpen: C,
|
|
182
|
+
openOnHover: !y,
|
|
183
183
|
onChange: (e) => {
|
|
184
|
-
e &&
|
|
184
|
+
e && Ce(e.value);
|
|
185
185
|
},
|
|
186
|
-
placeholder:
|
|
187
|
-
loading:
|
|
188
|
-
options:
|
|
186
|
+
placeholder: W ? G : A.backend.name,
|
|
187
|
+
loading: ge,
|
|
188
|
+
options: U,
|
|
189
189
|
className: "h-10 px-2 py-0 bg-transparent border-transparent hover:bg-[var(--oh-surface-raised)] focus-within:bg-[var(--oh-surface-raised)] focus-within:border-transparent focus-within:ring-0"
|
|
190
|
-
}, `${
|
|
191
|
-
}),
|
|
192
|
-
content:
|
|
193
|
-
placement:
|
|
190
|
+
}, `${K}-${q?.label ?? ""}`)
|
|
191
|
+
}), y ? null : /* @__PURE__ */ g(te, {
|
|
192
|
+
content: Y,
|
|
193
|
+
placement: he,
|
|
194
194
|
offset: 10,
|
|
195
|
-
children: /* @__PURE__ */
|
|
195
|
+
children: A.backend.kind === "cloud" ? /* @__PURE__ */ g("a", {
|
|
196
|
+
href: `${A.backend.host.replace(/\/+$/, "")}/settings`,
|
|
197
|
+
target: "_blank",
|
|
198
|
+
rel: "noopener noreferrer",
|
|
199
|
+
"data-testid": "backend-selector-settings-link",
|
|
200
|
+
"aria-label": Y,
|
|
201
|
+
className: i("inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)] cursor-pointer", c),
|
|
202
|
+
children: /* @__PURE__ */ g(r, {
|
|
203
|
+
width: 16,
|
|
204
|
+
height: 16
|
|
205
|
+
})
|
|
206
|
+
}) : /* @__PURE__ */ g(d, {
|
|
196
207
|
to: "/settings",
|
|
197
208
|
"data-testid": "backend-selector-settings-link",
|
|
198
|
-
"data-active":
|
|
199
|
-
"aria-label":
|
|
200
|
-
className: i(
|
|
201
|
-
children: /* @__PURE__ */
|
|
209
|
+
"data-active": J,
|
|
210
|
+
"aria-label": Y,
|
|
211
|
+
className: i(J ? "inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md bg-tertiary text-white font-normal cursor-pointer" : "inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)] cursor-pointer", c),
|
|
212
|
+
children: /* @__PURE__ */ g(r, {
|
|
202
213
|
width: 16,
|
|
203
214
|
height: 16
|
|
204
215
|
})
|
|
205
216
|
})
|
|
206
217
|
})]
|
|
207
218
|
}),
|
|
208
|
-
|
|
209
|
-
|
|
219
|
+
z ? /* @__PURE__ */ g(se, { onClose: () => B(!1) }) : null,
|
|
220
|
+
pe ? /* @__PURE__ */ g(m, { onClose: () => V(!1) }) : null
|
|
210
221
|
] });
|
|
211
222
|
}
|
|
212
223
|
//#endregion
|
|
213
|
-
export {
|
|
224
|
+
export { C as BackendSelector };
|
|
214
225
|
|
|
215
226
|
//# sourceMappingURL=backend-selector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-selector.js","names":[],"sources":["../../../../src/components/features/backends/backend-selector.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useMatch, useNavigate } from \"react-router\";\nimport { Plus, Settings } from \"lucide-react\";\nimport { Dropdown } from \"#/ui/dropdown/dropdown\";\nimport { DropdownOption } from \"#/ui/dropdown/types\";\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\nimport { isNoBackend } from \"#/api/backend-registry/active-store\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { useAllCloudOrganizations } from \"#/hooks/query/use-cloud-organizations\";\nimport { useCloudCurrentUserId } from \"#/hooks/query/use-cloud-current-user-id\";\nimport {\n useBackendsHealth,\n type BackendHealth,\n} from \"#/hooks/query/use-backends-health\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport type { Backend } from \"#/api/backend-registry/types\";\n// Import the trigger helpers from the lightweight store, not the overlay\n// component, so the eagerly-mounted sidebar/backend-selector graph does not\n// pull in the overlay's render code (the overlay is lazy-loaded from\n// `routes/root-layout.tsx`).\nimport {\n ENVIRONMENT_SWITCH_SETACTIVE_DELAY_MS,\n triggerEnvironmentSwitch,\n} from \"#/components/features/backends/environment-switch-store\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { AddBackendModal } from \"./add-backend-modal\";\nimport { BackendStatusDot } from \"./backend-status-dot\";\nimport { ManageBackendsModal } from \"./manage-backends-modal\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlTransitionClassName } from \"#/utils/form-control-classes\";\nimport {\n dropdownFooterActionClassName,\n dropdownMenuListClassName,\n dropdownMenuRowIconWrapperClassName,\n} from \"#/utils/dropdown-classes\";\n\nconst VALUE_SEPARATOR = \"::\";\n\nfunction makeOptionValue(backendId: string, orgId: string | null): string {\n return orgId ? `${backendId}${VALUE_SEPARATOR}${orgId}` : backendId;\n}\n\nfunction parseOptionValue(value: string): {\n backendId: string;\n orgId: string | null;\n} {\n const [backendId, orgId] = value.split(VALUE_SEPARATOR);\n return { backendId, orgId: orgId ?? null };\n}\n\nfunction buildStatusPrefix(health: BackendHealth | undefined) {\n return <BackendStatusDot isConnected={health?.isConnected ?? null} />;\n}\n\nfunction buildNoBackendPrefix() {\n return <BackendStatusDot isConnected=\"unavailable\" />;\n}\n\nfunction buildOptions(\n registered: Backend[],\n personalWorkspaceLabel: string,\n cloudOrgs: ReturnType<typeof useAllCloudOrganizations>,\n currentUserIds: ReturnType<typeof useCloudCurrentUserId>,\n healthByBackendId: Record<string, BackendHealth>,\n): DropdownOption[] {\n const options: DropdownOption[] = [];\n\n const locals = registered.filter((b) => b.kind === \"local\");\n const clouds = registered.filter((b) => b.kind === \"cloud\");\n\n for (const b of locals) {\n options.push({\n value: makeOptionValue(b.id, null),\n label: b.name,\n prefix: buildStatusPrefix(healthByBackendId[b.id]),\n });\n }\n\n for (const b of clouds) {\n const entry = cloudOrgs[b.id];\n const prefix = buildStatusPrefix(healthByBackendId[b.id]);\n if (!entry || entry.orgs.length === 0) {\n options.push({\n value: makeOptionValue(b.id, null),\n label: b.name,\n prefix,\n });\n } else {\n // Personal-workspace rule (per the cloud contract): the org whose\n // id matches the calling user's id is the user's personal\n // workspace. We resolve `user_id` once per backend (via /me on any\n // one org) and apply it across all orgs of that backend.\n const userIdForBackend = currentUserIds[b.id]?.userId ?? null;\n\n for (const org of entry.orgs) {\n const isPersonal = !!userIdForBackend && userIdForBackend === org.id;\n const orgLabel = isPersonal ? personalWorkspaceLabel : org.name;\n options.push({\n value: makeOptionValue(b.id, org.id),\n label: `${b.name} – ${orgLabel}`,\n // All org rows for the same cloud backend share that backend's\n // single connectivity verdict — there is no per-org probe.\n prefix,\n });\n }\n }\n }\n\n return options;\n}\n\ninterface BackendSelectorProps {\n /** Render the menu above the trigger (e.g. when pinned to bottom of sidebar). */\n openUpward?: boolean;\n /** Hide the selector input trigger and only render the dropdown menu. */\n hideTrigger?: boolean;\n /** Whether the dropdown menu should start open on mount. */\n defaultOpen?: boolean;\n /** Callback fired after selecting a backend/org option. */\n onSelectOption?: () => void;\n /**\n * Override the internal Add Backend modal handling. When provided,\n * clicking \"Add Backend\" calls this instead of opening BackendSelector's\n * own modal. Useful when the selector is mounted inside an ephemeral\n * container (e.g. the collapsed-sidebar popover) and the modal must\n * survive the parent unmounting.\n */\n onOpenAddBackend?: () => void;\n /** Same as onOpenAddBackend but for the Manage Backends modal. */\n onOpenManageBackends?: () => void;\n /**\n * Whether the surrounding sidebar rail is in its collapsed variant. Passed\n * down from `SidebarRailBody` so the mobile drawer (which always renders\n * the expanded rail) can override the persisted desktop value.\n */\n sidebarCollapsed?: boolean;\n}\n\nexport function BackendSelector({\n openUpward = false,\n hideTrigger = false,\n defaultOpen = false,\n onSelectOption,\n onOpenAddBackend,\n onOpenManageBackends,\n sidebarCollapsed = false,\n}: BackendSelectorProps = {}) {\n const { t } = useTranslation(\"openhands\");\n const { backends, active, setActive } = useActiveBackendContext();\n const cloudOrgs = useAllCloudOrganizations();\n const currentUserIds = useCloudCurrentUserId();\n // Probe each registered backend every 10s.\n const healthByBackendId = useBackendsHealth(backends);\n const navigate = useNavigate();\n const settingsMatch = useMatch(\"/settings\");\n const settingsSubrouteMatch = useMatch(\"/settings/*\");\n const conversationMatch = useMatch(\"/conversations/:conversationId\");\n const automationDetailMatch = useMatch(\"/automations/:automationId\");\n const [addBackendModalOpen, setAddBackendModalOpen] = React.useState(false);\n const [manageBackendsModalOpen, setManageBackendsModalOpen] =\n React.useState(false);\n\n const personalWorkspaceLabel = t(I18nKey.BACKEND$PERSONAL_WORKSPACE);\n\n const options = React.useMemo(\n () =>\n buildOptions(\n backends,\n personalWorkspaceLabel,\n cloudOrgs,\n currentUserIds,\n healthByBackendId,\n ),\n [\n backends,\n personalWorkspaceLabel,\n cloudOrgs,\n currentUserIds,\n healthByBackendId,\n ],\n );\n\n const noBackendSelected = isNoBackend(active.backend);\n const noBackendLabel = t(I18nKey.BACKEND$NO_BACKEND_AVAILABLE);\n const activeValue = makeOptionValue(active.backend.id, active.orgId);\n const activeOption = noBackendSelected\n ? undefined\n : options.find((o) => o.value === activeValue);\n const isSettingsActive = Boolean(settingsMatch || settingsSubrouteMatch);\n const settingsLabel = t(I18nKey.SIDEBAR$SETTINGS);\n const isRightPanelShown = useConversationStore(\n (state) => state.isRightPanelShown,\n );\n // When the sidebar rail is expanded, `placement=\"left\"` hugs the main\n // canvas and reads awkwardly; prefer above the control. When the rail is\n // collapsed, keep left except on active conversation + open right drawer.\n const settingsTooltipPlacement =\n !sidebarCollapsed || (conversationMatch && isRightPanelShown)\n ? \"top\"\n : \"left\";\n\n const someCloudLoading = Object.values(cloudOrgs).some((c) => c.isLoading);\n\n // Self-heal a malformed `(cloudBackendId, null)` selection.\n //\n // Once a cloud backend's orgs resolve, the dropdown only renders\n // per-org rows for it — the `(backendId, null)` row disappears, so\n // selecting that shape would drift from what the dropdown can render\n // (UI says \"Local\", APIs hit cloud). When we detect the drift, snap\n // the selection onto Cloud's current org first, then fall back to the\n // personal workspace (or, lacking a /me result, the first org). The\n // selection is recorded locally only; the cloud request scope follows\n // from the X-Org-Id header sent by `callCloudProxy`, so the cloud UI's\n // org choice is never mutated as a side effect.\n React.useEffect(() => {\n if (noBackendSelected || active.backend.kind !== \"cloud\" || active.orgId)\n return;\n const { backend } = active;\n const entry = cloudOrgs[backend.id];\n if (!entry || entry.orgs.length === 0) return;\n\n const currentOrg = entry.currentOrgId\n ? entry.orgs.find((o) => o.id === entry.currentOrgId)\n : undefined;\n const userId = currentUserIds[backend.id]?.userId ?? null;\n const personal = userId\n ? entry.orgs.find((o) => o.id === userId)\n : undefined;\n const target = currentOrg ?? personal ?? entry.orgs[0];\n if (target) {\n setActive(backend.id, target.id);\n }\n }, [active, cloudOrgs, currentUserIds, setActive, noBackendSelected]);\n\n const openAddBackendModal = React.useCallback(() => {\n if (onOpenAddBackend) {\n onOpenAddBackend();\n onSelectOption?.();\n return;\n }\n setAddBackendModalOpen(true);\n }, [onOpenAddBackend, onSelectOption]);\n\n const openManageBackendsModal = React.useCallback(() => {\n if (onOpenManageBackends) {\n onOpenManageBackends();\n onSelectOption?.();\n return;\n }\n setManageBackendsModalOpen(true);\n }, [onOpenManageBackends, onSelectOption]);\n\n const isLockedToCloud = getLockedCloudHost() !== null;\n\n const preventDropdownMenuClose = React.useCallback(\n (event: React.SyntheticEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n },\n [],\n );\n\n const handleAddBackendClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openAddBackendModal();\n },\n [openAddBackendModal, preventDropdownMenuClose],\n );\n\n const handleAddBackendTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openAddBackendModal();\n },\n [openAddBackendModal, preventDropdownMenuClose],\n );\n\n const handleManageBackendsClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openManageBackendsModal();\n },\n [openManageBackendsModal, preventDropdownMenuClose],\n );\n\n const handleManageBackendsTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openManageBackendsModal();\n },\n [openManageBackendsModal, preventDropdownMenuClose],\n );\n\n const addBackendFooter = (\n <div className={dropdownMenuListClassName}>\n {isLockedToCloud ? null : (\n <button\n type=\"button\"\n data-testid=\"add-backend-menu-item\"\n onMouseDown={preventDropdownMenuClose}\n onTouchStart={preventDropdownMenuClose}\n onTouchEnd={handleAddBackendTouchEnd}\n onClick={handleAddBackendClick}\n className={cn(\n dropdownFooterActionClassName,\n \"cursor-pointer rounded-md\",\n )}\n >\n <span className={dropdownMenuRowIconWrapperClassName} aria-hidden>\n <Plus width={16} height={16} />\n </span>\n {t(I18nKey.BACKEND$ADD)}\n </button>\n )}\n <button\n type=\"button\"\n data-testid=\"manage-backends-menu-item\"\n onMouseDown={preventDropdownMenuClose}\n onTouchStart={preventDropdownMenuClose}\n onTouchEnd={handleManageBackendsTouchEnd}\n onClick={handleManageBackendsClick}\n className={cn(\n dropdownFooterActionClassName,\n \"cursor-pointer rounded-md\",\n )}\n >\n <span className={dropdownMenuRowIconWrapperClassName} aria-hidden>\n <Settings width={16} height={16} />\n </span>\n {t(\n isLockedToCloud\n ? I18nKey.BACKEND$RECONNECT_CLOUD\n : I18nKey.BACKEND$MANAGE,\n )}\n </button>\n </div>\n );\n\n const handleSelectBackend = React.useCallback(\n async (value: string) => {\n if (value === activeValue) return;\n\n const { backendId, orgId } = parseOptionValue(value);\n const target = backends.find((b) => b.id === backendId);\n if (!target) return;\n\n triggerEnvironmentSwitch(\n options.find((option) => option.value === value)?.label ?? target.name,\n );\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ENVIRONMENT_SWITCH_SETACTIVE_DELAY_MS);\n });\n\n // @spec BM-002 — Switching backends keeps the user on the same page\n if (conversationMatch) navigate(\"/conversations\");\n else if (automationDetailMatch) navigate(\"/automations\");\n\n setActive(target.id, orgId);\n onSelectOption?.();\n },\n [\n activeValue,\n backends,\n conversationMatch,\n automationDetailMatch,\n navigate,\n options,\n setActive,\n t,\n onSelectOption,\n ],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-2 w-full\">\n <div className=\"flex-1 min-w-0\">\n <Dropdown\n testId=\"backend-selector\"\n key={`${activeValue}-${activeOption?.label ?? \"\"}`}\n defaultValue={\n activeOption ?? {\n value: activeValue,\n label: noBackendSelected ? noBackendLabel : active.backend.name,\n prefix: noBackendSelected\n ? buildNoBackendPrefix()\n : buildStatusPrefix(healthByBackendId[active.backend.id]),\n }\n }\n footer={addBackendFooter}\n openUpward={openUpward}\n hideTrigger={hideTrigger}\n defaultOpen={defaultOpen}\n openOnHover={!hideTrigger}\n onChange={(item) => {\n if (!item) return;\n void handleSelectBackend(item.value);\n }}\n placeholder={\n noBackendSelected ? noBackendLabel : active.backend.name\n }\n loading={someCloudLoading}\n options={options}\n className=\"h-10 px-2 py-0 bg-transparent border-transparent hover:bg-[var(--oh-surface-raised)] focus-within:bg-[var(--oh-surface-raised)] focus-within:border-transparent focus-within:ring-0\"\n />\n </div>\n {!hideTrigger ? (\n <StyledTooltip\n content={settingsLabel}\n placement={settingsTooltipPlacement}\n offset={10}\n >\n <NavigationLink\n to=\"/settings\"\n data-testid=\"backend-selector-settings-link\"\n data-active={isSettingsActive}\n aria-label={settingsLabel}\n className={\n isSettingsActive\n ? cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md bg-tertiary text-white font-normal cursor-pointer\",\n formControlTransitionClassName,\n )\n : cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)] cursor-pointer\",\n formControlTransitionClassName,\n )\n }\n >\n <Settings width={16} height={16} />\n </NavigationLink>\n </StyledTooltip>\n ) : null}\n </div>\n {addBackendModalOpen ? (\n <AddBackendModal onClose={() => setAddBackendModalOpen(false)} />\n ) : null}\n {manageBackendsModalOpen ? (\n <ManageBackendsModal\n onClose={() => setManageBackendsModalOpen(false)}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"backend-selector.js","names":[],"sources":["../../../../src/components/features/backends/backend-selector.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useMatch, useNavigate } from \"react-router\";\nimport { Plus, Settings } from \"lucide-react\";\nimport { Dropdown } from \"#/ui/dropdown/dropdown\";\nimport { DropdownOption } from \"#/ui/dropdown/types\";\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\nimport { isNoBackend } from \"#/api/backend-registry/active-store\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { useAllCloudOrganizations } from \"#/hooks/query/use-cloud-organizations\";\nimport { useCloudCurrentUserId } from \"#/hooks/query/use-cloud-current-user-id\";\nimport {\n useBackendsHealth,\n type BackendHealth,\n} from \"#/hooks/query/use-backends-health\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport type { Backend } from \"#/api/backend-registry/types\";\n// Import the trigger helpers from the lightweight store, not the overlay\n// component, so the eagerly-mounted sidebar/backend-selector graph does not\n// pull in the overlay's render code (the overlay is lazy-loaded from\n// `routes/root-layout.tsx`).\nimport {\n ENVIRONMENT_SWITCH_SETACTIVE_DELAY_MS,\n triggerEnvironmentSwitch,\n} from \"#/components/features/backends/environment-switch-store\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { AddBackendModal } from \"./add-backend-modal\";\nimport { BackendStatusDot } from \"./backend-status-dot\";\nimport { ManageBackendsModal } from \"./manage-backends-modal\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlTransitionClassName } from \"#/utils/form-control-classes\";\nimport {\n dropdownFooterActionClassName,\n dropdownMenuListClassName,\n dropdownMenuRowIconWrapperClassName,\n} from \"#/utils/dropdown-classes\";\n\nconst VALUE_SEPARATOR = \"::\";\n\nfunction makeOptionValue(backendId: string, orgId: string | null): string {\n return orgId ? `${backendId}${VALUE_SEPARATOR}${orgId}` : backendId;\n}\n\nfunction parseOptionValue(value: string): {\n backendId: string;\n orgId: string | null;\n} {\n const [backendId, orgId] = value.split(VALUE_SEPARATOR);\n return { backendId, orgId: orgId ?? null };\n}\n\nfunction buildStatusPrefix(health: BackendHealth | undefined) {\n return <BackendStatusDot isConnected={health?.isConnected ?? null} />;\n}\n\nfunction buildNoBackendPrefix() {\n return <BackendStatusDot isConnected=\"unavailable\" />;\n}\n\nfunction buildOptions(\n registered: Backend[],\n personalWorkspaceLabel: string,\n cloudOrgs: ReturnType<typeof useAllCloudOrganizations>,\n currentUserIds: ReturnType<typeof useCloudCurrentUserId>,\n healthByBackendId: Record<string, BackendHealth>,\n): DropdownOption[] {\n const options: DropdownOption[] = [];\n\n const locals = registered.filter((b) => b.kind === \"local\");\n const clouds = registered.filter((b) => b.kind === \"cloud\");\n\n for (const b of locals) {\n options.push({\n value: makeOptionValue(b.id, null),\n label: b.name,\n prefix: buildStatusPrefix(healthByBackendId[b.id]),\n });\n }\n\n for (const b of clouds) {\n const entry = cloudOrgs[b.id];\n const prefix = buildStatusPrefix(healthByBackendId[b.id]);\n if (!entry || entry.orgs.length === 0) {\n options.push({\n value: makeOptionValue(b.id, null),\n label: b.name,\n prefix,\n });\n } else {\n // Personal-workspace rule (per the cloud contract): the org whose\n // id matches the calling user's id is the user's personal\n // workspace. We resolve `user_id` once per backend (via /me on any\n // one org) and apply it across all orgs of that backend.\n const userIdForBackend = currentUserIds[b.id]?.userId ?? null;\n\n for (const org of entry.orgs) {\n const isPersonal = !!userIdForBackend && userIdForBackend === org.id;\n const orgLabel = isPersonal ? personalWorkspaceLabel : org.name;\n options.push({\n value: makeOptionValue(b.id, org.id),\n label: `${b.name} – ${orgLabel}`,\n // All org rows for the same cloud backend share that backend's\n // single connectivity verdict — there is no per-org probe.\n prefix,\n });\n }\n }\n }\n\n return options;\n}\n\ninterface BackendSelectorProps {\n /** Render the menu above the trigger (e.g. when pinned to bottom of sidebar). */\n openUpward?: boolean;\n /** Hide the selector input trigger and only render the dropdown menu. */\n hideTrigger?: boolean;\n /** Whether the dropdown menu should start open on mount. */\n defaultOpen?: boolean;\n /** Callback fired after selecting a backend/org option. */\n onSelectOption?: () => void;\n /**\n * Override the internal Add Backend modal handling. When provided,\n * clicking \"Add Backend\" calls this instead of opening BackendSelector's\n * own modal. Useful when the selector is mounted inside an ephemeral\n * container (e.g. the collapsed-sidebar popover) and the modal must\n * survive the parent unmounting.\n */\n onOpenAddBackend?: () => void;\n /** Same as onOpenAddBackend but for the Manage Backends modal. */\n onOpenManageBackends?: () => void;\n /**\n * Whether the surrounding sidebar rail is in its collapsed variant. Passed\n * down from `SidebarRailBody` so the mobile drawer (which always renders\n * the expanded rail) can override the persisted desktop value.\n */\n sidebarCollapsed?: boolean;\n}\n\nexport function BackendSelector({\n openUpward = false,\n hideTrigger = false,\n defaultOpen = false,\n onSelectOption,\n onOpenAddBackend,\n onOpenManageBackends,\n sidebarCollapsed = false,\n}: BackendSelectorProps = {}) {\n const { t } = useTranslation(\"openhands\");\n const { backends, active, setActive } = useActiveBackendContext();\n const cloudOrgs = useAllCloudOrganizations();\n const currentUserIds = useCloudCurrentUserId();\n // Probe each registered backend every 10s.\n const healthByBackendId = useBackendsHealth(backends);\n const navigate = useNavigate();\n const settingsMatch = useMatch(\"/settings\");\n const settingsSubrouteMatch = useMatch(\"/settings/*\");\n const conversationMatch = useMatch(\"/conversations/:conversationId\");\n const automationDetailMatch = useMatch(\"/automations/:automationId\");\n const [addBackendModalOpen, setAddBackendModalOpen] = React.useState(false);\n const [manageBackendsModalOpen, setManageBackendsModalOpen] =\n React.useState(false);\n\n const personalWorkspaceLabel = t(I18nKey.BACKEND$PERSONAL_WORKSPACE);\n\n const options = React.useMemo(\n () =>\n buildOptions(\n backends,\n personalWorkspaceLabel,\n cloudOrgs,\n currentUserIds,\n healthByBackendId,\n ),\n [\n backends,\n personalWorkspaceLabel,\n cloudOrgs,\n currentUserIds,\n healthByBackendId,\n ],\n );\n\n const noBackendSelected = isNoBackend(active.backend);\n const noBackendLabel = t(I18nKey.BACKEND$NO_BACKEND_AVAILABLE);\n const activeValue = makeOptionValue(active.backend.id, active.orgId);\n const activeOption = noBackendSelected\n ? undefined\n : options.find((o) => o.value === activeValue);\n const isSettingsActive = Boolean(settingsMatch || settingsSubrouteMatch);\n const settingsLabel = t(I18nKey.SIDEBAR$SETTINGS);\n const isRightPanelShown = useConversationStore(\n (state) => state.isRightPanelShown,\n );\n // When the sidebar rail is expanded, `placement=\"left\"` hugs the main\n // canvas and reads awkwardly; prefer above the control. When the rail is\n // collapsed, keep left except on active conversation + open right drawer.\n const settingsTooltipPlacement =\n !sidebarCollapsed || (conversationMatch && isRightPanelShown)\n ? \"top\"\n : \"left\";\n\n const someCloudLoading = Object.values(cloudOrgs).some((c) => c.isLoading);\n\n // Self-heal a malformed `(cloudBackendId, null)` selection.\n //\n // Once a cloud backend's orgs resolve, the dropdown only renders\n // per-org rows for it — the `(backendId, null)` row disappears, so\n // selecting that shape would drift from what the dropdown can render\n // (UI says \"Local\", APIs hit cloud). When we detect the drift, snap\n // the selection onto Cloud's current org first, then fall back to the\n // personal workspace (or, lacking a /me result, the first org). The\n // selection is recorded locally only; the cloud request scope follows\n // from the X-Org-Id header sent by `callCloudProxy`, so the cloud UI's\n // org choice is never mutated as a side effect.\n React.useEffect(() => {\n if (noBackendSelected || active.backend.kind !== \"cloud\" || active.orgId)\n return;\n const { backend } = active;\n const entry = cloudOrgs[backend.id];\n if (!entry || entry.orgs.length === 0) return;\n\n const currentOrg = entry.currentOrgId\n ? entry.orgs.find((o) => o.id === entry.currentOrgId)\n : undefined;\n const userId = currentUserIds[backend.id]?.userId ?? null;\n const personal = userId\n ? entry.orgs.find((o) => o.id === userId)\n : undefined;\n const target = currentOrg ?? personal ?? entry.orgs[0];\n if (target) {\n setActive(backend.id, target.id);\n }\n }, [active, cloudOrgs, currentUserIds, setActive, noBackendSelected]);\n\n const openAddBackendModal = React.useCallback(() => {\n if (onOpenAddBackend) {\n onOpenAddBackend();\n onSelectOption?.();\n return;\n }\n setAddBackendModalOpen(true);\n }, [onOpenAddBackend, onSelectOption]);\n\n const openManageBackendsModal = React.useCallback(() => {\n if (onOpenManageBackends) {\n onOpenManageBackends();\n onSelectOption?.();\n return;\n }\n setManageBackendsModalOpen(true);\n }, [onOpenManageBackends, onSelectOption]);\n\n const isLockedToCloud = getLockedCloudHost() !== null;\n // A cookie-auth (OHE-hosted) Canvas has nothing to add, manage, or\n // reconnect — its single locked backend is owned by the main-app session.\n const hideBackendFooter =\n isLockedToCloud && active.backend.authMode === \"cookie\";\n\n const preventDropdownMenuClose = React.useCallback(\n (event: React.SyntheticEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n },\n [],\n );\n\n const handleAddBackendClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openAddBackendModal();\n },\n [openAddBackendModal, preventDropdownMenuClose],\n );\n\n const handleAddBackendTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openAddBackendModal();\n },\n [openAddBackendModal, preventDropdownMenuClose],\n );\n\n const handleManageBackendsClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openManageBackendsModal();\n },\n [openManageBackendsModal, preventDropdownMenuClose],\n );\n\n const handleManageBackendsTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openManageBackendsModal();\n },\n [openManageBackendsModal, preventDropdownMenuClose],\n );\n\n const addBackendFooter = hideBackendFooter ? undefined : (\n <div className={dropdownMenuListClassName}>\n {isLockedToCloud ? null : (\n <button\n type=\"button\"\n data-testid=\"add-backend-menu-item\"\n onMouseDown={preventDropdownMenuClose}\n onTouchStart={preventDropdownMenuClose}\n onTouchEnd={handleAddBackendTouchEnd}\n onClick={handleAddBackendClick}\n className={cn(\n dropdownFooterActionClassName,\n \"cursor-pointer rounded-md\",\n )}\n >\n <span className={dropdownMenuRowIconWrapperClassName} aria-hidden>\n <Plus width={16} height={16} />\n </span>\n {t(I18nKey.BACKEND$ADD)}\n </button>\n )}\n <button\n type=\"button\"\n data-testid=\"manage-backends-menu-item\"\n onMouseDown={preventDropdownMenuClose}\n onTouchStart={preventDropdownMenuClose}\n onTouchEnd={handleManageBackendsTouchEnd}\n onClick={handleManageBackendsClick}\n className={cn(\n dropdownFooterActionClassName,\n \"cursor-pointer rounded-md\",\n )}\n >\n <span className={dropdownMenuRowIconWrapperClassName} aria-hidden>\n <Settings width={16} height={16} />\n </span>\n {t(\n isLockedToCloud\n ? I18nKey.BACKEND$RECONNECT_CLOUD\n : I18nKey.BACKEND$MANAGE,\n )}\n </button>\n </div>\n );\n\n const handleSelectBackend = React.useCallback(\n async (value: string) => {\n if (value === activeValue) return;\n\n const { backendId, orgId } = parseOptionValue(value);\n const target = backends.find((b) => b.id === backendId);\n if (!target) return;\n\n triggerEnvironmentSwitch(\n options.find((option) => option.value === value)?.label ?? target.name,\n );\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ENVIRONMENT_SWITCH_SETACTIVE_DELAY_MS);\n });\n\n // @spec BM-002 — Switching backends keeps the user on the same page\n if (conversationMatch) navigate(\"/conversations\");\n else if (automationDetailMatch) navigate(\"/automations\");\n\n setActive(target.id, orgId);\n onSelectOption?.();\n },\n [\n activeValue,\n backends,\n conversationMatch,\n automationDetailMatch,\n navigate,\n options,\n setActive,\n t,\n onSelectOption,\n ],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-2 w-full\">\n <div className=\"flex-1 min-w-0\">\n <Dropdown\n testId=\"backend-selector\"\n key={`${activeValue}-${activeOption?.label ?? \"\"}`}\n defaultValue={\n activeOption ?? {\n value: activeValue,\n label: noBackendSelected ? noBackendLabel : active.backend.name,\n prefix: noBackendSelected\n ? buildNoBackendPrefix()\n : buildStatusPrefix(healthByBackendId[active.backend.id]),\n }\n }\n footer={addBackendFooter}\n openUpward={openUpward}\n hideTrigger={hideTrigger}\n defaultOpen={defaultOpen}\n openOnHover={!hideTrigger}\n onChange={(item) => {\n if (!item) return;\n void handleSelectBackend(item.value);\n }}\n placeholder={\n noBackendSelected ? noBackendLabel : active.backend.name\n }\n loading={someCloudLoading}\n options={options}\n className=\"h-10 px-2 py-0 bg-transparent border-transparent hover:bg-[var(--oh-surface-raised)] focus-within:bg-[var(--oh-surface-raised)] focus-within:border-transparent focus-within:ring-0\"\n />\n </div>\n {!hideTrigger ? (\n <StyledTooltip\n content={settingsLabel}\n placement={settingsTooltipPlacement}\n offset={10}\n >\n {active.backend.kind === \"cloud\" ? (\n <a\n href={`${active.backend.host.replace(/\\/+$/, \"\")}/settings`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-testid=\"backend-selector-settings-link\"\n aria-label={settingsLabel}\n className={cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)] cursor-pointer\",\n formControlTransitionClassName,\n )}\n >\n <Settings width={16} height={16} />\n </a>\n ) : (\n <NavigationLink\n to=\"/settings\"\n data-testid=\"backend-selector-settings-link\"\n data-active={isSettingsActive}\n aria-label={settingsLabel}\n className={\n isSettingsActive\n ? cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md bg-tertiary text-white font-normal cursor-pointer\",\n formControlTransitionClassName,\n )\n : cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)] cursor-pointer\",\n formControlTransitionClassName,\n )\n }\n >\n <Settings width={16} height={16} />\n </NavigationLink>\n )}\n </StyledTooltip>\n ) : null}\n </div>\n {addBackendModalOpen ? (\n <AddBackendModal onClose={() => setAddBackendModalOpen(false)} />\n ) : null}\n {manageBackendsModalOpen ? (\n <ManageBackendsModal\n onClose={() => setManageBackendsModalOpen(false)}\n />\n ) : null}\n </>\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/useTranslation.cjs"),n=require("../../../i18n/declaration.cjs"),r=require("../../../node_modules/lucide-react/dist/esm/icons/plus.cjs"),i=require("../../../utils/utils.cjs"),a=require("../../../api/agent-server-config.cjs"),o=require("../../../contexts/active-backend-context.cjs"),s=require("../../shared/modals/modal-backdrop.cjs"),c=require("../../shared/modals/modal-body.cjs"),l=require("../../../utils/modal-classes.cjs"),u=require("../../shared/modals/modal-close-button.cjs"),d=require("../settings/brand-button.cjs"),f=require("
|
|
1
|
+
const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/react-i18next/dist/es/useTranslation.cjs"),n=require("../../../i18n/declaration.cjs"),r=require("../../../node_modules/lucide-react/dist/esm/icons/plus.cjs"),i=require("../../../utils/utils.cjs"),a=require("../../../api/agent-server-config.cjs"),o=require("../../../contexts/active-backend-context.cjs"),s=require("../../shared/modals/modal-backdrop.cjs"),c=require("../../shared/modals/modal-body.cjs"),l=require("../../../utils/modal-classes.cjs"),u=require("../../shared/modals/modal-close-button.cjs"),d=require("../settings/brand-button.cjs"),f=require("../../../hooks/query/use-cloud-organizations.cjs"),p=require("../../../hooks/query/use-cloud-current-user-id.cjs"),m=require("../../shared/modals/confirmation-modal.cjs"),h=require("../../../hooks/query/use-backends-health.cjs"),g=require("./device-flow-auth.cjs"),_=require("./backend-form-modal.cjs"),v=require("./backend-row.cjs");let y=require("react");y=e.__toESM(y,1);let b=require("react/jsx-runtime");function x(e,t,n,r){if(e.kind!==`cloud`)return;let i=t[e.id];if(!i||i.orgs.length===0)return;let a=n[e.id]?.userId??null;return i.orgs.map(e=>a&&a===e.id?r:e.name).join(`, `)}function S({onClose:e,recoveryMode:S=!1}){let{t:C}=t.useTranslation(`openhands`),{backends:w,active:T,removeBackend:E,setActive:D,updateBackend:O}=o.useActiveBackendContext(),k=h.useBackendsHealth(w,{probeDisabledOnce:!0}),A=f.useAllCloudOrganizations(),j=p.useCloudCurrentUserId(),M=C(n.I18nKey.BACKEND$PERSONAL_WORKSPACE),N=a.getLockedCloudHost(),P=N!==null,F=T.backend.authMode===`cookie`,I=P&&!F&&T.backend.kind===`cloud`?T.backend:null,L=N??I?.host??``,R=C(P&&!F?n.I18nKey.BACKEND$RECONNECT_CLOUD_TITLE:n.I18nKey.BACKEND$MANAGE_TITLE),[z,B]=y.default.useState(null),[V,H]=y.default.useState(null),[U,W]=y.default.useState(!1),G=()=>{z&&(E(z.id),B(null))},K=y.default.useCallback(t=>{(T.backend.id!==t.id||T.orgId!==null)&&D(t.id),e()},[T.backend.id,T.orgId,e,D]),q=y.default.useCallback((e,t)=>{O(e.id,{apiKey:t})},[O]),J=y.default.useCallback(e=>{I&&O(I.id,{apiKey:e})},[I,O]);return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(s.ModalBackdrop,{onClose:S?void 0:e,closeOnEscape:!S,closeOnBackdropClick:!S,"aria-label":R,children:(0,b.jsxs)(`div`,{"data-testid":`manage-backends-modal`,className:i.cn(`relative flex flex-col bg-[var(--oh-surface)] border border-[var(--oh-border)] rounded-xl`,c.modalWidthClassName(`lg`),c.MODAL_MAX_WIDTH_VIEWPORT,`max-h-[70vh]`),children:[S?null:(0,b.jsx)(u.ModalCloseButton,{onClose:e,testId:`close-manage-backends-modal`}),(0,b.jsx)(`div`,{className:i.cn(`p-5`,!S&&`pr-12`),children:(0,b.jsx)(`h2`,{className:l.modalTitleLgClassName,children:R})}),(0,b.jsx)(`div`,{className:`flex min-h-0 flex-1 flex-col px-5`,children:(0,b.jsx)(`div`,{className:`flex-1 overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always`,"data-testid":`manage-backends-list`,children:w.length===0?(0,b.jsx)(`p`,{className:`px-3 py-6 text-center text-sm text-[var(--oh-text-secondary)]`,children:C(n.I18nKey.BACKEND$MANAGE_EMPTY)}):(0,b.jsx)(`ul`,{className:`divide-y divide-[var(--oh-border)]`,children:w.map(e=>(0,b.jsx)(v.BackendRow,{backend:e,health:k[e.id],orgLabel:x(e,A,j,M),onSelect:()=>K(e),onEdit:()=>H(e),onRemove:()=>B({id:e.id,name:e.name}),onLogin:e.authMode===`cookie`?void 0:t=>q(e,t)},e.id))})})}),(0,b.jsxs)(`div`,{className:`flex justify-end gap-2 p-5`,children:[P?I?(0,b.jsx)(g.DeviceFlowAuth,{host:L,onSuccess:J,testIdRoot:`manage-backends-reconnect-cloud`,idleButtonLabel:C(n.I18nKey.BACKEND$RECONNECT_CLOUD),className:`w-full sm:w-auto`,buttonClassName:`w-full sm:w-auto`,statusDisplay:`modal`}):null:(0,b.jsx)(d.BrandButton,{type:`button`,variant:S?`primary`:`secondary`,onClick:()=>W(!0),testId:`manage-backends-add`,startContent:(0,b.jsx)(r.Plus,{width:14,height:14}),children:C(n.I18nKey.BACKEND$ADD)}),S?null:(0,b.jsx)(d.BrandButton,{type:`button`,variant:`primary`,onClick:e,testId:`manage-backends-done`,children:C(n.I18nKey.HOME$DONE)})]})]})}),U?(0,b.jsx)(_.BackendFormModal,{mode:`add`,source:`manage_backends_modal`,onClose:()=>W(!1)}):null,V?(0,b.jsx)(_.BackendFormModal,{mode:`edit`,backend:V,onClose:()=>H(null)}):null,z?(0,b.jsx)(m.ConfirmationModal,{text:C(n.I18nKey.BACKEND$REMOVE_CONFIRMATION,{name:z.name}),onConfirm:G,onCancel:()=>B(null)}):null]})}exports.ManageBackendsModal=S;
|
|
2
2
|
//# sourceMappingURL=manage-backends-modal.cjs.map
|