@openhands/agent-canvas 1.7.2 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.windows.md +2 -2
- package/build/assets/{Trans-DP5rcauH.js → Trans-Bwpzk1wT.js} +1 -1
- package/build/assets/{acp-providers-BHKZvEm5.js → acp-providers-C921BlYB.js} +1 -1
- package/build/assets/active-backend-context-BiwzkzDy.js +2 -0
- package/build/assets/agent-context-settings-DXNT_dcw.js +1 -0
- package/build/assets/agent-profiles-settings-BymJf3EP.js +1 -0
- package/build/assets/agent-server-conversation-service.api-CYSWw-2g.js +41 -0
- package/build/assets/agent-settings-BjgQQe-_.js +1 -0
- package/build/assets/{agent-settings-BIOsUglV.js → agent-settings-WzqXk6B4.js} +2 -2
- package/build/assets/{alert-banner-C1nzoXBC.js → alert-banner-DR8EVyZM.js} +1 -1
- package/build/assets/api-error-message-e16L1kwH.js +1 -0
- package/build/assets/api-key-entry-screen-DI0I04O3.js +1 -0
- package/build/assets/app-settings-DGistSFV.js +1 -0
- package/build/assets/automation-C_eCrGyP.js +1 -0
- package/build/assets/automation-detail-DY6x2FW1.js +2 -0
- package/build/assets/automation-export-C09f-Lua.js +2 -0
- package/build/assets/automation-setup-route-CqKp0717.js +1 -0
- package/build/assets/automations-list-CqWJ7qXW.js +1 -0
- package/build/assets/{back-nav-button-Be_L157B.js → back-nav-button-D4ngzpSh.js} +1 -1
- package/build/assets/backend-form-modal-B8D5hBzK.js +1 -0
- package/build/assets/{backend-synced-settings-badge-BNpEylNP.js → backend-synced-settings-badge-BnzI8Ysj.js} +1 -1
- package/build/assets/{badge-DwgrwohM.js → badge-1Mf1iPcX.js} +1 -1
- package/build/assets/{base-modal-CSHhJTSr.js → base-modal-BBuy0WQQ.js} +1 -1
- package/build/assets/{brand-button-CQO8oqVo.js → brand-button-DGN6Y9o6.js} +1 -1
- package/build/assets/browser-D_ekTlTS.js +6 -0
- package/build/assets/{browser-tab-CEApjoEV.js → browser-tab-D4a4Ou_w.js} +1 -1
- package/build/assets/{chat-send-button-D4614wUz.js → chat-send-button-CgbcjD97.js} +1 -1
- package/build/assets/check-CPLXgluF.js +1 -0
- package/build/assets/chevron-down-CP4QHvyc.js +1 -0
- package/build/assets/circle-check-Dpy2_xSI.js +1 -0
- package/build/assets/{circle-plus-check-toggle-E3Ecb_gg.js → circle-plus-check-toggle-yTAS-nX3.js} +1 -1
- package/build/assets/cloud-funnel-analytics-CEOl5Gxr.js +1 -0
- package/build/assets/{combobox-caret-C8_eGdp2.js → combobox-caret-Bd2yySnF.js} +1 -1
- package/build/assets/command-menu-Bj6X4ckE.js +1 -0
- package/build/assets/condenser-settings-EAXQNR2E.js +1 -0
- package/build/assets/{confirmation-modal-gZtbojCm.js → confirmation-modal-NCUPr2-O.js} +1 -1
- package/build/assets/{context-menu-list-item-BTHGFhIx.js → context-menu-list-item-CrCrYuPF.js} +1 -1
- package/build/assets/conversation-BzyIcSwr.js +1 -0
- package/build/assets/conversation-CUJ0Vo8g.js +90 -0
- package/build/assets/conversation-panel-BzyIcSwr.js +1 -0
- package/build/assets/conversation-state-store-F62HvuI1.js +1 -0
- package/build/assets/{conversation-tab-empty-state-BCMHkGQk.js → conversation-tab-empty-state-BCZ7rUMH.js} +1 -1
- package/build/assets/{copy-B8Y5ufoR.js → copy-DCmZtz6n.js} +1 -1
- package/build/assets/{copy-to-clipboard-button-C4l3CMSd.js → copy-to-clipboard-button-D_Lp6-Fl.js} +1 -1
- package/build/assets/{device-verify-C_M7Z8xs.js → device-verify-DLmolX8Q.js} +1 -1
- package/build/assets/{dropdown-classes-DQlj-MpS.js → dropdown-classes-BB8rzqXL.js} +1 -1
- package/build/assets/{entry.client-DETaouwO.js → entry.client-BbIYOsIg.js} +2 -2
- package/build/assets/{enum-filter-dropdown-paB-lFSP.js → enum-filter-dropdown-C08-srev.js} +1 -1
- package/build/assets/{environment-switch-overlay-D0FgCMqs.js → environment-switch-overlay-BepBBX66.js} +1 -1
- package/build/assets/extensions-hub-R3KNv-5V.js +1 -0
- package/build/assets/extensions-navigation-CfWFmI1I.js +1 -0
- package/build/assets/{external-link-Cnnd6ikC.js → external-link-BdBSg8rk.js} +1 -1
- package/build/assets/files-tab-DEq8MbHu.js +1 -0
- package/build/assets/{form-control-classes-CSPevi7c.js → form-control-classes-DAfsCJTe.js} +1 -1
- package/build/assets/{format-time-delta-DuhE50B-.js → format-time-delta-CxfPJpzC.js} +1 -1
- package/build/assets/git-provider-icon-BZqqUPlm.js +1 -0
- package/build/assets/git-repo-dropdown-9WKINV6J.js +1 -0
- package/build/assets/git-repo-dropdown-DEpOwUez.js +1 -0
- package/build/assets/{highlighted-source-view-suUKd5if.js → highlighted-source-view-CX9oIoVT.js} +1 -1
- package/build/assets/home-CY0JaxiY.js +1 -0
- package/build/assets/home-CaNWlVvB.js +1 -0
- package/build/assets/home-store-Ch1ErdBc.js +1 -0
- package/build/assets/index-home-CaNWlVvB.js +1 -0
- package/build/assets/info-CmWQXtRQ.js +1 -0
- package/build/assets/install-server-modal-BWrudmZU.js +1 -0
- package/build/assets/{launch-Ccnhte5b.js → launch-B1POpHuP.js} +1 -1
- package/build/assets/{list-todo-_BXQzOiB.js → list-todo-DtiL3lTp.js} +1 -1
- package/build/assets/llm-not-configured-banner-3tMsM4K6.js +27 -0
- package/build/assets/llm-settings-CXo8iPNW.js +1 -0
- package/build/assets/llm-settings-D0W8mJDk.js +1 -0
- package/build/assets/{llm-subscription-service-W5BprsNA.js → llm-subscription-service-DBJbfd8Z.js} +1 -1
- package/build/assets/loader-circle-B4QDBARx.js +1 -0
- package/build/assets/{loading-spinner-CcpnCr_d.js → loading-spinner-DfZ_bhV7.js} +1 -1
- package/build/assets/manage-backends-modal-CwyWsiag.js +1 -0
- package/build/assets/manifest-39f4789d.js +1 -0
- package/build/assets/{markdown-renderer-CvOO0YIr.js → markdown-renderer-DgiLLhW6.js} +6 -6
- package/build/assets/mcp-DXG9LWrI.js +9 -0
- package/build/assets/mcp-marketplace-utils-DFmhKc5s.js +1 -0
- package/build/assets/messages-kBjKaAeA.js +40 -0
- package/build/assets/{modal-body-DQhiw-AR.js → modal-body-CMsDpalT.js} +1 -1
- package/build/assets/{modal-classes-YaEEa5eZ.js → modal-classes-B6PDrxXo.js} +1 -1
- package/build/assets/{modal-close-button-turIYn0t.js → modal-close-button-DyxBZaAb.js} +1 -1
- package/build/assets/{onboarding-BegDrOKn.js → onboarding-47hh2IHA.js} +1 -1
- package/build/assets/onboarding-modal-9BuvvROo.js +1 -0
- package/build/assets/organization-service.api-UDy63-oC.js +1 -0
- package/build/assets/{pencil-8_lvWDoZ.js → pencil-BjgtZmWp.js} +1 -1
- package/build/assets/{planner-tab-w6HT0N_A.js → planner-tab-BWk8885v.js} +1 -1
- package/build/assets/plugins-management-service-CjkgF2dd.js +1 -0
- package/build/assets/plus-DrKuuvMe.js +1 -0
- package/build/assets/profiles-service.api-CukSFLzz.js +1 -0
- package/build/assets/providers-CqUWC85T.js +1 -0
- package/build/assets/proxy-BBUG3sd2.js +1 -0
- package/build/assets/{puzzle-DXWdfaa7.js → puzzle-BoNc6zZ8.js} +1 -1
- package/build/assets/recommended-automations-launcher-ejxy1P27.js +1 -0
- package/build/assets/{refresh-cw-D7CYLy-d.js → refresh-cw-BrM5ZAZD.js} +1 -1
- package/build/assets/root-5S-M8SYa.js +2 -0
- package/build/assets/root-DZ39lS5f.css +1 -0
- package/build/assets/root-layout-BPqoa0gv.js +3 -0
- package/build/assets/schema-field-nImDoY6-.js +1 -0
- package/build/assets/{sdk-section-page-BW-i45yr.js → sdk-section-page-BxMrtUNV.js} +1 -1
- package/build/assets/search-Dc2qR4O2.js +1 -0
- package/build/assets/secrets-service-Dhjh3HhH.js +1 -0
- package/build/assets/{secrets-settings-D7U1ErCH.js → secrets-settings-CPdxceT_.js} +1 -1
- package/build/assets/segmented-toggle-Do6oyepX.js +1 -0
- package/build/assets/settings-BRbnfKEm.js +1 -0
- package/build/assets/{settings-dropdown-input-Dx6vlkgf.js → settings-dropdown-input-DYCULKpp.js} +1 -1
- package/build/assets/{settings-index-COAdxm2Q.js → settings-index-C9o2NBO0.js} +1 -1
- package/build/assets/settings-input-B-q2gkVy.js +1 -0
- package/build/assets/{settings-list-classes-gQdBahdt.js → settings-list-classes-WpQi0q1L.js} +1 -1
- package/build/assets/{settings-modal-CFnbQ8_4.js → settings-modal-CEK0AIx6.js} +1 -1
- package/build/assets/settings-service.api-CZiPD8__.js +1 -0
- package/build/assets/{settings-switch-UNSf8K8I.js → settings-switch-LqKdGxHL.js} +1 -1
- package/build/assets/shared-conversation-Bu-dQlgp.js +1 -0
- package/build/assets/{sidebar-layout-DXHtbEj1.js → sidebar-layout-oHBGQmLh.js} +1 -1
- package/build/assets/{sidebar-mobile-menu-toggle-U78hQRJ1.js → sidebar-mobile-menu-toggle-ND-hgygu.js} +1 -1
- package/build/assets/{sidebar-nav-link-pvUivfK2.js → sidebar-nav-link-CrujNA09.js} +1 -1
- package/build/assets/{sidebar-store-DwrYKwYr.js → sidebar-store-Bui-WNEr.js} +1 -1
- package/build/assets/{skill-card-pill-row-D7XCz5uk.js → skill-card-pill-row-CZBI7OqH.js} +1 -1
- package/build/assets/{skill-icon-badge-HqBWZ2Eq.js → skill-icon-badge-BOov_phZ.js} +1 -1
- package/build/assets/{skills-plugins-BPhaNpfx.js → skills-plugins-D0PiHWAD.js} +1 -1
- package/build/assets/{skills-settings-CcwMtnnJ.js → skills-settings-B43KArIz.js} +2 -2
- package/build/assets/{styled-tooltip-DsjDnR_W.js → styled-tooltip-C7grwnOX.js} +1 -1
- package/build/assets/{task-list-tab-BmaTwjaS.js → task-list-tab-R3ac6m7O.js} +1 -1
- package/build/assets/{terminal-BRcoba5B.js → terminal-yqkNdEAx.js} +1 -1
- package/build/assets/{toggle-switch-BptY3XRG.js → toggle-switch-BeSrbgCg.js} +1 -1
- package/build/assets/{trash-2-Bq4lHbTB.js → trash-2-wW5TWcdN.js} +1 -1
- package/build/assets/{typography-C6fuRTTT.js → typography-iYhzLlHO.js} +1 -1
- package/build/assets/{use-acp-credential-form-B0_pZ_uS.js → use-acp-credential-form-DUxbxmbq.js} +1 -1
- package/build/assets/use-activate-agent-profile-CDHA52tC.js +1 -0
- package/build/assets/use-agent-profiles-TsOdIyw5.js +1 -0
- package/build/assets/{use-can-manage-org-profiles-CrG1km7R.js → use-can-manage-org-profiles-Bt1M71u5.js} +1 -1
- package/build/assets/use-cloud-current-user-id-DWt7HCgf.js +1 -0
- package/build/assets/{use-config-Csy8EAP9.js → use-config-CxlEdf_v.js} +1 -1
- package/build/assets/{use-create-conversation-Dsa4nzU9.js → use-create-conversation-nOJ6Um5h.js} +1 -1
- package/build/assets/{use-create-secret-BnxuAjDt.js → use-create-secret-Dj5ang9x.js} +1 -1
- package/build/assets/use-is-authed-BT7Iud4U.js +1 -0
- package/build/assets/{use-is-creating-conversation-CIAcnd8M.js → use-is-creating-conversation-CAggrM75.js} +1 -1
- package/build/assets/use-llm-profiles-2Wc2db8u.js +1 -0
- package/build/assets/use-onboarding-completion-gxQlcEy2.js +1 -0
- package/build/assets/use-plugins-marketplace-CVO7sXYR.js +1 -0
- package/build/assets/use-save-agent-profile-D0wC5ExW.js +1 -0
- package/build/assets/{use-save-settings-BRh9p_fv.js → use-save-settings-L3aMaDeS.js} +1 -1
- package/build/assets/use-settings-8nt3DGxW.js +1 -0
- package/build/assets/use-settings-nav-items-DHAAD-zk.js +16 -0
- package/build/assets/use-skills-CE6miQ3r.js +1 -0
- package/build/assets/use-tracking-BGboadaZ.js +68 -0
- package/build/assets/{use-user-conversation-GnGhs_Ob.js → use-user-conversation-BIIpGUgM.js} +1 -1
- package/build/assets/useInfiniteQuery-BLRVmVPU.js +1 -0
- package/build/assets/{useMutation-DyQXZFEF.js → useMutation-CaSHLnX0.js} +1 -1
- package/build/assets/{useQueries-B3T1a7qt.js → useQueries--d_WWAzc.js} +1 -1
- package/build/assets/{useQuery-B38jBavx.js → useQuery-DiPh8LRJ.js} +1 -1
- package/build/assets/utils-BgGG1znF.js +1 -0
- package/build/assets/{vendor~browser-CIoZCqGs.js → vendor~browser-IVYgIgG1.js} +1 -1
- package/build/assets/{vendor~entry.client-Di4qO77Y.js → vendor~entry.client-BcYIVQvB.js} +1 -1
- package/build/assets/{vendor~entry.client-BfviqoVc.js → vendor~entry.client-CXM9oiAk.js} +1 -1
- package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~g4xrpilz-CJ7amdtQ.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~b0bpqexo-CbTboogo.js} +2 -2
- package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f9xdmd0z-DLMP7bZx.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~d4by102p-C2f0ZhS-.js} +1 -1
- package/build/assets/{vendor~files-tab-vm3f67Pz.js → vendor~files-tab-C7RmQJwN.js} +1 -1
- package/build/assets/{vendor~index-home~home~conversation-panel~conversation-kX4LrGQC.js → vendor~index-home~home~conversation-panel~conversation-Bqp1ZqJM.js} +1 -1
- package/build/assets/{vendor~root-layout~conversation-panel~conversation-DpA6fir3.js → vendor~root-layout~conversation-panel~conversation-BCn8lzeG.js} +1 -1
- package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~automation-setup-route-B_L-gcOG.js +1 -0
- package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-sjx0x5ac.js +1 -0
- package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~automation-setup-route~onboarding-modal-D7IDevqN.js +1 -0
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~bi2r7bko-Bw4AuHN1.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~dfc8ddxy-tTyxnjXT.js} +1 -1
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hakxo2tj-ClV0p9g3.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gy8zbn65-CGt6bWRT.js} +1 -1
- package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~launch~skills-settings~a~eywn6ulz-BKxxr74w.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~dufan6ng-Dtdw8H0q.js} +17 -4
- package/build/assets/{verification-settings-CaCzojbc.js → verification-settings-DBsnSXC3.js} +1 -1
- package/build/assets/x-omAzpXkl.js +1 -0
- package/build/favicon-16x16.png +0 -0
- package/build/favicon-32x32.png +0 -0
- package/build/favicon.ico +0 -0
- package/build/index.html +4 -4
- package/build/locales/ar/openhands.json +39 -2
- package/build/locales/ca/openhands.json +39 -2
- package/build/locales/de/openhands.json +39 -2
- package/build/locales/en/openhands.json +40 -3
- package/build/locales/es/openhands.json +39 -2
- package/build/locales/fr/openhands.json +39 -2
- package/build/locales/it/openhands.json +39 -2
- package/build/locales/ja/openhands.json +39 -2
- package/build/locales/ko-KR/openhands.json +39 -2
- package/build/locales/no/openhands.json +39 -2
- package/build/locales/pt/openhands.json +39 -2
- package/build/locales/tr/openhands.json +39 -2
- package/build/locales/uk/openhands.json +39 -2
- package/build/locales/zh-CN/openhands.json +39 -2
- package/build/locales/zh-TW/openhands.json +39 -2
- package/config/defaults.json +4 -4
- package/dist/api/agent-server-adapter.cjs +3 -3
- package/dist/api/agent-server-adapter.cjs.map +1 -1
- package/dist/api/agent-server-adapter.d.ts +46 -6
- package/dist/api/agent-server-adapter.js +187 -168
- package/dist/api/agent-server-adapter.js.map +1 -1
- package/dist/api/agent-server-compatibility.cjs +1 -1
- package/dist/api/agent-server-compatibility.cjs.map +1 -1
- package/dist/api/agent-server-compatibility.d.ts +4 -0
- package/dist/api/agent-server-compatibility.js +41 -38
- package/dist/api/agent-server-compatibility.js.map +1 -1
- package/dist/api/automation-service/automation-service.api.cjs +1 -1
- package/dist/api/automation-service/automation-service.api.cjs.map +1 -1
- package/dist/api/automation-service/automation-service.api.d.ts +20 -0
- package/dist/api/automation-service/automation-service.api.js +136 -99
- package/dist/api/automation-service/automation-service.api.js.map +1 -1
- package/dist/api/backend-registry/storage.cjs +1 -1
- package/dist/api/backend-registry/storage.cjs.map +1 -1
- package/dist/api/backend-registry/storage.js +1 -1
- package/dist/api/backend-registry/storage.js.map +1 -1
- package/dist/api/backend-registry/types.d.ts +2 -0
- package/dist/api/cloud/conversation-service.api.cjs +1 -1
- package/dist/api/cloud/conversation-service.api.js +22 -22
- package/dist/api/mcp-service/mcp-service.api.cjs +1 -1
- package/dist/api/mcp-service/mcp-service.api.cjs.map +1 -1
- package/dist/api/mcp-service/mcp-service.api.js +19 -19
- package/dist/api/mcp-service/mcp-service.api.js.map +1 -1
- package/dist/api/settings-service/settings-service.api.cjs +1 -1
- package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
- package/dist/api/settings-service/settings-service.api.js +26 -12
- package/dist/api/settings-service/settings-service.api.js.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs +2 -0
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs.map +1 -0
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.d.ts +12 -0
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js +94 -0
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js.map +1 -0
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +31 -90
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
- package/dist/components/features/automations/recommended-automations-launcher.d.ts +0 -7
- package/dist/components/features/automations/recommended-automations-section.d.ts +0 -6
- package/dist/components/features/backends/backend-form-modal.cjs +1 -1
- package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
- package/dist/components/features/backends/backend-form-modal.js +568 -358
- package/dist/components/features/backends/backend-form-modal.js.map +1 -1
- package/dist/components/features/backends/device-flow-auth.cjs +1 -1
- package/dist/components/features/backends/device-flow-auth.cjs.map +1 -1
- package/dist/components/features/backends/device-flow-auth.d.ts +9 -1
- package/dist/components/features/backends/device-flow-auth.js +56 -55
- package/dist/components/features/backends/device-flow-auth.js.map +1 -1
- package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
- package/dist/components/features/backends/manage-backends-modal.cjs.map +1 -1
- package/dist/components/features/backends/manage-backends-modal.js +1 -1
- package/dist/components/features/backends/manage-backends-modal.js.map +1 -1
- package/dist/components/features/chat/chat-interface.cjs +1 -1
- package/dist/components/features/chat/chat-interface.cjs.map +1 -1
- package/dist/components/features/chat/chat-interface.js +105 -105
- package/dist/components/features/chat/chat-interface.js.map +1 -1
- package/dist/components/features/chat/chat-message.cjs +1 -1
- package/dist/components/features/chat/chat-message.cjs.map +1 -1
- package/dist/components/features/chat/chat-message.d.ts +2 -1
- package/dist/components/features/chat/chat-message.js +59 -49
- package/dist/components/features/chat/chat-message.js.map +1 -1
- package/dist/components/features/chat/pending-user-messages.cjs +1 -1
- package/dist/components/features/chat/pending-user-messages.cjs.map +1 -1
- package/dist/components/features/chat/pending-user-messages.js +4 -1
- package/dist/components/features/chat/pending-user-messages.js.map +1 -1
- package/dist/components/features/chat/typing-indicator.cjs +1 -1
- package/dist/components/features/chat/typing-indicator.cjs.map +1 -1
- package/dist/components/features/chat/typing-indicator.d.ts +8 -1
- package/dist/components/features/chat/typing-indicator.js +94 -10
- package/dist/components/features/chat/typing-indicator.js.map +1 -1
- package/dist/components/features/command-menu/command-menu-items.d.ts +5 -1
- package/dist/components/features/files-tab/segmented-toggle.cjs +1 -1
- package/dist/components/features/files-tab/segmented-toggle.cjs.map +1 -1
- package/dist/components/features/files-tab/segmented-toggle.d.ts +2 -0
- package/dist/components/features/files-tab/segmented-toggle.js +17 -14
- package/dist/components/features/files-tab/segmented-toggle.js.map +1 -1
- package/dist/components/features/manifest/manifest-form-field.d.ts +27 -0
- package/dist/components/features/manifest/manifest-prerequisites-step.d.ts +11 -0
- package/dist/components/features/manifest/manifest-review-step.d.ts +14 -0
- package/dist/components/features/manifest/manifest-setup-dialog.d.ts +14 -0
- package/dist/components/features/mcp-page/custom-server-editor.cjs +1 -1
- package/dist/components/features/mcp-page/custom-server-editor.js +16 -16
- package/dist/components/features/mcp-page/installed-server-card.cjs +1 -1
- package/dist/components/features/mcp-page/installed-server-card.cjs.map +1 -1
- package/dist/components/features/mcp-page/installed-server-card.d.ts +2 -2
- package/dist/components/features/mcp-page/installed-server-card.js +6 -7
- package/dist/components/features/mcp-page/installed-server-card.js.map +1 -1
- package/dist/components/features/mcp-page/installed-servers-section.cjs +1 -1
- package/dist/components/features/mcp-page/installed-servers-section.cjs.map +1 -1
- package/dist/components/features/mcp-page/installed-servers-section.d.ts +2 -2
- package/dist/components/features/mcp-page/installed-servers-section.js +2 -2
- package/dist/components/features/mcp-page/installed-servers-section.js.map +1 -1
- package/dist/components/features/mcp-page/mcp-server-health.cjs +1 -1
- package/dist/components/features/mcp-page/mcp-server-health.js +4 -4
- package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs +1 -1
- package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs.map +1 -1
- package/dist/components/features/settings/mcp-settings/mcp-server-form.js +2 -1
- package/dist/components/features/settings/mcp-settings/mcp-server-form.js.map +1 -1
- package/dist/components/features/settings/settings-input.cjs +1 -1
- package/dist/components/features/settings/settings-input.cjs.map +1 -1
- package/dist/components/features/settings/settings-input.d.ts +6 -0
- package/dist/components/features/settings/settings-input.js +13 -8
- package/dist/components/features/settings/settings-input.js.map +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.js +124 -123
- package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
- package/dist/config/defaults.cjs +1 -1
- package/dist/config/defaults.cjs.map +1 -1
- package/dist/config/defaults.js +3 -3
- package/dist/config/defaults.js.map +1 -1
- package/dist/contexts/active-backend-context.cjs +1 -1
- package/dist/contexts/active-backend-context.cjs.map +1 -1
- package/dist/contexts/active-backend-context.d.ts +3 -2
- package/dist/contexts/active-backend-context.js +55 -42
- package/dist/contexts/active-backend-context.js.map +1 -1
- package/dist/favicon-16x16.png +0 -0
- package/dist/favicon-32x32.png +0 -0
- package/dist/favicon.ico +0 -0
- package/dist/hooks/mutation/use-update-mcp-server.cjs +1 -1
- package/dist/hooks/mutation/use-update-mcp-server.js +5 -5
- package/dist/hooks/query/query-keys.cjs.map +1 -1
- package/dist/hooks/query/query-keys.d.ts +4 -0
- package/dist/hooks/query/query-keys.js.map +1 -1
- package/dist/hooks/query/use-cloud-current-user-id.cjs +1 -1
- package/dist/hooks/query/use-cloud-current-user-id.cjs.map +1 -1
- package/dist/hooks/query/use-cloud-current-user-id.js +7 -5
- package/dist/hooks/query/use-cloud-current-user-id.js.map +1 -1
- package/dist/hooks/query/use-cloud-organizations.cjs +1 -1
- package/dist/hooks/query/use-cloud-organizations.cjs.map +1 -1
- package/dist/hooks/query/use-cloud-organizations.js +5 -1
- package/dist/hooks/query/use-cloud-organizations.js.map +1 -1
- package/dist/hooks/query/use-manifest-capabilities.d.ts +21 -0
- package/dist/hooks/query/use-manifest-prerequisites.d.ts +24 -0
- package/dist/hooks/use-can-manage-org-profiles.cjs +1 -1
- package/dist/hooks/use-can-manage-org-profiles.cjs.map +1 -1
- package/dist/hooks/use-can-manage-org-profiles.js +2 -1
- package/dist/hooks/use-can-manage-org-profiles.js.map +1 -1
- package/dist/hooks/use-llm-configured.cjs +1 -1
- package/dist/hooks/use-llm-configured.cjs.map +1 -1
- package/dist/hooks/use-llm-configured.js +2 -1
- package/dist/hooks/use-llm-configured.js.map +1 -1
- package/dist/hooks/use-manifest-preflight.d.ts +18 -0
- package/dist/hooks/use-tracking.cjs +1 -1
- package/dist/hooks/use-tracking.cjs.map +1 -1
- package/dist/hooks/use-tracking.d.ts +14 -0
- package/dist/hooks/use-tracking.js +28 -10
- package/dist/hooks/use-tracking.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 +38 -1
- package/dist/i18n/declaration.js +1 -1
- package/dist/i18n/declaration.js.map +1 -1
- package/dist/i18n/translation.cjs +2 -2
- package/dist/i18n/translation.cjs.map +1 -1
- package/dist/i18n/translation.js +645 -16
- package/dist/i18n/translation.js.map +1 -1
- package/dist/icons/external-link.cjs +2 -0
- package/dist/icons/external-link.cjs.map +1 -0
- package/dist/icons/external-link.js +22 -0
- package/dist/icons/external-link.js.map +1 -0
- package/dist/icons/server.cjs +2 -0
- package/dist/icons/server.cjs.map +1 -0
- package/dist/icons/server.js +17 -0
- package/dist/icons/server.js.map +1 -0
- package/dist/locales/ar/openhands.json +39 -2
- package/dist/locales/ca/openhands.json +39 -2
- package/dist/locales/de/openhands.json +39 -2
- package/dist/locales/en/openhands.json +40 -3
- package/dist/locales/es/openhands.json +39 -2
- package/dist/locales/fr/openhands.json +39 -2
- package/dist/locales/it/openhands.json +39 -2
- package/dist/locales/ja/openhands.json +39 -2
- package/dist/locales/ko-KR/openhands.json +39 -2
- package/dist/locales/no/openhands.json +39 -2
- package/dist/locales/pt/openhands.json +39 -2
- package/dist/locales/tr/openhands.json +39 -2
- package/dist/locales/uk/openhands.json +39 -2
- package/dist/locales/zh-CN/openhands.json +39 -2
- package/dist/locales/zh-TW/openhands.json +39 -2
- package/dist/manifests/automation-interface.cjs +2 -0
- package/dist/manifests/automation-interface.cjs.map +1 -0
- package/dist/manifests/automation-interface.d.ts +44 -0
- package/dist/manifests/automation-interface.js +81 -0
- package/dist/manifests/automation-interface.js.map +1 -0
- package/dist/manifests/automation-setup.cjs +2 -0
- package/dist/manifests/automation-setup.cjs.map +1 -0
- package/dist/manifests/automation-setup.d.ts +52 -0
- package/dist/manifests/automation-setup.js +8 -0
- package/dist/manifests/automation-setup.js.map +1 -0
- package/dist/manifests/interface-validation.cjs +2 -0
- package/dist/manifests/interface-validation.cjs.map +1 -0
- package/dist/manifests/interface-validation.d.ts +27 -0
- package/dist/manifests/interface-validation.js +182 -0
- package/dist/manifests/interface-validation.js.map +1 -0
- package/dist/manifests/manifest-actions.d.ts +15 -0
- package/dist/manifests/manifest-capabilities.d.ts +25 -0
- package/dist/manifests/manifest-error-map.d.ts +40 -0
- package/dist/manifests/manifest-local-validation.d.ts +56 -0
- package/dist/manifests/manifest-registry.cjs +2 -0
- package/dist/manifests/manifest-registry.cjs.map +1 -0
- package/dist/manifests/manifest-registry.d.ts +15 -0
- package/dist/manifests/manifest-registry.js +26 -0
- package/dist/manifests/manifest-registry.js.map +1 -0
- package/dist/manifests/manifest-sources.cjs +2 -0
- package/dist/manifests/manifest-sources.cjs.map +1 -0
- package/dist/manifests/manifest-sources.d.ts +15 -0
- package/dist/manifests/manifest-sources.js +8 -0
- package/dist/manifests/manifest-sources.js.map +1 -0
- package/dist/manifests/manifest-template.d.ts +18 -0
- package/dist/manifests/manifest-validation.cjs +2 -0
- package/dist/manifests/manifest-validation.cjs.map +1 -0
- package/dist/manifests/manifest-validation.d.ts +30 -0
- package/dist/manifests/manifest-validation.js +145 -0
- package/dist/manifests/manifest-validation.js.map +1 -0
- package/dist/manifests/types.cjs +2 -0
- package/dist/manifests/types.cjs.map +1 -0
- package/dist/manifests/types.d.ts +227 -0
- package/dist/manifests/types.js +6 -0
- package/dist/manifests/types.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs +9 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js +75 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs +9 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js +78 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.cjs +17 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.js +89 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs +10 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js +17 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.cjs +9 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.js +15 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.cjs +9 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.js +18 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.cjs +9 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.js +14 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.cjs +9 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.js +14 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs +2 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.js +23 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/index.cjs +2 -0
- package/dist/node_modules/@openhands/extensions/automations/index.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/index.js +18 -0
- package/dist/node_modules/@openhands/extensions/automations/index.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/interface.cjs +2 -0
- package/dist/node_modules/@openhands/extensions/automations/interface.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/interface.js +89 -0
- package/dist/node_modules/@openhands/extensions/automations/interface.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js +3 -3
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/skills/index.cjs +17 -4
- package/dist/node_modules/@openhands/extensions/skills/index.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/skills/index.js +5 -5
- package/dist/node_modules/@openhands/extensions/skills/index.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/settings-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/settings-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/settings-client.js +9 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/settings-client.js.map +1 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/monitor.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/monitor.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/monitor.js +29 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/monitor.js.map +1 -0
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +3 -3
- package/dist/package.js.map +1 -1
- package/dist/routes/app-settings.cjs +1 -1
- package/dist/routes/app-settings.js +5 -5
- package/dist/routes/mcp.cjs +1 -1
- package/dist/routes/mcp.cjs.map +1 -1
- package/dist/routes/mcp.js +73 -82
- package/dist/routes/mcp.js.map +1 -1
- package/dist/services/telemetry.cjs +1 -1
- package/dist/services/telemetry.cjs.map +1 -1
- package/dist/services/telemetry.d.ts +8 -0
- package/dist/services/telemetry.js +163 -116
- package/dist/services/telemetry.js.map +1 -1
- package/dist/types/agent-server/core/events/conversation-state-event.d.ts +2 -19
- package/dist/types/agent-server/core/events/observation-event.d.ts +2 -18
- package/dist/types/automation.d.ts +7 -3
- package/dist/types/mcp-server.d.ts +5 -0
- package/dist/types/settings.d.ts +3 -0
- package/dist/utils/api-error-message.d.ts +6 -2
- package/dist/utils/automation-catalog.cjs +2 -0
- package/dist/utils/automation-catalog.cjs.map +1 -0
- package/dist/utils/automation-catalog.d.ts +28 -0
- package/dist/utils/automation-catalog.js +5 -0
- package/dist/utils/automation-catalog.js.map +1 -0
- package/dist/utils/automation-timeout.d.ts +3 -2
- package/dist/utils/mcp-config.cjs +1 -1
- package/dist/utils/mcp-config.cjs.map +1 -1
- package/dist/utils/mcp-config.d.ts +8 -0
- package/dist/utils/mcp-config.js +25 -20
- package/dist/utils/mcp-config.js.map +1 -1
- package/dist/utils/mcp-installed-servers.cjs +1 -1
- package/dist/utils/mcp-installed-servers.cjs.map +1 -1
- package/dist/utils/mcp-installed-servers.js +6 -3
- package/dist/utils/mcp-installed-servers.js.map +1 -1
- package/dist/utils/responder-deployment.d.ts +5 -1
- package/dist/utils/transcript-export/index.cjs +5 -5
- package/dist/utils/transcript-export/index.js +12 -12
- package/package.json +3 -3
- package/scripts/check-sdk-version-sync.mjs +6 -6
- package/scripts/check-translation-completeness.cjs +1 -0
- package/scripts/dev-safe.mjs +17 -12
- package/scripts/dev-static.mjs +17 -0
- package/scripts/dev-with-automation.mjs +12 -14
- package/scripts/ingress.mjs +22 -0
- package/scripts/proxy-utils.mjs +157 -2
- package/scripts/runtime-services-info.mjs +6 -6
- package/scripts/static-build.mjs +0 -7
- package/scripts/static-server.mjs +10 -0
- package/build/assets/active-backend-context-BlZPzZNU.js +0 -1
- package/build/assets/agent-context-settings-CTaN-Iw9.js +0 -1
- package/build/assets/agent-profiles-settings-CR4VTqv_.js +0 -1
- package/build/assets/agent-server-conversation-service.api-Btmi4q6d.js +0 -41
- package/build/assets/agent-settings-KQs-occT.js +0 -1
- package/build/assets/api-key-entry-screen-BhR24gkM.js +0 -1
- package/build/assets/app-settings-Bs4sY8WP.js +0 -1
- package/build/assets/automation-BGP_I1RR.js +0 -1
- package/build/assets/automation-detail-CwDnJbYR.js +0 -2
- package/build/assets/automation-export-Bu-r-EzL.js +0 -2
- package/build/assets/automations-list-CYw7_6FR.js +0 -1
- package/build/assets/backend-form-modal-Ce-KRHOJ.js +0 -1
- package/build/assets/browser-BUDJnBg4.js +0 -6
- package/build/assets/check-BMOG005H.js +0 -1
- package/build/assets/chevron-down-CV1zZP_K.js +0 -1
- package/build/assets/circle-check-lvN_jFN5.js +0 -1
- package/build/assets/client-source-1v-kWLNU.js +0 -1
- package/build/assets/cloud-funnel-analytics-CasMM7EO.js +0 -1
- package/build/assets/command-menu-N_BriUy8.js +0 -1
- package/build/assets/condenser-settings-Czi8cKxV.js +0 -1
- package/build/assets/conversation-C25pc2dT.js +0 -1
- package/build/assets/conversation-CObLYSJd.js +0 -90
- package/build/assets/conversation-panel-C25pc2dT.js +0 -1
- package/build/assets/conversation-state-store-DTq4hFoP.js +0 -1
- package/build/assets/extensions-hub-BKftOQ-X.js +0 -1
- package/build/assets/extensions-navigation-DF24q1H1.js +0 -1
- package/build/assets/files-tab-SAiFCnS5.js +0 -1
- package/build/assets/git-provider-icon-BREx-yUX.js +0 -1
- package/build/assets/home-EPNFgzUh.js +0 -1
- package/build/assets/home-sN90Xcxp.js +0 -1
- package/build/assets/index-home-EPNFgzUh.js +0 -1
- package/build/assets/install-server-modal-BI8yUfmr.js +0 -1
- package/build/assets/llm-not-configured-banner-DTWzISnk.js +0 -27
- package/build/assets/llm-settings-BXk5_Pac.js +0 -1
- package/build/assets/llm-settings-C1vpgWam.js +0 -1
- package/build/assets/loader-circle-6zlEYCJw.js +0 -1
- package/build/assets/manage-backends-modal-DhflyGTf.js +0 -1
- package/build/assets/manifest-8082e879.js +0 -1
- package/build/assets/mcp-CxLPda-W.js +0 -9
- package/build/assets/messages-DINDkPNK.js +0 -40
- package/build/assets/onboarding-modal-DdvE6rzw.js +0 -1
- package/build/assets/organization-service.api-CT2OQlLz.js +0 -1
- package/build/assets/plugins-management-service-DVkoM3eA.js +0 -1
- package/build/assets/plus-vIbGD459.js +0 -1
- package/build/assets/profiles-service.api-CBafmAPO.js +0 -1
- package/build/assets/providers-9UzRB9mT.js +0 -1
- package/build/assets/proxy-C79PCMjo.js +0 -1
- package/build/assets/recommended-automations-launcher-BF2mtAKw.js +0 -58
- package/build/assets/root-B5JXKp1P.css +0 -1
- package/build/assets/root-Sj7W28yE.js +0 -2
- package/build/assets/root-layout-DbhKVoc7.js +0 -3
- package/build/assets/schema-field-CV6bFnoL.js +0 -1
- package/build/assets/search-sKuYKllf.js +0 -1
- package/build/assets/secrets-service-BjK-bPN2.js +0 -1
- package/build/assets/segmented-toggle-DbbD3Tve.js +0 -1
- package/build/assets/settings-Bj5Oo45A.js +0 -1
- package/build/assets/settings-input-BjW_zyTN.js +0 -1
- package/build/assets/settings-service.api-DryhKdSr.js +0 -1
- package/build/assets/shared-conversation-CnMxy7p_.js +0 -1
- package/build/assets/telemetry-cmCL3o6Z.js +0 -2
- package/build/assets/use-activate-agent-profile-DH33MvVj.js +0 -1
- package/build/assets/use-agent-profiles-Dmd_4H8q.js +0 -1
- package/build/assets/use-cloud-current-user-id-B6DP3s47.js +0 -1
- package/build/assets/use-is-authed-BsS4XwSL.js +0 -1
- package/build/assets/use-llm-profiles-BMQoc612.js +0 -1
- package/build/assets/use-onboarding-completion-B-2BTS-y.js +0 -1
- package/build/assets/use-plugins-marketplace-PBc_XNz_.js +0 -1
- package/build/assets/use-save-agent-profile-2Mk9ZX37.js +0 -1
- package/build/assets/use-settings-DBI44RnH.js +0 -1
- package/build/assets/use-settings-nav-items-Cva28C-c.js +0 -16
- package/build/assets/use-skills-RQsCtdzN.js +0 -1
- package/build/assets/use-tracking-CN1nIMnY.js +0 -1
- package/build/assets/utils-qjs_KuS4.js +0 -1
- package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation-EShpjxey.js +0 -1
- package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-DD_UNO02.js +0 -1
- package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~onboarding-modal-Be63Q2Ln.js +0 -1
- package/build/assets/x-EjvKGawc.js +0 -1
- /package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f1hl7voa-BrmgjeOw.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~emdr2jt4-BrmgjeOw.js} +0 -0
|
@@ -12,6 +12,11 @@ export interface MCPServerConfig {
|
|
|
12
12
|
args?: string[];
|
|
13
13
|
env?: Record<string, string>;
|
|
14
14
|
auth?: MCPAuthCredential;
|
|
15
|
+
/**
|
|
16
|
+
* Whether the agent may use this server. Absent means enabled — only an
|
|
17
|
+
* explicit `false` disables, so existing configs stay untouched.
|
|
18
|
+
*/
|
|
19
|
+
enabled?: boolean;
|
|
15
20
|
}
|
|
16
21
|
export interface MCPTestToolCall {
|
|
17
22
|
name: string;
|
package/dist/types/settings.d.ts
CHANGED
|
@@ -17,12 +17,14 @@ export type MCPSSEServer = {
|
|
|
17
17
|
url: string;
|
|
18
18
|
headers?: Record<string, string>;
|
|
19
19
|
auth?: MCPAuthCredential;
|
|
20
|
+
enabled?: boolean;
|
|
20
21
|
};
|
|
21
22
|
export type MCPStdioServer = {
|
|
22
23
|
name: string;
|
|
23
24
|
command: string;
|
|
24
25
|
args?: string[];
|
|
25
26
|
env?: Record<string, string>;
|
|
27
|
+
enabled?: boolean;
|
|
26
28
|
};
|
|
27
29
|
export type MCPSHTTPServer = {
|
|
28
30
|
name?: string;
|
|
@@ -30,6 +32,7 @@ export type MCPSHTTPServer = {
|
|
|
30
32
|
headers?: Record<string, string>;
|
|
31
33
|
timeout?: number;
|
|
32
34
|
auth?: MCPAuthCredential;
|
|
35
|
+
enabled?: boolean;
|
|
33
36
|
};
|
|
34
37
|
export type MCPConfig = {
|
|
35
38
|
sse_servers: (string | MCPSSEServer)[];
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Extract
|
|
2
|
+
* Extract the parsed response body from a failed API call.
|
|
3
3
|
*
|
|
4
4
|
* Handles both transports the app uses: local agent-server calls that
|
|
5
5
|
* throw an `AxiosError` (body under `error.response.data`) and cloud
|
|
6
6
|
* calls through the shared TypeScript client that throw an `HttpError`
|
|
7
|
-
* (parsed body directly under `error.response`).
|
|
7
|
+
* (parsed body directly under `error.response`).
|
|
8
|
+
*/
|
|
9
|
+
export declare function getApiErrorBody(error: unknown): unknown;
|
|
10
|
+
/**
|
|
11
|
+
* Extract a human-readable message from a failed API call. Prefers the
|
|
8
12
|
* server-provided `message`/`detail` fields, then the `Error` message,
|
|
9
13
|
* then `fallback`.
|
|
10
14
|
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automation-catalog.cjs","names":[],"sources":["../../src/utils/automation-catalog.ts"],"sourcesContent":["import type { RecommendedAutomation } from \"@openhands/extensions/automations\";\nimport {\n SKILLS_CATALOG,\n type SkillCatalogEntry,\n} from \"@openhands/extensions/skills\";\n\n/**\n * Reading a published automation catalog entry.\n *\n * The catalog states each thing once and leaves the rest to be derived, so an\n * entry no longer carries its own launch command or a flat list of required\n * integration ids. This module is the single place that performs those\n * derivations, so the components consuming the catalog stay unaware of how it\n * is shaped.\n */\n\nconst SKILL_BY_NAME = new Map<string, SkillCatalogEntry>(\n SKILLS_CATALOG.map((skill) => [skill.name, skill]),\n);\n\n/** Every integration the entry declares, in declaration order. */\nexport function getIntegrationIds(automation: RecommendedAutomation): string[] {\n return Object.keys(automation.requires.integrations);\n}\n\n/**\n * The integrations that gate this automation. One marked `required: false` can\n * be connected later, during setup, so it is still worth showing on the card\n * but must never stand between the user and a launch.\n */\nexport function getRequiredIntegrationIds(\n automation: RecommendedAutomation,\n): string[] {\n return Object.entries(automation.requires.integrations)\n .filter(([, requirement]) => requirement.required !== false)\n .map(([id]) => id);\n}\n\n/**\n * The command that invokes this automation's skill, or null when that skill is\n * invoked by description instead.\n *\n * The command is declared once, in the owning skill's own `triggers`; the\n * catalog names that skill only where it differs from the entry id.\n */\nexport function findAutomationCommand(\n automation: Pick<RecommendedAutomation, \"id\" | \"skill\">,\n): string | null {\n const skill = SKILL_BY_NAME.get(automation.skill ?? automation.id);\n return skill?.triggers[0] ?? null;\n}\n\n/**\n * What launching an automation card hands to the agent.\n *\n * The resolved command is passed through as-is: API routing (host, auth) is\n * discovered by the agent at runtime from `<RUNTIME_SERVICES>` in the system\n * prompt, and the skills themselves carry the instructions for reading that\n * block. An automation whose skill declares no command has the request spelled\n * out instead. Both are instructions to the agent rather than user-facing UI\n * copy, so they are intentionally in English and not localized.\n */\nexport function getAutomationLaunchPrompt(\n automation: RecommendedAutomation,\n): string {\n return (\n findAutomationCommand(automation) ??\n `Set up the ${automation.name} automation`\n );\n}\n"],"mappings":"uHAgBsB,IAAI,IACxB,EAAA,QAAe,IAAK,GAAU,CAAC,EAAM,KAAM,CAAK,CAAC,CACnD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { RecommendedAutomation } from "@openhands/extensions/automations";
|
|
2
|
+
/** Every integration the entry declares, in declaration order. */
|
|
3
|
+
export declare function getIntegrationIds(automation: RecommendedAutomation): string[];
|
|
4
|
+
/**
|
|
5
|
+
* The integrations that gate this automation. One marked `required: false` can
|
|
6
|
+
* be connected later, during setup, so it is still worth showing on the card
|
|
7
|
+
* but must never stand between the user and a launch.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getRequiredIntegrationIds(automation: RecommendedAutomation): string[];
|
|
10
|
+
/**
|
|
11
|
+
* The command that invokes this automation's skill, or null when that skill is
|
|
12
|
+
* invoked by description instead.
|
|
13
|
+
*
|
|
14
|
+
* The command is declared once, in the owning skill's own `triggers`; the
|
|
15
|
+
* catalog names that skill only where it differs from the entry id.
|
|
16
|
+
*/
|
|
17
|
+
export declare function findAutomationCommand(automation: Pick<RecommendedAutomation, "id" | "skill">): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* What launching an automation card hands to the agent.
|
|
20
|
+
*
|
|
21
|
+
* The resolved command is passed through as-is: API routing (host, auth) is
|
|
22
|
+
* discovered by the agent at runtime from `<RUNTIME_SERVICES>` in the system
|
|
23
|
+
* prompt, and the skills themselves carry the instructions for reading that
|
|
24
|
+
* block. An automation whose skill declares no command has the request spelled
|
|
25
|
+
* out instead. Both are instructions to the agent rather than user-facing UI
|
|
26
|
+
* copy, so they are intentionally in English and not localized.
|
|
27
|
+
*/
|
|
28
|
+
export declare function getAutomationLaunchPrompt(automation: RecommendedAutomation): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automation-catalog.js","names":[],"sources":["../../src/utils/automation-catalog.ts"],"sourcesContent":["import type { RecommendedAutomation } from \"@openhands/extensions/automations\";\nimport {\n SKILLS_CATALOG,\n type SkillCatalogEntry,\n} from \"@openhands/extensions/skills\";\n\n/**\n * Reading a published automation catalog entry.\n *\n * The catalog states each thing once and leaves the rest to be derived, so an\n * entry no longer carries its own launch command or a flat list of required\n * integration ids. This module is the single place that performs those\n * derivations, so the components consuming the catalog stay unaware of how it\n * is shaped.\n */\n\nconst SKILL_BY_NAME = new Map<string, SkillCatalogEntry>(\n SKILLS_CATALOG.map((skill) => [skill.name, skill]),\n);\n\n/** Every integration the entry declares, in declaration order. */\nexport function getIntegrationIds(automation: RecommendedAutomation): string[] {\n return Object.keys(automation.requires.integrations);\n}\n\n/**\n * The integrations that gate this automation. One marked `required: false` can\n * be connected later, during setup, so it is still worth showing on the card\n * but must never stand between the user and a launch.\n */\nexport function getRequiredIntegrationIds(\n automation: RecommendedAutomation,\n): string[] {\n return Object.entries(automation.requires.integrations)\n .filter(([, requirement]) => requirement.required !== false)\n .map(([id]) => id);\n}\n\n/**\n * The command that invokes this automation's skill, or null when that skill is\n * invoked by description instead.\n *\n * The command is declared once, in the owning skill's own `triggers`; the\n * catalog names that skill only where it differs from the entry id.\n */\nexport function findAutomationCommand(\n automation: Pick<RecommendedAutomation, \"id\" | \"skill\">,\n): string | null {\n const skill = SKILL_BY_NAME.get(automation.skill ?? automation.id);\n return skill?.triggers[0] ?? null;\n}\n\n/**\n * What launching an automation card hands to the agent.\n *\n * The resolved command is passed through as-is: API routing (host, auth) is\n * discovered by the agent at runtime from `<RUNTIME_SERVICES>` in the system\n * prompt, and the skills themselves carry the instructions for reading that\n * block. An automation whose skill declares no command has the request spelled\n * out instead. Both are instructions to the agent rather than user-facing UI\n * copy, so they are intentionally in English and not localized.\n */\nexport function getAutomationLaunchPrompt(\n automation: RecommendedAutomation,\n): string {\n return (\n findAutomationCommand(automation) ??\n `Set up the ${automation.name} automation`\n );\n}\n"],"mappings":";AAgBsB,IAAI,IACxB,EAAe,KAAK,MAAU,CAAC,EAAM,MAAM,CAAK,CAAC,CACnD"}
|
|
@@ -14,6 +14,7 @@ export type AutomationTimeoutValidation = {
|
|
|
14
14
|
/**
|
|
15
15
|
* Validate a raw timeout string from the edit form. A blank string means "use
|
|
16
16
|
* the server default" (resolved as `null`). Otherwise the value must be a
|
|
17
|
-
* positive integer no greater than
|
|
17
|
+
* positive integer no greater than the ceiling, which the interface manifest
|
|
18
|
+
* may lower from {@link AUTOMATION_TIMEOUT_MAX_SECONDS}.
|
|
18
19
|
*/
|
|
19
|
-
export declare function validateAutomationTimeout(raw: string): AutomationTimeoutValidation;
|
|
20
|
+
export declare function validateAutomationTimeout(raw: string, maxSeconds?: number): AutomationTimeoutValidation;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs");const e=require("./mcp-server-name.cjs");var t={sse_servers:[],stdio_servers:[],shttp_servers:[]},n=`**********`;function r(e,t){return RegExp(`^${t}(_\\d+)?$`).test(e)?void 0:e}function i(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function a(e){if(!i(e))return null;let t=e.mcpServers;return i(t)&&!(`url`in t)&&!(`command`in t)?t:e}function o(e){if(!i(e))return;let t=Object.entries(e).filter(e=>typeof e[1]==`string`);return t.length>0?Object.fromEntries(t):void 0}function s(e){return e===`**********`?!0:Array.isArray(e)?e.some(s):i(e)?Object.values(e).some(s):!1}function c(e){if(!i(e))return;let t={};return i(e.tokens)&&(t.tokens=e.tokens),i(e.client_info)&&(t.client_info=e.client_info),(typeof e.token_expires_at==`number`||e.token_expires_at===null)&&(t.token_expires_at=e.token_expires_at),Object.keys(t).length>0?t:void 0}function l(e){if(i(e))switch(e.strategy){case`none`:return{strategy:`none`};case`api_key`:return typeof e.value==`string`?{strategy:`api_key`,value:e.value,...typeof e.header_name==`string`&&{header_name:e.header_name}}:void 0;case`bearer`:return typeof e.value==`string`?{strategy:`bearer`,value:e.value}:void 0;case`basic`:return typeof e.username!=`string`||typeof e.password!=`string`?void 0:{strategy:`basic`,username:e.username,password:e.password};case`header`:{let t=o(e.headers);return t?{strategy:`header`,headers:t}:void 0}case`oauth2`:{let t=
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");const e=require("./mcp-server-name.cjs");var t={sse_servers:[],stdio_servers:[],shttp_servers:[]},n=`**********`;function r(e,t){return RegExp(`^${t}(_\\d+)?$`).test(e)?void 0:e}function i(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function a(e){if(!i(e))return null;let t=e.mcpServers;return i(t)&&!(`url`in t)&&!(`command`in t)?t:e}function o(e){if(!i(e))return;let t=Object.entries(e).filter(e=>typeof e[1]==`string`);return t.length>0?Object.fromEntries(t):void 0}function s(e){return e===`**********`?!0:Array.isArray(e)?e.some(s):i(e)?Object.values(e).some(s):!1}function c(e){if(!i(e))return;let t={};return i(e.tokens)&&(t.tokens=e.tokens),i(e.client_info)&&(t.client_info=e.client_info),(typeof e.token_expires_at==`number`||e.token_expires_at===null)&&(t.token_expires_at=e.token_expires_at),Object.keys(t).length>0?t:void 0}function l(e){if(i(e))switch(e.strategy){case`none`:return{strategy:`none`};case`api_key`:return typeof e.value==`string`?{strategy:`api_key`,value:e.value,...typeof e.header_name==`string`&&{header_name:e.header_name}}:void 0;case`bearer`:return typeof e.value==`string`?{strategy:`bearer`,value:e.value}:void 0;case`basic`:return typeof e.username!=`string`||typeof e.password!=`string`?void 0:{strategy:`basic`,username:e.username,password:e.password};case`header`:{let t=o(e.headers);return t?{strategy:`header`,headers:t}:void 0}case`oauth2`:{let t=_(e.authentication),n=c(e.state);return{strategy:`oauth2`,...t&&{authentication:t},...n&&{state:n}}}default:return}}function u(e){return l(e.auth)}function d(e){let t={};return e.auth&&!s(e.auth)&&(t.auth=e.auth),e.headers&&Object.keys(e.headers).length>0&&(t.headers=e.headers),t}function f(e){return e.enabled===!1?{enabled:!1}:{}}function p(e){return{...e.name&&{name:e.name},url:e.url,...e.headers&&{headers:e.headers},...e.auth&&{auth:e.auth},...f(e)}}function m(e){return p(e)}function h(e){return{...p(e),...e.timeout!==void 0&&{timeout:e.timeout}}}function g(e){return{name:e.name,command:e.command,...e.args&&{args:e.args},...e.env&&{env:e.env},...f(e)}}function _(e){if(!e||typeof e!=`object`)return;let t=e;if(t.type!==`oauth`)return;let n={type:`oauth`};return(t.client_auth_method===`none`||t.client_auth_method===`client_secret_post`||t.client_auth_method===`client_secret_basic`||t.client_auth_method===`private_key_jwt`)&&(n.client_auth_method=t.client_auth_method),(typeof t.scopes==`string`||Array.isArray(t.scopes)&&t.scopes.every(e=>typeof e==`string`))&&(n.scopes=t.scopes),typeof t.client_name==`string`&&(n.client_name=t.client_name),typeof t.client_metadata_url==`string`&&(n.client_metadata_url=t.client_metadata_url),typeof t.client_id==`string`&&(n.client_id=t.client_id),typeof t.client_secret==`string`&&(n.client_secret=t.client_secret),t.additional_client_metadata&&typeof t.additional_client_metadata==`object`&&!Array.isArray(t.additional_client_metadata)&&(n.additional_client_metadata=t.additional_client_metadata),n}function v(e){let n=a(e);if(!n)return{...t};let s=[],c=[],l=[];for(let[e,t]of Object.entries(n)){if(!i(t))continue;let n=t.url,a=t.enabled===!1;if(n){let i=t.transport,c=u(t),d=o(t.headers);if(i===`sse`){let t=r(e,`sse`),i={url:n};t&&(i.name=t),c&&(i.auth=c),d&&(i.headers=d),a&&(i.enabled=!1),s.push(i)}else{let i=r(e,`shttp`),o={url:n};i&&(o.name=i),t.timeout!=null&&(o.timeout=t.timeout),c&&(o.auth=c),d&&(o.headers=d),a&&(o.enabled=!1),l.push(o)}}else{if(typeof t.command!=`string`)continue;let n={name:e,command:t.command};t.args&&(n.args=t.args),t.env&&(n.env=t.env),a&&(n.enabled=!1),c.push(n)}}return{sse_servers:s,stdio_servers:c,shttp_servers:l}}function y(t){let n={},r=t=>{let r=e.toMcpServerName(t);if(!(r in n))return r;let i=1;for(;`${r}_${i}`in n;)i+=1;return`${r}_${i}`};for(let e of t.sse_servers){let t={},i;typeof e==`string`?t.url=e:(i=e.name,t.url=e.url,Object.assign(t,d(e),f(e))),t.transport=`sse`,n[r(i||`sse`)]=t}for(let e of t.shttp_servers){let t={transport:`http`},i;typeof e==`string`?t.url=e:(i=e.name,t.url=e.url,Object.assign(t,d(e),f(e)),e.timeout!=null&&(t.timeout=e.timeout)),n[r(i||`shttp`)]=t}for(let e of t.stdio_servers){let t={command:e.command};e.args&&(t.args=e.args),e.env&&(t.env=e.env),Object.assign(t,f(e)),n[r(e.name||`stdio`)]=t}return Object.keys(n).length>0?n:null}exports.REDACTED_MCP_SECRET_VALUE=n,exports.getSdkMcpServerMap=a,exports.hasRedactedMcpSecretLeaf=s,exports.parseMcpConfig=v,exports.stringRecord=o,exports.toMcpShttpServer=h,exports.toMcpSseServer=m,exports.toMcpStdioServer=g,exports.toSdkMcpConfig=y;
|
|
2
2
|
//# sourceMappingURL=mcp-config.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-config.cjs","names":[],"sources":["../../src/utils/mcp-config.ts"],"sourcesContent":["import {\n MCPConfig,\n MCPSSEServer,\n MCPSHTTPServer,\n MCPStdioServer,\n SettingsValue,\n} from \"#/types/settings\";\nimport type {\n MCPAuthCredential,\n MCPAuthenticationConfig,\n MCPJsonValue,\n MCPOAuthState,\n} from \"#/types/mcp-auth\";\nimport type { MCPServerConfig } from \"#/types/mcp-server\";\nimport { toMcpServerName } from \"#/utils/mcp-server-name\";\n\nconst EMPTY_MCP_CONFIG: MCPConfig = {\n sse_servers: [],\n stdio_servers: [],\n shttp_servers: [],\n};\n\nexport const REDACTED_MCP_SECRET_VALUE = \"**********\";\n\ntype SdkMcpServerConfig = Record<string, SettingsValue | MCPAuthCredential>;\ntype SdkMcpConfig = Record<string, SdkMcpServerConfig>;\n\n/**\n * The dict key for an SSE/SHTTP server doubles as its display name once a\n * user provides one. Keys that match the auto-generated fallback pattern\n * (``sse``, ``shttp``, ``shttp_1``, …) emitted by {@link toSdkMcpConfig}\n * carry no user intent, so we surface them as \"no name\" — re-serializing\n * regenerates the identical fallback key and existing configs are left\n * untouched.\n */\nfunction userGivenServerName(\n serverName: string,\n base: \"sse\" | \"shttp\",\n): string | undefined {\n const autoGenerated = new RegExp(`^${base}(_\\\\d+)?$`);\n return autoGenerated.test(serverName) ? undefined : serverName;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function getSdkMcpServerMap(\n value: unknown,\n): Record<string, unknown> | null {\n if (!isRecord(value)) return null;\n\n const mcpServers = value.mcpServers;\n if (\n isRecord(mcpServers) &&\n !(\"url\" in mcpServers) &&\n !(\"command\" in mcpServers)\n ) {\n return mcpServers;\n }\n\n return value;\n}\n\nexport function stringRecord(\n value: unknown,\n): Record<string, string> | undefined {\n if (!isRecord(value)) return undefined;\n const entries = Object.entries(value).filter(\n (entry): entry is [string, string] => typeof entry[1] === \"string\",\n );\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\nexport function hasRedactedMcpSecretLeaf(value: unknown): boolean {\n if (value === REDACTED_MCP_SECRET_VALUE) return true;\n if (Array.isArray(value)) return value.some(hasRedactedMcpSecretLeaf);\n if (isRecord(value))\n return Object.values(value).some(hasRedactedMcpSecretLeaf);\n return false;\n}\n\nfunction getOAuthState(value: unknown): MCPOAuthState | undefined {\n if (!isRecord(value)) return undefined;\n const state: MCPOAuthState = {};\n if (isRecord(value.tokens)) {\n state.tokens = value.tokens as NonNullable<MCPOAuthState[\"tokens\"]>;\n }\n if (isRecord(value.client_info)) {\n state.client_info = value.client_info as NonNullable<\n MCPOAuthState[\"client_info\"]\n >;\n }\n if (\n typeof value.token_expires_at === \"number\" ||\n value.token_expires_at === null\n ) {\n state.token_expires_at = value.token_expires_at;\n }\n return Object.keys(state).length > 0 ? state : undefined;\n}\n\nfunction normalizeTaggedAuthCredential(\n value: unknown,\n): MCPAuthCredential | undefined {\n if (!isRecord(value)) return undefined;\n switch (value.strategy) {\n case \"none\":\n return { strategy: \"none\" };\n case \"api_key\":\n if (typeof value.value !== \"string\") return undefined;\n return {\n strategy: \"api_key\",\n value: value.value,\n ...(typeof value.header_name === \"string\" && {\n header_name: value.header_name,\n }),\n };\n case \"bearer\":\n if (typeof value.value !== \"string\") return undefined;\n return { strategy: \"bearer\", value: value.value };\n case \"basic\":\n if (\n typeof value.username !== \"string\" ||\n typeof value.password !== \"string\"\n ) {\n return undefined;\n }\n return {\n strategy: \"basic\",\n username: value.username,\n password: value.password,\n };\n case \"header\": {\n const headers = stringRecord(value.headers);\n return headers ? { strategy: \"header\", headers } : undefined;\n }\n case \"oauth2\": {\n const authentication = getAuthenticationConfig(value.authentication);\n const state = getOAuthState(value.state);\n return {\n strategy: \"oauth2\",\n ...(authentication && { authentication }),\n ...(state && { state }),\n };\n }\n default:\n return undefined;\n }\n}\n\nfunction authCredentialFromServerConfig(\n serverConfig: Record<string, unknown>,\n): MCPAuthCredential | undefined {\n return normalizeTaggedAuthCredential(serverConfig.auth);\n}\n\nfunction getRemoteSecretFields(entry: {\n auth?: MCPAuthCredential;\n headers?: Record<string, string>;\n}): Partial<SdkMcpServerConfig> {\n const fields: Partial<SdkMcpServerConfig> = {};\n if (entry.auth && !hasRedactedMcpSecretLeaf(entry.auth)) {\n fields.auth = entry.auth;\n }\n if (entry.headers && Object.keys(entry.headers).length > 0) {\n fields.headers = entry.headers;\n }\n return fields;\n}\n\nfunction getRemoteServerFields(server: MCPServerConfig) {\n return {\n ...(server.name && { name: server.name }),\n url: server.url!,\n ...(server.headers && { headers: server.headers }),\n ...(server.auth && { auth: server.auth }),\n };\n}\n\nexport function toMcpSseServer(server: MCPServerConfig): MCPSSEServer {\n return getRemoteServerFields(server);\n}\n\nexport function toMcpShttpServer(server: MCPServerConfig): MCPSHTTPServer {\n return {\n ...getRemoteServerFields(server),\n ...(server.timeout !== undefined && { timeout: server.timeout }),\n };\n}\n\nexport function toMcpStdioServer(server: MCPServerConfig): MCPStdioServer {\n return {\n name: server.name!,\n command: server.command!,\n ...(server.args && { args: server.args }),\n ...(server.env && { env: server.env }),\n };\n}\n\nfunction getAuthenticationConfig(\n value: unknown,\n): MCPAuthenticationConfig | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const record = value as Record<string, unknown>;\n if (record.type !== \"oauth\") return undefined;\n const authentication: MCPAuthenticationConfig = { type: \"oauth\" };\n if (\n record.client_auth_method === \"none\" ||\n record.client_auth_method === \"client_secret_post\" ||\n record.client_auth_method === \"client_secret_basic\" ||\n record.client_auth_method === \"private_key_jwt\"\n ) {\n authentication.client_auth_method = record.client_auth_method;\n }\n if (typeof record.scopes === \"string\") {\n authentication.scopes = record.scopes;\n } else if (\n Array.isArray(record.scopes) &&\n record.scopes.every((scope) => typeof scope === \"string\")\n ) {\n authentication.scopes = record.scopes;\n }\n if (typeof record.client_name === \"string\") {\n authentication.client_name = record.client_name;\n }\n if (typeof record.client_metadata_url === \"string\") {\n authentication.client_metadata_url = record.client_metadata_url;\n }\n if (typeof record.client_id === \"string\") {\n authentication.client_id = record.client_id;\n }\n if (typeof record.client_secret === \"string\") {\n authentication.client_secret = record.client_secret;\n }\n if (\n record.additional_client_metadata &&\n typeof record.additional_client_metadata === \"object\" &&\n !Array.isArray(record.additional_client_metadata)\n ) {\n authentication.additional_client_metadata =\n record.additional_client_metadata as Record<string, MCPJsonValue>;\n }\n return authentication;\n}\n\n/**\n * Parse the SDK-native ``agent_settings.mcp_config`` value and convert it\n * to the frontend MCPConfig format used by UI components.\n */\nexport function parseMcpConfig(value: unknown): MCPConfig {\n const mcpConfig = getSdkMcpServerMap(value);\n if (!mcpConfig) {\n return { ...EMPTY_MCP_CONFIG };\n }\n\n const sseServers: (string | MCPSSEServer)[] = [];\n const stdioServers: MCPStdioServer[] = [];\n const shttpServers: (string | MCPSHTTPServer)[] = [];\n\n for (const [serverName, serverConfig] of Object.entries(mcpConfig)) {\n if (!isRecord(serverConfig)) continue;\n\n const url = serverConfig.url as string | undefined;\n\n if (url) {\n const transport = serverConfig.transport as string | undefined;\n const auth = authCredentialFromServerConfig(serverConfig);\n const headers = stringRecord(serverConfig.headers);\n\n if (transport === \"sse\") {\n const name = userGivenServerName(serverName, \"sse\");\n const server: MCPSSEServer = { url };\n if (name) server.name = name;\n if (auth) server.auth = auth;\n if (headers) server.headers = headers;\n sseServers.push(server);\n } else {\n const name = userGivenServerName(serverName, \"shttp\");\n const server: MCPSHTTPServer = { url };\n if (name) server.name = name;\n if (serverConfig.timeout != null) {\n server.timeout = serverConfig.timeout as number;\n }\n if (auth) server.auth = auth;\n if (headers) server.headers = headers;\n shttpServers.push(server);\n }\n } else {\n if (typeof serverConfig.command !== \"string\") continue;\n const stdioServer: MCPStdioServer = {\n name: serverName,\n command: serverConfig.command,\n };\n if (serverConfig.args) {\n stdioServer.args = serverConfig.args as string[];\n }\n if (serverConfig.env) {\n stdioServer.env = serverConfig.env as Record<string, string>;\n }\n stdioServers.push(stdioServer);\n }\n }\n\n return {\n sse_servers: sseServers,\n stdio_servers: stdioServers,\n shttp_servers: shttpServers,\n };\n}\n\n/**\n * Convert the frontend MCPConfig format back to the SDK-native server map\n * expected by agent_settings.mcp_config on the backend.\n *\n * Names are only suffixed (``_1``, ``_2``, …) when an earlier entry has\n * already claimed the bare base name. We intentionally do NOT use a single\n * monotonic counter across server types: that would, for example, rename a\n * stdio server \"myname\" to \"myname_1\" the moment any sse/shttp entry is\n * persisted ahead of it, and shift the suffix on every save as the count\n * of other server types changes. With per-base collision suffixing,\n * unrelated entries keep their human-meaningful names stable across edits.\n */\nexport function toSdkMcpConfig(config: MCPConfig): SdkMcpConfig | null {\n const mcpConfig: SdkMcpConfig = {};\n\n const reserve = (base: string): string => {\n const safeBase = toMcpServerName(base);\n if (!(safeBase in mcpConfig)) return safeBase;\n let i = 1;\n while (`${safeBase}_${i}` in mcpConfig) i += 1;\n return `${safeBase}_${i}`;\n };\n\n for (const entry of config.sse_servers) {\n const server: SdkMcpServerConfig = {};\n let name: string | undefined;\n if (typeof entry === \"string\") {\n server.url = entry;\n } else {\n name = entry.name;\n server.url = entry.url;\n Object.assign(server, getRemoteSecretFields(entry));\n }\n server.transport = \"sse\";\n mcpConfig[reserve(name || \"sse\")] = server;\n }\n\n for (const entry of config.shttp_servers) {\n const server: SdkMcpServerConfig = { transport: \"http\" };\n let name: string | undefined;\n if (typeof entry === \"string\") {\n server.url = entry;\n } else {\n name = entry.name;\n server.url = entry.url;\n Object.assign(server, getRemoteSecretFields(entry));\n if (entry.timeout != null) server.timeout = entry.timeout;\n }\n mcpConfig[reserve(name || \"shttp\")] = server;\n }\n\n for (const entry of config.stdio_servers) {\n const server: SdkMcpServerConfig = {\n command: entry.command,\n };\n if (entry.args) server.args = entry.args;\n if (entry.env) server.env = entry.env;\n mcpConfig[reserve(entry.name || \"stdio\")] = server;\n }\n\n return Object.keys(mcpConfig).length > 0 ? mcpConfig : null;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mcp-config.cjs","names":[],"sources":["../../src/utils/mcp-config.ts"],"sourcesContent":["import {\n MCPConfig,\n MCPSSEServer,\n MCPSHTTPServer,\n MCPStdioServer,\n SettingsValue,\n} from \"#/types/settings\";\nimport type {\n MCPAuthCredential,\n MCPAuthenticationConfig,\n MCPJsonValue,\n MCPOAuthState,\n} from \"#/types/mcp-auth\";\nimport type { MCPServerConfig } from \"#/types/mcp-server\";\nimport { toMcpServerName } from \"#/utils/mcp-server-name\";\n\nconst EMPTY_MCP_CONFIG: MCPConfig = {\n sse_servers: [],\n stdio_servers: [],\n shttp_servers: [],\n};\n\nexport const REDACTED_MCP_SECRET_VALUE = \"**********\";\n\ntype SdkMcpServerConfig = Record<string, SettingsValue | MCPAuthCredential>;\ntype SdkMcpConfig = Record<string, SdkMcpServerConfig>;\n\n/**\n * The dict key for an SSE/SHTTP server doubles as its display name once a\n * user provides one. Keys that match the auto-generated fallback pattern\n * (``sse``, ``shttp``, ``shttp_1``, …) emitted by {@link toSdkMcpConfig}\n * carry no user intent, so we surface them as \"no name\" — re-serializing\n * regenerates the identical fallback key and existing configs are left\n * untouched.\n */\nfunction userGivenServerName(\n serverName: string,\n base: \"sse\" | \"shttp\",\n): string | undefined {\n const autoGenerated = new RegExp(`^${base}(_\\\\d+)?$`);\n return autoGenerated.test(serverName) ? undefined : serverName;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function getSdkMcpServerMap(\n value: unknown,\n): Record<string, unknown> | null {\n if (!isRecord(value)) return null;\n\n const mcpServers = value.mcpServers;\n if (\n isRecord(mcpServers) &&\n !(\"url\" in mcpServers) &&\n !(\"command\" in mcpServers)\n ) {\n return mcpServers;\n }\n\n return value;\n}\n\nexport function stringRecord(\n value: unknown,\n): Record<string, string> | undefined {\n if (!isRecord(value)) return undefined;\n const entries = Object.entries(value).filter(\n (entry): entry is [string, string] => typeof entry[1] === \"string\",\n );\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\nexport function hasRedactedMcpSecretLeaf(value: unknown): boolean {\n if (value === REDACTED_MCP_SECRET_VALUE) return true;\n if (Array.isArray(value)) return value.some(hasRedactedMcpSecretLeaf);\n if (isRecord(value))\n return Object.values(value).some(hasRedactedMcpSecretLeaf);\n return false;\n}\n\nfunction getOAuthState(value: unknown): MCPOAuthState | undefined {\n if (!isRecord(value)) return undefined;\n const state: MCPOAuthState = {};\n if (isRecord(value.tokens)) {\n state.tokens = value.tokens as NonNullable<MCPOAuthState[\"tokens\"]>;\n }\n if (isRecord(value.client_info)) {\n state.client_info = value.client_info as NonNullable<\n MCPOAuthState[\"client_info\"]\n >;\n }\n if (\n typeof value.token_expires_at === \"number\" ||\n value.token_expires_at === null\n ) {\n state.token_expires_at = value.token_expires_at;\n }\n return Object.keys(state).length > 0 ? state : undefined;\n}\n\nfunction normalizeTaggedAuthCredential(\n value: unknown,\n): MCPAuthCredential | undefined {\n if (!isRecord(value)) return undefined;\n switch (value.strategy) {\n case \"none\":\n return { strategy: \"none\" };\n case \"api_key\":\n if (typeof value.value !== \"string\") return undefined;\n return {\n strategy: \"api_key\",\n value: value.value,\n ...(typeof value.header_name === \"string\" && {\n header_name: value.header_name,\n }),\n };\n case \"bearer\":\n if (typeof value.value !== \"string\") return undefined;\n return { strategy: \"bearer\", value: value.value };\n case \"basic\":\n if (\n typeof value.username !== \"string\" ||\n typeof value.password !== \"string\"\n ) {\n return undefined;\n }\n return {\n strategy: \"basic\",\n username: value.username,\n password: value.password,\n };\n case \"header\": {\n const headers = stringRecord(value.headers);\n return headers ? { strategy: \"header\", headers } : undefined;\n }\n case \"oauth2\": {\n const authentication = getAuthenticationConfig(value.authentication);\n const state = getOAuthState(value.state);\n return {\n strategy: \"oauth2\",\n ...(authentication && { authentication }),\n ...(state && { state }),\n };\n }\n default:\n return undefined;\n }\n}\n\nfunction authCredentialFromServerConfig(\n serverConfig: Record<string, unknown>,\n): MCPAuthCredential | undefined {\n return normalizeTaggedAuthCredential(serverConfig.auth);\n}\n\nfunction getRemoteSecretFields(entry: {\n auth?: MCPAuthCredential;\n headers?: Record<string, string>;\n}): Partial<SdkMcpServerConfig> {\n const fields: Partial<SdkMcpServerConfig> = {};\n if (entry.auth && !hasRedactedMcpSecretLeaf(entry.auth)) {\n fields.auth = entry.auth;\n }\n if (entry.headers && Object.keys(entry.headers).length > 0) {\n fields.headers = entry.headers;\n }\n return fields;\n}\n\n/**\n * Only an explicit ``false`` is carried. Every mutation round-trips the whole\n * server map through these converters, so preserving the flag here is what\n * stops adding or deleting one server from silently re-enabling another.\n */\nfunction disabledField(server: { enabled?: boolean }) {\n return server.enabled === false ? { enabled: false as const } : {};\n}\n\nfunction getRemoteServerFields(server: MCPServerConfig) {\n return {\n ...(server.name && { name: server.name }),\n url: server.url!,\n ...(server.headers && { headers: server.headers }),\n ...(server.auth && { auth: server.auth }),\n ...disabledField(server),\n };\n}\n\nexport function toMcpSseServer(server: MCPServerConfig): MCPSSEServer {\n return getRemoteServerFields(server);\n}\n\nexport function toMcpShttpServer(server: MCPServerConfig): MCPSHTTPServer {\n return {\n ...getRemoteServerFields(server),\n ...(server.timeout !== undefined && { timeout: server.timeout }),\n };\n}\n\nexport function toMcpStdioServer(server: MCPServerConfig): MCPStdioServer {\n return {\n name: server.name!,\n command: server.command!,\n ...(server.args && { args: server.args }),\n ...(server.env && { env: server.env }),\n ...disabledField(server),\n };\n}\n\nfunction getAuthenticationConfig(\n value: unknown,\n): MCPAuthenticationConfig | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const record = value as Record<string, unknown>;\n if (record.type !== \"oauth\") return undefined;\n const authentication: MCPAuthenticationConfig = { type: \"oauth\" };\n if (\n record.client_auth_method === \"none\" ||\n record.client_auth_method === \"client_secret_post\" ||\n record.client_auth_method === \"client_secret_basic\" ||\n record.client_auth_method === \"private_key_jwt\"\n ) {\n authentication.client_auth_method = record.client_auth_method;\n }\n if (typeof record.scopes === \"string\") {\n authentication.scopes = record.scopes;\n } else if (\n Array.isArray(record.scopes) &&\n record.scopes.every((scope) => typeof scope === \"string\")\n ) {\n authentication.scopes = record.scopes;\n }\n if (typeof record.client_name === \"string\") {\n authentication.client_name = record.client_name;\n }\n if (typeof record.client_metadata_url === \"string\") {\n authentication.client_metadata_url = record.client_metadata_url;\n }\n if (typeof record.client_id === \"string\") {\n authentication.client_id = record.client_id;\n }\n if (typeof record.client_secret === \"string\") {\n authentication.client_secret = record.client_secret;\n }\n if (\n record.additional_client_metadata &&\n typeof record.additional_client_metadata === \"object\" &&\n !Array.isArray(record.additional_client_metadata)\n ) {\n authentication.additional_client_metadata =\n record.additional_client_metadata as Record<string, MCPJsonValue>;\n }\n return authentication;\n}\n\n/**\n * Parse the SDK-native ``agent_settings.mcp_config`` value and convert it\n * to the frontend MCPConfig format used by UI components.\n */\nexport function parseMcpConfig(value: unknown): MCPConfig {\n const mcpConfig = getSdkMcpServerMap(value);\n if (!mcpConfig) {\n return { ...EMPTY_MCP_CONFIG };\n }\n\n const sseServers: (string | MCPSSEServer)[] = [];\n const stdioServers: MCPStdioServer[] = [];\n const shttpServers: (string | MCPSHTTPServer)[] = [];\n\n for (const [serverName, serverConfig] of Object.entries(mcpConfig)) {\n if (!isRecord(serverConfig)) continue;\n\n const url = serverConfig.url as string | undefined;\n\n // The SDK omits ``enabled`` while it holds its default (true), so only an\n // explicit ``false`` marks a server as switched off.\n const disabled = serverConfig.enabled === false;\n\n if (url) {\n const transport = serverConfig.transport as string | undefined;\n const auth = authCredentialFromServerConfig(serverConfig);\n const headers = stringRecord(serverConfig.headers);\n\n if (transport === \"sse\") {\n const name = userGivenServerName(serverName, \"sse\");\n const server: MCPSSEServer = { url };\n if (name) server.name = name;\n if (auth) server.auth = auth;\n if (headers) server.headers = headers;\n if (disabled) server.enabled = false;\n sseServers.push(server);\n } else {\n const name = userGivenServerName(serverName, \"shttp\");\n const server: MCPSHTTPServer = { url };\n if (name) server.name = name;\n if (serverConfig.timeout != null) {\n server.timeout = serverConfig.timeout as number;\n }\n if (auth) server.auth = auth;\n if (headers) server.headers = headers;\n if (disabled) server.enabled = false;\n shttpServers.push(server);\n }\n } else {\n if (typeof serverConfig.command !== \"string\") continue;\n const stdioServer: MCPStdioServer = {\n name: serverName,\n command: serverConfig.command,\n };\n if (serverConfig.args) {\n stdioServer.args = serverConfig.args as string[];\n }\n if (serverConfig.env) {\n stdioServer.env = serverConfig.env as Record<string, string>;\n }\n if (disabled) stdioServer.enabled = false;\n stdioServers.push(stdioServer);\n }\n }\n\n return {\n sse_servers: sseServers,\n stdio_servers: stdioServers,\n shttp_servers: shttpServers,\n };\n}\n\n/**\n * Convert the frontend MCPConfig format back to the SDK-native server map\n * expected by agent_settings.mcp_config on the backend.\n *\n * Names are only suffixed (``_1``, ``_2``, …) when an earlier entry has\n * already claimed the bare base name. We intentionally do NOT use a single\n * monotonic counter across server types: that would, for example, rename a\n * stdio server \"myname\" to \"myname_1\" the moment any sse/shttp entry is\n * persisted ahead of it, and shift the suffix on every save as the count\n * of other server types changes. With per-base collision suffixing,\n * unrelated entries keep their human-meaningful names stable across edits.\n *\n * ``enabled`` is only emitted when a server is switched off — the SDK defaults\n * it to true. Omitting it is what *clears* a previously persisted\n * ``enabled: false``, and that only works because ``saveSettings`` pre-clears\n * ``mcp_config`` to null before every write (see\n * ``settings-service.api.ts``), turning the backend's RFC 7386 merge into a\n * full replace. If that pre-clear is ever removed, re-enabling a server\n * becomes a silent no-op.\n */\nexport function toSdkMcpConfig(config: MCPConfig): SdkMcpConfig | null {\n const mcpConfig: SdkMcpConfig = {};\n\n const reserve = (base: string): string => {\n const safeBase = toMcpServerName(base);\n if (!(safeBase in mcpConfig)) return safeBase;\n let i = 1;\n while (`${safeBase}_${i}` in mcpConfig) i += 1;\n return `${safeBase}_${i}`;\n };\n\n for (const entry of config.sse_servers) {\n const server: SdkMcpServerConfig = {};\n let name: string | undefined;\n if (typeof entry === \"string\") {\n server.url = entry;\n } else {\n name = entry.name;\n server.url = entry.url;\n Object.assign(server, getRemoteSecretFields(entry), disabledField(entry));\n }\n server.transport = \"sse\";\n mcpConfig[reserve(name || \"sse\")] = server;\n }\n\n for (const entry of config.shttp_servers) {\n const server: SdkMcpServerConfig = { transport: \"http\" };\n let name: string | undefined;\n if (typeof entry === \"string\") {\n server.url = entry;\n } else {\n name = entry.name;\n server.url = entry.url;\n Object.assign(server, getRemoteSecretFields(entry), disabledField(entry));\n if (entry.timeout != null) server.timeout = entry.timeout;\n }\n mcpConfig[reserve(name || \"shttp\")] = server;\n }\n\n for (const entry of config.stdio_servers) {\n const server: SdkMcpServerConfig = {\n command: entry.command,\n };\n if (entry.args) server.args = entry.args;\n if (entry.env) server.env = entry.env;\n Object.assign(server, disabledField(entry));\n mcpConfig[reserve(entry.name || \"stdio\")] = server;\n }\n\n return Object.keys(mcpConfig).length > 0 ? mcpConfig : null;\n}\n"],"mappings":"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"}
|
|
@@ -26,6 +26,14 @@ export declare function parseMcpConfig(value: unknown): MCPConfig;
|
|
|
26
26
|
* persisted ahead of it, and shift the suffix on every save as the count
|
|
27
27
|
* of other server types changes. With per-base collision suffixing,
|
|
28
28
|
* unrelated entries keep their human-meaningful names stable across edits.
|
|
29
|
+
*
|
|
30
|
+
* ``enabled`` is only emitted when a server is switched off — the SDK defaults
|
|
31
|
+
* it to true. Omitting it is what *clears* a previously persisted
|
|
32
|
+
* ``enabled: false``, and that only works because ``saveSettings`` pre-clears
|
|
33
|
+
* ``mcp_config`` to null before every write (see
|
|
34
|
+
* ``settings-service.api.ts``), turning the backend's RFC 7386 merge into a
|
|
35
|
+
* full replace. If that pre-clear is ever removed, re-enabling a server
|
|
36
|
+
* becomes a silent no-op.
|
|
29
37
|
*/
|
|
30
38
|
export declare function toSdkMcpConfig(config: MCPConfig): SdkMcpConfig | null;
|
|
31
39
|
export {};
|
package/dist/utils/mcp-config.js
CHANGED
|
@@ -54,7 +54,7 @@ function l(e) {
|
|
|
54
54
|
} : void 0;
|
|
55
55
|
}
|
|
56
56
|
case "oauth2": {
|
|
57
|
-
let t =
|
|
57
|
+
let t = _(e.authentication), n = c(e.state);
|
|
58
58
|
return {
|
|
59
59
|
strategy: "oauth2",
|
|
60
60
|
...t && { authentication: t },
|
|
@@ -72,52 +72,57 @@ function d(e) {
|
|
|
72
72
|
return e.auth && !s(e.auth) && (t.auth = e.auth), e.headers && Object.keys(e.headers).length > 0 && (t.headers = e.headers), t;
|
|
73
73
|
}
|
|
74
74
|
function f(e) {
|
|
75
|
+
return e.enabled === !1 ? { enabled: !1 } : {};
|
|
76
|
+
}
|
|
77
|
+
function p(e) {
|
|
75
78
|
return {
|
|
76
79
|
...e.name && { name: e.name },
|
|
77
80
|
url: e.url,
|
|
78
81
|
...e.headers && { headers: e.headers },
|
|
79
|
-
...e.auth && { auth: e.auth }
|
|
82
|
+
...e.auth && { auth: e.auth },
|
|
83
|
+
...f(e)
|
|
80
84
|
};
|
|
81
85
|
}
|
|
82
|
-
function p(e) {
|
|
83
|
-
return f(e);
|
|
84
|
-
}
|
|
85
86
|
function m(e) {
|
|
87
|
+
return p(e);
|
|
88
|
+
}
|
|
89
|
+
function h(e) {
|
|
86
90
|
return {
|
|
87
|
-
...
|
|
91
|
+
...p(e),
|
|
88
92
|
...e.timeout !== void 0 && { timeout: e.timeout }
|
|
89
93
|
};
|
|
90
94
|
}
|
|
91
|
-
function
|
|
95
|
+
function g(e) {
|
|
92
96
|
return {
|
|
93
97
|
name: e.name,
|
|
94
98
|
command: e.command,
|
|
95
99
|
...e.args && { args: e.args },
|
|
96
|
-
...e.env && { env: e.env }
|
|
100
|
+
...e.env && { env: e.env },
|
|
101
|
+
...f(e)
|
|
97
102
|
};
|
|
98
103
|
}
|
|
99
|
-
function
|
|
104
|
+
function _(e) {
|
|
100
105
|
if (!e || typeof e != "object") return;
|
|
101
106
|
let t = e;
|
|
102
107
|
if (t.type !== "oauth") return;
|
|
103
108
|
let n = { type: "oauth" };
|
|
104
109
|
return (t.client_auth_method === "none" || t.client_auth_method === "client_secret_post" || t.client_auth_method === "client_secret_basic" || t.client_auth_method === "private_key_jwt") && (n.client_auth_method = t.client_auth_method), (typeof t.scopes == "string" || Array.isArray(t.scopes) && t.scopes.every((e) => typeof e == "string")) && (n.scopes = t.scopes), typeof t.client_name == "string" && (n.client_name = t.client_name), typeof t.client_metadata_url == "string" && (n.client_metadata_url = t.client_metadata_url), typeof t.client_id == "string" && (n.client_id = t.client_id), typeof t.client_secret == "string" && (n.client_secret = t.client_secret), t.additional_client_metadata && typeof t.additional_client_metadata == "object" && !Array.isArray(t.additional_client_metadata) && (n.additional_client_metadata = t.additional_client_metadata), n;
|
|
105
110
|
}
|
|
106
|
-
function
|
|
111
|
+
function v(e) {
|
|
107
112
|
let n = a(e);
|
|
108
113
|
if (!n) return { ...t };
|
|
109
114
|
let s = [], c = [], l = [];
|
|
110
115
|
for (let [e, t] of Object.entries(n)) {
|
|
111
116
|
if (!i(t)) continue;
|
|
112
|
-
let n = t.url;
|
|
117
|
+
let n = t.url, a = t.enabled === !1;
|
|
113
118
|
if (n) {
|
|
114
|
-
let i = t.transport,
|
|
119
|
+
let i = t.transport, c = u(t), d = o(t.headers);
|
|
115
120
|
if (i === "sse") {
|
|
116
121
|
let t = r(e, "sse"), i = { url: n };
|
|
117
|
-
t && (i.name = t),
|
|
122
|
+
t && (i.name = t), c && (i.auth = c), d && (i.headers = d), a && (i.enabled = !1), s.push(i);
|
|
118
123
|
} else {
|
|
119
124
|
let i = r(e, "shttp"), o = { url: n };
|
|
120
|
-
i && (o.name = i), t.timeout != null && (o.timeout = t.timeout),
|
|
125
|
+
i && (o.name = i), t.timeout != null && (o.timeout = t.timeout), c && (o.auth = c), d && (o.headers = d), a && (o.enabled = !1), l.push(o);
|
|
121
126
|
}
|
|
122
127
|
} else {
|
|
123
128
|
if (typeof t.command != "string") continue;
|
|
@@ -125,7 +130,7 @@ function _(e) {
|
|
|
125
130
|
name: e,
|
|
126
131
|
command: t.command
|
|
127
132
|
};
|
|
128
|
-
t.args && (n.args = t.args), t.env && (n.env = t.env), c.push(n);
|
|
133
|
+
t.args && (n.args = t.args), t.env && (n.env = t.env), a && (n.enabled = !1), c.push(n);
|
|
129
134
|
}
|
|
130
135
|
}
|
|
131
136
|
return {
|
|
@@ -134,7 +139,7 @@ function _(e) {
|
|
|
134
139
|
shttp_servers: l
|
|
135
140
|
};
|
|
136
141
|
}
|
|
137
|
-
function
|
|
142
|
+
function y(t) {
|
|
138
143
|
let n = {}, r = (t) => {
|
|
139
144
|
let r = e(t);
|
|
140
145
|
if (!(r in n)) return r;
|
|
@@ -144,19 +149,19 @@ function v(t) {
|
|
|
144
149
|
};
|
|
145
150
|
for (let e of t.sse_servers) {
|
|
146
151
|
let t = {}, i;
|
|
147
|
-
typeof e == "string" ? t.url = e : (i = e.name, t.url = e.url, Object.assign(t, d(e))), t.transport = "sse", n[r(i || "sse")] = t;
|
|
152
|
+
typeof e == "string" ? t.url = e : (i = e.name, t.url = e.url, Object.assign(t, d(e), f(e))), t.transport = "sse", n[r(i || "sse")] = t;
|
|
148
153
|
}
|
|
149
154
|
for (let e of t.shttp_servers) {
|
|
150
155
|
let t = { transport: "http" }, i;
|
|
151
|
-
typeof e == "string" ? t.url = e : (i = e.name, t.url = e.url, Object.assign(t, d(e)), e.timeout != null && (t.timeout = e.timeout)), n[r(i || "shttp")] = t;
|
|
156
|
+
typeof e == "string" ? t.url = e : (i = e.name, t.url = e.url, Object.assign(t, d(e), f(e)), e.timeout != null && (t.timeout = e.timeout)), n[r(i || "shttp")] = t;
|
|
152
157
|
}
|
|
153
158
|
for (let e of t.stdio_servers) {
|
|
154
159
|
let t = { command: e.command };
|
|
155
|
-
e.args && (t.args = e.args), e.env && (t.env = e.env), n[r(e.name || "stdio")] = t;
|
|
160
|
+
e.args && (t.args = e.args), e.env && (t.env = e.env), Object.assign(t, f(e)), n[r(e.name || "stdio")] = t;
|
|
156
161
|
}
|
|
157
162
|
return Object.keys(n).length > 0 ? n : null;
|
|
158
163
|
}
|
|
159
164
|
//#endregion
|
|
160
|
-
export { n as REDACTED_MCP_SECRET_VALUE, a as getSdkMcpServerMap, s as hasRedactedMcpSecretLeaf,
|
|
165
|
+
export { n as REDACTED_MCP_SECRET_VALUE, a as getSdkMcpServerMap, s as hasRedactedMcpSecretLeaf, v as parseMcpConfig, o as stringRecord, h as toMcpShttpServer, m as toMcpSseServer, g as toMcpStdioServer, y as toSdkMcpConfig };
|
|
161
166
|
|
|
162
167
|
//# sourceMappingURL=mcp-config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-config.js","names":[],"sources":["../../src/utils/mcp-config.ts"],"sourcesContent":["import {\n MCPConfig,\n MCPSSEServer,\n MCPSHTTPServer,\n MCPStdioServer,\n SettingsValue,\n} from \"#/types/settings\";\nimport type {\n MCPAuthCredential,\n MCPAuthenticationConfig,\n MCPJsonValue,\n MCPOAuthState,\n} from \"#/types/mcp-auth\";\nimport type { MCPServerConfig } from \"#/types/mcp-server\";\nimport { toMcpServerName } from \"#/utils/mcp-server-name\";\n\nconst EMPTY_MCP_CONFIG: MCPConfig = {\n sse_servers: [],\n stdio_servers: [],\n shttp_servers: [],\n};\n\nexport const REDACTED_MCP_SECRET_VALUE = \"**********\";\n\ntype SdkMcpServerConfig = Record<string, SettingsValue | MCPAuthCredential>;\ntype SdkMcpConfig = Record<string, SdkMcpServerConfig>;\n\n/**\n * The dict key for an SSE/SHTTP server doubles as its display name once a\n * user provides one. Keys that match the auto-generated fallback pattern\n * (``sse``, ``shttp``, ``shttp_1``, …) emitted by {@link toSdkMcpConfig}\n * carry no user intent, so we surface them as \"no name\" — re-serializing\n * regenerates the identical fallback key and existing configs are left\n * untouched.\n */\nfunction userGivenServerName(\n serverName: string,\n base: \"sse\" | \"shttp\",\n): string | undefined {\n const autoGenerated = new RegExp(`^${base}(_\\\\d+)?$`);\n return autoGenerated.test(serverName) ? undefined : serverName;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function getSdkMcpServerMap(\n value: unknown,\n): Record<string, unknown> | null {\n if (!isRecord(value)) return null;\n\n const mcpServers = value.mcpServers;\n if (\n isRecord(mcpServers) &&\n !(\"url\" in mcpServers) &&\n !(\"command\" in mcpServers)\n ) {\n return mcpServers;\n }\n\n return value;\n}\n\nexport function stringRecord(\n value: unknown,\n): Record<string, string> | undefined {\n if (!isRecord(value)) return undefined;\n const entries = Object.entries(value).filter(\n (entry): entry is [string, string] => typeof entry[1] === \"string\",\n );\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\nexport function hasRedactedMcpSecretLeaf(value: unknown): boolean {\n if (value === REDACTED_MCP_SECRET_VALUE) return true;\n if (Array.isArray(value)) return value.some(hasRedactedMcpSecretLeaf);\n if (isRecord(value))\n return Object.values(value).some(hasRedactedMcpSecretLeaf);\n return false;\n}\n\nfunction getOAuthState(value: unknown): MCPOAuthState | undefined {\n if (!isRecord(value)) return undefined;\n const state: MCPOAuthState = {};\n if (isRecord(value.tokens)) {\n state.tokens = value.tokens as NonNullable<MCPOAuthState[\"tokens\"]>;\n }\n if (isRecord(value.client_info)) {\n state.client_info = value.client_info as NonNullable<\n MCPOAuthState[\"client_info\"]\n >;\n }\n if (\n typeof value.token_expires_at === \"number\" ||\n value.token_expires_at === null\n ) {\n state.token_expires_at = value.token_expires_at;\n }\n return Object.keys(state).length > 0 ? state : undefined;\n}\n\nfunction normalizeTaggedAuthCredential(\n value: unknown,\n): MCPAuthCredential | undefined {\n if (!isRecord(value)) return undefined;\n switch (value.strategy) {\n case \"none\":\n return { strategy: \"none\" };\n case \"api_key\":\n if (typeof value.value !== \"string\") return undefined;\n return {\n strategy: \"api_key\",\n value: value.value,\n ...(typeof value.header_name === \"string\" && {\n header_name: value.header_name,\n }),\n };\n case \"bearer\":\n if (typeof value.value !== \"string\") return undefined;\n return { strategy: \"bearer\", value: value.value };\n case \"basic\":\n if (\n typeof value.username !== \"string\" ||\n typeof value.password !== \"string\"\n ) {\n return undefined;\n }\n return {\n strategy: \"basic\",\n username: value.username,\n password: value.password,\n };\n case \"header\": {\n const headers = stringRecord(value.headers);\n return headers ? { strategy: \"header\", headers } : undefined;\n }\n case \"oauth2\": {\n const authentication = getAuthenticationConfig(value.authentication);\n const state = getOAuthState(value.state);\n return {\n strategy: \"oauth2\",\n ...(authentication && { authentication }),\n ...(state && { state }),\n };\n }\n default:\n return undefined;\n }\n}\n\nfunction authCredentialFromServerConfig(\n serverConfig: Record<string, unknown>,\n): MCPAuthCredential | undefined {\n return normalizeTaggedAuthCredential(serverConfig.auth);\n}\n\nfunction getRemoteSecretFields(entry: {\n auth?: MCPAuthCredential;\n headers?: Record<string, string>;\n}): Partial<SdkMcpServerConfig> {\n const fields: Partial<SdkMcpServerConfig> = {};\n if (entry.auth && !hasRedactedMcpSecretLeaf(entry.auth)) {\n fields.auth = entry.auth;\n }\n if (entry.headers && Object.keys(entry.headers).length > 0) {\n fields.headers = entry.headers;\n }\n return fields;\n}\n\nfunction getRemoteServerFields(server: MCPServerConfig) {\n return {\n ...(server.name && { name: server.name }),\n url: server.url!,\n ...(server.headers && { headers: server.headers }),\n ...(server.auth && { auth: server.auth }),\n };\n}\n\nexport function toMcpSseServer(server: MCPServerConfig): MCPSSEServer {\n return getRemoteServerFields(server);\n}\n\nexport function toMcpShttpServer(server: MCPServerConfig): MCPSHTTPServer {\n return {\n ...getRemoteServerFields(server),\n ...(server.timeout !== undefined && { timeout: server.timeout }),\n };\n}\n\nexport function toMcpStdioServer(server: MCPServerConfig): MCPStdioServer {\n return {\n name: server.name!,\n command: server.command!,\n ...(server.args && { args: server.args }),\n ...(server.env && { env: server.env }),\n };\n}\n\nfunction getAuthenticationConfig(\n value: unknown,\n): MCPAuthenticationConfig | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const record = value as Record<string, unknown>;\n if (record.type !== \"oauth\") return undefined;\n const authentication: MCPAuthenticationConfig = { type: \"oauth\" };\n if (\n record.client_auth_method === \"none\" ||\n record.client_auth_method === \"client_secret_post\" ||\n record.client_auth_method === \"client_secret_basic\" ||\n record.client_auth_method === \"private_key_jwt\"\n ) {\n authentication.client_auth_method = record.client_auth_method;\n }\n if (typeof record.scopes === \"string\") {\n authentication.scopes = record.scopes;\n } else if (\n Array.isArray(record.scopes) &&\n record.scopes.every((scope) => typeof scope === \"string\")\n ) {\n authentication.scopes = record.scopes;\n }\n if (typeof record.client_name === \"string\") {\n authentication.client_name = record.client_name;\n }\n if (typeof record.client_metadata_url === \"string\") {\n authentication.client_metadata_url = record.client_metadata_url;\n }\n if (typeof record.client_id === \"string\") {\n authentication.client_id = record.client_id;\n }\n if (typeof record.client_secret === \"string\") {\n authentication.client_secret = record.client_secret;\n }\n if (\n record.additional_client_metadata &&\n typeof record.additional_client_metadata === \"object\" &&\n !Array.isArray(record.additional_client_metadata)\n ) {\n authentication.additional_client_metadata =\n record.additional_client_metadata as Record<string, MCPJsonValue>;\n }\n return authentication;\n}\n\n/**\n * Parse the SDK-native ``agent_settings.mcp_config`` value and convert it\n * to the frontend MCPConfig format used by UI components.\n */\nexport function parseMcpConfig(value: unknown): MCPConfig {\n const mcpConfig = getSdkMcpServerMap(value);\n if (!mcpConfig) {\n return { ...EMPTY_MCP_CONFIG };\n }\n\n const sseServers: (string | MCPSSEServer)[] = [];\n const stdioServers: MCPStdioServer[] = [];\n const shttpServers: (string | MCPSHTTPServer)[] = [];\n\n for (const [serverName, serverConfig] of Object.entries(mcpConfig)) {\n if (!isRecord(serverConfig)) continue;\n\n const url = serverConfig.url as string | undefined;\n\n if (url) {\n const transport = serverConfig.transport as string | undefined;\n const auth = authCredentialFromServerConfig(serverConfig);\n const headers = stringRecord(serverConfig.headers);\n\n if (transport === \"sse\") {\n const name = userGivenServerName(serverName, \"sse\");\n const server: MCPSSEServer = { url };\n if (name) server.name = name;\n if (auth) server.auth = auth;\n if (headers) server.headers = headers;\n sseServers.push(server);\n } else {\n const name = userGivenServerName(serverName, \"shttp\");\n const server: MCPSHTTPServer = { url };\n if (name) server.name = name;\n if (serverConfig.timeout != null) {\n server.timeout = serverConfig.timeout as number;\n }\n if (auth) server.auth = auth;\n if (headers) server.headers = headers;\n shttpServers.push(server);\n }\n } else {\n if (typeof serverConfig.command !== \"string\") continue;\n const stdioServer: MCPStdioServer = {\n name: serverName,\n command: serverConfig.command,\n };\n if (serverConfig.args) {\n stdioServer.args = serverConfig.args as string[];\n }\n if (serverConfig.env) {\n stdioServer.env = serverConfig.env as Record<string, string>;\n }\n stdioServers.push(stdioServer);\n }\n }\n\n return {\n sse_servers: sseServers,\n stdio_servers: stdioServers,\n shttp_servers: shttpServers,\n };\n}\n\n/**\n * Convert the frontend MCPConfig format back to the SDK-native server map\n * expected by agent_settings.mcp_config on the backend.\n *\n * Names are only suffixed (``_1``, ``_2``, …) when an earlier entry has\n * already claimed the bare base name. We intentionally do NOT use a single\n * monotonic counter across server types: that would, for example, rename a\n * stdio server \"myname\" to \"myname_1\" the moment any sse/shttp entry is\n * persisted ahead of it, and shift the suffix on every save as the count\n * of other server types changes. With per-base collision suffixing,\n * unrelated entries keep their human-meaningful names stable across edits.\n */\nexport function toSdkMcpConfig(config: MCPConfig): SdkMcpConfig | null {\n const mcpConfig: SdkMcpConfig = {};\n\n const reserve = (base: string): string => {\n const safeBase = toMcpServerName(base);\n if (!(safeBase in mcpConfig)) return safeBase;\n let i = 1;\n while (`${safeBase}_${i}` in mcpConfig) i += 1;\n return `${safeBase}_${i}`;\n };\n\n for (const entry of config.sse_servers) {\n const server: SdkMcpServerConfig = {};\n let name: string | undefined;\n if (typeof entry === \"string\") {\n server.url = entry;\n } else {\n name = entry.name;\n server.url = entry.url;\n Object.assign(server, getRemoteSecretFields(entry));\n }\n server.transport = \"sse\";\n mcpConfig[reserve(name || \"sse\")] = server;\n }\n\n for (const entry of config.shttp_servers) {\n const server: SdkMcpServerConfig = { transport: \"http\" };\n let name: string | undefined;\n if (typeof entry === \"string\") {\n server.url = entry;\n } else {\n name = entry.name;\n server.url = entry.url;\n Object.assign(server, getRemoteSecretFields(entry));\n if (entry.timeout != null) server.timeout = entry.timeout;\n }\n mcpConfig[reserve(name || \"shttp\")] = server;\n }\n\n for (const entry of config.stdio_servers) {\n const server: SdkMcpServerConfig = {\n command: entry.command,\n };\n if (entry.args) server.args = entry.args;\n if (entry.env) server.env = entry.env;\n mcpConfig[reserve(entry.name || \"stdio\")] = server;\n }\n\n return Object.keys(mcpConfig).length > 0 ? mcpConfig : null;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mcp-config.js","names":[],"sources":["../../src/utils/mcp-config.ts"],"sourcesContent":["import {\n MCPConfig,\n MCPSSEServer,\n MCPSHTTPServer,\n MCPStdioServer,\n SettingsValue,\n} from \"#/types/settings\";\nimport type {\n MCPAuthCredential,\n MCPAuthenticationConfig,\n MCPJsonValue,\n MCPOAuthState,\n} from \"#/types/mcp-auth\";\nimport type { MCPServerConfig } from \"#/types/mcp-server\";\nimport { toMcpServerName } from \"#/utils/mcp-server-name\";\n\nconst EMPTY_MCP_CONFIG: MCPConfig = {\n sse_servers: [],\n stdio_servers: [],\n shttp_servers: [],\n};\n\nexport const REDACTED_MCP_SECRET_VALUE = \"**********\";\n\ntype SdkMcpServerConfig = Record<string, SettingsValue | MCPAuthCredential>;\ntype SdkMcpConfig = Record<string, SdkMcpServerConfig>;\n\n/**\n * The dict key for an SSE/SHTTP server doubles as its display name once a\n * user provides one. Keys that match the auto-generated fallback pattern\n * (``sse``, ``shttp``, ``shttp_1``, …) emitted by {@link toSdkMcpConfig}\n * carry no user intent, so we surface them as \"no name\" — re-serializing\n * regenerates the identical fallback key and existing configs are left\n * untouched.\n */\nfunction userGivenServerName(\n serverName: string,\n base: \"sse\" | \"shttp\",\n): string | undefined {\n const autoGenerated = new RegExp(`^${base}(_\\\\d+)?$`);\n return autoGenerated.test(serverName) ? undefined : serverName;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function getSdkMcpServerMap(\n value: unknown,\n): Record<string, unknown> | null {\n if (!isRecord(value)) return null;\n\n const mcpServers = value.mcpServers;\n if (\n isRecord(mcpServers) &&\n !(\"url\" in mcpServers) &&\n !(\"command\" in mcpServers)\n ) {\n return mcpServers;\n }\n\n return value;\n}\n\nexport function stringRecord(\n value: unknown,\n): Record<string, string> | undefined {\n if (!isRecord(value)) return undefined;\n const entries = Object.entries(value).filter(\n (entry): entry is [string, string] => typeof entry[1] === \"string\",\n );\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\nexport function hasRedactedMcpSecretLeaf(value: unknown): boolean {\n if (value === REDACTED_MCP_SECRET_VALUE) return true;\n if (Array.isArray(value)) return value.some(hasRedactedMcpSecretLeaf);\n if (isRecord(value))\n return Object.values(value).some(hasRedactedMcpSecretLeaf);\n return false;\n}\n\nfunction getOAuthState(value: unknown): MCPOAuthState | undefined {\n if (!isRecord(value)) return undefined;\n const state: MCPOAuthState = {};\n if (isRecord(value.tokens)) {\n state.tokens = value.tokens as NonNullable<MCPOAuthState[\"tokens\"]>;\n }\n if (isRecord(value.client_info)) {\n state.client_info = value.client_info as NonNullable<\n MCPOAuthState[\"client_info\"]\n >;\n }\n if (\n typeof value.token_expires_at === \"number\" ||\n value.token_expires_at === null\n ) {\n state.token_expires_at = value.token_expires_at;\n }\n return Object.keys(state).length > 0 ? state : undefined;\n}\n\nfunction normalizeTaggedAuthCredential(\n value: unknown,\n): MCPAuthCredential | undefined {\n if (!isRecord(value)) return undefined;\n switch (value.strategy) {\n case \"none\":\n return { strategy: \"none\" };\n case \"api_key\":\n if (typeof value.value !== \"string\") return undefined;\n return {\n strategy: \"api_key\",\n value: value.value,\n ...(typeof value.header_name === \"string\" && {\n header_name: value.header_name,\n }),\n };\n case \"bearer\":\n if (typeof value.value !== \"string\") return undefined;\n return { strategy: \"bearer\", value: value.value };\n case \"basic\":\n if (\n typeof value.username !== \"string\" ||\n typeof value.password !== \"string\"\n ) {\n return undefined;\n }\n return {\n strategy: \"basic\",\n username: value.username,\n password: value.password,\n };\n case \"header\": {\n const headers = stringRecord(value.headers);\n return headers ? { strategy: \"header\", headers } : undefined;\n }\n case \"oauth2\": {\n const authentication = getAuthenticationConfig(value.authentication);\n const state = getOAuthState(value.state);\n return {\n strategy: \"oauth2\",\n ...(authentication && { authentication }),\n ...(state && { state }),\n };\n }\n default:\n return undefined;\n }\n}\n\nfunction authCredentialFromServerConfig(\n serverConfig: Record<string, unknown>,\n): MCPAuthCredential | undefined {\n return normalizeTaggedAuthCredential(serverConfig.auth);\n}\n\nfunction getRemoteSecretFields(entry: {\n auth?: MCPAuthCredential;\n headers?: Record<string, string>;\n}): Partial<SdkMcpServerConfig> {\n const fields: Partial<SdkMcpServerConfig> = {};\n if (entry.auth && !hasRedactedMcpSecretLeaf(entry.auth)) {\n fields.auth = entry.auth;\n }\n if (entry.headers && Object.keys(entry.headers).length > 0) {\n fields.headers = entry.headers;\n }\n return fields;\n}\n\n/**\n * Only an explicit ``false`` is carried. Every mutation round-trips the whole\n * server map through these converters, so preserving the flag here is what\n * stops adding or deleting one server from silently re-enabling another.\n */\nfunction disabledField(server: { enabled?: boolean }) {\n return server.enabled === false ? { enabled: false as const } : {};\n}\n\nfunction getRemoteServerFields(server: MCPServerConfig) {\n return {\n ...(server.name && { name: server.name }),\n url: server.url!,\n ...(server.headers && { headers: server.headers }),\n ...(server.auth && { auth: server.auth }),\n ...disabledField(server),\n };\n}\n\nexport function toMcpSseServer(server: MCPServerConfig): MCPSSEServer {\n return getRemoteServerFields(server);\n}\n\nexport function toMcpShttpServer(server: MCPServerConfig): MCPSHTTPServer {\n return {\n ...getRemoteServerFields(server),\n ...(server.timeout !== undefined && { timeout: server.timeout }),\n };\n}\n\nexport function toMcpStdioServer(server: MCPServerConfig): MCPStdioServer {\n return {\n name: server.name!,\n command: server.command!,\n ...(server.args && { args: server.args }),\n ...(server.env && { env: server.env }),\n ...disabledField(server),\n };\n}\n\nfunction getAuthenticationConfig(\n value: unknown,\n): MCPAuthenticationConfig | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const record = value as Record<string, unknown>;\n if (record.type !== \"oauth\") return undefined;\n const authentication: MCPAuthenticationConfig = { type: \"oauth\" };\n if (\n record.client_auth_method === \"none\" ||\n record.client_auth_method === \"client_secret_post\" ||\n record.client_auth_method === \"client_secret_basic\" ||\n record.client_auth_method === \"private_key_jwt\"\n ) {\n authentication.client_auth_method = record.client_auth_method;\n }\n if (typeof record.scopes === \"string\") {\n authentication.scopes = record.scopes;\n } else if (\n Array.isArray(record.scopes) &&\n record.scopes.every((scope) => typeof scope === \"string\")\n ) {\n authentication.scopes = record.scopes;\n }\n if (typeof record.client_name === \"string\") {\n authentication.client_name = record.client_name;\n }\n if (typeof record.client_metadata_url === \"string\") {\n authentication.client_metadata_url = record.client_metadata_url;\n }\n if (typeof record.client_id === \"string\") {\n authentication.client_id = record.client_id;\n }\n if (typeof record.client_secret === \"string\") {\n authentication.client_secret = record.client_secret;\n }\n if (\n record.additional_client_metadata &&\n typeof record.additional_client_metadata === \"object\" &&\n !Array.isArray(record.additional_client_metadata)\n ) {\n authentication.additional_client_metadata =\n record.additional_client_metadata as Record<string, MCPJsonValue>;\n }\n return authentication;\n}\n\n/**\n * Parse the SDK-native ``agent_settings.mcp_config`` value and convert it\n * to the frontend MCPConfig format used by UI components.\n */\nexport function parseMcpConfig(value: unknown): MCPConfig {\n const mcpConfig = getSdkMcpServerMap(value);\n if (!mcpConfig) {\n return { ...EMPTY_MCP_CONFIG };\n }\n\n const sseServers: (string | MCPSSEServer)[] = [];\n const stdioServers: MCPStdioServer[] = [];\n const shttpServers: (string | MCPSHTTPServer)[] = [];\n\n for (const [serverName, serverConfig] of Object.entries(mcpConfig)) {\n if (!isRecord(serverConfig)) continue;\n\n const url = serverConfig.url as string | undefined;\n\n // The SDK omits ``enabled`` while it holds its default (true), so only an\n // explicit ``false`` marks a server as switched off.\n const disabled = serverConfig.enabled === false;\n\n if (url) {\n const transport = serverConfig.transport as string | undefined;\n const auth = authCredentialFromServerConfig(serverConfig);\n const headers = stringRecord(serverConfig.headers);\n\n if (transport === \"sse\") {\n const name = userGivenServerName(serverName, \"sse\");\n const server: MCPSSEServer = { url };\n if (name) server.name = name;\n if (auth) server.auth = auth;\n if (headers) server.headers = headers;\n if (disabled) server.enabled = false;\n sseServers.push(server);\n } else {\n const name = userGivenServerName(serverName, \"shttp\");\n const server: MCPSHTTPServer = { url };\n if (name) server.name = name;\n if (serverConfig.timeout != null) {\n server.timeout = serverConfig.timeout as number;\n }\n if (auth) server.auth = auth;\n if (headers) server.headers = headers;\n if (disabled) server.enabled = false;\n shttpServers.push(server);\n }\n } else {\n if (typeof serverConfig.command !== \"string\") continue;\n const stdioServer: MCPStdioServer = {\n name: serverName,\n command: serverConfig.command,\n };\n if (serverConfig.args) {\n stdioServer.args = serverConfig.args as string[];\n }\n if (serverConfig.env) {\n stdioServer.env = serverConfig.env as Record<string, string>;\n }\n if (disabled) stdioServer.enabled = false;\n stdioServers.push(stdioServer);\n }\n }\n\n return {\n sse_servers: sseServers,\n stdio_servers: stdioServers,\n shttp_servers: shttpServers,\n };\n}\n\n/**\n * Convert the frontend MCPConfig format back to the SDK-native server map\n * expected by agent_settings.mcp_config on the backend.\n *\n * Names are only suffixed (``_1``, ``_2``, …) when an earlier entry has\n * already claimed the bare base name. We intentionally do NOT use a single\n * monotonic counter across server types: that would, for example, rename a\n * stdio server \"myname\" to \"myname_1\" the moment any sse/shttp entry is\n * persisted ahead of it, and shift the suffix on every save as the count\n * of other server types changes. With per-base collision suffixing,\n * unrelated entries keep their human-meaningful names stable across edits.\n *\n * ``enabled`` is only emitted when a server is switched off — the SDK defaults\n * it to true. Omitting it is what *clears* a previously persisted\n * ``enabled: false``, and that only works because ``saveSettings`` pre-clears\n * ``mcp_config`` to null before every write (see\n * ``settings-service.api.ts``), turning the backend's RFC 7386 merge into a\n * full replace. If that pre-clear is ever removed, re-enabling a server\n * becomes a silent no-op.\n */\nexport function toSdkMcpConfig(config: MCPConfig): SdkMcpConfig | null {\n const mcpConfig: SdkMcpConfig = {};\n\n const reserve = (base: string): string => {\n const safeBase = toMcpServerName(base);\n if (!(safeBase in mcpConfig)) return safeBase;\n let i = 1;\n while (`${safeBase}_${i}` in mcpConfig) i += 1;\n return `${safeBase}_${i}`;\n };\n\n for (const entry of config.sse_servers) {\n const server: SdkMcpServerConfig = {};\n let name: string | undefined;\n if (typeof entry === \"string\") {\n server.url = entry;\n } else {\n name = entry.name;\n server.url = entry.url;\n Object.assign(server, getRemoteSecretFields(entry), disabledField(entry));\n }\n server.transport = \"sse\";\n mcpConfig[reserve(name || \"sse\")] = server;\n }\n\n for (const entry of config.shttp_servers) {\n const server: SdkMcpServerConfig = { transport: \"http\" };\n let name: string | undefined;\n if (typeof entry === \"string\") {\n server.url = entry;\n } else {\n name = entry.name;\n server.url = entry.url;\n Object.assign(server, getRemoteSecretFields(entry), disabledField(entry));\n if (entry.timeout != null) server.timeout = entry.timeout;\n }\n mcpConfig[reserve(name || \"shttp\")] = server;\n }\n\n for (const entry of config.stdio_servers) {\n const server: SdkMcpServerConfig = {\n command: entry.command,\n };\n if (entry.args) server.args = entry.args;\n if (entry.env) server.env = entry.env;\n Object.assign(server, disabledField(entry));\n mcpConfig[reserve(entry.name || \"stdio\")] = server;\n }\n\n return Object.keys(mcpConfig).length > 0 ? mcpConfig : null;\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs");function e(e){return[...e.sse_servers.map((e,t)=>({id:`sse-${t}`,type:`sse`,name:typeof e==`object`?e.name:void 0,url:typeof e==`string`?e:e.url,headers:typeof e==`object`?e.headers:void 0,auth:typeof e==`object`?e.auth:void 0})),...e.stdio_servers.map((e,t)=>({id:`stdio-${t}`,type:`stdio`,name:e.name,command:e.command,args:e.args,env:e.env})),...e.shttp_servers.map((e,t)=>({id:`shttp-${t}`,type:`shttp`,name:typeof e==`object`?e.name:void 0,url:typeof e==`string`?e:e.url,headers:typeof e==`object`?e.headers:void 0,timeout:typeof e==`object`?e.timeout:void 0,auth:typeof e==`object`?e.auth:void 0}))]}exports.flattenMcpConfig=e;
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");function e(e){return[...e.sse_servers.map((e,t)=>({id:`sse-${t}`,type:`sse`,name:typeof e==`object`?e.name:void 0,url:typeof e==`string`?e:e.url,headers:typeof e==`object`?e.headers:void 0,auth:typeof e==`object`?e.auth:void 0,enabled:typeof e==`object`?e.enabled:void 0})),...e.stdio_servers.map((e,t)=>({id:`stdio-${t}`,type:`stdio`,name:e.name,command:e.command,args:e.args,env:e.env,enabled:e.enabled})),...e.shttp_servers.map((e,t)=>({id:`shttp-${t}`,type:`shttp`,name:typeof e==`object`?e.name:void 0,url:typeof e==`string`?e:e.url,headers:typeof e==`object`?e.headers:void 0,timeout:typeof e==`object`?e.timeout:void 0,auth:typeof e==`object`?e.auth:void 0,enabled:typeof e==`object`?e.enabled:void 0}))]}exports.flattenMcpConfig=e;
|
|
2
2
|
//# sourceMappingURL=mcp-installed-servers.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-installed-servers.cjs","names":[],"sources":["../../src/utils/mcp-installed-servers.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport { MCPConfig } from \"#/types/settings\";\n\nexport function flattenMcpConfig(config: MCPConfig): MCPServerConfig[] {\n return [\n ...config.sse_servers.map((server, index) => ({\n id: `sse-${index}`,\n type: \"sse\" as const,\n name: typeof server === \"object\" ? server.name : undefined,\n url: typeof server === \"string\" ? server : server.url,\n headers: typeof server === \"object\" ? server.headers : undefined,\n auth: typeof server === \"object\" ? server.auth : undefined,\n })),\n ...config.stdio_servers.map((server, index) => ({\n id: `stdio-${index}`,\n type: \"stdio\" as const,\n name: server.name,\n command: server.command,\n args: server.args,\n env: server.env,\n })),\n ...config.shttp_servers.map((server, index) => ({\n id: `shttp-${index}`,\n type: \"shttp\" as const,\n name: typeof server === \"object\" ? server.name : undefined,\n url: typeof server === \"string\" ? server : server.url,\n headers: typeof server === \"object\" ? server.headers : undefined,\n timeout: typeof server === \"object\" ? server.timeout : undefined,\n auth: typeof server === \"object\" ? server.auth : undefined,\n })),\n ];\n}\n"],"mappings":"6CAGA,SAAgB,EAAiB,EAAsC,CACrE,MAAO,CACL,GAAG,EAAO,YAAY,KAAK,EAAQ,KAAW,CAC5C,GAAI,OAAO,IACX,KAAM,MACN,KAAM,OAAO,GAAW,SAAW,EAAO,KAAO,IAAA,GACjD,IAAK,OAAO,GAAW,SAAW,EAAS,EAAO,IAClD,QAAS,OAAO,GAAW,SAAW,EAAO,QAAU,IAAA,GACvD,KAAM,OAAO,GAAW,SAAW,EAAO,KAAO,IAAA,
|
|
1
|
+
{"version":3,"file":"mcp-installed-servers.cjs","names":[],"sources":["../../src/utils/mcp-installed-servers.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport { MCPConfig } from \"#/types/settings\";\n\nexport function flattenMcpConfig(config: MCPConfig): MCPServerConfig[] {\n return [\n ...config.sse_servers.map((server, index) => ({\n id: `sse-${index}`,\n type: \"sse\" as const,\n name: typeof server === \"object\" ? server.name : undefined,\n url: typeof server === \"string\" ? server : server.url,\n headers: typeof server === \"object\" ? server.headers : undefined,\n auth: typeof server === \"object\" ? server.auth : undefined,\n enabled: typeof server === \"object\" ? server.enabled : undefined,\n })),\n ...config.stdio_servers.map((server, index) => ({\n id: `stdio-${index}`,\n type: \"stdio\" as const,\n name: server.name,\n command: server.command,\n args: server.args,\n env: server.env,\n enabled: server.enabled,\n })),\n ...config.shttp_servers.map((server, index) => ({\n id: `shttp-${index}`,\n type: \"shttp\" as const,\n name: typeof server === \"object\" ? server.name : undefined,\n url: typeof server === \"string\" ? server : server.url,\n headers: typeof server === \"object\" ? server.headers : undefined,\n timeout: typeof server === \"object\" ? server.timeout : undefined,\n auth: typeof server === \"object\" ? server.auth : undefined,\n enabled: typeof server === \"object\" ? server.enabled : undefined,\n })),\n ];\n}\n"],"mappings":"6CAGA,SAAgB,EAAiB,EAAsC,CACrE,MAAO,CACL,GAAG,EAAO,YAAY,KAAK,EAAQ,KAAW,CAC5C,GAAI,OAAO,IACX,KAAM,MACN,KAAM,OAAO,GAAW,SAAW,EAAO,KAAO,IAAA,GACjD,IAAK,OAAO,GAAW,SAAW,EAAS,EAAO,IAClD,QAAS,OAAO,GAAW,SAAW,EAAO,QAAU,IAAA,GACvD,KAAM,OAAO,GAAW,SAAW,EAAO,KAAO,IAAA,GACjD,QAAS,OAAO,GAAW,SAAW,EAAO,QAAU,IAAA,EACzD,EAAE,EACF,GAAG,EAAO,cAAc,KAAK,EAAQ,KAAW,CAC9C,GAAI,SAAS,IACb,KAAM,QACN,KAAM,EAAO,KACb,QAAS,EAAO,QAChB,KAAM,EAAO,KACb,IAAK,EAAO,IACZ,QAAS,EAAO,OAClB,EAAE,EACF,GAAG,EAAO,cAAc,KAAK,EAAQ,KAAW,CAC9C,GAAI,SAAS,IACb,KAAM,QACN,KAAM,OAAO,GAAW,SAAW,EAAO,KAAO,IAAA,GACjD,IAAK,OAAO,GAAW,SAAW,EAAS,EAAO,IAClD,QAAS,OAAO,GAAW,SAAW,EAAO,QAAU,IAAA,GACvD,QAAS,OAAO,GAAW,SAAW,EAAO,QAAU,IAAA,GACvD,KAAM,OAAO,GAAW,SAAW,EAAO,KAAO,IAAA,GACjD,QAAS,OAAO,GAAW,SAAW,EAAO,QAAU,IAAA,EACzD,EAAE,CACJ,CACF"}
|
|
@@ -7,7 +7,8 @@ function e(e) {
|
|
|
7
7
|
name: typeof e == "object" ? e.name : void 0,
|
|
8
8
|
url: typeof e == "string" ? e : e.url,
|
|
9
9
|
headers: typeof e == "object" ? e.headers : void 0,
|
|
10
|
-
auth: typeof e == "object" ? e.auth : void 0
|
|
10
|
+
auth: typeof e == "object" ? e.auth : void 0,
|
|
11
|
+
enabled: typeof e == "object" ? e.enabled : void 0
|
|
11
12
|
})),
|
|
12
13
|
...e.stdio_servers.map((e, t) => ({
|
|
13
14
|
id: `stdio-${t}`,
|
|
@@ -15,7 +16,8 @@ function e(e) {
|
|
|
15
16
|
name: e.name,
|
|
16
17
|
command: e.command,
|
|
17
18
|
args: e.args,
|
|
18
|
-
env: e.env
|
|
19
|
+
env: e.env,
|
|
20
|
+
enabled: e.enabled
|
|
19
21
|
})),
|
|
20
22
|
...e.shttp_servers.map((e, t) => ({
|
|
21
23
|
id: `shttp-${t}`,
|
|
@@ -24,7 +26,8 @@ function e(e) {
|
|
|
24
26
|
url: typeof e == "string" ? e : e.url,
|
|
25
27
|
headers: typeof e == "object" ? e.headers : void 0,
|
|
26
28
|
timeout: typeof e == "object" ? e.timeout : void 0,
|
|
27
|
-
auth: typeof e == "object" ? e.auth : void 0
|
|
29
|
+
auth: typeof e == "object" ? e.auth : void 0,
|
|
30
|
+
enabled: typeof e == "object" ? e.enabled : void 0
|
|
28
31
|
}))
|
|
29
32
|
];
|
|
30
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-installed-servers.js","names":[],"sources":["../../src/utils/mcp-installed-servers.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport { MCPConfig } from \"#/types/settings\";\n\nexport function flattenMcpConfig(config: MCPConfig): MCPServerConfig[] {\n return [\n ...config.sse_servers.map((server, index) => ({\n id: `sse-${index}`,\n type: \"sse\" as const,\n name: typeof server === \"object\" ? server.name : undefined,\n url: typeof server === \"string\" ? server : server.url,\n headers: typeof server === \"object\" ? server.headers : undefined,\n auth: typeof server === \"object\" ? server.auth : undefined,\n })),\n ...config.stdio_servers.map((server, index) => ({\n id: `stdio-${index}`,\n type: \"stdio\" as const,\n name: server.name,\n command: server.command,\n args: server.args,\n env: server.env,\n })),\n ...config.shttp_servers.map((server, index) => ({\n id: `shttp-${index}`,\n type: \"shttp\" as const,\n name: typeof server === \"object\" ? server.name : undefined,\n url: typeof server === \"string\" ? server : server.url,\n headers: typeof server === \"object\" ? server.headers : undefined,\n timeout: typeof server === \"object\" ? server.timeout : undefined,\n auth: typeof server === \"object\" ? server.auth : undefined,\n })),\n ];\n}\n"],"mappings":";AAGA,SAAgB,EAAiB,GAAsC;CACrE,OAAO;EACL,GAAG,EAAO,YAAY,KAAK,GAAQ,OAAW;GAC5C,IAAI,OAAO;GACX,MAAM;GACN,MAAM,OAAO,KAAW,WAAW,EAAO,OAAO,KAAA;GACjD,KAAK,OAAO,KAAW,WAAW,IAAS,EAAO;GAClD,SAAS,OAAO,KAAW,WAAW,EAAO,UAAU,KAAA;GACvD,MAAM,OAAO,KAAW,WAAW,EAAO,OAAO,KAAA;
|
|
1
|
+
{"version":3,"file":"mcp-installed-servers.js","names":[],"sources":["../../src/utils/mcp-installed-servers.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport { MCPConfig } from \"#/types/settings\";\n\nexport function flattenMcpConfig(config: MCPConfig): MCPServerConfig[] {\n return [\n ...config.sse_servers.map((server, index) => ({\n id: `sse-${index}`,\n type: \"sse\" as const,\n name: typeof server === \"object\" ? server.name : undefined,\n url: typeof server === \"string\" ? server : server.url,\n headers: typeof server === \"object\" ? server.headers : undefined,\n auth: typeof server === \"object\" ? server.auth : undefined,\n enabled: typeof server === \"object\" ? server.enabled : undefined,\n })),\n ...config.stdio_servers.map((server, index) => ({\n id: `stdio-${index}`,\n type: \"stdio\" as const,\n name: server.name,\n command: server.command,\n args: server.args,\n env: server.env,\n enabled: server.enabled,\n })),\n ...config.shttp_servers.map((server, index) => ({\n id: `shttp-${index}`,\n type: \"shttp\" as const,\n name: typeof server === \"object\" ? server.name : undefined,\n url: typeof server === \"string\" ? server : server.url,\n headers: typeof server === \"object\" ? server.headers : undefined,\n timeout: typeof server === \"object\" ? server.timeout : undefined,\n auth: typeof server === \"object\" ? server.auth : undefined,\n enabled: typeof server === \"object\" ? server.enabled : undefined,\n })),\n ];\n}\n"],"mappings":";AAGA,SAAgB,EAAiB,GAAsC;CACrE,OAAO;EACL,GAAG,EAAO,YAAY,KAAK,GAAQ,OAAW;GAC5C,IAAI,OAAO;GACX,MAAM;GACN,MAAM,OAAO,KAAW,WAAW,EAAO,OAAO,KAAA;GACjD,KAAK,OAAO,KAAW,WAAW,IAAS,EAAO;GAClD,SAAS,OAAO,KAAW,WAAW,EAAO,UAAU,KAAA;GACvD,MAAM,OAAO,KAAW,WAAW,EAAO,OAAO,KAAA;GACjD,SAAS,OAAO,KAAW,WAAW,EAAO,UAAU,KAAA;EACzD,EAAE;EACF,GAAG,EAAO,cAAc,KAAK,GAAQ,OAAW;GAC9C,IAAI,SAAS;GACb,MAAM;GACN,MAAM,EAAO;GACb,SAAS,EAAO;GAChB,MAAM,EAAO;GACb,KAAK,EAAO;GACZ,SAAS,EAAO;EAClB,EAAE;EACF,GAAG,EAAO,cAAc,KAAK,GAAQ,OAAW;GAC9C,IAAI,SAAS;GACb,MAAM;GACN,MAAM,OAAO,KAAW,WAAW,EAAO,OAAO,KAAA;GACjD,KAAK,OAAO,KAAW,WAAW,IAAS,EAAO;GAClD,SAAS,OAAO,KAAW,WAAW,EAAO,UAAU,KAAA;GACvD,SAAS,OAAO,KAAW,WAAW,EAAO,UAAU,KAAA;GACvD,MAAM,OAAO,KAAW,WAAW,EAAO,OAAO,KAAA;GACjD,SAAS,OAAO,KAAW,WAAW,EAAO,UAAU,KAAA;EACzD,EAAE;CACJ;AACF"}
|
|
@@ -4,7 +4,11 @@ import { I18nKey } from "#/i18n/declaration";
|
|
|
4
4
|
export declare const OPENHANDS_CLOUD_INTEGRATIONS_URL: string;
|
|
5
5
|
/**
|
|
6
6
|
* Single source of truth for "does this automation get the deployment-choice
|
|
7
|
-
* modal?" — true only for
|
|
7
|
+
* modal?" — true only for automations whose required integrations are
|
|
8
|
+
* exclusively responder ones (owned by the interface manifest, GitHub/Slack by
|
|
9
|
+
* default), so multi-tool digests (e.g. slack + linear + notion) are not
|
|
10
|
+
* treated as Slack responders. An integration the automation can start without
|
|
11
|
+
* does not decide where it runs, so only the required ones are classified.
|
|
8
12
|
*/
|
|
9
13
|
export declare function isResponderAutomation(automation: RecommendedAutomation): boolean;
|
|
10
14
|
/**
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
require("../../_virtual/_rolldown/runtime.cjs");const e=require("../../i18n/declaration.cjs"),t=require("../../i18n/index.cjs"),n=require("../../types/agent-server/type-guards.cjs"),r=require("../../components/conversation-events/chat/event-thought-helpers.cjs"),i=require("../handle-event-for-ui.cjs"),a=require("../../components/conversation-events/chat/event-content-helpers/should-render-event.cjs"),o=require("../../components/conversation-events/chat/event-content-helpers/
|
|
1
|
+
require("../../_virtual/_rolldown/runtime.cjs");const e=require("../../i18n/declaration.cjs"),t=require("../../i18n/index.cjs"),n=require("../../types/agent-server/type-guards.cjs"),r=require("../../components/conversation-events/chat/event-thought-helpers.cjs"),i=require("../handle-event-for-ui.cjs"),a=require("../../components/conversation-events/chat/event-content-helpers/should-render-event.cjs"),o=require("../../components/conversation-events/chat/event-content-helpers/get-acp-tool-call-content.cjs"),s=require("../../components/conversation-events/chat/event-content-helpers/parse-message-from-event.cjs"),c=require("../../components/conversation-events/chat/event-content-helpers/get-action-content.cjs"),l=require("../../components/conversation-events/chat/event-content-helpers/get-observation-content.cjs"),u=require("../../components/conversation-events/chat/group-events.cjs");var d=new Set([`BrowserClickAction`,`BrowserCloseTabAction`,`BrowserGetContentAction`,`BrowserGetStateAction`,`BrowserGoBackAction`,`BrowserListTabsAction`,`BrowserNavigateAction`,`BrowserScrollAction`,`BrowserSwitchTabAction`,`BrowserTypeAction`,`ExecuteBashAction`,`FileEditorAction`,`GlobAction`,`GrepAction`,`InvokeSkillAction`,`MCPToolAction`,`StrReplaceEditorAction`,`TaskAction`,`TaskTrackerAction`,`TerminalAction`,`ThinkAction`]),f=new Set([`BrowserObservation`,`CanvasUIObservation`,`ExecuteBashObservation`,`FileEditorObservation`,`GlobObservation`,`GrepObservation`,`InvokeSkillObservation`,`MCPToolObservation`,`StrReplaceEditorObservation`,`SwitchLLMObservation`,`TaskTrackerObservation`,`TaskObservation`,`TerminalObservation`]),p=e=>e.replace(/[\r\n]+/g,` `).replace(/\s+/g,` `).trim(),m=(e,t=100)=>e.length>t?`${e.slice(0,t)}…`:e,h=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toISOString()},g=e=>e.replaceAll(`&`,`&`).replaceAll(`<`,`<`).replaceAll(`>`,`>`).replaceAll(`"`,`"`).replaceAll(`'`,`'`),_=e=>e.replaceAll(`&`,`&`).replaceAll(`<`,`<`).replaceAll(`>`,`>`).replace(/(!?)\[([^\]]*)\]\(\s*((?:javascript|data|vbscript):[^)]*)\)/gi,`$1\\[$2\\]($3)`).replace(/^(\s{0,3})\[([^\]]+)\]:(\s*<?(?:javascript|data|vbscript):)/gim,`$1\\[$2\\]:$3`),v=n=>p(n||t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$DEFAULT_TITLE))||t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$DEFAULT_TITLE),y=(e,n)=>p(t.default.t(e,n).replace(/<\/?(?:cmd|path)>/g,``)),b=e=>/^[a-z][a-z0-9_]*\s*:\s*[[{]/i.test(e),x=e=>e.replace(/(?:Action|Observation)$/,``).replace(/([a-z])([A-Z])/g,`$1 $2`).trim(),S=e=>{let t=p(e.summary||``);return t&&!b(t)?t:p(e.tool_name)||x(e.action.kind)},C=(e,t)=>t?S(t):p(e.tool_name)||x(e.observation.kind),w=e=>e.filter(e=>e.type===`text`&&typeof e.text==`string`).map(e=>e.text).join(`
|
|
2
2
|
`),T=n=>[`${t.default.t(e.I18nKey.TASK$SUBAGENT)}: ${n.subagent_type}`,`${t.default.t(e.I18nKey.TASK$QUERY)}:\n${n.prompt}`].join(`
|
|
3
3
|
|
|
4
4
|
`),E=(n,r)=>{let i=r?.action.kind===`TaskAction`?r.action:void 0;return[`${t.default.t(e.I18nKey.TASK$SUBAGENT)}: ${n.subagent}`,`${t.default.t(e.I18nKey.TASK$TASK_ID)}: ${n.task_id}`,i?`${t.default.t(e.I18nKey.TASK$QUERY)}:\n${i.prompt}`:``,`${t.default.t(e.I18nKey.TASK$RESULT)}:\n${w(n.content)}`].filter(Boolean).join(`
|
|
5
5
|
|
|
6
|
-
`)},D=e=>e.action.kind===`TaskAction`?T(e.action):d.has(e.action.kind)?
|
|
6
|
+
`)},D=e=>e.action.kind===`TaskAction`?T(e.action):d.has(e.action.kind)?c.getActionContent(e):``,O=(e,t)=>e.observation.kind===`TaskObservation`?E(e.observation,t):f.has(e.observation.kind)?l.getObservationContent(e):``,k=e=>n.isHookExecutionEvent(e)?[e.reason,e.error,e.stdout,e.stderr].filter(e=>!!e?.trim()).join(`
|
|
7
7
|
|
|
8
8
|
`):``,A=e=>[r.getReasoningContent(e),r.getActionThoughtText(e)].map(e=>e.trim()).filter(Boolean).join(`
|
|
9
9
|
|
|
10
|
-
`),j=e=>![`FinishAction`,`SwitchLLMAction`,`ThinkAction`].includes(e.action.kind),M=(
|
|
11
|
-
`),timestamp:a.timestamp});continue}if(n.isMessageEvent(a)){let e=
|
|
10
|
+
`),j=e=>![`FinishAction`,`SwitchLLMAction`,`ThinkAction`].includes(e.action.kind),M=(c,l)=>{let d=c.reduce((e,t)=>{try{return i.handleEventForUI(t,e)}catch{return e}},[]),f=new Map(c.filter(n.isActionEvent).map(e=>[e.id,e])),h=[],g=new Set,_=u.groupEvents(d.filter(e=>n.isSwitchLLMObservationEvent(e)&&!e.observation.is_error||a.shouldRenderEvent(e)),2**53-1,c),v=e=>{if(g.has(e.id)||!j(e))return;g.add(e.id);let t=A(e);t&&h.push({kind:`message`,author:`assistant`,content:t,timestamp:e.timestamp})};for(let i of _){if(i.kind===`group`)continue;if(i.kind===`thought`){v(i.action);continue}let{event:a}=i;try{let i=n.isActionEvent(a)?a:n.isObservationEvent(a)?f.get(a.action_id):void 0;if(i&&v(i),n.isSwitchLLMObservationEvent(a)&&!a.observation.is_error){h.push({kind:`note`,summary:y(e.I18nKey.MODEL$SWITCHED_TO_PROFILE,{name:a.observation.profile_name}),content:[a.observation.active_model?`${t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$MODEL)}: ${a.observation.active_model}`:``,a.observation.reason?`${t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$REASON)}: ${a.observation.reason}`:``].filter(Boolean).join(`
|
|
11
|
+
`),timestamp:a.timestamp});continue}if(n.isMessageEvent(a)){let e=s.parseMessageFromEvent(a).trim();if(a.source===`agent`){let{reasoning:t,message:n}=r.splitInlineThink(e);[t,n].filter(Boolean).forEach(e=>{h.push({kind:`message`,author:`assistant`,content:e,timestamp:a.timestamp})})}else e&&h.push({kind:`message`,author:`user`,content:e,timestamp:a.timestamp});continue}if(n.isStreamingDeltaEvent(a)){let{reasoning:e,message:t}=r.splitInlineThink(a.content??``,{streaming:!0}),n=[a.reasoning_content?.trim()||``,e].filter(Boolean).join(`
|
|
12
12
|
|
|
13
|
-
`);n&&h.push({kind:`message`,author:`assistant`,content:n,timestamp:a.timestamp}),t.trim()&&h.push({kind:`message`,author:`assistant`,content:t.trim(),timestamp:a.timestamp});continue}if(n.isAgentErrorEvent(a)){h.push({kind:`error`,content:a.error,timestamp:a.timestamp});continue}if(n.isActionEvent(a)){if(a.action.kind===`FinishAction`){let e=a.action.message.trim();e&&h.push({kind:`message`,author:`assistant`,content:e,timestamp:a.timestamp})}else h.push({kind:`tool`,summary:S(a),details:
|
|
13
|
+
`);n&&h.push({kind:`message`,author:`assistant`,content:n,timestamp:a.timestamp}),t.trim()&&h.push({kind:`message`,author:`assistant`,content:t.trim(),timestamp:a.timestamp});continue}if(n.isAgentErrorEvent(a)){h.push({kind:`error`,content:a.error,timestamp:a.timestamp});continue}if(n.isActionEvent(a)){if(a.action.kind===`FinishAction`){let e=a.action.message.trim();e&&h.push({kind:`message`,author:`assistant`,content:e,timestamp:a.timestamp})}else h.push({kind:`tool`,summary:S(a),details:l?D(a):``,timestamp:a.timestamp});continue}if(n.isObservationEvent(a)){let e=f.get(a.action_id);h.push({kind:`tool`,summary:C(a,e),details:l?O(a,e):``,timestamp:a.timestamp});continue}if(n.isACPToolCallEvent(a)){h.push({kind:`tool`,summary:o.stripRedundantTitlePrefix(a)||t.default.t(e.I18nKey.ACTION_MESSAGE$ACP_TOOL),details:l?o.getACPToolCallContent(a):``,timestamp:a.timestamp});continue}if(n.isHookExecutionEvent(a)){h.push({kind:`tool`,summary:t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$HOOK,{command:m(p(a.hook_command),100)}),details:l?k(a):``,timestamp:a.timestamp});continue}n.isConversationStateUpdateEvent(a)&&n.isGoalConversationStateUpdateEvent(a)&&h.push({kind:`note`,summary:`${t.default.t(e.I18nKey.GOAL$PREFIX)} ${t.default.t({running:e.I18nKey.GOAL$STATUS_RUNNING,complete:e.I18nKey.GOAL$STATUS_COMPLETE,capped:e.I18nKey.GOAL$STATUS_CAPPED,interrupted:e.I18nKey.GOAL$STATUS_INTERRUPTED}[a.value.status])}`,content:[a.value.objective,a.value.verdict?.missing||``].filter(Boolean).join(`
|
|
14
14
|
|
|
15
15
|
`),timestamp:a.timestamp})}catch{}}return h},N=(e,t)=>t.includeTimestamps?`<sub>${g(h(e.timestamp))}</sub>\n\n`:``,P=e=>{let t=Math.max(0,...Array.from(e.matchAll(/`+/g),e=>e[0].length)),n="`".repeat(Math.max(3,t+1));return`${n}text\n${e}\n${n}`},F=(n,r)=>{let i=[`# ${_(v(r.title))}`,``];r.model&&i.push(`**${t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$MODEL)}:** ${_(p(r.model))}`,``);for(let a of M(n,r.includeToolDetails)){let n=N(a,r);if(a.kind===`message`){let r=a.author===`user`?t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$USER):t.default.t(e.I18nKey.CHAT_INTERFACE$ASSISTANT);i.push(`## ${r}`,``,n+_(a.content),``)}else if(a.kind===`error`){let r=a.content.split(`
|
|
16
16
|
`).map(e=>`> ${_(e)}`).join(`
|