@openhands/agent-canvas 1.0.0-rc.1 → 1.0.0-rc.2
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 +2 -2
- package/README.windows.md +2 -2
- package/build/assets/{QueryClientProvider-w1cZWY41.js → QueryClientProvider-7oLZ1RtQ.js} +1 -1
- package/build/assets/{Trans-BJeYqz2A.js → Trans-rF21Jwln.js} +1 -1
- package/build/assets/{acp-providers-DJr8DlNG.js → acp-providers-DZEi8wDz.js} +1 -1
- package/build/assets/active-backend-context-CQTk4wD8.js +1 -0
- package/build/assets/add-backend-modal-CIfhseZn.js +1 -0
- package/build/assets/agent-server-client-options-Dvgeb3x4.js +1 -0
- package/build/assets/agent-server-compatibility-BANjmMTo.js +1 -0
- package/build/assets/agent-server-conversation-service.api-B82pNNTm.js +5 -0
- package/build/assets/{agent-settings-BXBaybB_.js → agent-settings-B6htMeS2.js} +1 -1
- package/build/assets/{alert-banner-NeUl1-PQ.js → alert-banner-D41ZKDZT.js} +1 -1
- package/build/assets/{analytics-consent-form-modal-DxkThW4K.js → analytics-consent-form-modal-TINgM_jV.js} +1 -1
- package/build/assets/api-key-entry-screen-Di1vHgIU.js +1 -0
- package/build/assets/{app-settings-C-U6jONZ.js → app-settings-CjCa1MOB.js} +1 -1
- package/build/assets/automation-detail-DPoxzTdV.js +1 -0
- package/build/assets/{automations-list-BLJzAd-p.js → automations-list-DwUEe2Ea.js} +1 -1
- package/build/assets/{back-nav-button-DgkK0Ka6.js → back-nav-button-BDM9vr_o.js} +1 -1
- package/build/assets/backend-form-modal-B6q897ZX.js +1 -0
- package/build/assets/{backend-synced-settings-badge-BktJcGgH.js → backend-synced-settings-badge-BwTawSCE.js} +1 -1
- package/build/assets/{base-modal-DZCNv0A4.js → base-modal-Ba5WcNb6.js} +1 -1
- package/build/assets/{brand-button-LBFNic99.js → brand-button-BoiPxAGm.js} +1 -1
- package/build/assets/{browser-D08Sp3ZY.js → browser-DTei6kki.js} +1 -1
- package/build/assets/browser-store-BjhV_9wS.js +1 -0
- package/build/assets/{browser-tab-be3QvXg9.js → browser-tab-DiRTKik8.js} +1 -1
- package/build/assets/chat-send-button-06dIuWXm.js +1 -0
- package/build/assets/check-BDAbW7je.js +1 -0
- package/build/assets/{checkmark-Rmpruj7q.js → checkmark-BB7QCG5T.js} +1 -1
- package/build/assets/{chevron-down-KhWYEjeW.js → chevron-down-DUxWwzTm.js} +1 -1
- package/build/assets/{chevron-left-small-6nyFCWVQ.js → chevron-left-small-CuuwpRi9.js} +1 -1
- package/build/assets/{circle-plus-check-toggle-DquBwJ_6.js → circle-plus-check-toggle-B3_W6-nt.js} +1 -1
- package/build/assets/{close-D_o3d8QM.js → close-Cz0OAgTy.js} +1 -1
- package/build/assets/{code-tag-DhsjDB-v.js → code-tag-Cz9AIz-X.js} +1 -1
- package/build/assets/{color-themes-0biOprdo.js → color-themes-B9n7pBQl.js} +1 -1
- package/build/assets/{combobox-caret-CO7eozIY.js → combobox-caret-DwMmhrrA.js} +1 -1
- package/build/assets/{command-store-UzKGSUC2.js → command-store-DAd3K0d_.js} +1 -1
- package/build/assets/{condenser-settings-BulzYEuW.js → condenser-settings-DczjwkIp.js} +1 -1
- package/build/assets/{confirmation-modal-CMAtd9R0.js → confirmation-modal-C_lds1Tb.js} +1 -1
- package/build/assets/{context-menu-list-item-D0swnhFt.js → context-menu-list-item-DhG1Ln5m.js} +1 -1
- package/build/assets/conversation-CBlJiDaV.js +19 -0
- package/build/assets/conversation-Dss8XCN_.js +1 -0
- package/build/assets/conversation-panel-B5sVpsz5.js +1 -0
- package/build/assets/conversation-service.api-B4s-xIOK.js +1 -0
- package/build/assets/conversation-state-store-BUU90dVq.js +1 -0
- package/build/assets/{conversation-store-CC-isCnP.js → conversation-store-kHcewy1E.js} +1 -1
- package/build/assets/{conversation-tab-empty-state-DYjKsg_c.js → conversation-tab-empty-state-5bW9CQke.js} +1 -1
- package/build/assets/conversation-websocket-context-C2yKCqvj.js +3 -0
- package/build/assets/{copy-BM0RpLez.js → copy-CA1Dblua.js} +1 -1
- package/build/assets/{custom-toast-handlers-BohXx7uh.js → custom-toast-handlers-fgD4IYsu.js} +1 -1
- package/build/assets/{declaration-DaUdB2Wg.js → declaration-IA661TBv.js} +1 -1
- package/build/assets/{device-verify-DiEJqpJb.js → device-verify-BVl4GEvt.js} +1 -1
- package/build/assets/{dist-xtCm0O6P.js → dist-B-SKiGDl.js} +1 -1
- package/build/assets/dist-CBUfAk0Z.js +1 -0
- package/build/assets/{dropdown-classes-Vqz86I0R.js → dropdown-classes-lT1LUsbO.js} +1 -1
- package/build/assets/edit-automation-modal-kc_FzbzK.js +1 -0
- package/build/assets/ellipsis-button-DRRmCrWi.js +1 -0
- package/build/assets/{entry.client-BvKgdCQ9.js → entry.client-CWkbusD1.js} +2 -2
- package/build/assets/{enum-filter-dropdown-DdFgk0EM.js → enum-filter-dropdown-DlY0Q3fj.js} +1 -1
- package/build/assets/{environment-switch-overlay-CuBuZOaa.js → environment-switch-overlay-BrHKX6_Z.js} +1 -1
- package/build/assets/{extensions-hub-Dayqvv0n.js → extensions-hub-NbQnt-cn.js} +1 -1
- package/build/assets/extensions-navigation-oOk5yl8X.js +1 -0
- package/build/assets/{file-DwHCkWZT.js → file-DM0ihEsO.js} +1 -1
- package/build/assets/files-tab-mK7Mdyuf.js +1 -0
- package/build/assets/files-tab-store-QlUCuW8b.js +1 -0
- package/build/assets/{folder-2h1hR1Qb.js → folder-UGYUKpqb.js} +1 -1
- package/build/assets/git-control-bar-branch-button-C1qmab0K.js +27 -0
- package/build/assets/{globe-qFjFNG6J.js → globe-2otpEmVh.js} +1 -1
- package/build/assets/home-ChuA06Hv.js +1 -0
- package/build/assets/{i18n-zDndR1Ne.js → i18n-CyvU1o95.js} +1 -1
- package/build/assets/install-server-modal--lZ1HSHB.js +1 -0
- package/build/assets/{launch-I00QV8YT.js → launch-BADsYeGp.js} +1 -1
- package/build/assets/{lesson-plan-C18uB_56.js → lesson-plan-5O2tVbD1.js} +1 -1
- package/build/assets/{link-external-DtcdPFbw.js → link-external-kU6aFXU6.js} +1 -1
- package/build/assets/llm-client-BnqeDPua.js +1 -0
- package/build/assets/llm-settings-D477P0Lg.js +1 -0
- package/build/assets/llm-settings-DtlQ7i4C.js +1 -0
- package/build/assets/{loading-spinner-DNwR4--Z.js → loading-spinner-CFuA0UNt.js} +1 -1
- package/build/assets/manage-backends-modal-sH7l5NgI.js +1 -0
- package/build/assets/manifest-17af0b17.js +1 -0
- package/build/assets/{markdown-renderer-D6B-u2nM.js → markdown-renderer-CZq_UdmE.js} +1 -1
- package/build/assets/mcp-DdQ72_AO.js +9 -0
- package/build/assets/mcp-client-xEdbDxOL.js +1 -0
- package/build/assets/{messages-Bz9TWjlh.js → messages-luW9zf1w.js} +1 -1
- package/build/assets/{modal-backdrop-BDqI1zBV.js → modal-backdrop-B1si6TUd.js} +1 -1
- package/build/assets/{modal-body-CCLCqX1J.js → modal-body-2Po2nl1e.js} +1 -1
- package/build/assets/{modal-classes-DwTdT3IK.js → modal-classes-9XTtWCtF.js} +1 -1
- package/build/assets/{modal-close-button-gQgKqUf-.js → modal-close-button-BCvw9IUN.js} +1 -1
- package/build/assets/model-selector-DzQRgNGZ.js +1 -0
- package/build/assets/{navigation-context-aNGUUtdq.js → navigation-context-CszaA-CJ.js} +1 -1
- package/build/assets/{navigation-link-CYkF2y3K.js → navigation-link-DXg4oo29.js} +1 -1
- package/build/assets/onboarding-DCL9stdH.js +1 -0
- package/build/assets/{openhands-logo-CHmtDV-t.js → openhands-logo-B-IDE1ER.js} +1 -1
- package/build/assets/{option-service.api-CGNANEcT.js → option-service.api-DHOGfYKh.js} +1 -1
- package/build/assets/organization-service.api-D79cdERN.js +1 -0
- package/build/assets/path-utils-CNd_jqv_.js +1 -0
- package/build/assets/{pencil-Dr0b2jL1.js → pencil-COslZGUC.js} +1 -1
- package/build/assets/{plan-components--aLlpASH.js → plan-components-BRiIX8Wn.js} +1 -1
- package/build/assets/{planner-tab-B-5EeCEm.js → planner-tab-QBnZgIXd.js} +1 -1
- package/build/assets/plus-D8aJZRkD.js +1 -0
- package/build/assets/profiles-client-CesbAK-7.js +1 -0
- package/build/assets/{providers-DknP6O2g.js → providers-Bpq3xFRA.js} +1 -1
- package/build/assets/proxy-wIasY2Po.js +1 -0
- package/build/assets/{query-client-config-CWWGQWvw.js → query-client-config-CITeuHD7.js} +1 -1
- package/build/assets/{recommended-automations-launcher-BIul0osB.js → recommended-automations-launcher-B01jchhe.js} +1 -1
- package/build/assets/root-BBV8Ew9E.js +2 -0
- package/build/assets/root-layout-pQASEqtQ.js +2 -0
- package/build/assets/{sdk-section-page-VmtJWH3A.js → sdk-section-page-BQKe3asw.js} +1 -1
- package/build/assets/{sdk-settings-schema-DFievvEK.js → sdk-settings-schema-DoRnefvb.js} +1 -1
- package/build/assets/{search-BeVRXvX7.js → search-Cbh-hHBu.js} +1 -1
- package/build/assets/secrets-service-DEIB-Cfk.js +1 -0
- package/build/assets/{secrets-settings-BLMvCkKm.js → secrets-settings-D2EfzdpC.js} +1 -1
- package/build/assets/server-client-Cz8PyIbN.js +1 -0
- package/build/assets/settings-B7jVceyu.js +1 -0
- package/build/assets/settings-client-BUlG0Gzq.js +1 -0
- package/build/assets/{settings-dropdown-input-DA_pzHWE.js → settings-dropdown-input-BD7ziSoR.js} +1 -1
- package/build/assets/{settings-gear-aNebYlCy.js → settings-gear-xGs_SPgZ.js} +1 -1
- package/build/assets/{settings-index-CycvkOoq.js → settings-index-Xj0v9Oas.js} +1 -1
- package/build/assets/{settings-input-8y5p4kze.js → settings-input-CPr7vX81.js} +1 -1
- package/build/assets/{settings-list-classes-Qk7zl0Wu.js → settings-list-classes-CYDn4jUg.js} +1 -1
- package/build/assets/{settings-modal-DdntdOGP.js → settings-modal-CDBy1S9S.js} +1 -1
- package/build/assets/{settings-section-header-context-B77tsYlx.js → settings-section-header-context-aD2iq1gD.js} +1 -1
- package/build/assets/settings-service.api-CTQ-LpAA.js +1 -0
- package/build/assets/{settings-switch-ba4DuiNO.js → settings-switch-CSHSqH99.js} +1 -1
- package/build/assets/{settings-utils-BxzHqLmZ.js → settings-utils-BCbzc6-u.js} +1 -1
- package/build/assets/shared-conversation-BHEbOdHj.js +1 -0
- package/build/assets/{sidebar-mobile-menu-toggle-C0mmabKj.js → sidebar-mobile-menu-toggle-YYPXGikp.js} +1 -1
- package/build/assets/{sidebar-nav-link-BsYdDFfb.js → sidebar-nav-link-CiXbBMQx.js} +1 -1
- package/build/assets/{sidebar-store-DnQAJAE5.js → sidebar-store-B76R2gP8.js} +1 -1
- package/build/assets/{skill-card-pill-row-BhUlGcYB.js → skill-card-pill-row-BXILn-GK.js} +1 -1
- package/build/assets/{skills-TYjOUQ2d.js → skills-CCaEu1KQ.js} +1 -1
- package/build/assets/skills-client-Cr9F5306.js +1 -0
- package/build/assets/{skills-plugins-D0pdqgKa.js → skills-plugins-Bs5HiF1O.js} +1 -1
- package/build/assets/{skills-settings-VqKTkmVl.js → skills-settings-CQYxMmWf.js} +1 -1
- package/build/assets/{styled-tooltip-TCp7svY3.js → styled-tooltip-DEr7oa0m.js} +1 -1
- package/build/assets/suspense-C9MBE_9N.js +1 -0
- package/build/assets/{switch-skeleton-cKrdaYGj.js → switch-skeleton-C87Tx3Tc.js} +1 -1
- package/build/assets/{task-list-tab-BiizRsY3.js → task-list-tab-R9N3Wd-U.js} +1 -1
- package/build/assets/{telemetry-fQFd-8V3.js → telemetry-DCrd7gnV.js} +2 -2
- package/build/assets/{terminal-CpgZx6go.js → terminal-BTM3UFcQ.js} +1 -1
- package/build/assets/{terminal-BSYITdM0.js → terminal-DQJ6IJUd.js} +1 -1
- package/build/assets/{toggle-switch-CUgOZqZu.js → toggle-switch-C-7juZ1u.js} +1 -1
- package/build/assets/{trash-2-CbVljPko.js → trash-2-DAKXV2Wm.js} +1 -1
- package/build/assets/{typography-Bvw0IxaN.js → typography-U1gkzkXo.js} +1 -1
- package/build/assets/{u-check-circle-half-DjpjzWu3.js → u-check-circle-half-CirnoxXG.js} +1 -1
- package/build/assets/{u-check-circle-u9QiS4Fr.js → u-check-circle-lbkXL2z4.js} +1 -1
- package/build/assets/{u-circuit-DlBlOwx9.js → u-circuit-Danff2ks.js} +1 -1
- package/build/assets/{u-edit-BIYzjs3v.js → u-edit-CH5nNya1.js} +1 -1
- package/build/assets/{use-active-conversation-q1wT8LI5.js → use-active-conversation-BY5F6A1G.js} +1 -1
- package/build/assets/use-agent-settings-schema-CsuMq16G.js +1 -0
- package/build/assets/{use-agent-state-CCHlVqvY.js → use-agent-state-DX5NKEa_.js} +1 -1
- package/build/assets/{use-cloud-current-user-id-BAKf91Zx.js → use-cloud-current-user-id-e1Pk7NxQ.js} +1 -1
- package/build/assets/use-config-DSzkljTq.js +1 -0
- package/build/assets/use-create-conversation-4iJytCT1.js +1 -0
- package/build/assets/{use-event-store-Cxqc45Sw.js → use-event-store-Rw1YbvLm.js} +1 -1
- package/build/assets/use-get-secrets-BMnFFBUx.js +1 -0
- package/build/assets/{use-handle-plan-click-Bfl0zIBr.js → use-handle-plan-click-DYd5a6zN.js} +1 -1
- package/build/assets/use-is-authed-DrocXcet.js +1 -0
- package/build/assets/{use-launch-skill-in-chat-3ydwpi_M.js → use-launch-skill-in-chat-BoqKmEHC.js} +1 -1
- package/build/assets/use-llm-profiles-BhZRf-NX.js +1 -0
- package/build/assets/use-runtime-is-ready-DP-KKHO6.js +1 -0
- package/build/assets/{use-save-settings-rE9aA29R.js → use-save-settings-hK6LYt0s.js} +1 -1
- package/build/assets/use-settings-Clf0Y_P3.js +1 -0
- package/build/assets/{use-settings-nav-items-C7MOWj09.js → use-settings-nav-items-oZ-BlOWX.js} +1 -1
- package/build/assets/use-skills-v8pQ02ze.js +1 -0
- package/build/assets/{use-task-list-YMkSzdDv.js → use-task-list-DydbuRFM.js} +1 -1
- package/build/assets/{use-tracking-DQYdZpxi.js → use-tracking-DQU60djN.js} +1 -1
- package/build/assets/use-unified-vscode-url-D2Buvmxj.js +1 -0
- package/build/assets/use-user-conversation-DwOGM1lc.js +1 -0
- package/build/assets/{useMutation-DDo48A8t.js → useMutation-7hG0GuPx.js} +1 -1
- package/build/assets/useQuery-JDs8UaWj.js +1 -0
- package/build/assets/{useTranslation-CEcjrme-.js → useTranslation-CbJtty1g.js} +1 -1
- package/build/assets/{utils-CdgBzLA7.js → utils-CVcuFUYj.js} +1 -1
- package/build/assets/{vendor~browser-DWk6fNtJ.js → vendor~browser-3J6WDaAB.js} +1 -1
- package/build/assets/{vendor~browser-tab-NZdVoI2Z.js → vendor~browser-tab-DYZ-OmbT.js} +1 -1
- package/build/assets/{vendor~conversation-panel~conversation-gp03cWZW.js → vendor~conversation-panel~conversation-DYHL7QoY.js} +1 -1
- package/build/assets/{vendor~conversation-panel~conversation~index-BZ5C6Xpz.js → vendor~conversation-panel~conversation~index-Be58Romv.js} +1 -1
- package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~oli4dvxu-BodGsxSf.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~oli4dvxu-CBEOG8NF.js} +1 -1
- package/build/assets/{vendor~files-tab-Buz36Y-q.js → vendor~files-tab-Diy4WrQz.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation-DG0H5SkJ.js → vendor~home~conversation-panel~conversation-DZ-F7J6T.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Ceeqkj0k.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BighOCzm.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-9Il_wz8U.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CWwn0K2j.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CXivI4Ym.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Cntsv2EN.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-B7I1ZxCx.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-D13hiNGV.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-1pTajrpX.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-dZ3D8RVL.js} +1 -1
- package/build/assets/{vendor~launch-DXL78kBf.js → vendor~launch-D65Vw0VZ.js} +1 -1
- package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-CfAc3nMS.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-BJPgfJoU.js} +1 -1
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation-DkwcKRtv.js → vendor~root-layout~home~conversation-panel~conversation-Cg0nXqVs.js} +1 -1
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-DSqEbr0N.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~bok0tgtf-Dr8Ly0at.js} +1 -1
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-BC9XTECT.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~bok0tgtf-DveauQfg.js} +1 -1
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-D0XUSHNN.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~jpfhx3ls-BkicN-14.js} +2 -2
- package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~settings~settings-index~agen~jxrvuot9-Cwz6a1DC.js +48 -0
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-CcFtthyg.js → vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-C37jLHRk.js} +1 -1
- package/build/assets/{vendor~root-layout~home~mcp~automations-list-BnIlGhjl.js → vendor~root-layout~home~mcp~automations-list-BTTZ58Mb.js} +1 -1
- package/build/assets/{vendor~root-layout~home~mcp~automations-list-cNHi83v_.js → vendor~root-layout~home~mcp~automations-list-JQ-neDIa.js} +1 -1
- package/build/assets/{vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-BGWUbqUq.js → vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-CbuXadI-.js} +1 -1
- package/build/assets/{vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-BuCSnjsW.js → vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-UYEKKX0Y.js} +2 -2
- package/build/assets/{verification-settings-CIqtxWat.js → verification-settings-Rabe5TpK.js} +1 -1
- package/build/assets/{vscode-tab-DEt72yJX.js → vscode-tab-zLD5Z-PP.js} +1 -1
- package/build/assets/{waiting-for-runtime-message-DSjJfeoj.js → waiting-for-runtime-message-B1Dzhtj5.js} +1 -1
- package/build/assets/x-8AbJWTbX.js +1 -0
- package/build/assets/{x-mark-DsJ9tDD0.js → x-mark-CmcVOTk2.js} +1 -1
- package/build/index.html +4 -4
- package/build/locales/ar/openhands.json +1 -0
- package/build/locales/ca/openhands.json +1 -0
- package/build/locales/de/openhands.json +1 -0
- package/build/locales/en/openhands.json +1 -0
- package/build/locales/es/openhands.json +1 -0
- package/build/locales/fr/openhands.json +1 -0
- package/build/locales/it/openhands.json +1 -0
- package/build/locales/ja/openhands.json +1 -0
- package/build/locales/ko-KR/openhands.json +1 -0
- package/build/locales/no/openhands.json +1 -0
- package/build/locales/pt/openhands.json +1 -0
- package/build/locales/tr/openhands.json +1 -0
- package/build/locales/uk/openhands.json +1 -0
- package/build/locales/zh-CN/openhands.json +1 -0
- package/build/locales/zh-TW/openhands.json +1 -0
- package/dist/api/agent-server-adapter.cjs +2 -2
- package/dist/api/agent-server-adapter.cjs.map +1 -1
- package/dist/api/agent-server-adapter.js +6 -3
- package/dist/api/agent-server-adapter.js.map +1 -1
- package/dist/api/cloud/proxy.cjs +1 -1
- package/dist/api/cloud/proxy.cjs.map +1 -1
- package/dist/api/cloud/proxy.d.ts +18 -6
- package/dist/api/cloud/proxy.js +1 -1
- package/dist/api/cloud/proxy.js.map +1 -1
- package/dist/api/conversation-metadata-store.cjs.map +1 -1
- package/dist/api/conversation-metadata-store.d.ts +8 -0
- package/dist/api/conversation-metadata-store.js.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.types.d.ts +9 -0
- package/dist/components/features/chat/switch-profile-button.cjs +1 -1
- package/dist/components/features/chat/switch-profile-button.cjs.map +1 -1
- package/dist/components/features/chat/switch-profile-button.js +5 -5
- package/dist/components/features/chat/switch-profile-button.js.map +1 -1
- package/dist/components/features/conversation-panel/skills-modal.cjs +1 -1
- package/dist/components/features/conversation-panel/skills-modal.cjs.map +1 -1
- package/dist/components/features/conversation-panel/skills-modal.js +34 -37
- package/dist/components/features/conversation-panel/skills-modal.js.map +1 -1
- package/dist/components/features/settings/llm-profiles/profile-actions-menu.cjs +1 -1
- package/dist/components/features/settings/llm-profiles/profile-actions-menu.js +1 -0
- 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.d.ts +0 -8
- package/dist/components/features/skills/extensions-navigation.js +34 -51
- package/dist/components/features/skills/extensions-navigation.js.map +1 -1
- package/dist/constants/acp-providers.cjs +1 -1
- package/dist/constants/acp-providers.js +1 -1
- 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 +26 -14
- package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile-and-log.cjs +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile-and-log.cjs.map +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile-and-log.js +26 -15
- package/dist/hooks/mutation/use-switch-llm-profile-and-log.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 +1 -0
- package/dist/i18n/declaration.js +1 -1
- package/dist/i18n/declaration.js.map +1 -1
- package/dist/i18n/translation.cjs +1 -1
- package/dist/i18n/translation.cjs.map +1 -1
- package/dist/i18n/translation.js +17 -0
- package/dist/i18n/translation.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +10 -10
- package/dist/lib/index.cjs +1 -1
- package/dist/lib/index.js +1 -1
- package/dist/locales/ar/openhands.json +1 -0
- package/dist/locales/ca/openhands.json +1 -0
- package/dist/locales/de/openhands.json +1 -0
- package/dist/locales/en/openhands.json +1 -0
- package/dist/locales/es/openhands.json +1 -0
- package/dist/locales/fr/openhands.json +1 -0
- package/dist/locales/it/openhands.json +1 -0
- package/dist/locales/ja/openhands.json +1 -0
- package/dist/locales/ko-KR/openhands.json +1 -0
- package/dist/locales/no/openhands.json +1 -0
- package/dist/locales/pt/openhands.json +1 -0
- package/dist/locales/tr/openhands.json +1 -0
- package/dist/locales/uk/openhands.json +1 -0
- package/dist/locales/zh-CN/openhands.json +1 -0
- package/dist/locales/zh-TW/openhands.json +1 -0
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/dist/routes/mcp.cjs +1 -1
- package/dist/routes/mcp.cjs.map +1 -1
- package/dist/routes/mcp.d.ts +0 -1
- package/dist/routes/mcp.js +0 -1
- package/dist/routes/mcp.js.map +1 -1
- package/package.json +1 -1
- package/scripts/dev-safe.mjs +18 -2
- package/build/assets/acp-route-guard-A__sWgbc.js +0 -1
- package/build/assets/active-backend-context-I2w666XY.js +0 -1
- package/build/assets/add-backend-modal-BDBDBXsJ.js +0 -1
- package/build/assets/agent-server-client-options-9agOSarV.js +0 -1
- package/build/assets/agent-server-compatibility-B7QStIcH.js +0 -1
- package/build/assets/agent-server-conversation-service.api-Cagoqq1V.js +0 -5
- package/build/assets/api-key-entry-screen-ByXA4hXH.js +0 -1
- package/build/assets/automation-detail-Dbmgt974.js +0 -1
- package/build/assets/backend-form-modal-CeB983Sj.js +0 -1
- package/build/assets/browser-store-JRrcGdlk.js +0 -1
- package/build/assets/chat-send-button-5qz0zj6R.js +0 -1
- package/build/assets/check-CZhEL6rP.js +0 -1
- package/build/assets/conversation-BrjF2-Ky.js +0 -1
- package/build/assets/conversation-HgR_TTPE.js +0 -19
- package/build/assets/conversation-panel-BlRcO5AC.js +0 -1
- package/build/assets/conversation-service.api-B_Pdmwsa.js +0 -1
- package/build/assets/conversation-state-store-D-w0uurj.js +0 -1
- package/build/assets/conversation-websocket-context-G95yfL81.js +0 -3
- package/build/assets/dist-Bl-1K5Tv.js +0 -1
- package/build/assets/edit-automation-modal-CNZgSSiH.js +0 -1
- package/build/assets/extensions-navigation-yFLAU06N.js +0 -1
- package/build/assets/files-tab-CMredyYX.js +0 -1
- package/build/assets/files-tab-store-DLU28g8C.js +0 -1
- package/build/assets/git-control-bar-branch-button-D8blTNXh.js +0 -27
- package/build/assets/home-CWw845Rz.js +0 -1
- package/build/assets/install-server-modal-D8Q0xZcN.js +0 -1
- package/build/assets/llm-client-BqyLKgUN.js +0 -1
- package/build/assets/llm-settings-CAnFYAEG.js +0 -1
- package/build/assets/llm-settings-DotqpmCF.js +0 -1
- package/build/assets/manage-backends-modal-Ceo_SOcf.js +0 -1
- package/build/assets/manifest-61ec2d68.js +0 -1
- package/build/assets/mcp-EvrLVTla.js +0 -9
- package/build/assets/model-selector-CZOi4V7r.js +0 -1
- package/build/assets/onboarding-CPCKYvFh.js +0 -1
- package/build/assets/organization-service.api-Dn74hBTH.js +0 -1
- package/build/assets/path-utils-BjxzIGLp.js +0 -1
- package/build/assets/plus-DT-M0FA1.js +0 -1
- package/build/assets/profiles-client-BrqNmaDV.js +0 -1
- package/build/assets/proxy-sRh0WKI7.js +0 -1
- package/build/assets/root-CklXEh3W.js +0 -2
- package/build/assets/root-layout-BCA_X8XL.js +0 -2
- package/build/assets/secrets-service-DVtlLWY8.js +0 -1
- package/build/assets/server-client-DYv_GHPl.js +0 -1
- package/build/assets/settings-CXvJUx_j.js +0 -1
- package/build/assets/settings-service.api-DxIEtvx6.js +0 -1
- package/build/assets/shared-conversation-x41nZQi7.js +0 -1
- package/build/assets/use-agent-settings-schema-Yxf7KGyG.js +0 -1
- package/build/assets/use-config-DwfigQ_Y.js +0 -1
- package/build/assets/use-create-conversation-BEzddjXn.js +0 -1
- package/build/assets/use-get-secrets-BlO1BfUo.js +0 -1
- package/build/assets/use-is-authed-hHndEep7.js +0 -1
- package/build/assets/use-llm-profiles-E-jjZMZw.js +0 -1
- package/build/assets/use-runtime-is-ready-DBWzvAmc.js +0 -1
- package/build/assets/use-settings-BPTbE7lg.js +0 -1
- package/build/assets/use-skills-QhoaIYGF.js +0 -1
- package/build/assets/use-unified-vscode-url-DFtNIC1Q.js +0 -1
- package/build/assets/use-user-conversation-BRAseenw.js +0 -1
- package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-D8soyAAx.js +0 -48
- package/build/assets/vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~jaomi49z-Cw89stA6.js +0 -1
- package/build/assets/x-JOBEVLW0.js +0 -1
- package/dist/components/features/conversation-panel/skills-runtime-waiting-state.cjs +0 -2
- package/dist/components/features/conversation-panel/skills-runtime-waiting-state.cjs.map +0 -1
- package/dist/components/features/conversation-panel/skills-runtime-waiting-state.d.ts +0 -1
- package/dist/components/features/conversation-panel/skills-runtime-waiting-state.js +0 -21
- package/dist/components/features/conversation-panel/skills-runtime-waiting-state.js.map +0 -1
- package/dist/utils/acp-route-guard.cjs +0 -1
- package/dist/utils/acp-route-guard.d.ts +0 -26
- package/dist/utils/acp-route-guard.js +0 -4
- /package/build/assets/{agent-server-ui-style-scope-BwIZYdC1.js → agent-server-ui-style-scope-Bhc5vpWO.js} +0 -0
- /package/build/assets/{automation-DJ_3GeXD.js → automation-LZB0MjdV.js} +0 -0
- /package/build/assets/{common-DqjLSBOt.js → common-Cfviy7yT.js} +0 -0
- /package/build/assets/{context-CEQZwATj.js → context-BBqptpXX.js} +0 -0
- /package/build/assets/{conversation-local-storage-YmOVXxxW.js → conversation-local-storage-D5Tre_GA.js} +0 -0
- /package/build/assets/{createLucideIcon-Ddu8jDOQ.js → createLucideIcon-C9OEnwvX.js} +0 -0
- /package/build/assets/{environment-switch-store-CiurvTtK.js → environment-switch-store-BpKxp6Xq.js} +0 -0
- /package/build/assets/{git-status-mapper-DnL9OC8_.js → git-status-mapper-N4-7eaeC.js} +0 -0
- /package/build/assets/{handle-capture-consent-3XrjZ8wi.js → handle-capture-consent-OitMkDHc.js} +0 -0
- /package/build/assets/{health-store-B5f0S2FY.js → health-store-d-d2ssv4.js} +0 -0
- /package/build/assets/{iconBase-BVhFI-0E.js → iconBase-B_5IRYeZ.js} +0 -0
- /package/build/assets/{map-provider-C3Z5Dx2J.js → map-provider-BHow6ugd.js} +0 -0
- /package/build/assets/{middleware-CfatjPYZ.js → middleware-B5rcobhi.js} +0 -0
- /package/build/assets/{objectWithoutPropertiesLoose-DSQKyRhw.js → objectWithoutPropertiesLoose-B-IA9dU9.js} +0 -0
- /package/build/assets/{query-keys-tAsQcc_9.js → query-keys-CQaji0wJ.js} +0 -0
- /package/build/assets/{react-Dy05vyj5.js → react-CuAHzoGi.js} +0 -0
- /package/build/assets/{retrieve-axios-error-message-BY-yIkIq.js → retrieve-axios-error-message-DbnSBc_1.js} +0 -0
- /package/build/assets/{sdk-settings-field-metadata-C6KMD-jZ.js → sdk-settings-field-metadata-CtO73dY6.js} +0 -0
- /package/build/assets/{settings-DGY6n4J2.js → settings-KgLvVrSm.js} +0 -0
- /package/build/assets/{settings-like-page-layout-classes-DNg2vKSM.js → settings-like-page-layout-classes-GknosJgv.js} +0 -0
- /package/build/assets/{use-breakpoint-DpxHDmuH.js → use-breakpoint-2sN462wJ.js} +0 -0
- /package/build/assets/{use-click-outside-element-DhxCUyWl.js → use-click-outside-element-_vianyPb.js} +0 -0
- /package/build/assets/{v4-khGvL7i2.js → v4-BMWDcIWQ.js} +0 -0
- /package/build/assets/{vendor~browser-BDNLFng6.js → vendor~browser-C3GKF4mj.js} +0 -0
- /package/build/assets/{vendor~conversation-panel~conversation~alert-banner-D_hRW_zc.js → vendor~conversation-panel~conversation~alert-banner-DMcFTqbt.js} +0 -0
- /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~j8sdb9mk-OFpe9fX_.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~j8sdb9mk-oCzr0-9g.js} +0 -0
- /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~lpdshwee-BPuuVEqr.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~lpdshwee-CTmh4bwd.js} +0 -0
- /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~skills-settings~m~o9nrx3fm-D44TR8hL.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~skills-settings~m~o9nrx3fm-87v-LliW.js} +0 -0
- /package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Dr3Ow7Ms.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DTosGXG7.js} +0 -0
- /package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~i4kjfqhl-B1TKKuuH.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~ntycl9e1-DspdqGPW.js} +0 -0
- /package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~e9ykmtgh-Fa-nXZ4M.js → vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~e9ykmtgh-DMH1jSwL.js} +0 -0
- /package/build/assets/{vendor~terminal-0ObOedYm.js → vendor~terminal-CnKZILnC.js} +0 -0
- /package/build/assets/{vscode-url-helper-BMq8JBhB.js → vscode-url-helper-CwQPl6QN.js} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Backend } from "../backend-registry/types";
|
|
2
|
-
interface CloudProxyRequest {
|
|
2
|
+
export interface CloudProxyRequest {
|
|
3
3
|
/**
|
|
4
4
|
* Cloud backend whose bearer token authenticates the upstream call.
|
|
5
5
|
* `backend.host` is also the default upstream host unless `hostOverride`
|
|
@@ -40,15 +40,27 @@ interface CloudProxyRequest {
|
|
|
40
40
|
* payload (e.g. ZIP downloads); leave undefined for default JSON.
|
|
41
41
|
*/
|
|
42
42
|
responseType?: "blob";
|
|
43
|
+
/**
|
|
44
|
+
* Force this app-host call through the bundled agent-server's
|
|
45
|
+
* `/api/cloud-proxy` instead of calling the cloud host directly from the
|
|
46
|
+
* browser. App-host calls normally go direct because the main cloud API
|
|
47
|
+
* loosens CORS for bearer-token requests (ApiKeyAwareCORSMiddleware →
|
|
48
|
+
* `Access-Control-Allow-Origin: *`). The standalone automation service
|
|
49
|
+
* (`/api/automation/*`) uses a strict origin allowlist instead, so direct
|
|
50
|
+
* browser requests fail CORS preflight; the same-origin proxy hop avoids
|
|
51
|
+
* cross-origin entirely while attaching the same auth and `X-Org-Id`
|
|
52
|
+
* headers server-side.
|
|
53
|
+
*/
|
|
54
|
+
forceProxy?: boolean;
|
|
43
55
|
}
|
|
44
56
|
/**
|
|
45
57
|
* Send a cloud request. App-host calls (`backend.host`) go directly to the
|
|
46
|
-
* cloud API with the cloud backend's auth headers
|
|
47
|
-
* `hostOverride`, and those still go through
|
|
48
|
-
* per-conversation runtime hosts are not the
|
|
58
|
+
* cloud API with the cloud backend's auth headers, unless `forceProxy` is
|
|
59
|
+
* set. Runtime-sandbox calls pass `hostOverride`, and those still go through
|
|
60
|
+
* `/api/cloud-proxy` because the per-conversation runtime hosts are not the
|
|
61
|
+
* configured cloud app origin.
|
|
49
62
|
*
|
|
50
|
-
* App-host auth headers are sent directly to the cloud host.
|
|
63
|
+
* App-host auth headers are sent directly to the cloud host. Proxied auth
|
|
51
64
|
* headers are carried in the proxy envelope and attached server-side.
|
|
52
65
|
*/
|
|
53
66
|
export declare function callCloudProxy<TResponse = unknown>(req: CloudProxyRequest): Promise<TResponse>;
|
|
54
|
-
export {};
|
package/dist/api/cloud/proxy.js
CHANGED
|
@@ -14,7 +14,7 @@ async function s(a) {
|
|
|
14
14
|
...c,
|
|
15
15
|
...a.headers ?? {}
|
|
16
16
|
}, u = a.hostOverride ?? a.backend.host;
|
|
17
|
-
if (!a.hostOverride) return (await r.request({
|
|
17
|
+
if (!a.hostOverride && !a.forceProxy) return (await r.request({
|
|
18
18
|
url: `${u.replace(/\/+$/, "")}${a.path}`,
|
|
19
19
|
method: a.method,
|
|
20
20
|
headers: l,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.js","names":[],"sources":["../../../src/api/cloud/proxy.ts"],"sourcesContent":["import axios from \"axios\";\nimport {\n getAgentServerBaseUrl,\n getAgentServerHeaders,\n} from \"../agent-server-config\";\nimport { getActiveBackend } from \"../backend-registry/active-store\";\nimport { NoBackendAvailableError } from \"../agent-server-client-options\";\nimport { buildAuthHeaders } from \"../backend-registry/auth\";\nimport type { Backend } from \"../backend-registry/types\";\n\
|
|
1
|
+
{"version":3,"file":"proxy.js","names":[],"sources":["../../../src/api/cloud/proxy.ts"],"sourcesContent":["import axios from \"axios\";\nimport {\n getAgentServerBaseUrl,\n getAgentServerHeaders,\n} from \"../agent-server-config\";\nimport { getActiveBackend } from \"../backend-registry/active-store\";\nimport { NoBackendAvailableError } from \"../agent-server-client-options\";\nimport { buildAuthHeaders } from \"../backend-registry/auth\";\nimport type { Backend } from \"../backend-registry/types\";\n\nexport interface CloudProxyRequest {\n /**\n * Cloud backend whose bearer token authenticates the upstream call.\n * `backend.host` is also the default upstream host unless `hostOverride`\n * is set.\n */\n backend: Backend;\n /** HTTP method against the upstream host. */\n method: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\";\n /** Path on the upstream host, e.g. \"/api/v1/conversation/123/events/search\". */\n path: string;\n /** Optional JSON body for non-GET methods. */\n body?: unknown;\n /** Extra headers merged with the auth header for the upstream call. */\n headers?: Record<string, string>;\n /** Override the upstream timeout, in seconds. */\n timeoutSeconds?: number;\n /**\n * Override the upstream host. When set, the proxy targets this host\n * instead of `backend.host`. Used for runtime-sandbox calls where the\n * upstream lives at the conversation's runtime URL (e.g.\n * `http://<id>.prod-runtime.all-hands.dev`) rather than the cloud API.\n * The host must still pass the proxy's allowlist server-side.\n */\n hostOverride?: string;\n /**\n * Auth strategy for the upstream call. Defaults to \"bearer\" (uses the\n * cloud backend's bearer token via `buildAuthHeaders`). For\n * runtime-sandbox calls, set to \"session-api-key\" and pass\n * `sessionApiKey` — those endpoints don't accept bearer tokens, only\n * `X-Session-API-Key`. \"none\" sends no auth header.\n */\n authMode?: \"bearer\" | \"session-api-key\" | \"none\";\n /** Required when `authMode === \"session-api-key\"`. */\n sessionApiKey?: string | null;\n /**\n * Axios responseType for the inner POST to the bundled agent-server.\n * Set to \"blob\" when the upstream cloud endpoint returns a binary\n * payload (e.g. ZIP downloads); leave undefined for default JSON.\n */\n responseType?: \"blob\";\n /**\n * Force this app-host call through the bundled agent-server's\n * `/api/cloud-proxy` instead of calling the cloud host directly from the\n * browser. App-host calls normally go direct because the main cloud API\n * loosens CORS for bearer-token requests (ApiKeyAwareCORSMiddleware →\n * `Access-Control-Allow-Origin: *`). The standalone automation service\n * (`/api/automation/*`) uses a strict origin allowlist instead, so direct\n * browser requests fail CORS preflight; the same-origin proxy hop avoids\n * cross-origin entirely while attaching the same auth and `X-Org-Id`\n * headers server-side.\n */\n forceProxy?: boolean;\n}\n\nfunction buildUpstreamAuthHeaders(\n req: CloudProxyRequest,\n): Record<string, string> {\n const mode = req.authMode ?? \"bearer\";\n if (mode === \"bearer\") return buildAuthHeaders(req.backend);\n if (mode === \"session-api-key\") {\n return req.sessionApiKey ? { \"X-Session-API-Key\": req.sessionApiKey } : {};\n }\n return {};\n}\n\n/**\n * Send a cloud request. App-host calls (`backend.host`) go directly to the\n * cloud API with the cloud backend's auth headers, unless `forceProxy` is\n * set. Runtime-sandbox calls pass `hostOverride`, and those still go through\n * `/api/cloud-proxy` because the per-conversation runtime hosts are not the\n * configured cloud app origin.\n *\n * App-host auth headers are sent directly to the cloud host. Proxied auth\n * headers are carried in the proxy envelope and attached server-side.\n */\nexport async function callCloudProxy<TResponse = unknown>(\n req: CloudProxyRequest,\n): Promise<TResponse> {\n // Send `X-Org-Id` so the upstream scopes per-request to the org the user\n // selected locally, instead of the user's globally-shared\n // `current_org_id` on the cloud backend. Restricted to calls against the active\n // backend: the selector also fans out per-backend bookkeeping calls\n // (e.g. `getCloudOrganizations(b)`) that would otherwise carry the\n // active backend's orgId across an unrelated API key, which the cloud backend\n // rejects when api_key_org_id and X-Org-Id disagree.\n const active = getActiveBackend();\n const orgIdHeader =\n active.backend.id === req.backend.id && active.orgId\n ? { \"X-Org-Id\": active.orgId }\n : {};\n const upstreamHeaders = {\n ...buildUpstreamAuthHeaders(req),\n ...orgIdHeader,\n ...(req.headers ?? {}),\n };\n const upstreamHost = req.hostOverride ?? req.backend.host;\n\n if (!req.hostOverride && !req.forceProxy) {\n const response = await axios.request<TResponse>({\n url: `${upstreamHost.replace(/\\/+$/, \"\")}${req.path}`,\n method: req.method,\n headers: upstreamHeaders,\n ...(req.body !== undefined ? { data: req.body } : {}),\n timeout: (req.timeoutSeconds ?? 30) * 1000,\n ...(req.responseType ? { responseType: req.responseType } : {}),\n });\n\n return response.data;\n }\n\n const proxyBaseUrl = getAgentServerBaseUrl();\n if (!proxyBaseUrl) throw new NoBackendAvailableError();\n const localAuthHeaders = getAgentServerHeaders();\n\n // Talk to the configured app/ingress origin that exposes /api/cloud-proxy.\n // Do not resolve this through the backend registry: when the active backend\n // is cloud, borrowing some other registered local backend would silently\n // route cloud traffic through the wrong user-configured server.\n const response = await axios.post<TResponse>(\n `${proxyBaseUrl.replace(/\\/+$/, \"\")}/api/cloud-proxy`,\n {\n host: upstreamHost,\n method: req.method,\n path: req.path,\n headers: upstreamHeaders,\n body: req.body ?? null,\n ...(req.timeoutSeconds ? { timeout_seconds: req.timeoutSeconds } : {}),\n },\n {\n headers: localAuthHeaders,\n timeout: 30_000,\n ...(req.responseType ? { responseType: req.responseType } : {}),\n },\n );\n\n return response.data;\n}\n"],"mappings":";;;;;;AAiEA,SAAS,EACP,GACwB;CACxB,IAAM,IAAO,EAAI,YAAY;AAK7B,QAJI,MAAS,WAAiB,EAAiB,EAAI,QAAQ,GACvD,MAAS,qBACJ,EAAI,gBAAgB,EAAE,qBAAqB,EAAI,eAAe,GAAG,EAAE;;AAe9E,eAAsB,EACpB,GACoB;CAQpB,IAAM,IAAS,GAAkB,EAC3B,IACJ,EAAO,QAAQ,OAAO,EAAI,QAAQ,MAAM,EAAO,QAC3C,EAAE,YAAY,EAAO,OAAO,GAC5B,EAAE,EACF,IAAkB;EACtB,GAAG,EAAyB,EAAI;EAChC,GAAG;EACH,GAAI,EAAI,WAAW,EAAE;EACtB,EACK,IAAe,EAAI,gBAAgB,EAAI,QAAQ;AAErD,KAAI,CAAC,EAAI,gBAAgB,CAAC,EAAI,WAU5B,SAAO,MATgB,EAAM,QAAmB;EAC9C,KAAK,GAAG,EAAa,QAAQ,QAAQ,GAAG,GAAG,EAAI;EAC/C,QAAQ,EAAI;EACZ,SAAS;EACT,GAAI,EAAI,SAAS,KAAA,IAAiC,EAAE,GAAvB,EAAE,MAAM,EAAI,MAAM;EAC/C,UAAU,EAAI,kBAAkB,MAAM;EACtC,GAAI,EAAI,eAAe,EAAE,cAAc,EAAI,cAAc,GAAG,EAAE;EAC/D,CAAC,EAEc;CAGlB,IAAM,IAAe,GAAuB;AAC5C,KAAI,CAAC,EAAc,OAAM,IAAI,GAAyB;CACtD,IAAM,IAAmB,GAAuB;AAuBhD,SAAO,MAjBgB,EAAM,KAC3B,GAAG,EAAa,QAAQ,QAAQ,GAAG,CAAC,mBACpC;EACE,MAAM;EACN,QAAQ,EAAI;EACZ,MAAM,EAAI;EACV,SAAS;EACT,MAAM,EAAI,QAAQ;EAClB,GAAI,EAAI,iBAAiB,EAAE,iBAAiB,EAAI,gBAAgB,GAAG,EAAE;EACtE,EACD;EACE,SAAS;EACT,SAAS;EACT,GAAI,EAAI,eAAe,EAAE,cAAc,EAAI,cAAc,GAAG,EAAE;EAC/D,CACF,EAEe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-metadata-store.cjs","names":[],"sources":["../../src/api/conversation-metadata-store.ts"],"sourcesContent":["import { Provider } from \"#/types/settings\";\n\nconst STORAGE_KEY = \"openhands-agent-server-conversation-metadata\";\n\nexport interface ConversationMetadata {\n selected_repository: string | null;\n selected_branch: string | null;\n git_provider: Provider | null;\n /**\n * The local workspace path the user explicitly attached at conversation\n * creation time. Distinct from `selected_repository` (which is set by\n * the repo picker on the home page). Used by the Files tab to decide\n * whether to default to diff view: if the user attached *anything*\n * (repo or local workspace), we lean diff-first because there's a real\n * git baseline to compare against.\n */\n selected_workspace?: string | null;\n}\n\ntype StoredMetadata = Record<string, ConversationMetadata>;\n\nconst readAll = (): StoredMetadata => {\n if (typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) return {};\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\") return {};\n return parsed as StoredMetadata;\n } catch {\n return {};\n }\n};\n\nconst writeAll = (next: StoredMetadata): void => {\n if (typeof window === \"undefined\") return;\n if (Object.keys(next).length === 0) {\n window.localStorage.removeItem(STORAGE_KEY);\n return;\n }\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(next));\n};\n\nexport const getStoredConversationMetadata = (\n conversationId: string,\n): ConversationMetadata | null => readAll()[conversationId] ?? null;\n\nexport const setStoredConversationMetadata = (\n conversationId: string,\n metadata: ConversationMetadata,\n): void => {\n const all = readAll();\n all[conversationId] = metadata;\n writeAll(all);\n};\n\nexport const removeStoredConversationMetadata = (\n conversationId: string,\n): void => {\n const all = readAll();\n if (!(conversationId in all)) return;\n delete all[conversationId];\n writeAll(all);\n};\n"],"mappings":"6CAEA,IAAM,EAAc,+
|
|
1
|
+
{"version":3,"file":"conversation-metadata-store.cjs","names":[],"sources":["../../src/api/conversation-metadata-store.ts"],"sourcesContent":["import { Provider } from \"#/types/settings\";\n\nconst STORAGE_KEY = \"openhands-agent-server-conversation-metadata\";\n\nexport interface ConversationMetadata {\n selected_repository: string | null;\n selected_branch: string | null;\n git_provider: Provider | null;\n /**\n * The local workspace path the user explicitly attached at conversation\n * creation time. Distinct from `selected_repository` (which is set by\n * the repo picker on the home page). Used by the Files tab to decide\n * whether to default to diff view: if the user attached *anything*\n * (repo or local workspace), we lean diff-first because there's a real\n * git baseline to compare against.\n */\n selected_workspace?: string | null;\n /**\n * The LLM profile the conversation was created with (or last switched to).\n * Client-side only. Lets the chat-header switcher show the exact profile\n * name even when several profiles share the same underlying model — the\n * agent-server only round-trips the model string, so matching on it alone\n * is ambiguous (issue #1082).\n */\n active_profile?: string | null;\n}\n\ntype StoredMetadata = Record<string, ConversationMetadata>;\n\nconst readAll = (): StoredMetadata => {\n if (typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) return {};\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\") return {};\n return parsed as StoredMetadata;\n } catch {\n return {};\n }\n};\n\nconst writeAll = (next: StoredMetadata): void => {\n if (typeof window === \"undefined\") return;\n if (Object.keys(next).length === 0) {\n window.localStorage.removeItem(STORAGE_KEY);\n return;\n }\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(next));\n};\n\nexport const getStoredConversationMetadata = (\n conversationId: string,\n): ConversationMetadata | null => readAll()[conversationId] ?? null;\n\nexport const setStoredConversationMetadata = (\n conversationId: string,\n metadata: ConversationMetadata,\n): void => {\n const all = readAll();\n all[conversationId] = metadata;\n writeAll(all);\n};\n\nexport const removeStoredConversationMetadata = (\n conversationId: string,\n): void => {\n const all = readAll();\n if (!(conversationId in all)) return;\n delete all[conversationId];\n writeAll(all);\n};\n"],"mappings":"6CAEA,IAAM,EAAc,+CA2Bd,MAAgC,CACpC,GAAI,OAAO,OAAW,IAAa,MAAO,EAAE,CAC5C,GAAI,CACF,IAAM,EAAM,OAAO,aAAa,QAAQ,EAAY,CACpD,GAAI,CAAC,EAAK,MAAO,EAAE,CACnB,IAAM,EAAS,KAAK,MAAM,EAAI,CAE9B,MADI,CAAC,GAAU,OAAO,GAAW,SAAiB,EAAE,CAC7C,OACD,CACN,MAAO,EAAE,GAIP,EAAY,GAA+B,CAC3C,YAAO,OAAW,KACtB,IAAI,OAAO,KAAK,EAAK,CAAC,SAAW,EAAG,CAClC,OAAO,aAAa,WAAW,EAAY,CAC3C,OAEF,OAAO,aAAa,QAAQ,EAAa,KAAK,UAAU,EAAK,CAAC,GAGnD,EACX,GACgC,GAAS,CAAC,IAAmB,KAElD,GACX,EACA,IACS,CACT,IAAM,EAAM,GAAS,CACrB,EAAI,GAAkB,EACtB,EAAS,EAAI,EAGF,EACX,GACS,CACT,IAAM,EAAM,GAAS,CACf,KAAkB,IACxB,OAAO,EAAI,GACX,EAAS,EAAI"}
|
|
@@ -12,6 +12,14 @@ export interface ConversationMetadata {
|
|
|
12
12
|
* git baseline to compare against.
|
|
13
13
|
*/
|
|
14
14
|
selected_workspace?: string | null;
|
|
15
|
+
/**
|
|
16
|
+
* The LLM profile the conversation was created with (or last switched to).
|
|
17
|
+
* Client-side only. Lets the chat-header switcher show the exact profile
|
|
18
|
+
* name even when several profiles share the same underlying model — the
|
|
19
|
+
* agent-server only round-trips the model string, so matching on it alone
|
|
20
|
+
* is ambiguous (issue #1082).
|
|
21
|
+
*/
|
|
22
|
+
active_profile?: string | null;
|
|
15
23
|
}
|
|
16
24
|
export declare const getStoredConversationMetadata: (conversationId: string) => ConversationMetadata | null;
|
|
17
25
|
export declare const setStoredConversationMetadata: (conversationId: string, metadata: ConversationMetadata) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-metadata-store.js","names":[],"sources":["../../src/api/conversation-metadata-store.ts"],"sourcesContent":["import { Provider } from \"#/types/settings\";\n\nconst STORAGE_KEY = \"openhands-agent-server-conversation-metadata\";\n\nexport interface ConversationMetadata {\n selected_repository: string | null;\n selected_branch: string | null;\n git_provider: Provider | null;\n /**\n * The local workspace path the user explicitly attached at conversation\n * creation time. Distinct from `selected_repository` (which is set by\n * the repo picker on the home page). Used by the Files tab to decide\n * whether to default to diff view: if the user attached *anything*\n * (repo or local workspace), we lean diff-first because there's a real\n * git baseline to compare against.\n */\n selected_workspace?: string | null;\n}\n\ntype StoredMetadata = Record<string, ConversationMetadata>;\n\nconst readAll = (): StoredMetadata => {\n if (typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) return {};\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\") return {};\n return parsed as StoredMetadata;\n } catch {\n return {};\n }\n};\n\nconst writeAll = (next: StoredMetadata): void => {\n if (typeof window === \"undefined\") return;\n if (Object.keys(next).length === 0) {\n window.localStorage.removeItem(STORAGE_KEY);\n return;\n }\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(next));\n};\n\nexport const getStoredConversationMetadata = (\n conversationId: string,\n): ConversationMetadata | null => readAll()[conversationId] ?? null;\n\nexport const setStoredConversationMetadata = (\n conversationId: string,\n metadata: ConversationMetadata,\n): void => {\n const all = readAll();\n all[conversationId] = metadata;\n writeAll(all);\n};\n\nexport const removeStoredConversationMetadata = (\n conversationId: string,\n): void => {\n const all = readAll();\n if (!(conversationId in all)) return;\n delete all[conversationId];\n writeAll(all);\n};\n"],"mappings":";AAEA,IAAM,IAAc,
|
|
1
|
+
{"version":3,"file":"conversation-metadata-store.js","names":[],"sources":["../../src/api/conversation-metadata-store.ts"],"sourcesContent":["import { Provider } from \"#/types/settings\";\n\nconst STORAGE_KEY = \"openhands-agent-server-conversation-metadata\";\n\nexport interface ConversationMetadata {\n selected_repository: string | null;\n selected_branch: string | null;\n git_provider: Provider | null;\n /**\n * The local workspace path the user explicitly attached at conversation\n * creation time. Distinct from `selected_repository` (which is set by\n * the repo picker on the home page). Used by the Files tab to decide\n * whether to default to diff view: if the user attached *anything*\n * (repo or local workspace), we lean diff-first because there's a real\n * git baseline to compare against.\n */\n selected_workspace?: string | null;\n /**\n * The LLM profile the conversation was created with (or last switched to).\n * Client-side only. Lets the chat-header switcher show the exact profile\n * name even when several profiles share the same underlying model — the\n * agent-server only round-trips the model string, so matching on it alone\n * is ambiguous (issue #1082).\n */\n active_profile?: string | null;\n}\n\ntype StoredMetadata = Record<string, ConversationMetadata>;\n\nconst readAll = (): StoredMetadata => {\n if (typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) return {};\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\") return {};\n return parsed as StoredMetadata;\n } catch {\n return {};\n }\n};\n\nconst writeAll = (next: StoredMetadata): void => {\n if (typeof window === \"undefined\") return;\n if (Object.keys(next).length === 0) {\n window.localStorage.removeItem(STORAGE_KEY);\n return;\n }\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(next));\n};\n\nexport const getStoredConversationMetadata = (\n conversationId: string,\n): ConversationMetadata | null => readAll()[conversationId] ?? null;\n\nexport const setStoredConversationMetadata = (\n conversationId: string,\n metadata: ConversationMetadata,\n): void => {\n const all = readAll();\n all[conversationId] = metadata;\n writeAll(all);\n};\n\nexport const removeStoredConversationMetadata = (\n conversationId: string,\n): void => {\n const all = readAll();\n if (!(conversationId in all)) return;\n delete all[conversationId];\n writeAll(all);\n};\n"],"mappings":";AAEA,IAAM,IAAc,gDA2Bd,UAAgC;AACpC,KAAI,OAAO,SAAW,IAAa,QAAO,EAAE;AAC5C,KAAI;EACF,IAAM,IAAM,OAAO,aAAa,QAAQ,EAAY;AACpD,MAAI,CAAC,EAAK,QAAO,EAAE;EACnB,IAAM,IAAS,KAAK,MAAM,EAAI;AAE9B,SADI,CAAC,KAAU,OAAO,KAAW,WAAiB,EAAE,GAC7C;SACD;AACN,SAAO,EAAE;;GAIP,KAAY,MAA+B;AAC3C,cAAO,SAAW,MACtB;MAAI,OAAO,KAAK,EAAK,CAAC,WAAW,GAAG;AAClC,UAAO,aAAa,WAAW,EAAY;AAC3C;;AAEF,SAAO,aAAa,QAAQ,GAAa,KAAK,UAAU,EAAK,CAAC;;GAGnD,KACX,MACgC,GAAS,CAAC,MAAmB,MAElD,KACX,GACA,MACS;CACT,IAAM,IAAM,GAAS;AAErB,CADA,EAAI,KAAkB,GACtB,EAAS,EAAI;GAGF,KACX,MACS;CACT,IAAM,IAAM,GAAS;AACf,MAAkB,MACxB,OAAO,EAAI,IACX,EAAS,EAAI"}
|
|
@@ -132,6 +132,15 @@ export interface AppConversation {
|
|
|
132
132
|
* the runtime actually operates in).
|
|
133
133
|
*/
|
|
134
134
|
selected_workspace?: string | null;
|
|
135
|
+
/**
|
|
136
|
+
* The LLM profile this conversation was created with / last switched to.
|
|
137
|
+
* Hydrated from client-side metadata (see
|
|
138
|
+
* `ConversationMetadata.active_profile`). Preferred over matching
|
|
139
|
+
* `llm_model` against the profile list, which is ambiguous when several
|
|
140
|
+
* profiles share a model (#1082). Null when unknown (e.g. created by an
|
|
141
|
+
* older client) — consumers fall back to model-matching.
|
|
142
|
+
*/
|
|
143
|
+
active_profile?: string | null;
|
|
135
144
|
public?: boolean;
|
|
136
145
|
sub_conversation_ids: string[];
|
|
137
146
|
}
|
|
@@ -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(`../../../utils/utils.cjs`),i=require(`../../../hooks/use-conversation-id.cjs`),a=require(`../../../stores/model-store.cjs`),o=require(`../../../hooks/query/use-active-conversation.cjs`),s=require(`../../../utils/form-control-classes.cjs`),c=require(`../../../hooks/query/use-settings.cjs`),l=require(`../../../hooks/query/use-llm-profiles.cjs`),u=require(`../../../ui/combobox-caret.cjs`),d=require(`../../../hooks/mutation/use-switch-llm-profile-and-log.cjs`),f=require(`./switch-profile-context-menu.cjs`);let p=require(`react`);p=e.__toESM(p,1);let m=require(`react/jsx-runtime`);function h(){let{t:e}=t.useTranslation(`openhands`),[h,g]=p.default.useState(!1),{conversationId:_}=i.useOptionalConversationId(),{data:v}=l.useLlmProfiles(),{data:y}=o.useActiveConversation(),{data:b}=c.useSettings(),{switchAndLog:x,isPending:S}=d.useSwitchLlmProfileAndLog(),C=a.useModelStore(e=>_?e.activeProfileByConversation[_]:void 0),w=v?.profiles??[],T=y?.llm_model??null,E=y?.agent_kind===`acp`||!y&&b?.agent_settings?.agent_kind===`acp`,D=C??(T?w.find(e=>e.model===T)?.name??null:v?.active_profile??null),
|
|
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(`../../../utils/utils.cjs`),i=require(`../../../hooks/use-conversation-id.cjs`),a=require(`../../../stores/model-store.cjs`),o=require(`../../../hooks/query/use-active-conversation.cjs`),s=require(`../../../utils/form-control-classes.cjs`),c=require(`../../../hooks/query/use-settings.cjs`),l=require(`../../../hooks/query/use-llm-profiles.cjs`),u=require(`../../../ui/combobox-caret.cjs`),d=require(`../../../hooks/mutation/use-switch-llm-profile-and-log.cjs`),f=require(`./switch-profile-context-menu.cjs`);let p=require(`react`);p=e.__toESM(p,1);let m=require(`react/jsx-runtime`);function h(){let{t:e}=t.useTranslation(`openhands`),[h,g]=p.default.useState(!1),{conversationId:_}=i.useOptionalConversationId(),{data:v}=l.useLlmProfiles(),{data:y}=o.useActiveConversation(),{data:b}=c.useSettings(),{switchAndLog:x,isPending:S}=d.useSwitchLlmProfileAndLog(),C=a.useModelStore(e=>_?e.activeProfileByConversation[_]:void 0),w=v?.profiles??[],T=y?.llm_model??null,E=y?.agent_kind===`acp`||!y&&b?.agent_settings?.agent_kind===`acp`,D=y?.active_profile??null,O=D&&w.some(e=>e.name===D)?D:null,k=C??O??(T?w.find(e=>e.model===T)?.name??null:v?.active_profile??null),A=w.find(e=>e.name===k)?.model??T??null;return w.length===0||E?null:(0,m.jsxs)(`div`,{className:`relative`,children:[(0,m.jsxs)(`button`,{type:`button`,onClick:e=>{e.preventDefault(),e.stopPropagation(),g(e=>!e)},disabled:S,"data-testid":`switch-profile-button`,title:A??void 0,"aria-haspopup":`menu`,"aria-expanded":h,className:r.cn(s.chatInputPillButtonClassName,`max-w-[200px]`,`disabled:opacity-50 disabled:cursor-not-allowed`),children:[(0,m.jsx)(`span`,{className:`truncate`,children:k??e(n.I18nKey.LLM$SELECT_MODEL_PLACEHOLDER)}),(0,m.jsx)(u.ComboboxCaretInline,{isOpen:h})]}),h&&(0,m.jsx)(f.SwitchProfileContextMenu,{profiles:w,activeProfileName:k,onSelect:e=>{e!==k&&x(_,e)},onClose:()=>g(!1)})]})}exports.SwitchProfileButton=h;
|
|
2
2
|
//# sourceMappingURL=switch-profile-button.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch-profile-button.cjs","names":[],"sources":["../../../../src/components/features/chat/switch-profile-button.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\nimport { useSwitchLlmProfileAndLog } from \"#/hooks/mutation/use-switch-llm-profile-and-log\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\nimport { SwitchProfileContextMenu } from \"./switch-profile-context-menu\";\n\nexport function SwitchProfileButton() {\n const { t } = useTranslation(\"openhands\");\n const [contextMenuOpen, setContextMenuOpen] = React.useState(false);\n // Null on the home page; `useSwitchLlmProfileAndLog` is fine with that\n // because /api/profiles/<name>/activate is a global endpoint.\n const { conversationId } = useOptionalConversationId();\n const { data } = useLlmProfiles();\n const { data: conversation } = useActiveConversation();\n const { data: settings } = useSettings();\n const { switchAndLog, isPending } = useSwitchLlmProfileAndLog();\n // Optimistic value written by recordSwitch on a successful switch — gives\n // instant in-conversation feedback before the conversation refetch lands\n // with the new `llm_model`.\n const optimisticActiveProfile = useModelStore((s) =>\n conversationId ? s.activeProfileByConversation[conversationId] : undefined,\n );\n\n const profiles = data?.profiles ?? [];\n const conversationModel = conversation?.llm_model ?? null;\n // ACPAgent conversations route prompts to a CLI subprocess whose model is\n // controlled by ``acp_model`` (set in Settings → Agent), not by the LLM\n // profile picker. Surfacing the switcher here would let the user \"change\n // the model\" while the running subprocess silently keeps its own — a\n // confusing no-op. Hide the button even when ``llm_model`` carries an ACP\n // display model for chips/headers.\n //\n // On the home screen ``conversation`` is undefined; fall back to\n // ``settings.agent_settings.agent_kind`` so the picker also hides when\n // ACP is the *default* the next-created conversation would inherit.\n // Otherwise an ACP user lands on a home page with an LLM-switch\n // control that contradicts the ACP nav gating everywhere else.\n const isAcpActive =\n conversation?.agent_kind === \"acp\" ||\n (!conversation && settings?.agent_settings?.agent_kind === \"acp\");\n\n // Resolution priority for the active profile name:\n // 1. Optimistic (just-clicked) — instant feedback before the refetch.\n // 2. Profile whose model matches the running llm_model —
|
|
1
|
+
{"version":3,"file":"switch-profile-button.cjs","names":[],"sources":["../../../../src/components/features/chat/switch-profile-button.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\nimport { useSwitchLlmProfileAndLog } from \"#/hooks/mutation/use-switch-llm-profile-and-log\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\nimport { SwitchProfileContextMenu } from \"./switch-profile-context-menu\";\n\nexport function SwitchProfileButton() {\n const { t } = useTranslation(\"openhands\");\n const [contextMenuOpen, setContextMenuOpen] = React.useState(false);\n // Null on the home page; `useSwitchLlmProfileAndLog` is fine with that\n // because /api/profiles/<name>/activate is a global endpoint.\n const { conversationId } = useOptionalConversationId();\n const { data } = useLlmProfiles();\n const { data: conversation } = useActiveConversation();\n const { data: settings } = useSettings();\n const { switchAndLog, isPending } = useSwitchLlmProfileAndLog();\n // Optimistic value written by recordSwitch on a successful switch — gives\n // instant in-conversation feedback before the conversation refetch lands\n // with the new `llm_model`.\n const optimisticActiveProfile = useModelStore((s) =>\n conversationId ? s.activeProfileByConversation[conversationId] : undefined,\n );\n\n const profiles = data?.profiles ?? [];\n const conversationModel = conversation?.llm_model ?? null;\n // ACPAgent conversations route prompts to a CLI subprocess whose model is\n // controlled by ``acp_model`` (set in Settings → Agent), not by the LLM\n // profile picker. Surfacing the switcher here would let the user \"change\n // the model\" while the running subprocess silently keeps its own — a\n // confusing no-op. Hide the button even when ``llm_model`` carries an ACP\n // display model for chips/headers.\n //\n // On the home screen ``conversation`` is undefined; fall back to\n // ``settings.agent_settings.agent_kind`` so the picker also hides when\n // ACP is the *default* the next-created conversation would inherit.\n // Otherwise an ACP user lands on a home page with an LLM-switch\n // control that contradicts the ACP nav gating everywhere else.\n const isAcpActive =\n conversation?.agent_kind === \"acp\" ||\n (!conversation && settings?.agent_settings?.agent_kind === \"acp\");\n\n // Resolution priority for the active profile name:\n // 1. Optimistic (just-clicked) — instant feedback before the refetch.\n // 2. Profile stamped on the conversation at creation / last switch —\n // exact identity, survives reload, and is unambiguous when several\n // profiles share one underlying model (#1082). Validated against the\n // live list so a since-deleted/renamed profile falls through.\n // 3. Profile whose model matches the running llm_model — legacy fallback.\n // 4. User-level active_profile — home page / before the conversation has\n // sent any messages.\n const stampedProfile = conversation?.active_profile ?? null;\n const conversationProfile =\n stampedProfile && profiles.some((p) => p.name === stampedProfile)\n ? stampedProfile\n : null;\n const activeProfileName =\n optimisticActiveProfile ??\n conversationProfile ??\n (conversationModel\n ? (profiles.find((p) => p.model === conversationModel)?.name ?? null)\n : (data?.active_profile ?? null));\n const activeProfileModel =\n profiles.find((p) => p.name === activeProfileName)?.model ??\n conversationModel ??\n null;\n\n if (profiles.length === 0 || isAcpActive) {\n return null;\n }\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n setContextMenuOpen((open) => !open);\n };\n\n const handleSelect = (profileName: string) => {\n if (profileName === activeProfileName) return;\n switchAndLog(conversationId, profileName);\n };\n\n return (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isPending}\n data-testid=\"switch-profile-button\"\n title={activeProfileModel ?? undefined}\n aria-haspopup=\"menu\"\n aria-expanded={contextMenuOpen}\n className={cn(\n chatInputPillButtonClassName,\n \"max-w-[200px]\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n )}\n >\n <span className=\"truncate\">\n {activeProfileName ?? t(I18nKey.LLM$SELECT_MODEL_PLACEHOLDER)}\n </span>\n <ComboboxCaretInline isOpen={contextMenuOpen} />\n </button>\n {contextMenuOpen && (\n <SwitchProfileContextMenu\n profiles={profiles}\n activeProfileName={activeProfileName}\n onSelect={handleSelect}\n onClose={() => setContextMenuOpen(false)}\n />\n )}\n </div>\n );\n}\n"],"mappings":"owBAcA,SAAgB,GAAsB,CACpC,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,CAAC,EAAiB,GAAsB,EAAA,QAAM,SAAS,GAAM,CAG7D,CAAE,kBAAmB,EAAA,2BAA2B,CAChD,CAAE,QAAS,EAAA,gBAAgB,CAC3B,CAAE,KAAM,GAAiB,EAAA,uBAAuB,CAChD,CAAE,KAAM,GAAa,EAAA,aAAa,CAClC,CAAE,eAAc,aAAc,EAAA,2BAA2B,CAIzD,EAA0B,EAAA,cAAe,GAC7C,EAAiB,EAAE,4BAA4B,GAAkB,IAAA,GAClE,CAEK,EAAW,GAAM,UAAY,EAAE,CAC/B,EAAoB,GAAc,WAAa,KAa/C,EACJ,GAAc,aAAe,OAC5B,CAAC,GAAgB,GAAU,gBAAgB,aAAe,MAWvD,EAAiB,GAAc,gBAAkB,KACjD,EACJ,GAAkB,EAAS,KAAM,GAAM,EAAE,OAAS,EAAe,CAC7D,EACA,KACA,EACJ,GACA,IACC,EACI,EAAS,KAAM,GAAM,EAAE,QAAU,EAAkB,EAAE,MAAQ,KAC7D,GAAM,gBAAkB,MACzB,EACJ,EAAS,KAAM,GAAM,EAAE,OAAS,EAAkB,EAAE,OACpD,GACA,KAiBF,OAfI,EAAS,SAAW,GAAK,EACpB,MAeP,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oBAAf,EACE,EAAA,EAAA,MAAC,SAAD,CACE,KAAK,SACL,QAfe,GAA+C,CAClE,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,CACvB,EAAoB,GAAS,CAAC,EAAK,EAa/B,SAAU,EACV,cAAY,wBACZ,MAAO,GAAsB,IAAA,GAC7B,gBAAc,OACd,gBAAe,EACf,UAAW,EAAA,GACT,EAAA,6BACA,gBACA,kDACD,UAZH,EAcE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oBACb,GAAqB,EAAE,EAAA,QAAQ,6BAA6B,CACxD,CAAA,EACP,EAAA,EAAA,KAAC,EAAA,oBAAD,CAAqB,OAAQ,EAAmB,CAAA,CACzC,GACR,IACC,EAAA,EAAA,KAAC,EAAA,yBAAD,CACY,WACS,oBACnB,SA9Bc,GAAwB,CACxC,IAAgB,GACpB,EAAa,EAAgB,EAAY,EA6BnC,YAAe,EAAmB,GAAM,CACxC,CAAA,CAEA"}
|
|
@@ -14,7 +14,7 @@ import f from "react";
|
|
|
14
14
|
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
15
15
|
//#region src/components/features/chat/switch-profile-button.tsx
|
|
16
16
|
function h() {
|
|
17
|
-
let { t: h } = e("openhands"), [g, _] = f.useState(!1), { conversationId: v } = r(), { data: y } = c(), { data: b } = a(), { data: x } = s(), { switchAndLog: S, isPending: C } = u(), w = i((e) => v ? e.activeProfileByConversation[v] : void 0), T = y?.profiles ?? [], E = b?.llm_model ?? null, D = b?.agent_kind === "acp" || !b && x?.agent_settings?.agent_kind === "acp", O = w ?? (E ? T.find((e) => e.model === E)?.name ?? null : y?.active_profile ?? null),
|
|
17
|
+
let { t: h } = e("openhands"), [g, _] = f.useState(!1), { conversationId: v } = r(), { data: y } = c(), { data: b } = a(), { data: x } = s(), { switchAndLog: S, isPending: C } = u(), w = i((e) => v ? e.activeProfileByConversation[v] : void 0), T = y?.profiles ?? [], E = b?.llm_model ?? null, D = b?.agent_kind === "acp" || !b && x?.agent_settings?.agent_kind === "acp", O = b?.active_profile ?? null, k = O && T.some((e) => e.name === O) ? O : null, A = w ?? k ?? (E ? T.find((e) => e.model === E)?.name ?? null : y?.active_profile ?? null), j = T.find((e) => e.name === A)?.model ?? E ?? null;
|
|
18
18
|
return T.length === 0 || D ? null : /* @__PURE__ */ m("div", {
|
|
19
19
|
className: "relative",
|
|
20
20
|
children: [/* @__PURE__ */ m("button", {
|
|
@@ -24,19 +24,19 @@ function h() {
|
|
|
24
24
|
},
|
|
25
25
|
disabled: C,
|
|
26
26
|
"data-testid": "switch-profile-button",
|
|
27
|
-
title:
|
|
27
|
+
title: j ?? void 0,
|
|
28
28
|
"aria-haspopup": "menu",
|
|
29
29
|
"aria-expanded": g,
|
|
30
30
|
className: n(o, "max-w-[200px]", "disabled:opacity-50 disabled:cursor-not-allowed"),
|
|
31
31
|
children: [/* @__PURE__ */ p("span", {
|
|
32
32
|
className: "truncate",
|
|
33
|
-
children:
|
|
33
|
+
children: A ?? h(t.LLM$SELECT_MODEL_PLACEHOLDER)
|
|
34
34
|
}), /* @__PURE__ */ p(l, { isOpen: g })]
|
|
35
35
|
}), g && /* @__PURE__ */ p(d, {
|
|
36
36
|
profiles: T,
|
|
37
|
-
activeProfileName:
|
|
37
|
+
activeProfileName: A,
|
|
38
38
|
onSelect: (e) => {
|
|
39
|
-
e !==
|
|
39
|
+
e !== A && S(v, e);
|
|
40
40
|
},
|
|
41
41
|
onClose: () => _(!1)
|
|
42
42
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch-profile-button.js","names":[],"sources":["../../../../src/components/features/chat/switch-profile-button.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\nimport { useSwitchLlmProfileAndLog } from \"#/hooks/mutation/use-switch-llm-profile-and-log\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\nimport { SwitchProfileContextMenu } from \"./switch-profile-context-menu\";\n\nexport function SwitchProfileButton() {\n const { t } = useTranslation(\"openhands\");\n const [contextMenuOpen, setContextMenuOpen] = React.useState(false);\n // Null on the home page; `useSwitchLlmProfileAndLog` is fine with that\n // because /api/profiles/<name>/activate is a global endpoint.\n const { conversationId } = useOptionalConversationId();\n const { data } = useLlmProfiles();\n const { data: conversation } = useActiveConversation();\n const { data: settings } = useSettings();\n const { switchAndLog, isPending } = useSwitchLlmProfileAndLog();\n // Optimistic value written by recordSwitch on a successful switch — gives\n // instant in-conversation feedback before the conversation refetch lands\n // with the new `llm_model`.\n const optimisticActiveProfile = useModelStore((s) =>\n conversationId ? s.activeProfileByConversation[conversationId] : undefined,\n );\n\n const profiles = data?.profiles ?? [];\n const conversationModel = conversation?.llm_model ?? null;\n // ACPAgent conversations route prompts to a CLI subprocess whose model is\n // controlled by ``acp_model`` (set in Settings → Agent), not by the LLM\n // profile picker. Surfacing the switcher here would let the user \"change\n // the model\" while the running subprocess silently keeps its own — a\n // confusing no-op. Hide the button even when ``llm_model`` carries an ACP\n // display model for chips/headers.\n //\n // On the home screen ``conversation`` is undefined; fall back to\n // ``settings.agent_settings.agent_kind`` so the picker also hides when\n // ACP is the *default* the next-created conversation would inherit.\n // Otherwise an ACP user lands on a home page with an LLM-switch\n // control that contradicts the ACP nav gating everywhere else.\n const isAcpActive =\n conversation?.agent_kind === \"acp\" ||\n (!conversation && settings?.agent_settings?.agent_kind === \"acp\");\n\n // Resolution priority for the active profile name:\n // 1. Optimistic (just-clicked) — instant feedback before the refetch.\n // 2. Profile whose model matches the running llm_model —
|
|
1
|
+
{"version":3,"file":"switch-profile-button.js","names":[],"sources":["../../../../src/components/features/chat/switch-profile-button.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\nimport { useSwitchLlmProfileAndLog } from \"#/hooks/mutation/use-switch-llm-profile-and-log\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\nimport { SwitchProfileContextMenu } from \"./switch-profile-context-menu\";\n\nexport function SwitchProfileButton() {\n const { t } = useTranslation(\"openhands\");\n const [contextMenuOpen, setContextMenuOpen] = React.useState(false);\n // Null on the home page; `useSwitchLlmProfileAndLog` is fine with that\n // because /api/profiles/<name>/activate is a global endpoint.\n const { conversationId } = useOptionalConversationId();\n const { data } = useLlmProfiles();\n const { data: conversation } = useActiveConversation();\n const { data: settings } = useSettings();\n const { switchAndLog, isPending } = useSwitchLlmProfileAndLog();\n // Optimistic value written by recordSwitch on a successful switch — gives\n // instant in-conversation feedback before the conversation refetch lands\n // with the new `llm_model`.\n const optimisticActiveProfile = useModelStore((s) =>\n conversationId ? s.activeProfileByConversation[conversationId] : undefined,\n );\n\n const profiles = data?.profiles ?? [];\n const conversationModel = conversation?.llm_model ?? null;\n // ACPAgent conversations route prompts to a CLI subprocess whose model is\n // controlled by ``acp_model`` (set in Settings → Agent), not by the LLM\n // profile picker. Surfacing the switcher here would let the user \"change\n // the model\" while the running subprocess silently keeps its own — a\n // confusing no-op. Hide the button even when ``llm_model`` carries an ACP\n // display model for chips/headers.\n //\n // On the home screen ``conversation`` is undefined; fall back to\n // ``settings.agent_settings.agent_kind`` so the picker also hides when\n // ACP is the *default* the next-created conversation would inherit.\n // Otherwise an ACP user lands on a home page with an LLM-switch\n // control that contradicts the ACP nav gating everywhere else.\n const isAcpActive =\n conversation?.agent_kind === \"acp\" ||\n (!conversation && settings?.agent_settings?.agent_kind === \"acp\");\n\n // Resolution priority for the active profile name:\n // 1. Optimistic (just-clicked) — instant feedback before the refetch.\n // 2. Profile stamped on the conversation at creation / last switch —\n // exact identity, survives reload, and is unambiguous when several\n // profiles share one underlying model (#1082). Validated against the\n // live list so a since-deleted/renamed profile falls through.\n // 3. Profile whose model matches the running llm_model — legacy fallback.\n // 4. User-level active_profile — home page / before the conversation has\n // sent any messages.\n const stampedProfile = conversation?.active_profile ?? null;\n const conversationProfile =\n stampedProfile && profiles.some((p) => p.name === stampedProfile)\n ? stampedProfile\n : null;\n const activeProfileName =\n optimisticActiveProfile ??\n conversationProfile ??\n (conversationModel\n ? (profiles.find((p) => p.model === conversationModel)?.name ?? null)\n : (data?.active_profile ?? null));\n const activeProfileModel =\n profiles.find((p) => p.name === activeProfileName)?.model ??\n conversationModel ??\n null;\n\n if (profiles.length === 0 || isAcpActive) {\n return null;\n }\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n setContextMenuOpen((open) => !open);\n };\n\n const handleSelect = (profileName: string) => {\n if (profileName === activeProfileName) return;\n switchAndLog(conversationId, profileName);\n };\n\n return (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isPending}\n data-testid=\"switch-profile-button\"\n title={activeProfileModel ?? undefined}\n aria-haspopup=\"menu\"\n aria-expanded={contextMenuOpen}\n className={cn(\n chatInputPillButtonClassName,\n \"max-w-[200px]\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n )}\n >\n <span className=\"truncate\">\n {activeProfileName ?? t(I18nKey.LLM$SELECT_MODEL_PLACEHOLDER)}\n </span>\n <ComboboxCaretInline isOpen={contextMenuOpen} />\n </button>\n {contextMenuOpen && (\n <SwitchProfileContextMenu\n profiles={profiles}\n activeProfileName={activeProfileName}\n onSelect={handleSelect}\n onClose={() => setContextMenuOpen(false)}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAcA,SAAgB,IAAsB;CACpC,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,CAAC,GAAiB,KAAsB,EAAM,SAAS,GAAM,EAG7D,EAAE,sBAAmB,GAA2B,EAChD,EAAE,YAAS,GAAgB,EAC3B,EAAE,MAAM,MAAiB,GAAuB,EAChD,EAAE,MAAM,MAAa,GAAa,EAClC,EAAE,iBAAc,iBAAc,GAA2B,EAIzD,IAA0B,GAAe,MAC7C,IAAiB,EAAE,4BAA4B,KAAkB,KAAA,EAClE,EAEK,IAAW,GAAM,YAAY,EAAE,EAC/B,IAAoB,GAAc,aAAa,MAa/C,IACJ,GAAc,eAAe,SAC5B,CAAC,KAAgB,GAAU,gBAAgB,eAAe,OAWvD,IAAiB,GAAc,kBAAkB,MACjD,IACJ,KAAkB,EAAS,MAAM,MAAM,EAAE,SAAS,EAAe,GAC7D,IACA,MACA,IACJ,KACA,MACC,IACI,EAAS,MAAM,MAAM,EAAE,UAAU,EAAkB,EAAE,QAAQ,OAC7D,GAAM,kBAAkB,OACzB,IACJ,EAAS,MAAM,MAAM,EAAE,SAAS,EAAkB,EAAE,SACpD,KACA;AAiBF,QAfI,EAAS,WAAW,KAAK,IACpB,OAeP,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,UAAD;GACE,MAAK;GACL,UAfe,MAA+C;AAGlE,IAFA,EAAM,gBAAgB,EACtB,EAAM,iBAAiB,EACvB,GAAoB,MAAS,CAAC,EAAK;;GAa/B,UAAU;GACV,eAAY;GACZ,OAAO,KAAsB,KAAA;GAC7B,iBAAc;GACd,iBAAe;GACf,WAAW,EACT,GACA,iBACA,kDACD;aAZH,CAcE,kBAAC,QAAD;IAAM,WAAU;cACb,KAAqB,EAAE,EAAQ,6BAA6B;IACxD,CAAA,EACP,kBAAC,GAAD,EAAqB,QAAQ,GAAmB,CAAA,CACzC;MACR,KACC,kBAAC,GAAD;GACY;GACS;GACnB,WA9Bc,MAAwB;AACxC,UAAgB,KACpB,EAAa,GAAgB,EAAY;;GA6BnC,eAAe,EAAmB,GAAM;GACxC,CAAA,CAEA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../../../
|
|
1
|
+
require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../../../api/agent-server-config.cjs`),r=require(`../../../hooks/query/use-conversation-skills.cjs`),i=require(`../../shared/modals/modal-backdrop.cjs`),a=require(`../../shared/modals/modal-body.cjs`),o=require(`../../../utils/skill-scope.cjs`),s=require(`./skills-modal-header.cjs`),c=require(`./skills-modal-section.cjs`),l=require(`./skills-loading-state.cjs`),u=require(`./skills-empty-state.cjs`),d=require(`./skill-item.cjs`);let f=require(`react`),p=require(`react/jsx-runtime`);var m={project:t.I18nKey.SKILLS_MODAL$SECTION_PROJECT,personal:t.I18nKey.SKILLS_MODAL$SECTION_USER,public:t.I18nKey.SKILLS_MODAL$SECTION_PUBLIC};function h({onClose:t}){let{t:h}=e.useTranslation(`openhands`),g=n.getAgentServerWorkingDir(),[_,v]=(0,f.useState)({}),{data:y,isLoading:b,isError:x,refetch:S,isRefetching:C}=r.useConversationSkills(),w=(0,f.useMemo)(()=>y?o.groupSkillsByScope(y,g):null,[y,g]),T=e=>{v(t=>({...t,[e]:!t[e]}))};return(0,p.jsx)(i.ModalBackdrop,{onClose:t,children:(0,p.jsxs)(a.ModalBody,{width:`lg`,className:`relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]`,testID:`skills-modal`,children:[(0,p.jsx)(s.SkillsModalHeader,{isLoading:b,isRefetching:C,onRefresh:S,onClose:t}),(0,p.jsx)(`div`,{className:`w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always`,children:b?(0,p.jsx)(l.SkillsLoadingState,{}):x||!y||y.length===0?(0,p.jsx)(u.SkillsEmptyState,{isError:x}):w&&(0,p.jsx)(`div`,{className:`divide-y divide-[var(--oh-border)]`,children:o.SKILL_SCOPE_ORDER.map(e=>{let t=w[e];return t.length===0?null:(0,p.jsx)(c.SkillsModalSection,{title:h(m[e]),count:t.length,children:t.map(t=>(0,p.jsx)(d.SkillItem,{skill:t,isExpanded:_[t.name]||!1,onToggle:T},`${e}-${t.name}`))},e)})})})]})})}exports.SkillsModal=h;
|
|
2
2
|
//# sourceMappingURL=skills-modal.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills-modal.cjs","names":[],"sources":["../../../../src/components/features/conversation-panel/skills-modal.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getAgentServerWorkingDir } from \"#/api/agent-server-config\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport {
|
|
1
|
+
{"version":3,"file":"skills-modal.cjs","names":[],"sources":["../../../../src/components/features/conversation-panel/skills-modal.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getAgentServerWorkingDir } from \"#/api/agent-server-config\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport {\n groupSkillsByScope,\n SKILL_SCOPE_ORDER,\n type SkillScope,\n} from \"#/utils/skill-scope\";\nimport { SkillsModalHeader } from \"./skills-modal-header\";\nimport { SkillsModalSection } from \"./skills-modal-section\";\nimport { SkillsLoadingState } from \"./skills-loading-state\";\nimport { SkillsEmptyState } from \"./skills-empty-state\";\nimport { SkillItem } from \"./skill-item\";\n\ninterface SkillsModalProps {\n onClose: () => void;\n}\n\nconst SECTION_TITLE_KEY: Record<SkillScope, I18nKey> = {\n project: I18nKey.SKILLS_MODAL$SECTION_PROJECT,\n personal: I18nKey.SKILLS_MODAL$SECTION_USER,\n public: I18nKey.SKILLS_MODAL$SECTION_PUBLIC,\n};\n\nexport function SkillsModal({ onClose }: SkillsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const projectDir = getAgentServerWorkingDir();\n const [expandedAgents, setExpandedAgents] = useState<Record<string, boolean>>(\n {},\n );\n // Scope the catalog to this conversation's attached workspace so the listed\n // skills match the project skills actually loaded into the conversation.\n const {\n data: skills,\n isLoading,\n isError,\n refetch,\n isRefetching,\n } = useConversationSkills();\n\n const groupedSkills = useMemo(\n () => (skills ? groupSkillsByScope(skills, projectDir) : null),\n [skills, projectDir],\n );\n\n const toggleAgent = (agentName: string) => {\n setExpandedAgents((prev) => ({\n ...prev,\n [agentName]: !prev[agentName],\n }));\n };\n\n return (\n <ModalBackdrop onClose={onClose}>\n <ModalBody\n width=\"lg\"\n className=\"relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]\"\n testID=\"skills-modal\"\n >\n <SkillsModalHeader\n isLoading={isLoading}\n isRefetching={isRefetching}\n onRefresh={refetch}\n onClose={onClose}\n />\n\n <div className=\"w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\">\n {isLoading ? (\n <SkillsLoadingState />\n ) : isError || !skills || skills.length === 0 ? (\n <SkillsEmptyState isError={isError} />\n ) : (\n groupedSkills && (\n <div className=\"divide-y divide-[var(--oh-border)]\">\n {SKILL_SCOPE_ORDER.map((scope) => {\n const scopedSkills = groupedSkills[scope];\n if (scopedSkills.length === 0) {\n return null;\n }\n\n return (\n <SkillsModalSection\n key={scope}\n title={t(SECTION_TITLE_KEY[scope])}\n count={scopedSkills.length}\n >\n {scopedSkills.map((skill) => {\n const isExpanded = expandedAgents[skill.name] || false;\n\n return (\n <SkillItem\n key={`${scope}-${skill.name}`}\n skill={skill}\n isExpanded={isExpanded}\n onToggle={toggleAgent}\n />\n );\n })}\n </SkillsModalSection>\n );\n })}\n </div>\n )\n )}\n </div>\n </ModalBody>\n </ModalBackdrop>\n );\n}\n"],"mappings":"iqBAsBA,IAAM,EAAiD,CACrD,QAAS,EAAA,QAAQ,6BACjB,SAAU,EAAA,QAAQ,0BAClB,OAAQ,EAAA,QAAQ,4BACjB,CAED,SAAgB,EAAY,CAAE,WAA6B,CACzD,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,EAAa,EAAA,0BAA0B,CACvC,CAAC,EAAgB,IAAA,EAAA,EAAA,UACrB,EAAE,CACH,CAGK,CACJ,KAAM,EACN,YACA,UACA,UACA,gBACE,EAAA,uBAAuB,CAErB,GAAA,EAAA,EAAA,aACG,EAAS,EAAA,mBAAmB,EAAQ,EAAW,CAAG,KACzD,CAAC,EAAQ,EAAW,CACrB,CAEK,EAAe,GAAsB,CACzC,EAAmB,IAAU,CAC3B,GAAG,GACF,GAAY,CAAC,EAAK,GACpB,EAAE,EAGL,OACE,EAAA,EAAA,KAAC,EAAA,cAAD,CAAwB,oBACtB,EAAA,EAAA,MAAC,EAAA,UAAD,CACE,MAAM,KACN,UAAU,mFACV,OAAO,wBAHT,EAKE,EAAA,EAAA,KAAC,EAAA,kBAAD,CACa,YACG,eACd,UAAW,EACF,UACT,CAAA,EAEF,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+HACZ,GACC,EAAA,EAAA,KAAC,EAAA,mBAAD,EAAsB,CAAA,CACpB,GAAW,CAAC,GAAU,EAAO,SAAW,GAC1C,EAAA,EAAA,KAAC,EAAA,iBAAD,CAA2B,UAAW,CAAA,CAEtC,IACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,8CACZ,EAAA,kBAAkB,IAAK,GAAU,CAChC,IAAM,EAAe,EAAc,GAKnC,OAJI,EAAa,SAAW,EACnB,MAIP,EAAA,EAAA,KAAC,EAAA,mBAAD,CAEE,MAAO,EAAE,EAAkB,GAAO,CAClC,MAAO,EAAa,gBAEnB,EAAa,IAAK,IAIf,EAAA,EAAA,KAAC,EAAA,UAAD,CAES,QACK,WANG,EAAe,EAAM,OAAS,GAO7C,SAAU,EACV,CAJK,GAAG,EAAM,GAAG,EAAM,OAIvB,CAEJ,CACiB,CAhBd,EAgBc,EAEvB,CACE,CAAA,CAGN,CAAA,CACI,GACE,CAAA"}
|
|
@@ -1,66 +1,63 @@
|
|
|
1
1
|
import { useTranslation as e } from "../../../node_modules/react-i18next/dist/es/useTranslation.js";
|
|
2
2
|
import { I18nKey as t } from "../../../i18n/declaration.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import { SkillItem as h } from "./skill-item.js";
|
|
16
|
-
import { useMemo as g, useState as _ } from "react";
|
|
17
|
-
import { jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
3
|
+
import { getAgentServerWorkingDir as n } from "../../../api/agent-server-config.js";
|
|
4
|
+
import { useConversationSkills as r } from "../../../hooks/query/use-conversation-skills.js";
|
|
5
|
+
import { ModalBackdrop as i } from "../../shared/modals/modal-backdrop.js";
|
|
6
|
+
import { ModalBody as a } from "../../shared/modals/modal-body.js";
|
|
7
|
+
import { SKILL_SCOPE_ORDER as o, groupSkillsByScope as s } from "../../../utils/skill-scope.js";
|
|
8
|
+
import { SkillsModalHeader as c } from "./skills-modal-header.js";
|
|
9
|
+
import { SkillsModalSection as l } from "./skills-modal-section.js";
|
|
10
|
+
import { SkillsLoadingState as u } from "./skills-loading-state.js";
|
|
11
|
+
import { SkillsEmptyState as d } from "./skills-empty-state.js";
|
|
12
|
+
import { SkillItem as f } from "./skill-item.js";
|
|
13
|
+
import { useMemo as p, useState as m } from "react";
|
|
14
|
+
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
18
15
|
//#region src/components/features/conversation-panel/skills-modal.tsx
|
|
19
|
-
var
|
|
16
|
+
var _ = {
|
|
20
17
|
project: t.SKILLS_MODAL$SECTION_PROJECT,
|
|
21
18
|
personal: t.SKILLS_MODAL$SECTION_USER,
|
|
22
19
|
public: t.SKILLS_MODAL$SECTION_PUBLIC
|
|
23
20
|
};
|
|
24
|
-
function
|
|
25
|
-
let { t:
|
|
26
|
-
|
|
21
|
+
function v({ onClose: t }) {
|
|
22
|
+
let { t: v } = e("openhands"), y = n(), [b, x] = m({}), { data: S, isLoading: C, isError: w, refetch: T, isRefetching: E } = r(), D = p(() => S ? s(S, y) : null, [S, y]), O = (e) => {
|
|
23
|
+
x((t) => ({
|
|
27
24
|
...t,
|
|
28
25
|
[e]: !t[e]
|
|
29
26
|
}));
|
|
30
|
-
}
|
|
31
|
-
return /* @__PURE__ */
|
|
27
|
+
};
|
|
28
|
+
return /* @__PURE__ */ h(i, {
|
|
32
29
|
onClose: t,
|
|
33
|
-
children: /* @__PURE__ */
|
|
30
|
+
children: /* @__PURE__ */ g(a, {
|
|
34
31
|
width: "lg",
|
|
35
32
|
className: "relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]",
|
|
36
33
|
testID: "skills-modal",
|
|
37
|
-
children: [/* @__PURE__ */
|
|
38
|
-
isLoading:
|
|
39
|
-
isRefetching:
|
|
40
|
-
onRefresh:
|
|
34
|
+
children: [/* @__PURE__ */ h(c, {
|
|
35
|
+
isLoading: C,
|
|
36
|
+
isRefetching: E,
|
|
37
|
+
onRefresh: T,
|
|
41
38
|
onClose: t
|
|
42
|
-
}), /* @__PURE__ */
|
|
39
|
+
}), /* @__PURE__ */ h("div", {
|
|
43
40
|
className: "w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always",
|
|
44
|
-
children:
|
|
41
|
+
children: C ? /* @__PURE__ */ h(u, {}) : w || !S || S.length === 0 ? /* @__PURE__ */ h(d, { isError: w }) : D && /* @__PURE__ */ h("div", {
|
|
45
42
|
className: "divide-y divide-[var(--oh-border)]",
|
|
46
|
-
children:
|
|
47
|
-
let t =
|
|
48
|
-
return t.length === 0 ? null : /* @__PURE__ */
|
|
49
|
-
title:
|
|
43
|
+
children: o.map((e) => {
|
|
44
|
+
let t = D[e];
|
|
45
|
+
return t.length === 0 ? null : /* @__PURE__ */ h(l, {
|
|
46
|
+
title: v(_[e]),
|
|
50
47
|
count: t.length,
|
|
51
|
-
children: t.map((t) => /* @__PURE__ */
|
|
48
|
+
children: t.map((t) => /* @__PURE__ */ h(f, {
|
|
52
49
|
skill: t,
|
|
53
|
-
isExpanded:
|
|
54
|
-
onToggle:
|
|
50
|
+
isExpanded: b[t.name] || !1,
|
|
51
|
+
onToggle: O
|
|
55
52
|
}, `${e}-${t.name}`))
|
|
56
53
|
}, e);
|
|
57
54
|
})
|
|
58
|
-
})
|
|
55
|
+
})
|
|
59
56
|
})]
|
|
60
57
|
})
|
|
61
58
|
});
|
|
62
59
|
}
|
|
63
60
|
//#endregion
|
|
64
|
-
export {
|
|
61
|
+
export { v as SkillsModal };
|
|
65
62
|
|
|
66
63
|
//# sourceMappingURL=skills-modal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills-modal.js","names":[],"sources":["../../../../src/components/features/conversation-panel/skills-modal.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getAgentServerWorkingDir } from \"#/api/agent-server-config\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport {
|
|
1
|
+
{"version":3,"file":"skills-modal.js","names":[],"sources":["../../../../src/components/features/conversation-panel/skills-modal.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getAgentServerWorkingDir } from \"#/api/agent-server-config\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport {\n groupSkillsByScope,\n SKILL_SCOPE_ORDER,\n type SkillScope,\n} from \"#/utils/skill-scope\";\nimport { SkillsModalHeader } from \"./skills-modal-header\";\nimport { SkillsModalSection } from \"./skills-modal-section\";\nimport { SkillsLoadingState } from \"./skills-loading-state\";\nimport { SkillsEmptyState } from \"./skills-empty-state\";\nimport { SkillItem } from \"./skill-item\";\n\ninterface SkillsModalProps {\n onClose: () => void;\n}\n\nconst SECTION_TITLE_KEY: Record<SkillScope, I18nKey> = {\n project: I18nKey.SKILLS_MODAL$SECTION_PROJECT,\n personal: I18nKey.SKILLS_MODAL$SECTION_USER,\n public: I18nKey.SKILLS_MODAL$SECTION_PUBLIC,\n};\n\nexport function SkillsModal({ onClose }: SkillsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const projectDir = getAgentServerWorkingDir();\n const [expandedAgents, setExpandedAgents] = useState<Record<string, boolean>>(\n {},\n );\n // Scope the catalog to this conversation's attached workspace so the listed\n // skills match the project skills actually loaded into the conversation.\n const {\n data: skills,\n isLoading,\n isError,\n refetch,\n isRefetching,\n } = useConversationSkills();\n\n const groupedSkills = useMemo(\n () => (skills ? groupSkillsByScope(skills, projectDir) : null),\n [skills, projectDir],\n );\n\n const toggleAgent = (agentName: string) => {\n setExpandedAgents((prev) => ({\n ...prev,\n [agentName]: !prev[agentName],\n }));\n };\n\n return (\n <ModalBackdrop onClose={onClose}>\n <ModalBody\n width=\"lg\"\n className=\"relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]\"\n testID=\"skills-modal\"\n >\n <SkillsModalHeader\n isLoading={isLoading}\n isRefetching={isRefetching}\n onRefresh={refetch}\n onClose={onClose}\n />\n\n <div className=\"w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\">\n {isLoading ? (\n <SkillsLoadingState />\n ) : isError || !skills || skills.length === 0 ? (\n <SkillsEmptyState isError={isError} />\n ) : (\n groupedSkills && (\n <div className=\"divide-y divide-[var(--oh-border)]\">\n {SKILL_SCOPE_ORDER.map((scope) => {\n const scopedSkills = groupedSkills[scope];\n if (scopedSkills.length === 0) {\n return null;\n }\n\n return (\n <SkillsModalSection\n key={scope}\n title={t(SECTION_TITLE_KEY[scope])}\n count={scopedSkills.length}\n >\n {scopedSkills.map((skill) => {\n const isExpanded = expandedAgents[skill.name] || false;\n\n return (\n <SkillItem\n key={`${scope}-${skill.name}`}\n skill={skill}\n isExpanded={isExpanded}\n onToggle={toggleAgent}\n />\n );\n })}\n </SkillsModalSection>\n );\n })}\n </div>\n )\n )}\n </div>\n </ModalBody>\n </ModalBackdrop>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAsBA,IAAM,IAAiD;CACrD,SAAS,EAAQ;CACjB,UAAU,EAAQ;CAClB,QAAQ,EAAQ;CACjB;AAED,SAAgB,EAAY,EAAE,cAA6B;CACzD,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,IAAa,GAA0B,EACvC,CAAC,GAAgB,KAAqB,EAC1C,EAAE,CACH,EAGK,EACJ,MAAM,GACN,cACA,YACA,YACA,oBACE,GAAuB,EAErB,IAAgB,QACb,IAAS,EAAmB,GAAQ,EAAW,GAAG,MACzD,CAAC,GAAQ,EAAW,CACrB,EAEK,KAAe,MAAsB;AACzC,KAAmB,OAAU;GAC3B,GAAG;IACF,IAAY,CAAC,EAAK;GACpB,EAAE;;AAGL,QACE,kBAAC,GAAD;EAAwB;YACtB,kBAAC,GAAD;GACE,OAAM;GACN,WAAU;GACV,QAAO;aAHT,CAKE,kBAAC,GAAD;IACa;IACG;IACd,WAAW;IACF;IACT,CAAA,EAEF,kBAAC,OAAD;IAAK,WAAU;cACZ,IACC,kBAAC,GAAD,EAAsB,CAAA,GACpB,KAAW,CAAC,KAAU,EAAO,WAAW,IAC1C,kBAAC,GAAD,EAA2B,YAAW,CAAA,GAEtC,KACE,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAkB,KAAK,MAAU;MAChC,IAAM,IAAe,EAAc;AAKnC,aAJI,EAAa,WAAW,IACnB,OAIP,kBAAC,GAAD;OAEE,OAAO,EAAE,EAAkB,GAAO;OAClC,OAAO,EAAa;iBAEnB,EAAa,KAAK,MAIf,kBAAC,GAAD;QAES;QACK,YANG,EAAe,EAAM,SAAS;QAO7C,UAAU;QACV,EAJK,GAAG,EAAM,GAAG,EAAM,OAIvB,CAEJ;OACiB,EAhBd,EAgBc;OAEvB;KACE,CAAA;IAGN,CAAA,CACI;;EACE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require(`../../../../_virtual/_rolldown/runtime.cjs`);require(`../../../../utils/utils.cjs`),require(`../../../../utils/dropdown-classes.cjs`),require(`../../../../icons/u-check-circle.cjs`),require(`../../../../icons/u-edit.cjs`),require(`../../../../icons/u-delete.cjs`),require(`../../conversation/conversation-name-context-menu-icon-text.cjs`),require(`react`),require(`react/jsx-runtime`);let t=require(`react-dom`);t=e.__toESM(t,1);
|
|
1
|
+
const e=require(`../../../../_virtual/_rolldown/runtime.cjs`);require(`../../../../utils/utils.cjs`),require(`../../../shared/buttons/styled-tooltip.cjs`),require(`../../../../utils/dropdown-classes.cjs`),require(`../../../../icons/u-check-circle.cjs`),require(`../../../../icons/u-edit.cjs`),require(`../../../../icons/u-delete.cjs`),require(`../../conversation/conversation-name-context-menu-icon-text.cjs`),require(`react`),require(`react/jsx-runtime`);let t=require(`react-dom`);t=e.__toESM(t,1);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../../../utils/utils.cjs`),r=require(
|
|
1
|
+
require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../../../utils/utils.cjs`),r=require(`../../shared/navigation-link.cjs`),i=require(`../../../icons/skills.cjs`),a=require(`../../../hooks/use-breakpoint.cjs`),o=require(`../sidebar/sidebar-layout.cjs`),s=require(`../settings/backend-synced-settings-badge.cjs`),c=require(`../../../icons/server-process.cjs`),l=require(`../../../stores/sidebar-store.cjs`);let u=require(`react/jsx-runtime`);var d=[{to:`/skills`,label:`Skills`,icon:(0,u.jsx)(i.default,{width:16,height:16,"aria-hidden":`true`}),end:!0},{to:`/mcp`,label:`MCP Servers`,icon:(0,u.jsx)(c.default,{width:16,height:16}),end:!0},{to:`/plugins`,label:`Plugins`,icon:(0,u.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,width:16,height:16,"aria-hidden":`true`,children:[(0,u.jsx)(`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`}),(0,u.jsx)(`path`,{d:`m3.3 7 8.7 5 8.7-5`}),(0,u.jsx)(`path`,{d:`M12 22V12`})]}),end:!0,comingSoon:!0}];function f(){let{t:i}=e.useTranslation(`openhands`),c=l.useSidebarStore(e=>e.collapsed),f=a.useBreakpoint(1023),p=a.useBreakpoint(767);return!c&&f&&!p?null:(0,u.jsxs)(`aside`,{"data-testid":`extensions-navbar-desktop`,className:`hidden md:flex md:w-[260px] md:shrink-0 md:flex-col md:gap-2 md:sticky md:top-8 md:self-start`,children:[(0,u.jsx)(`span`,{className:`px-2 text-sm font-normal text-white`,children:i(t.I18nKey.NAV$CUSTOMIZE)}),(0,u.jsx)(`div`,{className:`flex flex-col gap-0.5 pt-0.5`,children:d.map(e=>{let a=(0,u.jsx)(`span`,{className:`shrink-0 flex items-center justify-center`,children:e.icon}),s=(0,u.jsx)(`span`,{className:`truncate`,children:e.label}),c=e.comingSoon&&(0,u.jsx)(`span`,{className:`ml-auto shrink-0 rounded-full border border-white/20 bg-white/5 px-1.5 py-0.5 text-[10px] font-medium text-[var(--oh-text-dim)]`,children:i(t.I18nKey.NAV$COMING_SOON)});return(0,u.jsxs)(r.NavigationLink,{to:e.to,end:e.end,"data-testid":`sidebar-extensions-${e.to}`,className:({isActive:e})=>n.cn(o.sidebarNavRowClassName(),`truncate`,e?o.SIDEBAR_ROW_INTERACTIVE_CLASS.active:o.SIDEBAR_ROW_INTERACTIVE_CLASS.idle),children:[a,s,c]},e.to)})}),(0,u.jsx)(`div`,{className:`px-2 pt-3`,children:(0,u.jsx)(s.BackendSyncedSettingsBadge,{})})]})}exports.ExtensionsNavigation=f;
|
|
2
2
|
//# sourceMappingURL=extensions-navigation.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensions-navigation.cjs","names":[],"sources":["../../../../src/components/features/skills/extensions-navigation.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport {
|
|
1
|
+
{"version":3,"file":"extensions-navigation.cjs","names":[],"sources":["../../../../src/components/features/skills/extensions-navigation.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { cn } from \"#/utils/utils\";\nimport SkillsIcon from \"#/icons/skills.svg?react\";\nimport ServerProcessIcon from \"#/icons/server-process.svg?react\";\nimport { BackendSyncedSettingsBadge } from \"#/components/features/settings/backend-synced-settings-badge\";\nimport {\n SIDEBAR_ROW_INTERACTIVE_CLASS,\n sidebarNavRowClassName,\n} from \"#/components/features/sidebar/sidebar-layout\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useSidebarStore } from \"#/stores/sidebar-store\";\nimport { useBreakpoint } from \"#/hooks/use-breakpoint\";\n\ninterface ExtensionNavItem {\n to: string;\n label: string;\n icon: React.ReactElement;\n end?: boolean;\n comingSoon?: boolean;\n}\n\nexport const EXTENSIONS_NAV_ITEMS: ExtensionNavItem[] = [\n {\n to: \"/skills\",\n label: \"Skills\",\n icon: <SkillsIcon width={16} height={16} aria-hidden=\"true\" />,\n end: true,\n },\n {\n to: \"/mcp\",\n label: \"MCP Servers\",\n icon: <ServerProcessIcon width={16} height={16} />,\n end: true,\n },\n {\n to: \"/plugins\",\n label: \"Plugins\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n width={16}\n height={16}\n aria-hidden=\"true\"\n >\n <path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\" />\n <path d=\"m3.3 7 8.7 5 8.7-5\" />\n <path d=\"M12 22V12\" />\n </svg>\n ),\n end: true,\n comingSoon: true,\n },\n];\n\nexport function ExtensionsNavigation() {\n const { t } = useTranslation(\"openhands\");\n const sidebarCollapsed = useSidebarStore((state) => state.collapsed);\n // At iPad portrait widths (md to <lg) an expanded primary Sidebar (300px)\n // plus this nav (260px) leaves the main content unreadable. Hide ourselves\n // until the user collapses the Sidebar or the viewport reaches `lg`.\n const belowLg = useBreakpoint(1023);\n const belowMd = useBreakpoint(767);\n const hideForExpandedSidebar = !sidebarCollapsed && belowLg && !belowMd;\n\n if (hideForExpandedSidebar) return null;\n\n return (\n <aside\n data-testid=\"extensions-navbar-desktop\"\n className=\"hidden md:flex md:w-[260px] md:shrink-0 md:flex-col md:gap-2 md:sticky md:top-8 md:self-start\"\n >\n <span className=\"px-2 text-sm font-normal text-white\">\n {t(I18nKey.NAV$CUSTOMIZE)}\n </span>\n <div className=\"flex flex-col gap-0.5 pt-0.5\">\n {EXTENSIONS_NAV_ITEMS.map((item) => {\n const baseRow = (\n <span className=\"shrink-0 flex items-center justify-center\">\n {item.icon}\n </span>\n );\n const label = <span className=\"truncate\">{item.label}</span>;\n const comingSoonBadge = item.comingSoon && (\n <span className=\"ml-auto shrink-0 rounded-full border border-white/20 bg-white/5 px-1.5 py-0.5 text-[10px] font-medium text-[var(--oh-text-dim)]\">\n {t(I18nKey.NAV$COMING_SOON)}\n </span>\n );\n\n return (\n <NavigationLink\n key={item.to}\n to={item.to}\n end={item.end}\n data-testid={`sidebar-extensions-${item.to}`}\n className={({ isActive }) =>\n cn(\n sidebarNavRowClassName(),\n \"truncate\",\n isActive\n ? SIDEBAR_ROW_INTERACTIVE_CLASS.active\n : SIDEBAR_ROW_INTERACTIVE_CLASS.idle,\n )\n }\n >\n {baseRow}\n {label}\n {comingSoonBadge}\n </NavigationLink>\n );\n })}\n </div>\n <div className=\"px-2 pt-3\">\n <BackendSyncedSettingsBadge />\n </div>\n </aside>\n );\n}\n"],"mappings":"ikBAsBA,IAAa,EAA2C,CACtD,CACE,GAAI,UACJ,MAAO,SACP,MAAM,EAAA,EAAA,KAAC,EAAA,QAAD,CAAY,MAAO,GAAI,OAAQ,GAAI,cAAY,OAAS,CAAA,CAC9D,IAAK,GACN,CACD,CACE,GAAI,OACJ,MAAO,cACP,MAAM,EAAA,EAAA,KAAC,EAAA,QAAD,CAAmB,MAAO,GAAI,OAAQ,GAAM,CAAA,CAClD,IAAK,GACN,CACD,CACE,GAAI,WACJ,MAAO,UACP,MACE,EAAA,EAAA,MAAC,MAAD,CACE,MAAM,6BACN,QAAQ,YACR,KAAK,OACL,OAAO,eACP,YAAY,IACZ,cAAc,QACd,eAAe,QACf,MAAO,GACP,OAAQ,GACR,cAAY,gBAVd,EAYE,EAAA,EAAA,KAAC,OAAD,CAAM,EAAE,yHAA2H,CAAA,EACnI,EAAA,EAAA,KAAC,OAAD,CAAM,EAAE,qBAAuB,CAAA,EAC/B,EAAA,EAAA,KAAC,OAAD,CAAM,EAAE,YAAc,CAAA,CAClB,GAER,IAAK,GACL,WAAY,GACb,CACF,CAED,SAAgB,GAAuB,CACrC,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,EAAmB,EAAA,gBAAiB,GAAU,EAAM,UAAU,CAI9D,EAAU,EAAA,cAAc,KAAK,CAC7B,EAAU,EAAA,cAAc,IAAI,CAKlC,MAJ+B,CAAC,GAAoB,GAAW,CAAC,EAE7B,MAGjC,EAAA,EAAA,MAAC,QAAD,CACE,cAAY,4BACZ,UAAU,yGAFZ,EAIE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,+CACb,EAAE,EAAA,QAAQ,cAAc,CACpB,CAAA,EACP,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,wCACZ,EAAqB,IAAK,GAAS,CAClC,IAAM,GACJ,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qDACb,EAAK,KACD,CAAA,CAEH,GAAQ,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oBAAY,EAAK,MAAa,CAAA,CACtD,EAAkB,EAAK,aAC3B,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,2IACb,EAAE,EAAA,QAAQ,gBAAgB,CACtB,CAAA,CAGT,OACE,EAAA,EAAA,MAAC,EAAA,eAAD,CAEE,GAAI,EAAK,GACT,IAAK,EAAK,IACV,cAAa,sBAAsB,EAAK,KACxC,WAAY,CAAE,cACZ,EAAA,GACE,EAAA,wBAAwB,CACxB,WACA,EACI,EAAA,8BAA8B,OAC9B,EAAA,8BAA8B,KACnC,UAZL,CAeG,EACA,EACA,EACc,EAjBV,EAAK,GAiBK,EAEnB,CACE,CAAA,EACN,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,sBACb,EAAA,EAAA,KAAC,EAAA,2BAAD,EAA8B,CAAA,CAC1B,CAAA,CACA"}
|
|
@@ -4,14 +4,6 @@ interface ExtensionNavItem {
|
|
|
4
4
|
icon: React.ReactElement;
|
|
5
5
|
end?: boolean;
|
|
6
6
|
comingSoon?: boolean;
|
|
7
|
-
/**
|
|
8
|
-
* When true, this item greys out (and the /route's ``clientLoader``
|
|
9
|
-
* bounces to ``/settings/agent``) while an ACP agent is active.
|
|
10
|
-
* The ACP sub-agent manages its own MCP servers; the SDK rejects
|
|
11
|
-
* ``mcp_config`` on ``ACPAgent`` init outright, so the OpenHands-
|
|
12
|
-
* side editor would silently no-op against the running subprocess.
|
|
13
|
-
*/
|
|
14
|
-
disabledByAcp?: boolean;
|
|
15
7
|
}
|
|
16
8
|
export declare const EXTENSIONS_NAV_ITEMS: ExtensionNavItem[];
|
|
17
9
|
export declare function ExtensionsNavigation(): import("react/jsx-runtime").JSX.Element | null;
|