@openhands/agent-canvas 1.0.0-alpha.7 → 1.0.0-alpha.9

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.
Files changed (745) hide show
  1. package/README.md +25 -23
  2. package/bin/agent-canvas.mjs +27 -1
  3. package/build/assets/{QueryClientProvider-DITRCGAK.js → QueryClientProvider-B7kl84Kj.js} +1 -1
  4. package/build/assets/{Trans-D43bd3yR.js → Trans-1j65oy9O.js} +1 -1
  5. package/build/assets/{acp-providers-SCPK1BIU.js → acp-providers-DauuOsW9.js} +1 -1
  6. package/build/assets/{acp-route-guard-IWlFmS6x.js → acp-route-guard-CQTmeJwM.js} +1 -1
  7. package/build/assets/{active-backend-context-CkP3ZEJs.js → active-backend-context-TVbjnvmP.js} +1 -1
  8. package/build/assets/add-backend-modal-FsnpTTgO.js +1 -0
  9. package/build/assets/{agent-server-client-options-8OJSXbm8.js → agent-server-client-options-DT2GP6VJ.js} +1 -1
  10. package/build/assets/{agent-server-compatibility-DvKtnXHw.js → agent-server-compatibility-2aOx5iWd.js} +1 -1
  11. package/build/assets/agent-server-conversation-service.api-BZmUqtiO.js +5 -0
  12. package/build/assets/{agent-settings-DdisD2Xx.js → agent-settings-B247S9G3.js} +2 -2
  13. package/build/assets/{alert-banner-CvTYN73l.js → alert-banner-BWoqueRw.js} +1 -1
  14. package/build/assets/{analytics-consent-form-modal-BKgT9i2w.js → analytics-consent-form-modal-C7sXfxRh.js} +1 -1
  15. package/build/assets/{app-settings-DcYXtxGP.js → app-settings-BVeSaty9.js} +1 -1
  16. package/build/assets/{automation-detail-D7GEU0vR.js → automation-detail-R-99FUce.js} +1 -1
  17. package/build/assets/{automations-list-CkVNsgzm.js → automations-list-Dfu2c-_D.js} +1 -1
  18. package/build/assets/backend-form-modal-DxYjqqAK.js +1 -0
  19. package/build/assets/{backend-synced-settings-badge-BFy2HylT.js → backend-synced-settings-badge-nAfiUWvM.js} +1 -1
  20. package/build/assets/{base-modal-B4HvlFHE.js → base-modal-CQRvRHu1.js} +1 -1
  21. package/build/assets/{brand-button-8fVVei4i.js → brand-button-C2nEKopC.js} +1 -1
  22. package/build/assets/browser-HrYc5Gce.js +5 -0
  23. package/build/assets/{browser-tab-DTM6RyoV.js → browser-tab-B_BuTvrO.js} +1 -1
  24. package/build/assets/{checkmark-BcvXE9bf.js → checkmark-BJJrZUF8.js} +1 -1
  25. package/build/assets/{chevron-left-small-BqSkXTeq.js → chevron-left-small-CSh-sE9L.js} +1 -1
  26. package/build/assets/{circle-plus-check-toggle-DRvuu-RD.js → circle-plus-check-toggle-qs8Va1cC.js} +1 -1
  27. package/build/assets/{clock-DfoVUZVq.js → clock-ZR4Kn-_Y.js} +1 -1
  28. package/build/assets/{close-SnIy2eLD.js → close-BdmyeRqS.js} +1 -1
  29. package/build/assets/{combobox-caret-BMsz5mQX.js → combobox-caret-B53O9Hsq.js} +1 -1
  30. package/build/assets/{condenser-settings-DduLQcpV.js → condenser-settings-A35V3yng.js} +1 -1
  31. package/build/assets/{confirmation-modal-B-DOYMUH.js → confirmation-modal-C9-La0h3.js} +1 -1
  32. package/build/assets/{context-menu-list-item-DzjPB8aC.js → context-menu-list-item-Buu9nc0q.js} +1 -1
  33. package/build/assets/conversation--ldUK72N.js +19 -0
  34. package/build/assets/conversation-eNrhH94O.js +1 -0
  35. package/build/assets/conversation-panel-B49Jpqpb.js +1 -0
  36. package/build/assets/{conversation-service.api-YTGTw0pz.js → conversation-service.api--f8WglOC.js} +1 -1
  37. package/build/assets/{conversation-tab-empty-state-BtFDbyTe.js → conversation-tab-empty-state-D8dNvo-V.js} +1 -1
  38. package/build/assets/conversation-websocket-context-BW68-J8o.js +3 -0
  39. package/build/assets/{copy-BxgbrjDT.js → copy-C7Ti2d8C.js} +1 -1
  40. package/build/assets/{custom-toast-handlers-BYxhSr3t.js → custom-toast-handlers-BOc3qeQ7.js} +1 -1
  41. package/build/assets/declaration-D378OjpZ.js +1 -0
  42. package/build/assets/{device-verify-CTbXX9CQ.js → device-verify-CMusn8nX.js} +1 -1
  43. package/build/assets/edit-automation-modal-Dnjxbjn7.js +1 -0
  44. package/build/assets/{ellipsis-button-BoU2-xlG.js → ellipsis-button-ugUATsNo.js} +1 -1
  45. package/build/assets/{entry.client-DU7-q4ZU.js → entry.client-CqqXOSvd.js} +2 -2
  46. package/build/assets/{enum-filter-dropdown-BJt-NplD.js → enum-filter-dropdown-1vpOGySB.js} +1 -1
  47. package/build/assets/{environment-switch-overlay-DQ1n6Iu6.js → environment-switch-overlay-CTCTQikP.js} +1 -1
  48. package/build/assets/{extensions-hub-BW1FAKFJ.js → extensions-hub-BSUseHVF.js} +1 -1
  49. package/build/assets/{extensions-navigation-CbPMhSML.js → extensions-navigation-CT1kc1u_.js} +1 -1
  50. package/build/assets/files-tab-CQHdWpQt.js +1 -0
  51. package/build/assets/{folder-CerIk8uG.js → folder-0WSMImNX.js} +1 -1
  52. package/build/assets/git-control-bar-branch-button-C8u5rzjc.js +27 -0
  53. package/build/assets/{git-provider-icon-D8RE4unY.js → git-provider-icon-D-a-rcLm.js} +1 -1
  54. package/build/assets/{home-DR11ejqB.js → home-DD0GroCu.js} +1 -1
  55. package/build/assets/{i18n-DkYgs32x.js → i18n-DjAGhTis.js} +1 -1
  56. package/build/assets/install-server-modal-z5VaHeXd.js +1 -0
  57. package/build/assets/{launch-DKCU9uJH.js → launch-B2mbfOSm.js} +1 -1
  58. package/build/assets/{lesson-plan-CmkRbe6Z.js → lesson-plan-DRYG5SLI.js} +1 -1
  59. package/build/assets/{link-external-CvxB0BmI.js → link-external-C9d6Fo3x.js} +1 -1
  60. package/build/assets/{llm-client-BpIfxETv.js → llm-client-ChQzg4wX.js} +1 -1
  61. package/build/assets/llm-settings-BEyqixPI.js +1 -0
  62. package/build/assets/{llm-settings-BOJC4vD-.js → llm-settings-BdiaGFbg.js} +1 -1
  63. package/build/assets/{loading-spinner-91b5FiMQ.js → loading-spinner-C04FGh14.js} +1 -1
  64. package/build/assets/{manage-backends-modal-DqpzcxdI.js → manage-backends-modal-s22zCdEW.js} +1 -1
  65. package/build/assets/{manage-workspaces-modal-eG6XgAvw.js → manage-workspaces-modal-C5EuW8m1.js} +1 -1
  66. package/build/assets/manifest-9d1c34fb.js +1 -0
  67. package/build/assets/{markdown-renderer-wZnLDbA1.js → markdown-renderer-CEX4Becj.js} +1 -1
  68. package/build/assets/mcp-C06YssEI.js +9 -0
  69. package/build/assets/messages-6aOyUu3r.js +36 -0
  70. package/build/assets/{modal-backdrop-B04pVYAD.js → modal-backdrop-DTYGVmOR.js} +1 -1
  71. package/build/assets/{modal-body-CgUoFQA1.js → modal-body-YElmM1dV.js} +1 -1
  72. package/build/assets/{modal-close-button-SM_WXzDY.js → modal-close-button-C_GpQt9F.js} +1 -1
  73. package/build/assets/{model-selector-7id-Uirf.js → model-selector-DeMmw-Xa.js} +1 -1
  74. package/build/assets/{navigation-context-BFjstyH6.js → navigation-context-DeIPtGPp.js} +1 -1
  75. package/build/assets/{navigation-link-DFQ7YcWq.js → navigation-link-C9JD4PYD.js} +1 -1
  76. package/build/assets/{openhands-logo-DkDp75rC.js → openhands-logo-CI5Fhn1W.js} +1 -1
  77. package/build/assets/{option-service.api-DN0ZcGjw.js → option-service.api-DsI1UW7N.js} +1 -1
  78. package/build/assets/{organization-service.api-Ct2dZF8M.js → organization-service.api-COwMPFg5.js} +1 -1
  79. package/build/assets/{path-utils-D1ZtqFC7.js → path-utils-BVbe598W.js} +1 -1
  80. package/build/assets/{plan-components-gOm-daR3.js → plan-components-DEjMuDDG.js} +1 -1
  81. package/build/assets/{planner-tab-yubfN-6U.js → planner-tab-bN6r1G-1.js} +1 -1
  82. package/build/assets/{profiles-client-D4twHRVf.js → profiles-client-BGkKEV9j.js} +1 -1
  83. package/build/assets/{providers-C2T07PM3.js → providers-DXvCAN_u.js} +1 -1
  84. package/build/assets/{proxy-BMZyC45G.js → proxy-CurRmrqf.js} +1 -1
  85. package/build/assets/{query-client-config-CiK0GJJO.js → query-client-config-Ba7qAAoO.js} +1 -1
  86. package/build/assets/recommended-automations-launcher-mJhK6Atl.js +52 -0
  87. package/build/assets/root-3t9rxEpE.js +2 -0
  88. package/build/assets/root-DHeCXo9N.css +1 -0
  89. package/build/assets/{root-layout-B4QioBS6.js → root-layout-BjVwHmta.js} +2 -2
  90. package/build/assets/{sdk-section-page-03k88tIR.js → sdk-section-page-CJW0G04-.js} +1 -1
  91. package/build/assets/{sdk-settings-schema-BY8dOy3a.js → sdk-settings-schema-QBYH-ONX.js} +1 -1
  92. package/build/assets/{search-BCAF9EDS.js → search-Cq_cFrDt.js} +1 -1
  93. package/build/assets/{secrets-service-Z3qtRb_G.js → secrets-service-Bwd5DeUs.js} +1 -1
  94. package/build/assets/{secrets-settings-BnlByuMZ.js → secrets-settings-MLXqOtX2.js} +1 -1
  95. package/build/assets/{server-client-CG1zHqph.js → server-client-C3mC8Hl3.js} +1 -1
  96. package/build/assets/{settings-DyzGLF_d.js → settings-D7E2U5tK.js} +1 -1
  97. package/build/assets/{settings-client-CkXDJwIY.js → settings-client-CwjfwoiB.js} +1 -1
  98. package/build/assets/{settings-dropdown-input-CAQWQgx-.js → settings-dropdown-input-VwAXNrOb.js} +1 -1
  99. package/build/assets/{settings-gear-D4ZkEDGb.js → settings-gear-BJwWR1ej.js} +1 -1
  100. package/build/assets/{settings-index-KtTw49xL.js → settings-index-J-3BNR0W.js} +1 -1
  101. package/build/assets/{settings-input-BWCZt9g2.js → settings-input-DBywAnA7.js} +1 -1
  102. package/build/assets/{settings-list-classes-xMleGkTC.js → settings-list-classes-BOS092DR.js} +1 -1
  103. package/build/assets/{settings-modal-Cv2YWSUY.js → settings-modal-B8vgWDTe.js} +1 -1
  104. package/build/assets/{settings-section-header-context-1wfkgjZZ.js → settings-section-header-context-32x6WTyL.js} +1 -1
  105. package/build/assets/settings-service.api-FvJGK45W.js +1 -0
  106. package/build/assets/{settings-switch-CGap2LtG.js → settings-switch-DTKmHC8F.js} +1 -1
  107. package/build/assets/{settings-utils-BBozxqqi.js → settings-utils-BsvSU3OM.js} +1 -1
  108. package/build/assets/{shared-conversation-DQlzwdpo.js → shared-conversation-EZV0FRIf.js} +1 -1
  109. package/build/assets/{sidebar-mobile-menu-toggle-DXplko7u.js → sidebar-mobile-menu-toggle-BnbzzpQl.js} +1 -1
  110. package/build/assets/{sidebar-nav-link-B4h8naZ7.js → sidebar-nav-link-CnWoZcwc.js} +1 -1
  111. package/build/assets/{skill-card-pill-row-D0oTWx-a.js → skill-card-pill-row-tZ599jli.js} +1 -1
  112. package/build/assets/{skills-BN8atjgW.js → skills-ZyAO5dyK.js} +1 -1
  113. package/build/assets/{skills-plugins-BTnp7QcQ.js → skills-plugins-BSRz041I.js} +1 -1
  114. package/build/assets/{skills-settings-CbOQvzkR.js → skills-settings-CG2hu34D.js} +2 -2
  115. package/build/assets/{status-DDL-ipIP.js → status-CsatcFbK.js} +1 -1
  116. package/build/assets/{styled-tooltip-Awq4HMw3.js → styled-tooltip-CS3mB_1X.js} +1 -1
  117. package/build/assets/{switch-skeleton-Bv21RGWd.js → switch-skeleton-C-CfhYYV.js} +1 -1
  118. package/build/assets/{task-list-tab-B45ktzHM.js → task-list-tab-465DDju0.js} +1 -1
  119. package/build/assets/{terminal-D5pzR9Ru.js → terminal-CcgBEVnC.js} +1 -1
  120. package/build/assets/{terminal-DGuR4559.js → terminal-LNa-iU5c.js} +1 -1
  121. package/build/assets/{toggle-switch-gj6T-wsU.js → toggle-switch-k-IZCDbt.js} +1 -1
  122. package/build/assets/{typography-BbaUAC4V.js → typography-vVUMoNUg.js} +1 -1
  123. package/build/assets/{u-check-circle-DHGiAi-w.js → u-check-circle-DplbarS5.js} +1 -1
  124. package/build/assets/{u-check-circle-half-BPcWtWwv.js → u-check-circle-half-yDuiSZHC.js} +1 -1
  125. package/build/assets/{u-circuit-B_nK9hOu.js → u-circuit-C9tYkpeK.js} +1 -1
  126. package/build/assets/{u-edit-BPFJBd34.js → u-edit-KAUlufD8.js} +1 -1
  127. package/build/assets/{use-active-conversation-Bu5J9iLy.js → use-active-conversation-DS5j9R4q.js} +1 -1
  128. package/build/assets/{use-agent-settings-schema-BbtOsR7P.js → use-agent-settings-schema-Bvp5UzV8.js} +1 -1
  129. package/build/assets/{use-agent-state-DN9Nc5pP.js → use-agent-state-D2C9SeGw.js} +1 -1
  130. package/build/assets/{use-cloud-current-user-id-B_rMUiu8.js → use-cloud-current-user-id-DWVar4st.js} +1 -1
  131. package/build/assets/{use-config-Bcz2JL2t.js → use-config-BSu_53GL.js} +1 -1
  132. package/build/assets/{use-conversation-id-BOaaZahn.js → use-conversation-id-DajhCn2A.js} +1 -1
  133. package/build/assets/{use-create-conversation-BWFA_FId.js → use-create-conversation-BEZg__Vv.js} +1 -1
  134. package/build/assets/{use-event-store-CQZCcVz-.js → use-event-store-BT_gV3ut.js} +1 -1
  135. package/build/assets/{use-handle-plan-click-CgrCGmT1.js → use-handle-plan-click-uOpew2LO.js} +1 -1
  136. package/build/assets/use-is-authed-hXC8vxgT.js +1 -0
  137. package/build/assets/{use-is-creating-conversation-DhoM7UAB.js → use-is-creating-conversation-DhDeeWfA.js} +1 -1
  138. package/build/assets/{use-launch-skill-in-chat-DOyQsXFO.js → use-launch-skill-in-chat-DVGPFrbI.js} +1 -1
  139. package/build/assets/{use-llm-profiles-CAIzHJDX.js → use-llm-profiles-O4a9V6RC.js} +1 -1
  140. package/build/assets/use-runtime-is-ready-pGSbPddC.js +1 -0
  141. package/build/assets/{use-save-settings-5m3w89Ph.js → use-save-settings-CEEKSTWG.js} +1 -1
  142. package/build/assets/{use-settings-DzG0C3vO.js → use-settings-DQ7Oo1Hj.js} +1 -1
  143. package/build/assets/{use-settings-nav-items-BIsKeX52.js → use-settings-nav-items-YmrXrjn9.js} +2 -2
  144. package/build/assets/use-skills-BIvlWblA.js +1 -0
  145. package/build/assets/{use-task-list-Bs90uF2N.js → use-task-list-DDeNHprj.js} +1 -1
  146. package/build/assets/{use-unified-vscode-url-C5iI-Z5A.js → use-unified-vscode-url-wAMzv8Sn.js} +1 -1
  147. package/build/assets/use-user-conversation-B_zDoSeh.js +1 -0
  148. package/build/assets/{useMutation-CRJwk4cR.js → useMutation-B4OUESdw.js} +1 -1
  149. package/build/assets/{useTranslation-01pF7z10.js → useTranslation-CpIcQBq6.js} +1 -1
  150. package/build/assets/{utils-Czcl6buL.js → utils-D-HX7JCe.js} +1 -1
  151. package/build/assets/{vendor~conversation-panel~conversation-CbjvWBSu.js → vendor~conversation-panel~conversation-BlCIz9XQ.js} +1 -1
  152. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CofhIDpd.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Ds9quNZ9.js} +1 -1
  153. package/build/assets/vendor~home~mcp~automations-list-C5PoHCy6.js +1 -0
  154. package/build/assets/{vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-BQPOygpY.js → vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-CGlZoBKa.js} +1 -1
  155. package/build/assets/{vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-CyYIBiBk.js → vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-DE11mPxp.js} +1 -1
  156. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-CuGq_cxH.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-8b8V5bfO.js} +1 -1
  157. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-CFpDeb9o.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-Dy7L6fMG.js} +1 -1
  158. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-C1p8-pMr.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-D40EXhZx.js} +1 -1
  159. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-CHrEOFl6.js +48 -0
  160. package/build/assets/{vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~kyz9p27j-DlKA6SoO.js → vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~kyz9p27j-CyUbhpbm.js} +1 -1
  161. package/build/assets/{verification-settings-DbziMp4K.js → verification-settings-BtlTiHP8.js} +1 -1
  162. package/build/assets/{vscode-tab-BVhQR2rt.js → vscode-tab-B0vdh9gU.js} +1 -1
  163. package/build/assets/{waiting-for-runtime-message-JotSOBdC.js → waiting-for-runtime-message-DWPl_Yby.js} +1 -1
  164. package/build/assets/{x-mark-CZ57VvRX.js → x-mark-CWI0f9yI.js} +1 -1
  165. package/build/favicon.svg +1 -0
  166. package/build/index.html +4 -4
  167. package/build/locales/ar/openhands.json +8 -0
  168. package/build/locales/ca/openhands.json +8 -0
  169. package/build/locales/de/openhands.json +8 -0
  170. package/build/locales/en/openhands.json +8 -0
  171. package/build/locales/es/openhands.json +8 -0
  172. package/build/locales/fr/openhands.json +8 -0
  173. package/build/locales/it/openhands.json +8 -0
  174. package/build/locales/ja/openhands.json +8 -0
  175. package/build/locales/ko-KR/openhands.json +8 -0
  176. package/build/locales/no/openhands.json +8 -0
  177. package/build/locales/pt/openhands.json +8 -0
  178. package/build/locales/tr/openhands.json +8 -0
  179. package/build/locales/uk/openhands.json +8 -0
  180. package/build/locales/zh-CN/openhands.json +8 -0
  181. package/build/locales/zh-TW/openhands.json +8 -0
  182. package/config/defaults.json +1 -1
  183. package/dist/api/agent-server-adapter.cjs +1 -1
  184. package/dist/api/agent-server-adapter.cjs.map +1 -1
  185. package/dist/api/agent-server-adapter.js +1 -0
  186. package/dist/api/agent-server-adapter.js.map +1 -1
  187. package/dist/api/agent-server-config.cjs +1 -1
  188. package/dist/api/agent-server-config.cjs.map +1 -1
  189. package/dist/api/agent-server-config.d.ts +1 -1
  190. package/dist/api/agent-server-config.js +1 -1
  191. package/dist/api/agent-server-config.js.map +1 -1
  192. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
  193. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
  194. package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +12 -0
  195. package/dist/api/conversation-service/agent-server-conversation-service.api.js +4 -0
  196. package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
  197. package/dist/api/mcp-service/mcp-service.api.cjs +2 -0
  198. package/dist/api/mcp-service/mcp-service.api.cjs.map +1 -0
  199. package/dist/api/mcp-service/mcp-service.api.d.ts +6 -0
  200. package/dist/api/mcp-service/mcp-service.api.js +36 -0
  201. package/dist/api/mcp-service/mcp-service.api.js.map +1 -0
  202. package/dist/api/settings-service/settings-service.api.cjs +1 -1
  203. package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
  204. package/dist/api/settings-service/settings-service.api.d.ts +1 -0
  205. package/dist/api/settings-service/settings-service.api.js +59 -41
  206. package/dist/api/settings-service/settings-service.api.js.map +1 -1
  207. package/dist/api/skills-service.cjs +1 -1
  208. package/dist/api/skills-service.cjs.map +1 -1
  209. package/dist/api/skills-service.d.ts +1 -1
  210. package/dist/api/skills-service.js +2 -2
  211. package/dist/api/skills-service.js.map +1 -1
  212. package/dist/components/features/automations/detail/activity-log-item.d.ts +1 -1
  213. package/dist/components/features/automations/recommended-automations-launcher.d.ts +1 -1
  214. package/dist/components/features/backends/backend-form-modal.cjs +1 -1
  215. package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
  216. package/dist/components/features/backends/backend-form-modal.js +149 -142
  217. package/dist/components/features/backends/backend-form-modal.js.map +1 -1
  218. package/dist/components/features/chat/change-agent-button.cjs +1 -1
  219. package/dist/components/features/chat/change-agent-button.cjs.map +1 -1
  220. package/dist/components/features/chat/change-agent-button.js +65 -59
  221. package/dist/components/features/chat/change-agent-button.js.map +1 -1
  222. package/dist/components/features/chat/chat-interface.cjs +2 -2
  223. package/dist/components/features/chat/chat-interface.cjs.map +1 -1
  224. package/dist/components/features/chat/chat-interface.js +15 -14
  225. package/dist/components/features/chat/chat-interface.js.map +1 -1
  226. package/dist/components/features/chat/components/chat-input-actions.cjs +1 -1
  227. package/dist/components/features/chat/components/chat-input-actions.cjs.map +1 -1
  228. package/dist/components/features/chat/components/chat-input-actions.js +127 -149
  229. package/dist/components/features/chat/components/chat-input-actions.js.map +1 -1
  230. package/dist/components/features/chat/components/chat-input-model.cjs +1 -1
  231. package/dist/components/features/chat/components/chat-input-model.cjs.map +1 -1
  232. package/dist/components/features/chat/components/chat-input-model.d.ts +10 -0
  233. package/dist/components/features/chat/components/chat-input-model.js +95 -60
  234. package/dist/components/features/chat/components/chat-input-model.js.map +1 -1
  235. package/dist/components/features/chat/git-control-bar.cjs +1 -1
  236. package/dist/components/features/chat/git-control-bar.cjs.map +1 -1
  237. package/dist/components/features/chat/git-control-bar.js +60 -59
  238. package/dist/components/features/chat/git-control-bar.js.map +1 -1
  239. package/dist/components/features/conversation/conversation-name-with-status.cjs +1 -1
  240. package/dist/components/features/conversation/conversation-name-with-status.cjs.map +1 -1
  241. package/dist/components/features/conversation/conversation-name-with-status.js +2 -2
  242. package/dist/components/features/conversation/conversation-name-with-status.js.map +1 -1
  243. package/dist/components/features/conversation/conversation-name.cjs +1 -1
  244. package/dist/components/features/conversation/conversation-name.cjs.map +1 -1
  245. package/dist/components/features/conversation/conversation-name.js +3 -3
  246. package/dist/components/features/conversation/conversation-name.js.map +1 -1
  247. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs +1 -1
  248. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs.map +1 -1
  249. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js +1 -1
  250. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js.map +1 -1
  251. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs +1 -1
  252. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs.map +1 -1
  253. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js +16 -16
  254. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js.map +1 -1
  255. package/dist/components/features/conversation-panel/skills-modal.cjs +1 -1
  256. package/dist/components/features/conversation-panel/skills-modal.cjs.map +1 -1
  257. package/dist/components/features/conversation-panel/skills-modal.js +1 -1
  258. package/dist/components/features/conversation-panel/skills-modal.js.map +1 -1
  259. package/dist/components/features/mcp-logo-badge.cjs +1 -1
  260. package/dist/components/features/mcp-logo-badge.cjs.map +1 -1
  261. package/dist/components/features/mcp-logo-badge.d.ts +2 -2
  262. package/dist/components/features/mcp-logo-badge.js +1 -1
  263. package/dist/components/features/mcp-logo-badge.js.map +1 -1
  264. package/dist/components/features/mcp-page/custom-server-editor.cjs +1 -1
  265. package/dist/components/features/mcp-page/custom-server-editor.cjs.map +1 -1
  266. package/dist/components/features/mcp-page/custom-server-editor.js +64 -41
  267. package/dist/components/features/mcp-page/custom-server-editor.js.map +1 -1
  268. package/dist/components/features/mcp-page/install-server-modal.cjs +1 -1
  269. package/dist/components/features/mcp-page/install-server-modal.cjs.map +1 -1
  270. package/dist/components/features/mcp-page/install-server-modal.d.ts +1 -1
  271. package/dist/components/features/mcp-page/install-server-modal.js +126 -102
  272. package/dist/components/features/mcp-page/install-server-modal.js.map +1 -1
  273. package/dist/components/features/mcp-page/installed-server-card.cjs +1 -1
  274. package/dist/components/features/mcp-page/installed-server-card.cjs.map +1 -1
  275. package/dist/components/features/mcp-page/installed-server-card.js +1 -1
  276. package/dist/components/features/mcp-page/installed-server-card.js.map +1 -1
  277. package/dist/components/features/mcp-page/marketplace-card.cjs +1 -1
  278. package/dist/components/features/mcp-page/marketplace-card.cjs.map +1 -1
  279. package/dist/components/features/mcp-page/marketplace-card.d.ts +1 -1
  280. package/dist/components/features/mcp-page/marketplace-card.js +27 -25
  281. package/dist/components/features/mcp-page/marketplace-card.js.map +1 -1
  282. package/dist/components/features/mcp-page/marketplace-section.cjs +1 -1
  283. package/dist/components/features/mcp-page/marketplace-section.cjs.map +1 -1
  284. package/dist/components/features/mcp-page/marketplace-section.d.ts +1 -1
  285. package/dist/components/features/mcp-page/marketplace-section.js +1 -1
  286. package/dist/components/features/mcp-page/marketplace-section.js.map +1 -1
  287. package/dist/components/features/mcp-page/mcp-logo-stack-badge.d.ts +2 -2
  288. package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs +7 -7
  289. package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs.map +1 -1
  290. package/dist/components/features/settings/mcp-settings/mcp-server-form.d.ts +8 -12
  291. package/dist/components/features/settings/mcp-settings/mcp-server-form.js +114 -87
  292. package/dist/components/features/settings/mcp-settings/mcp-server-form.js.map +1 -1
  293. package/dist/context/scroll-context.cjs +1 -1
  294. package/dist/context/scroll-context.cjs.map +1 -1
  295. package/dist/context/scroll-context.d.ts +1 -0
  296. package/dist/context/scroll-context.js +4 -1
  297. package/dist/context/scroll-context.js.map +1 -1
  298. package/dist/contexts/conversation-websocket-context.cjs +3 -3
  299. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  300. package/dist/contexts/conversation-websocket-context.js +97 -89
  301. package/dist/contexts/conversation-websocket-context.js.map +1 -1
  302. package/dist/favicon.svg +1 -0
  303. package/dist/hooks/chat/use-slash-command.cjs +1 -1
  304. package/dist/hooks/chat/use-slash-command.cjs.map +1 -1
  305. package/dist/hooks/chat/use-slash-command.js +1 -1
  306. package/dist/hooks/chat/use-slash-command.js.map +1 -1
  307. package/dist/hooks/mutation/use-switch-acp-model.cjs +2 -0
  308. package/dist/hooks/mutation/use-switch-acp-model.cjs.map +1 -0
  309. package/dist/hooks/mutation/use-switch-acp-model.d.ts +23 -0
  310. package/dist/hooks/mutation/use-switch-acp-model.js +26 -0
  311. package/dist/hooks/mutation/use-switch-acp-model.js.map +1 -0
  312. package/dist/hooks/mutation/use-test-mcp-server.cjs +2 -0
  313. package/dist/hooks/mutation/use-test-mcp-server.cjs.map +1 -0
  314. package/dist/hooks/mutation/use-test-mcp-server.d.ts +2 -0
  315. package/dist/hooks/mutation/use-test-mcp-server.js +10 -0
  316. package/dist/hooks/mutation/use-test-mcp-server.js.map +1 -0
  317. package/dist/hooks/query/use-automation-detail.d.ts +3 -2
  318. package/dist/hooks/query/use-conversation-skills.cjs +2 -0
  319. package/dist/hooks/query/use-conversation-skills.cjs.map +1 -0
  320. package/dist/hooks/query/use-conversation-skills.d.ts +7 -0
  321. package/dist/hooks/query/use-conversation-skills.js +8 -0
  322. package/dist/hooks/query/use-conversation-skills.js.map +1 -0
  323. package/dist/hooks/query/use-skills.cjs +1 -1
  324. package/dist/hooks/query/use-skills.cjs.map +1 -1
  325. package/dist/hooks/query/use-skills.d.ts +6 -1
  326. package/dist/hooks/query/use-skills.js +3 -3
  327. package/dist/hooks/query/use-skills.js.map +1 -1
  328. package/dist/hooks/use-acp-model-context.cjs.map +1 -1
  329. package/dist/hooks/use-acp-model-context.d.ts +3 -4
  330. package/dist/hooks/use-acp-model-context.js.map +1 -1
  331. package/dist/hooks/use-chat-input-model-state.cjs +2 -0
  332. package/dist/hooks/use-chat-input-model-state.cjs.map +1 -0
  333. package/dist/hooks/use-chat-input-model-state.d.ts +12 -0
  334. package/dist/hooks/use-chat-input-model-state.js +29 -0
  335. package/dist/hooks/use-chat-input-model-state.js.map +1 -0
  336. package/dist/i18n/declaration.cjs +1 -1
  337. package/dist/i18n/declaration.cjs.map +1 -1
  338. package/dist/i18n/declaration.d.ts +8 -0
  339. package/dist/i18n/declaration.js +1 -1
  340. package/dist/i18n/declaration.js.map +1 -1
  341. package/dist/i18n/translation.cjs +2 -2
  342. package/dist/i18n/translation.cjs.map +1 -1
  343. package/dist/i18n/translation.js +136 -0
  344. package/dist/i18n/translation.js.map +1 -1
  345. package/dist/locales/ar/openhands.json +8 -0
  346. package/dist/locales/ca/openhands.json +8 -0
  347. package/dist/locales/de/openhands.json +8 -0
  348. package/dist/locales/en/openhands.json +8 -0
  349. package/dist/locales/es/openhands.json +8 -0
  350. package/dist/locales/fr/openhands.json +8 -0
  351. package/dist/locales/it/openhands.json +8 -0
  352. package/dist/locales/ja/openhands.json +8 -0
  353. package/dist/locales/ko-KR/openhands.json +8 -0
  354. package/dist/locales/no/openhands.json +8 -0
  355. package/dist/locales/pt/openhands.json +8 -0
  356. package/dist/locales/tr/openhands.json +8 -0
  357. package/dist/locales/uk/openhands.json +8 -0
  358. package/dist/locales/zh-CN/openhands.json +8 -0
  359. package/dist/locales/zh-TW/openhands.json +8 -0
  360. package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.cjs +2 -0
  361. package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.cjs.map +1 -0
  362. package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.js +37 -0
  363. package/dist/node_modules/@openhands/extensions/integrations/catalog/airtable.js.map +1 -0
  364. package/dist/node_modules/@openhands/extensions/integrations/catalog/apify.cjs +2 -0
  365. package/dist/node_modules/@openhands/extensions/integrations/catalog/apify.cjs.map +1 -0
  366. package/dist/node_modules/@openhands/extensions/integrations/catalog/apify.js +36 -0
  367. package/dist/node_modules/@openhands/extensions/integrations/catalog/apify.js.map +1 -0
  368. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/atlassian.cjs +1 -1
  369. package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.cjs.map +1 -0
  370. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/atlassian.js +15 -5
  371. package/dist/node_modules/@openhands/extensions/integrations/catalog/atlassian.js.map +1 -0
  372. package/dist/node_modules/@openhands/extensions/integrations/catalog/brave-search.cjs +2 -0
  373. package/dist/node_modules/@openhands/extensions/integrations/catalog/brave-search.cjs.map +1 -0
  374. package/dist/node_modules/@openhands/extensions/integrations/catalog/brave-search.js +36 -0
  375. package/dist/node_modules/@openhands/extensions/integrations/catalog/brave-search.js.map +1 -0
  376. package/dist/node_modules/@openhands/extensions/integrations/catalog/browser-mcp.cjs +2 -0
  377. package/dist/node_modules/@openhands/extensions/integrations/catalog/browser-mcp.cjs.map +1 -0
  378. package/dist/node_modules/@openhands/extensions/integrations/catalog/browser-mcp.js +31 -0
  379. package/dist/node_modules/@openhands/extensions/integrations/catalog/browser-mcp.js.map +1 -0
  380. package/dist/node_modules/@openhands/extensions/integrations/catalog/clickhouse.cjs +2 -0
  381. package/dist/node_modules/@openhands/extensions/integrations/catalog/clickhouse.cjs.map +1 -0
  382. package/dist/node_modules/@openhands/extensions/integrations/catalog/clickhouse.js +52 -0
  383. package/dist/node_modules/@openhands/extensions/integrations/catalog/clickhouse.js.map +1 -0
  384. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-bindings.cjs +1 -1
  385. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-bindings.cjs.map +1 -0
  386. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-bindings.js +15 -5
  387. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-bindings.js.map +1 -0
  388. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-browser-rendering.cjs +2 -0
  389. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-browser-rendering.cjs.map +1 -0
  390. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-browser-rendering.js +15 -5
  391. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-browser-rendering.js.map +1 -0
  392. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-builds.cjs +1 -1
  393. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-builds.cjs.map +1 -0
  394. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-builds.js +15 -5
  395. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-builds.js.map +1 -0
  396. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-docs.cjs +1 -1
  397. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-docs.cjs.map +1 -0
  398. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-docs.js +15 -5
  399. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-docs.js.map +1 -0
  400. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-observability.cjs +2 -0
  401. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-observability.cjs.map +1 -0
  402. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/cloudflare-observability.js +15 -5
  403. package/dist/node_modules/@openhands/extensions/integrations/catalog/cloudflare-observability.js.map +1 -0
  404. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/deepwiki.cjs +1 -1
  405. package/dist/node_modules/@openhands/extensions/integrations/catalog/deepwiki.cjs.map +1 -0
  406. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/deepwiki.js +15 -5
  407. package/dist/node_modules/@openhands/extensions/integrations/catalog/deepwiki.js.map +1 -0
  408. package/dist/node_modules/@openhands/extensions/integrations/catalog/elevenlabs.cjs +2 -0
  409. package/dist/node_modules/@openhands/extensions/integrations/catalog/elevenlabs.cjs.map +1 -0
  410. package/dist/node_modules/@openhands/extensions/integrations/catalog/elevenlabs.js +36 -0
  411. package/dist/node_modules/@openhands/extensions/integrations/catalog/elevenlabs.js.map +1 -0
  412. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/everything.cjs +1 -1
  413. package/dist/node_modules/@openhands/extensions/integrations/catalog/everything.cjs.map +1 -0
  414. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/everything.js +13 -6
  415. package/dist/node_modules/@openhands/extensions/integrations/catalog/everything.js.map +1 -0
  416. package/dist/node_modules/@openhands/extensions/integrations/catalog/exa.cjs +2 -0
  417. package/dist/node_modules/@openhands/extensions/integrations/catalog/exa.cjs.map +1 -0
  418. package/dist/node_modules/@openhands/extensions/integrations/catalog/exa.js +36 -0
  419. package/dist/node_modules/@openhands/extensions/integrations/catalog/exa.js.map +1 -0
  420. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/fetch.cjs +1 -1
  421. package/dist/node_modules/@openhands/extensions/integrations/catalog/fetch.cjs.map +1 -0
  422. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/fetch.js +13 -6
  423. package/dist/node_modules/@openhands/extensions/integrations/catalog/fetch.js.map +1 -0
  424. package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.cjs +2 -0
  425. package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.cjs.map +1 -0
  426. package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.js +40 -0
  427. package/dist/node_modules/@openhands/extensions/integrations/catalog/figma.js.map +1 -0
  428. package/dist/node_modules/@openhands/extensions/integrations/catalog/filesystem.cjs +2 -0
  429. package/dist/node_modules/@openhands/extensions/integrations/catalog/filesystem.cjs.map +1 -0
  430. package/dist/node_modules/@openhands/extensions/integrations/catalog/filesystem.js +39 -0
  431. package/dist/node_modules/@openhands/extensions/integrations/catalog/filesystem.js.map +1 -0
  432. package/dist/node_modules/@openhands/extensions/integrations/catalog/firecrawl.cjs +2 -0
  433. package/dist/node_modules/@openhands/extensions/integrations/catalog/firecrawl.cjs.map +1 -0
  434. package/dist/node_modules/@openhands/extensions/integrations/catalog/firecrawl.js +36 -0
  435. package/dist/node_modules/@openhands/extensions/integrations/catalog/firecrawl.js.map +1 -0
  436. package/dist/node_modules/@openhands/extensions/integrations/catalog/git.cjs +2 -0
  437. package/dist/node_modules/@openhands/extensions/integrations/catalog/git.cjs.map +1 -0
  438. package/dist/node_modules/@openhands/extensions/integrations/catalog/git.js +40 -0
  439. package/dist/node_modules/@openhands/extensions/integrations/catalog/git.js.map +1 -0
  440. package/dist/node_modules/@openhands/extensions/integrations/catalog/github.cjs +2 -0
  441. package/dist/node_modules/@openhands/extensions/integrations/catalog/github.cjs.map +1 -0
  442. package/dist/node_modules/@openhands/extensions/integrations/catalog/github.js +47 -0
  443. package/dist/node_modules/@openhands/extensions/integrations/catalog/github.js.map +1 -0
  444. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/huggingface.cjs +1 -1
  445. package/dist/node_modules/@openhands/extensions/integrations/catalog/huggingface.cjs.map +1 -0
  446. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/huggingface.js +15 -5
  447. package/dist/node_modules/@openhands/extensions/integrations/catalog/huggingface.js.map +1 -0
  448. package/dist/node_modules/@openhands/extensions/integrations/catalog/kagi.cjs +2 -0
  449. package/dist/node_modules/@openhands/extensions/integrations/catalog/kagi.cjs.map +1 -0
  450. package/dist/node_modules/@openhands/extensions/integrations/catalog/kagi.js +36 -0
  451. package/dist/node_modules/@openhands/extensions/integrations/catalog/kagi.js.map +1 -0
  452. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/linear.cjs +1 -1
  453. package/dist/node_modules/@openhands/extensions/integrations/catalog/linear.cjs.map +1 -0
  454. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/linear.js +15 -5
  455. package/dist/node_modules/@openhands/extensions/integrations/catalog/linear.js.map +1 -0
  456. package/dist/node_modules/@openhands/extensions/integrations/catalog/memory.cjs +2 -0
  457. package/dist/node_modules/@openhands/extensions/integrations/catalog/memory.cjs.map +1 -0
  458. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/memory.js +13 -6
  459. package/dist/node_modules/@openhands/extensions/integrations/catalog/memory.js.map +1 -0
  460. package/dist/node_modules/@openhands/extensions/integrations/catalog/mongodb.cjs +2 -0
  461. package/dist/node_modules/@openhands/extensions/integrations/catalog/mongodb.cjs.map +1 -0
  462. package/dist/node_modules/@openhands/extensions/integrations/catalog/mongodb.js +36 -0
  463. package/dist/node_modules/@openhands/extensions/integrations/catalog/mongodb.js.map +1 -0
  464. package/dist/node_modules/@openhands/extensions/integrations/catalog/neon.cjs +2 -0
  465. package/dist/node_modules/@openhands/extensions/integrations/catalog/neon.cjs.map +1 -0
  466. package/dist/node_modules/@openhands/extensions/integrations/catalog/neon.js +40 -0
  467. package/dist/node_modules/@openhands/extensions/integrations/catalog/neon.js.map +1 -0
  468. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.cjs +2 -0
  469. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.cjs.map +1 -0
  470. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.js +39 -0
  471. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.js.map +1 -0
  472. package/dist/node_modules/@openhands/extensions/integrations/catalog/obsidian.cjs +2 -0
  473. package/dist/node_modules/@openhands/extensions/integrations/catalog/obsidian.cjs.map +1 -0
  474. package/dist/node_modules/@openhands/extensions/integrations/catalog/obsidian.js +38 -0
  475. package/dist/node_modules/@openhands/extensions/integrations/catalog/obsidian.js.map +1 -0
  476. package/dist/node_modules/@openhands/extensions/integrations/catalog/paypal.cjs +2 -0
  477. package/dist/node_modules/@openhands/extensions/integrations/catalog/paypal.cjs.map +1 -0
  478. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/paypal.js +15 -5
  479. package/dist/node_modules/@openhands/extensions/integrations/catalog/paypal.js.map +1 -0
  480. package/dist/node_modules/@openhands/extensions/integrations/catalog/playwright.cjs +2 -0
  481. package/dist/node_modules/@openhands/extensions/integrations/catalog/playwright.cjs.map +1 -0
  482. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/playwright.js +13 -6
  483. package/dist/node_modules/@openhands/extensions/integrations/catalog/playwright.js.map +1 -0
  484. package/dist/node_modules/@openhands/extensions/integrations/catalog/redis.cjs +2 -0
  485. package/dist/node_modules/@openhands/extensions/integrations/catalog/redis.cjs.map +1 -0
  486. package/dist/node_modules/@openhands/extensions/integrations/catalog/redis.js +43 -0
  487. package/dist/node_modules/@openhands/extensions/integrations/catalog/redis.js.map +1 -0
  488. package/dist/node_modules/@openhands/extensions/integrations/catalog/resend.cjs +2 -0
  489. package/dist/node_modules/@openhands/extensions/integrations/catalog/resend.cjs.map +1 -0
  490. package/dist/node_modules/@openhands/extensions/integrations/catalog/resend.js +41 -0
  491. package/dist/node_modules/@openhands/extensions/integrations/catalog/resend.js.map +1 -0
  492. package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.cjs +2 -0
  493. package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.cjs.map +1 -0
  494. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/sentry.js +15 -5
  495. package/dist/node_modules/@openhands/extensions/integrations/catalog/sentry.js.map +1 -0
  496. package/dist/node_modules/@openhands/extensions/integrations/catalog/sequential-thinking.cjs +2 -0
  497. package/dist/node_modules/@openhands/extensions/integrations/catalog/sequential-thinking.cjs.map +1 -0
  498. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/sequential-thinking.js +13 -6
  499. package/dist/node_modules/@openhands/extensions/integrations/catalog/sequential-thinking.js.map +1 -0
  500. package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.cjs +2 -0
  501. package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.cjs.map +1 -0
  502. package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.js +45 -0
  503. package/dist/node_modules/@openhands/extensions/integrations/catalog/slack.js.map +1 -0
  504. package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.cjs +2 -0
  505. package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.cjs.map +1 -0
  506. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/stripe.js +15 -5
  507. package/dist/node_modules/@openhands/extensions/integrations/catalog/stripe.js.map +1 -0
  508. package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.cjs +2 -0
  509. package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.cjs.map +1 -0
  510. package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.js +37 -0
  511. package/dist/node_modules/@openhands/extensions/integrations/catalog/supabase.js.map +1 -0
  512. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/tavily.cjs +1 -1
  513. package/dist/node_modules/@openhands/extensions/integrations/catalog/tavily.cjs.map +1 -0
  514. package/dist/node_modules/@openhands/extensions/integrations/catalog/tavily.js +39 -0
  515. package/dist/node_modules/@openhands/extensions/integrations/catalog/tavily.js.map +1 -0
  516. package/dist/node_modules/@openhands/extensions/integrations/catalog/time.cjs +2 -0
  517. package/dist/node_modules/@openhands/extensions/integrations/catalog/time.cjs.map +1 -0
  518. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/catalog/time.js +13 -6
  519. package/dist/node_modules/@openhands/extensions/integrations/catalog/time.js.map +1 -0
  520. package/dist/node_modules/@openhands/extensions/integrations/index.cjs +2 -0
  521. package/dist/node_modules/@openhands/extensions/integrations/index.cjs.map +1 -0
  522. package/dist/node_modules/@openhands/extensions/integrations/index.js +175 -0
  523. package/dist/node_modules/@openhands/extensions/integrations/index.js.map +1 -0
  524. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/logos.cjs +1 -1
  525. package/dist/node_modules/@openhands/extensions/integrations/logos.cjs.map +1 -0
  526. package/dist/node_modules/@openhands/extensions/{mcps → integrations}/logos.js +2 -2
  527. package/dist/node_modules/@openhands/extensions/integrations/logos.js.map +1 -0
  528. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-catalog.cjs +2 -0
  529. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-catalog.cjs.map +1 -0
  530. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-catalog.js +548 -0
  531. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-catalog.js.map +1 -0
  532. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-registration-defaults.cjs +2 -0
  533. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-registration-defaults.cjs.map +1 -0
  534. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-registration-defaults.js +482 -0
  535. package/dist/node_modules/@openhands/extensions/integrations/oauth-provider-registration-defaults.js.map +1 -0
  536. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs +1 -1
  537. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs.map +1 -1
  538. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.js +3 -0
  539. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.js.map +1 -1
  540. package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.cjs +2 -0
  541. package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.cjs.map +1 -0
  542. package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.js +22 -0
  543. package/dist/node_modules/@openhands/typescript-client/dist/client/mcp-client.js.map +1 -0
  544. package/dist/node_modules/@openhands/typescript-client/dist/index.cjs +1 -1
  545. package/dist/node_modules/@openhands/typescript-client/dist/index.js +1 -0
  546. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs +1 -1
  547. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs.map +1 -1
  548. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js +3 -0
  549. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js.map +1 -1
  550. package/dist/package.cjs +1 -1
  551. package/dist/package.cjs.map +1 -1
  552. package/dist/package.js +6 -4
  553. package/dist/package.js.map +1 -1
  554. package/dist/routes/conversation.cjs +1 -1
  555. package/dist/routes/conversation.cjs.map +1 -1
  556. package/dist/routes/conversation.js +61 -63
  557. package/dist/routes/conversation.js.map +1 -1
  558. package/dist/routes/mcp.cjs +1 -1
  559. package/dist/routes/mcp.cjs.map +1 -1
  560. package/dist/routes/mcp.js +1 -1
  561. package/dist/routes/mcp.js.map +1 -1
  562. package/dist/stores/use-event-store.cjs +1 -1
  563. package/dist/stores/use-event-store.cjs.map +1 -1
  564. package/dist/stores/use-event-store.d.ts +22 -0
  565. package/dist/stores/use-event-store.js +9 -1
  566. package/dist/stores/use-event-store.js.map +1 -1
  567. package/dist/ui/context-menu.d.ts +1 -1
  568. package/dist/ui/help-link.d.ts +1 -1
  569. package/dist/utils/mcp-marketplace-utils.cjs +1 -1
  570. package/dist/utils/mcp-marketplace-utils.cjs.map +1 -1
  571. package/dist/utils/mcp-marketplace-utils.d.ts +21 -1
  572. package/dist/utils/mcp-marketplace-utils.js +23 -13
  573. package/dist/utils/mcp-marketplace-utils.js.map +1 -1
  574. package/dist/utils/settings-utils.cjs.map +1 -1
  575. package/dist/utils/settings-utils.js.map +1 -1
  576. package/package.json +6 -4
  577. package/scripts/check-sdk-version-sync.mjs +6 -6
  578. package/scripts/dev-safe.mjs +60 -24
  579. package/scripts/dev-with-automation.mjs +30 -50
  580. package/tools/canvas_ui_tool.py +129 -0
  581. package/build/assets/add-backend-modal-CqjNjGqY.js +0 -1
  582. package/build/assets/agent-server-conversation-service.api-BdEre_71.js +0 -5
  583. package/build/assets/backend-form-modal-KudhWUX8.js +0 -1
  584. package/build/assets/browser-vYpdU3CR.js +0 -5
  585. package/build/assets/conversation-COZAKz_K.js +0 -1
  586. package/build/assets/conversation-DWcvnmds.js +0 -19
  587. package/build/assets/conversation-panel-CZDStT0b.js +0 -1
  588. package/build/assets/conversation-websocket-context-DulnrIHh.js +0 -3
  589. package/build/assets/declaration-C9nuq2Dj.js +0 -1
  590. package/build/assets/edit-automation-modal-C3bFxS2f.js +0 -1
  591. package/build/assets/files-tab-CbJ4s7Ik.js +0 -1
  592. package/build/assets/git-control-bar-branch-button-Bm6rzSpo.js +0 -27
  593. package/build/assets/install-server-modal-VB5hOBpW.js +0 -1
  594. package/build/assets/llm-settings-CIdxmimN.js +0 -1
  595. package/build/assets/manifest-f041e61a.js +0 -1
  596. package/build/assets/mcp-BdfyCW1l.js +0 -9
  597. package/build/assets/messages-v-q35ObG.js +0 -36
  598. package/build/assets/recommended-automations-launcher-Cx7svuGE.js +0 -52
  599. package/build/assets/root-D2PVd51i.js +0 -2
  600. package/build/assets/root-DEotKI6b.css +0 -1
  601. package/build/assets/settings-service.api-Z6x0l0GU.js +0 -1
  602. package/build/assets/use-is-authed-BFoh8Ogh.js +0 -1
  603. package/build/assets/use-runtime-is-ready-BQWLEyqa.js +0 -1
  604. package/build/assets/use-skills-Cn-78xP1.js +0 -1
  605. package/build/assets/use-user-conversation-BCYpbPT1.js +0 -1
  606. package/build/assets/vendor~home~mcp~automations-list-DRfWZRnF.js +0 -1
  607. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-BJm2mGIp.js +0 -48
  608. package/dist/node_modules/@openhands/extensions/mcps/catalog/airtable.cjs +0 -2
  609. package/dist/node_modules/@openhands/extensions/mcps/catalog/airtable.cjs.map +0 -1
  610. package/dist/node_modules/@openhands/extensions/mcps/catalog/airtable.js +0 -30
  611. package/dist/node_modules/@openhands/extensions/mcps/catalog/airtable.js.map +0 -1
  612. package/dist/node_modules/@openhands/extensions/mcps/catalog/apify.cjs +0 -2
  613. package/dist/node_modules/@openhands/extensions/mcps/catalog/apify.cjs.map +0 -1
  614. package/dist/node_modules/@openhands/extensions/mcps/catalog/apify.js +0 -29
  615. package/dist/node_modules/@openhands/extensions/mcps/catalog/apify.js.map +0 -1
  616. package/dist/node_modules/@openhands/extensions/mcps/catalog/atlassian.cjs.map +0 -1
  617. package/dist/node_modules/@openhands/extensions/mcps/catalog/atlassian.js.map +0 -1
  618. package/dist/node_modules/@openhands/extensions/mcps/catalog/brave-search.cjs +0 -2
  619. package/dist/node_modules/@openhands/extensions/mcps/catalog/brave-search.cjs.map +0 -1
  620. package/dist/node_modules/@openhands/extensions/mcps/catalog/brave-search.js +0 -29
  621. package/dist/node_modules/@openhands/extensions/mcps/catalog/brave-search.js.map +0 -1
  622. package/dist/node_modules/@openhands/extensions/mcps/catalog/browser-mcp.cjs +0 -2
  623. package/dist/node_modules/@openhands/extensions/mcps/catalog/browser-mcp.cjs.map +0 -1
  624. package/dist/node_modules/@openhands/extensions/mcps/catalog/browser-mcp.js +0 -24
  625. package/dist/node_modules/@openhands/extensions/mcps/catalog/browser-mcp.js.map +0 -1
  626. package/dist/node_modules/@openhands/extensions/mcps/catalog/clickhouse.cjs +0 -2
  627. package/dist/node_modules/@openhands/extensions/mcps/catalog/clickhouse.cjs.map +0 -1
  628. package/dist/node_modules/@openhands/extensions/mcps/catalog/clickhouse.js +0 -45
  629. package/dist/node_modules/@openhands/extensions/mcps/catalog/clickhouse.js.map +0 -1
  630. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-bindings.cjs.map +0 -1
  631. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-bindings.js.map +0 -1
  632. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-browser-rendering.cjs +0 -2
  633. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-browser-rendering.cjs.map +0 -1
  634. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-browser-rendering.js.map +0 -1
  635. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-builds.cjs.map +0 -1
  636. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-builds.js.map +0 -1
  637. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-docs.cjs.map +0 -1
  638. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-docs.js.map +0 -1
  639. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-observability.cjs +0 -2
  640. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-observability.cjs.map +0 -1
  641. package/dist/node_modules/@openhands/extensions/mcps/catalog/cloudflare-observability.js.map +0 -1
  642. package/dist/node_modules/@openhands/extensions/mcps/catalog/deepwiki.cjs.map +0 -1
  643. package/dist/node_modules/@openhands/extensions/mcps/catalog/deepwiki.js.map +0 -1
  644. package/dist/node_modules/@openhands/extensions/mcps/catalog/elevenlabs.cjs +0 -2
  645. package/dist/node_modules/@openhands/extensions/mcps/catalog/elevenlabs.cjs.map +0 -1
  646. package/dist/node_modules/@openhands/extensions/mcps/catalog/elevenlabs.js +0 -29
  647. package/dist/node_modules/@openhands/extensions/mcps/catalog/elevenlabs.js.map +0 -1
  648. package/dist/node_modules/@openhands/extensions/mcps/catalog/everything.cjs.map +0 -1
  649. package/dist/node_modules/@openhands/extensions/mcps/catalog/everything.js.map +0 -1
  650. package/dist/node_modules/@openhands/extensions/mcps/catalog/exa.cjs +0 -2
  651. package/dist/node_modules/@openhands/extensions/mcps/catalog/exa.cjs.map +0 -1
  652. package/dist/node_modules/@openhands/extensions/mcps/catalog/exa.js +0 -29
  653. package/dist/node_modules/@openhands/extensions/mcps/catalog/exa.js.map +0 -1
  654. package/dist/node_modules/@openhands/extensions/mcps/catalog/fetch.cjs.map +0 -1
  655. package/dist/node_modules/@openhands/extensions/mcps/catalog/fetch.js.map +0 -1
  656. package/dist/node_modules/@openhands/extensions/mcps/catalog/figma.cjs +0 -2
  657. package/dist/node_modules/@openhands/extensions/mcps/catalog/figma.cjs.map +0 -1
  658. package/dist/node_modules/@openhands/extensions/mcps/catalog/figma.js +0 -33
  659. package/dist/node_modules/@openhands/extensions/mcps/catalog/figma.js.map +0 -1
  660. package/dist/node_modules/@openhands/extensions/mcps/catalog/filesystem.cjs +0 -2
  661. package/dist/node_modules/@openhands/extensions/mcps/catalog/filesystem.cjs.map +0 -1
  662. package/dist/node_modules/@openhands/extensions/mcps/catalog/filesystem.js +0 -32
  663. package/dist/node_modules/@openhands/extensions/mcps/catalog/filesystem.js.map +0 -1
  664. package/dist/node_modules/@openhands/extensions/mcps/catalog/firecrawl.cjs +0 -2
  665. package/dist/node_modules/@openhands/extensions/mcps/catalog/firecrawl.cjs.map +0 -1
  666. package/dist/node_modules/@openhands/extensions/mcps/catalog/firecrawl.js +0 -29
  667. package/dist/node_modules/@openhands/extensions/mcps/catalog/firecrawl.js.map +0 -1
  668. package/dist/node_modules/@openhands/extensions/mcps/catalog/git.cjs +0 -2
  669. package/dist/node_modules/@openhands/extensions/mcps/catalog/git.cjs.map +0 -1
  670. package/dist/node_modules/@openhands/extensions/mcps/catalog/git.js +0 -33
  671. package/dist/node_modules/@openhands/extensions/mcps/catalog/git.js.map +0 -1
  672. package/dist/node_modules/@openhands/extensions/mcps/catalog/github.cjs +0 -2
  673. package/dist/node_modules/@openhands/extensions/mcps/catalog/github.cjs.map +0 -1
  674. package/dist/node_modules/@openhands/extensions/mcps/catalog/github.js +0 -40
  675. package/dist/node_modules/@openhands/extensions/mcps/catalog/github.js.map +0 -1
  676. package/dist/node_modules/@openhands/extensions/mcps/catalog/huggingface.cjs.map +0 -1
  677. package/dist/node_modules/@openhands/extensions/mcps/catalog/huggingface.js.map +0 -1
  678. package/dist/node_modules/@openhands/extensions/mcps/catalog/kagi.cjs +0 -2
  679. package/dist/node_modules/@openhands/extensions/mcps/catalog/kagi.cjs.map +0 -1
  680. package/dist/node_modules/@openhands/extensions/mcps/catalog/kagi.js +0 -29
  681. package/dist/node_modules/@openhands/extensions/mcps/catalog/kagi.js.map +0 -1
  682. package/dist/node_modules/@openhands/extensions/mcps/catalog/linear.cjs.map +0 -1
  683. package/dist/node_modules/@openhands/extensions/mcps/catalog/linear.js.map +0 -1
  684. package/dist/node_modules/@openhands/extensions/mcps/catalog/memory.cjs +0 -2
  685. package/dist/node_modules/@openhands/extensions/mcps/catalog/memory.cjs.map +0 -1
  686. package/dist/node_modules/@openhands/extensions/mcps/catalog/memory.js.map +0 -1
  687. package/dist/node_modules/@openhands/extensions/mcps/catalog/mongodb.cjs +0 -2
  688. package/dist/node_modules/@openhands/extensions/mcps/catalog/mongodb.cjs.map +0 -1
  689. package/dist/node_modules/@openhands/extensions/mcps/catalog/mongodb.js +0 -29
  690. package/dist/node_modules/@openhands/extensions/mcps/catalog/mongodb.js.map +0 -1
  691. package/dist/node_modules/@openhands/extensions/mcps/catalog/neon.cjs +0 -2
  692. package/dist/node_modules/@openhands/extensions/mcps/catalog/neon.cjs.map +0 -1
  693. package/dist/node_modules/@openhands/extensions/mcps/catalog/neon.js +0 -33
  694. package/dist/node_modules/@openhands/extensions/mcps/catalog/neon.js.map +0 -1
  695. package/dist/node_modules/@openhands/extensions/mcps/catalog/notion.cjs +0 -2
  696. package/dist/node_modules/@openhands/extensions/mcps/catalog/notion.cjs.map +0 -1
  697. package/dist/node_modules/@openhands/extensions/mcps/catalog/notion.js +0 -32
  698. package/dist/node_modules/@openhands/extensions/mcps/catalog/notion.js.map +0 -1
  699. package/dist/node_modules/@openhands/extensions/mcps/catalog/obsidian.cjs +0 -2
  700. package/dist/node_modules/@openhands/extensions/mcps/catalog/obsidian.cjs.map +0 -1
  701. package/dist/node_modules/@openhands/extensions/mcps/catalog/obsidian.js +0 -31
  702. package/dist/node_modules/@openhands/extensions/mcps/catalog/obsidian.js.map +0 -1
  703. package/dist/node_modules/@openhands/extensions/mcps/catalog/paypal.cjs +0 -2
  704. package/dist/node_modules/@openhands/extensions/mcps/catalog/paypal.cjs.map +0 -1
  705. package/dist/node_modules/@openhands/extensions/mcps/catalog/paypal.js.map +0 -1
  706. package/dist/node_modules/@openhands/extensions/mcps/catalog/playwright.cjs +0 -2
  707. package/dist/node_modules/@openhands/extensions/mcps/catalog/playwright.cjs.map +0 -1
  708. package/dist/node_modules/@openhands/extensions/mcps/catalog/playwright.js.map +0 -1
  709. package/dist/node_modules/@openhands/extensions/mcps/catalog/redis.cjs +0 -2
  710. package/dist/node_modules/@openhands/extensions/mcps/catalog/redis.cjs.map +0 -1
  711. package/dist/node_modules/@openhands/extensions/mcps/catalog/redis.js +0 -36
  712. package/dist/node_modules/@openhands/extensions/mcps/catalog/redis.js.map +0 -1
  713. package/dist/node_modules/@openhands/extensions/mcps/catalog/resend.cjs +0 -2
  714. package/dist/node_modules/@openhands/extensions/mcps/catalog/resend.cjs.map +0 -1
  715. package/dist/node_modules/@openhands/extensions/mcps/catalog/resend.js +0 -34
  716. package/dist/node_modules/@openhands/extensions/mcps/catalog/resend.js.map +0 -1
  717. package/dist/node_modules/@openhands/extensions/mcps/catalog/sentry.cjs +0 -2
  718. package/dist/node_modules/@openhands/extensions/mcps/catalog/sentry.cjs.map +0 -1
  719. package/dist/node_modules/@openhands/extensions/mcps/catalog/sentry.js.map +0 -1
  720. package/dist/node_modules/@openhands/extensions/mcps/catalog/sequential-thinking.cjs +0 -2
  721. package/dist/node_modules/@openhands/extensions/mcps/catalog/sequential-thinking.cjs.map +0 -1
  722. package/dist/node_modules/@openhands/extensions/mcps/catalog/sequential-thinking.js.map +0 -1
  723. package/dist/node_modules/@openhands/extensions/mcps/catalog/slack.cjs +0 -2
  724. package/dist/node_modules/@openhands/extensions/mcps/catalog/slack.cjs.map +0 -1
  725. package/dist/node_modules/@openhands/extensions/mcps/catalog/slack.js +0 -38
  726. package/dist/node_modules/@openhands/extensions/mcps/catalog/slack.js.map +0 -1
  727. package/dist/node_modules/@openhands/extensions/mcps/catalog/stripe.cjs +0 -2
  728. package/dist/node_modules/@openhands/extensions/mcps/catalog/stripe.cjs.map +0 -1
  729. package/dist/node_modules/@openhands/extensions/mcps/catalog/stripe.js.map +0 -1
  730. package/dist/node_modules/@openhands/extensions/mcps/catalog/supabase.cjs +0 -2
  731. package/dist/node_modules/@openhands/extensions/mcps/catalog/supabase.cjs.map +0 -1
  732. package/dist/node_modules/@openhands/extensions/mcps/catalog/supabase.js +0 -30
  733. package/dist/node_modules/@openhands/extensions/mcps/catalog/supabase.js.map +0 -1
  734. package/dist/node_modules/@openhands/extensions/mcps/catalog/tavily.cjs.map +0 -1
  735. package/dist/node_modules/@openhands/extensions/mcps/catalog/tavily.js +0 -32
  736. package/dist/node_modules/@openhands/extensions/mcps/catalog/tavily.js.map +0 -1
  737. package/dist/node_modules/@openhands/extensions/mcps/catalog/time.cjs +0 -2
  738. package/dist/node_modules/@openhands/extensions/mcps/catalog/time.cjs.map +0 -1
  739. package/dist/node_modules/@openhands/extensions/mcps/catalog/time.js.map +0 -1
  740. package/dist/node_modules/@openhands/extensions/mcps/index.cjs +0 -2
  741. package/dist/node_modules/@openhands/extensions/mcps/index.cjs.map +0 -1
  742. package/dist/node_modules/@openhands/extensions/mcps/index.js +0 -87
  743. package/dist/node_modules/@openhands/extensions/mcps/index.js.map +0 -1
  744. package/dist/node_modules/@openhands/extensions/mcps/logos.cjs.map +0 -1
  745. package/dist/node_modules/@openhands/extensions/mcps/logos.js.map +0 -1
@@ -10,65 +10,65 @@ import { SettingsDropdownInput as c } from "../settings-dropdown-input.js";
10
10
  import l from "react";
11
11
  import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
12
12
  //#region src/components/features/settings/mcp-settings/mcp-server-form.tsx
13
- function p({ mode: p, server: m, existingServers: h, onSubmit: g, onCancel: _, onDelete: v, isActionDisabled: y = !1 }) {
14
- let { t: b } = e("openhands"), [x, S] = l.useState(m?.type || "sse"), [C, w] = l.useState(null), T = [
13
+ function p({ mode: p, server: m, existingServers: h, onSubmit: g, onCancel: _, onDelete: v, isActionDisabled: y = !1, onTest: b, isTestPending: x = !1, testMessage: S = null }) {
14
+ let { t: C } = e("openhands"), [w, T] = l.useState(m?.type || "sse"), [E, D] = l.useState(null), O = l.useRef(null), k = [
15
15
  {
16
16
  key: "sse",
17
- label: b(t.SETTINGS$MCP_SERVER_TYPE_SSE)
17
+ label: C(t.SETTINGS$MCP_SERVER_TYPE_SSE)
18
18
  },
19
19
  {
20
20
  key: "stdio",
21
- label: b(t.SETTINGS$MCP_SERVER_TYPE_STDIO)
21
+ label: C(t.SETTINGS$MCP_SERVER_TYPE_STDIO)
22
22
  },
23
23
  {
24
24
  key: "shttp",
25
- label: b(t.SETTINGS$MCP_SERVER_TYPE_SHTTP)
25
+ label: C(t.SETTINGS$MCP_SERVER_TYPE_SHTTP)
26
26
  }
27
- ], E = (e) => {
28
- if (!e) return b(t.SETTINGS$MCP_ERROR_URL_REQUIRED);
27
+ ], A = (e) => {
28
+ if (!e) return C(t.SETTINGS$MCP_ERROR_URL_REQUIRED);
29
29
  try {
30
30
  let n = new URL(e);
31
- if (!["http:", "https:"].includes(n.protocol)) return b(t.SETTINGS$MCP_ERROR_URL_INVALID_PROTOCOL);
31
+ if (!["http:", "https:"].includes(n.protocol)) return C(t.SETTINGS$MCP_ERROR_URL_INVALID_PROTOCOL);
32
32
  } catch {
33
- return b(t.SETTINGS$MCP_ERROR_URL_INVALID);
33
+ return C(t.SETTINGS$MCP_ERROR_URL_INVALID);
34
34
  }
35
35
  return null;
36
- }, D = (e) => e ? /^[a-zA-Z0-9_-]+$/.test(e) ? null : b(t.SETTINGS$MCP_ERROR_NAME_INVALID) : b(t.SETTINGS$MCP_ERROR_NAME_REQUIRED), O = (e) => !h || !(p === "add" || p === "edit" && m?.name !== e) ? null : h.filter((e) => e.type === "stdio").map((e) => e.name).filter(Boolean).includes(e) ? b(t.SETTINGS$MCP_ERROR_NAME_DUPLICATE) : null, k = (e) => e ? e.includes(" ") ? b(t.SETTINGS$MCP_ERROR_COMMAND_NO_SPACES) : null : b(t.SETTINGS$MCP_ERROR_COMMAND_REQUIRED), A = (e) => {
36
+ }, j = (e) => e ? /^[a-zA-Z0-9_-]+$/.test(e) ? null : C(t.SETTINGS$MCP_ERROR_NAME_INVALID) : C(t.SETTINGS$MCP_ERROR_NAME_REQUIRED), M = (e) => !h || !(p === "add" || p === "edit" && m?.name !== e) ? null : h.filter((e) => e.type === "stdio").map((e) => e.name).filter(Boolean).includes(e) ? C(t.SETTINGS$MCP_ERROR_NAME_DUPLICATE) : null, N = (e) => e ? e.includes(" ") ? C(t.SETTINGS$MCP_ERROR_COMMAND_NO_SPACES) : null : C(t.SETTINGS$MCP_ERROR_COMMAND_REQUIRED), P = (e) => {
37
37
  if (!h) return null;
38
38
  let n = m?.url;
39
- return (p === "add" || p === "edit" && n !== e) && h.some((t) => (t.type === "sse" || t.type === "shttp") && t.url === e) ? b(t.SETTINGS$MCP_ERROR_URL_DUPLICATE) : null;
40
- }, j = (e) => {
39
+ return (p === "add" || p === "edit" && n !== e) && h.some((t) => (t.type === "sse" || t.type === "shttp") && t.url === e) ? C(t.SETTINGS$MCP_ERROR_URL_DUPLICATE) : null;
40
+ }, F = (e) => {
41
41
  if (!e.trim()) return null;
42
42
  let n = e.split("\n");
43
43
  for (let e = 0; e < n.length; e += 1) {
44
44
  let r = n[e].trim();
45
45
  if (r) {
46
46
  let e = r.indexOf("=");
47
- if (e === -1 || !r.substring(0, e).trim()) return b(t.SETTINGS$MCP_ERROR_ENV_INVALID_FORMAT);
47
+ if (e === -1 || !r.substring(0, e).trim()) return C(t.SETTINGS$MCP_ERROR_ENV_INVALID_FORMAT);
48
48
  }
49
49
  }
50
50
  return null;
51
- }, M = (e) => {
51
+ }, I = (e) => {
52
52
  if (!e.trim()) return null;
53
53
  let n = parseInt(e.trim(), 10);
54
- return Number.isNaN(n) ? b(t.SETTINGS$MCP_ERROR_TIMEOUT_INVALID_NUMBER) : n <= 0 ? b(t.SETTINGS$MCP_ERROR_TIMEOUT_POSITIVE) : n > 3600 ? b(t.SETTINGS$MCP_ERROR_TIMEOUT_MAX_EXCEEDED) : null;
55
- }, N = (e) => {
54
+ return Number.isNaN(n) ? C(t.SETTINGS$MCP_ERROR_TIMEOUT_INVALID_NUMBER) : n <= 0 ? C(t.SETTINGS$MCP_ERROR_TIMEOUT_POSITIVE) : n > 3600 ? C(t.SETTINGS$MCP_ERROR_TIMEOUT_MAX_EXCEEDED) : null;
55
+ }, L = (e) => {
56
56
  let t = e.get("name")?.toString().trim() || "", n = e.get("command")?.toString().trim() || "", r = e.get("env")?.toString() || "";
57
- return D(t) || O(t) || k(n) || j(r) || null;
58
- }, P = (e) => {
59
- if (x === "sse" || x === "shttp") {
60
- let t = e.get("url")?.toString().trim() || "", n = E(t);
57
+ return j(t) || M(t) || N(n) || F(r) || null;
58
+ }, R = (e) => {
59
+ if (w === "sse" || w === "shttp") {
60
+ let t = e.get("url")?.toString().trim() || "", n = A(t);
61
61
  if (n) return n;
62
- let r = A(t);
62
+ let r = P(t);
63
63
  if (r) return r;
64
- if (x === "shttp") {
65
- let t = M(e.get("timeout")?.toString() || "");
64
+ if (w === "shttp") {
65
+ let t = I(e.get("timeout")?.toString() || "");
66
66
  if (t) return t;
67
67
  }
68
68
  return null;
69
69
  }
70
- return x === "stdio" ? N(e) : null;
71
- }, F = (e) => {
70
+ return w === "stdio" ? L(e) : null;
71
+ }, z = (e) => {
72
72
  let t = {}, n = e.trim();
73
73
  if (!n) return t;
74
74
  for (let e of n.split("\n")) {
@@ -76,67 +76,69 @@ function p({ mode: p, server: m, existingServers: h, onSubmit: g, onCancel: _, o
76
76
  n && r !== -1 && i && (t[i] = n.substring(r + 1).trim());
77
77
  }
78
78
  return t;
79
+ }, B = (e) => e ? Object.entries(e).map(([e, t]) => `${e}=${t}`).join("\n") : "", V = (e) => {
80
+ let t = {
81
+ id: m?.id || `${w}-${Date.now()}`,
82
+ type: w
83
+ };
84
+ if (w === "sse" || w === "shttp") {
85
+ let n = e.get("url")?.toString().trim(), r = e.get("api_key")?.toString().trim(), i = e.get("timeout")?.toString().trim(), a = {
86
+ ...t,
87
+ url: n,
88
+ ...r && { api_key: r }
89
+ };
90
+ if (w === "shttp" && i) {
91
+ let e = parseInt(i, 10);
92
+ Number.isNaN(e) || (a.timeout = e);
93
+ }
94
+ return a;
95
+ }
96
+ let n = e.get("name")?.toString().trim(), r = e.get("command")?.toString().trim(), i = e.get("args")?.toString().trim(), a = e.get("env")?.toString().trim(), o = i ? i.split("\n").map((e) => e.trim()).filter(Boolean) : [], s = z(a || "");
97
+ return {
98
+ ...t,
99
+ name: n,
100
+ command: r,
101
+ ...o.length > 0 && { args: o },
102
+ ...Object.keys(s).length > 0 && { env: s }
103
+ };
79
104
  };
80
105
  return /* @__PURE__ */ f("form", {
106
+ ref: O,
81
107
  "data-testid": p === "add" ? "add-mcp-server-form" : "edit-mcp-server-form",
82
108
  onSubmit: (e) => {
83
- e.preventDefault(), w(null);
84
- let t = new FormData(e.currentTarget), n = P(t);
109
+ e.preventDefault(), D(null);
110
+ let t = new FormData(e.currentTarget), n = R(t);
85
111
  if (n) {
86
- w(n);
112
+ D(n);
87
113
  return;
88
114
  }
89
- let r = {
90
- id: m?.id || `${x}-${Date.now()}`,
91
- type: x
92
- };
93
- if (x === "sse" || x === "shttp") {
94
- let e = t.get("url")?.toString().trim(), n = t.get("api_key")?.toString().trim(), i = t.get("timeout")?.toString().trim(), a = {
95
- ...r,
96
- url: e,
97
- ...n && { api_key: n }
98
- };
99
- if (x === "shttp" && i) {
100
- let e = parseInt(i, 10);
101
- Number.isNaN(e) || (a.timeout = e);
102
- }
103
- g(a);
104
- } else if (x === "stdio") {
105
- let e = t.get("name")?.toString().trim(), n = t.get("command")?.toString().trim(), i = t.get("args")?.toString().trim(), a = t.get("env")?.toString().trim(), o = i ? i.split("\n").map((e) => e.trim()).filter(Boolean) : [], s = F(a || "");
106
- g({
107
- ...r,
108
- name: e,
109
- command: n,
110
- ...o.length > 0 && { args: o },
111
- ...Object.keys(s).length > 0 && { env: s }
112
- });
113
- }
115
+ g(V(t));
114
116
  },
115
117
  className: "flex flex-col items-start gap-6",
116
118
  children: [
117
119
  p === "add" && /* @__PURE__ */ d(c, {
118
120
  testId: "server-type-dropdown",
119
121
  name: "server-type",
120
- label: b(t.SETTINGS$MCP_SERVER_TYPE),
121
- items: T,
122
- selectedKey: x,
123
- onSelectionChange: (e) => S(e),
122
+ label: C(t.SETTINGS$MCP_SERVER_TYPE),
123
+ items: k,
124
+ selectedKey: w,
125
+ onSelectionChange: (e) => T(e),
124
126
  onInputChange: () => {},
125
127
  isClearable: !1,
126
128
  allowsCustomValue: !1,
127
129
  required: !0,
128
130
  wrapperClassName: "w-full min-w-0"
129
131
  }),
130
- C && /* @__PURE__ */ d("p", {
132
+ E && /* @__PURE__ */ d("p", {
131
133
  className: "text-red-500 text-sm",
132
- children: C
134
+ children: E
133
135
  }),
134
- (x === "sse" || x === "shttp") && /* @__PURE__ */ f(u, { children: [
136
+ (w === "sse" || w === "shttp") && /* @__PURE__ */ f(u, { children: [
135
137
  /* @__PURE__ */ d(s, {
136
138
  testId: "url-input",
137
139
  name: "url",
138
140
  type: "url",
139
- label: b(t.SETTINGS$MCP_URL),
141
+ label: C(t.SETTINGS$MCP_URL),
140
142
  className: "w-full min-w-0",
141
143
  required: !0,
142
144
  defaultValue: m?.url || "",
@@ -146,17 +148,17 @@ function p({ mode: p, server: m, existingServers: h, onSubmit: g, onCancel: _, o
146
148
  testId: "api-key-input",
147
149
  name: "api_key",
148
150
  type: "password",
149
- label: b(t.SETTINGS$MCP_API_KEY),
151
+ label: C(t.SETTINGS$MCP_API_KEY),
150
152
  className: "w-full min-w-0",
151
153
  showOptionalTag: !0,
152
154
  defaultValue: m?.api_key || "",
153
- placeholder: b(t.SETTINGS$MCP_API_KEY_PLACEHOLDER)
155
+ placeholder: C(t.SETTINGS$MCP_API_KEY_PLACEHOLDER)
154
156
  }),
155
- x === "shttp" && /* @__PURE__ */ d(s, {
157
+ w === "shttp" && /* @__PURE__ */ d(s, {
156
158
  testId: "timeout-input",
157
159
  name: "timeout",
158
160
  type: "number",
159
- label: b(t.SETTINGS$MCP_TIMEOUT_LABEL),
161
+ label: C(t.SETTINGS$MCP_TIMEOUT_LABEL),
160
162
  className: "w-full min-w-0",
161
163
  showOptionalTag: !0,
162
164
  defaultValue: m?.timeout?.toString() || "",
@@ -165,12 +167,12 @@ function p({ mode: p, server: m, existingServers: h, onSubmit: g, onCancel: _, o
165
167
  max: 3600
166
168
  })
167
169
  ] }),
168
- x === "stdio" && /* @__PURE__ */ f(u, { children: [
170
+ w === "stdio" && /* @__PURE__ */ f(u, { children: [
169
171
  /* @__PURE__ */ d(s, {
170
172
  testId: "name-input",
171
173
  name: "name",
172
174
  type: "text",
173
- label: b(t.SETTINGS$MCP_NAME),
175
+ label: C(t.SETTINGS$MCP_NAME),
174
176
  className: "w-full min-w-0",
175
177
  required: !0,
176
178
  defaultValue: m?.name || "",
@@ -181,7 +183,7 @@ function p({ mode: p, server: m, existingServers: h, onSubmit: g, onCancel: _, o
181
183
  testId: "command-input",
182
184
  name: "command",
183
185
  type: "text",
184
- label: b(t.SETTINGS$MCP_COMMAND),
186
+ label: C(t.SETTINGS$MCP_COMMAND),
185
187
  className: "w-full min-w-0",
186
188
  required: !0,
187
189
  defaultValue: m?.command || "",
@@ -194,7 +196,7 @@ function p({ mode: p, server: m, existingServers: h, onSubmit: g, onCancel: _, o
194
196
  className: "flex items-center gap-2",
195
197
  children: [/* @__PURE__ */ d("span", {
196
198
  className: "text-sm",
197
- children: b(t.SETTINGS$MCP_COMMAND_ARGUMENTS)
199
+ children: C(t.SETTINGS$MCP_COMMAND_ARGUMENTS)
198
200
  }), /* @__PURE__ */ d(o, {})]
199
201
  }),
200
202
  /* @__PURE__ */ d("textarea", {
@@ -207,7 +209,7 @@ function p({ mode: p, server: m, existingServers: h, onSubmit: g, onCancel: _, o
207
209
  }),
208
210
  /* @__PURE__ */ d("p", {
209
211
  className: "text-xs text-tertiary-alt",
210
- children: b(t.SETTINGS$MCP_COMMAND_ARGUMENTS_HELP)
212
+ children: C(t.SETTINGS$MCP_COMMAND_ARGUMENTS_HELP)
211
213
  })
212
214
  ]
213
215
  }),
@@ -217,18 +219,23 @@ function p({ mode: p, server: m, existingServers: h, onSubmit: g, onCancel: _, o
217
219
  className: "flex items-center gap-2",
218
220
  children: [/* @__PURE__ */ d("span", {
219
221
  className: "text-sm",
220
- children: b(t.SETTINGS$MCP_ENVIRONMENT_VARIABLES)
222
+ children: C(t.SETTINGS$MCP_ENVIRONMENT_VARIABLES)
221
223
  }), /* @__PURE__ */ d(o, {})]
222
224
  }), /* @__PURE__ */ d("textarea", {
223
225
  "data-testid": "env-input",
224
226
  name: "env",
225
227
  rows: 4,
226
- defaultValue: ((e) => e ? Object.entries(e).map(([e, t]) => `${e}=${t}`).join("\n") : "")(m?.env),
228
+ defaultValue: B(m?.env),
227
229
  placeholder: "KEY1=value1\nKEY2=value2",
228
230
  className: n(i, "resize-none placeholder:italic", "disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]")
229
231
  })]
230
232
  })
231
233
  ] }),
234
+ S && /* @__PURE__ */ d("p", {
235
+ "data-testid": "mcp-test-message",
236
+ className: S.ok ? "text-sm text-green-500 whitespace-pre-wrap" : "text-sm text-red-500 whitespace-pre-wrap",
237
+ children: S.text
238
+ }),
232
239
  /* @__PURE__ */ f("div", {
233
240
  className: n("flex w-full items-center gap-2", v ? "justify-between" : "justify-end"),
234
241
  children: [v ? /* @__PURE__ */ d(a, {
@@ -242,23 +249,43 @@ function p({ mode: p, server: m, existingServers: h, onSubmit: g, onCancel: _, o
242
249
  className: "size-4",
243
250
  strokeWidth: 2
244
251
  }),
245
- children: b(t.BUTTON$DELETE)
252
+ children: C(t.BUTTON$DELETE)
246
253
  }) : null, /* @__PURE__ */ f("div", {
247
254
  className: "flex items-center gap-2",
248
- children: [/* @__PURE__ */ d(a, {
249
- testId: "cancel-button",
250
- type: "button",
251
- variant: "secondary",
252
- onClick: _,
253
- isDisabled: y,
254
- children: b(t.BUTTON$CANCEL)
255
- }), /* @__PURE__ */ f(a, {
256
- testId: "submit-button",
257
- type: "submit",
258
- variant: "primary",
259
- isDisabled: y,
260
- children: [p === "add" && b(t.SETTINGS$MCP_ADD_SERVER), p === "edit" && b(t.SETTINGS$MCP_SAVE_SERVER)]
261
- })]
255
+ children: [
256
+ /* @__PURE__ */ d(a, {
257
+ testId: "cancel-button",
258
+ type: "button",
259
+ variant: "secondary",
260
+ onClick: _,
261
+ isDisabled: y,
262
+ children: C(t.BUTTON$CANCEL)
263
+ }),
264
+ b && /* @__PURE__ */ d(a, {
265
+ testId: "mcp-test-connection",
266
+ type: "button",
267
+ variant: "secondary",
268
+ onClick: () => {
269
+ if (!b || !O.current) return;
270
+ D(null);
271
+ let e = new FormData(O.current), t = R(e);
272
+ if (t) {
273
+ D(t);
274
+ return;
275
+ }
276
+ b(V(e));
277
+ },
278
+ isDisabled: y || x,
279
+ children: C(x ? t.MCP$VERIFYING : t.MCP$TEST_BUTTON)
280
+ }),
281
+ /* @__PURE__ */ f(a, {
282
+ testId: "submit-button",
283
+ type: "submit",
284
+ variant: "primary",
285
+ isDisabled: y || x,
286
+ children: [p === "add" && C(t.SETTINGS$MCP_ADD_SERVER), p === "edit" && C(t.SETTINGS$MCP_SAVE_SERVER)]
287
+ })
288
+ ]
262
289
  })]
263
290
  })
264
291
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server-form.js","names":[],"sources":["../../../../../src/components/features/settings/mcp-settings/mcp-server-form.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Trash2 } from \"lucide-react\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { SettingsInput } from \"../settings-input\";\nimport { SettingsDropdownInput } from \"../settings-dropdown-input\";\nimport { BrandButton } from \"../brand-button\";\nimport { OptionalTag } from \"../optional-tag\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlMultilineFieldClassName } from \"#/utils/form-control-classes\";\n\ntype MCPServerType = \"sse\" | \"stdio\" | \"shttp\";\n\ninterface MCPServerConfig {\n id: string;\n type: MCPServerType;\n name?: string;\n url?: string;\n api_key?: string;\n timeout?: number;\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\ninterface MCPServerFormProps {\n mode: \"add\" | \"edit\";\n server?: MCPServerConfig;\n existingServers?: MCPServerConfig[];\n onSubmit: (server: MCPServerConfig) => void;\n onCancel: () => void;\n onDelete?: () => void;\n isActionDisabled?: boolean;\n}\n\nexport function MCPServerForm({\n mode,\n server,\n existingServers,\n onSubmit,\n onCancel,\n onDelete,\n isActionDisabled = false,\n}: MCPServerFormProps) {\n const { t } = useTranslation(\"openhands\");\n const [serverType, setServerType] = React.useState<MCPServerType>(\n server?.type || \"sse\",\n );\n const [error, setError] = React.useState<string | null>(null);\n\n const serverTypeOptions = [\n { key: \"sse\", label: t(I18nKey.SETTINGS$MCP_SERVER_TYPE_SSE) },\n { key: \"stdio\", label: t(I18nKey.SETTINGS$MCP_SERVER_TYPE_STDIO) },\n { key: \"shttp\", label: t(I18nKey.SETTINGS$MCP_SERVER_TYPE_SHTTP) },\n ];\n\n const validateUrl = (url: string): string | null => {\n if (!url) return t(I18nKey.SETTINGS$MCP_ERROR_URL_REQUIRED);\n try {\n const urlObj = new URL(url);\n if (![\"http:\", \"https:\"].includes(urlObj.protocol)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_URL_INVALID_PROTOCOL);\n }\n } catch {\n return t(I18nKey.SETTINGS$MCP_ERROR_URL_INVALID);\n }\n return null;\n };\n\n const validateName = (name: string): string | null => {\n if (!name) return t(I18nKey.SETTINGS$MCP_ERROR_NAME_REQUIRED);\n if (!/^[a-zA-Z0-9_-]+$/.test(name)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_NAME_INVALID);\n }\n return null;\n };\n\n const validateNameUniqueness = (name: string): string | null => {\n if (!existingServers) return null;\n const shouldCheckUniqueness =\n mode === \"add\" || (mode === \"edit\" && server?.name !== name);\n if (!shouldCheckUniqueness) return null;\n\n const existingStdioNames = existingServers\n .filter((s) => s.type === \"stdio\")\n .map((s) => s.name)\n .filter(Boolean);\n if (existingStdioNames.includes(name)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_NAME_DUPLICATE);\n }\n return null;\n };\n\n const validateCommand = (command: string): string | null => {\n if (!command) return t(I18nKey.SETTINGS$MCP_ERROR_COMMAND_REQUIRED);\n if (command.includes(\" \")) {\n return t(I18nKey.SETTINGS$MCP_ERROR_COMMAND_NO_SPACES);\n }\n return null;\n };\n\n const validateUrlUniqueness = (url: string): string | null => {\n if (!existingServers) return null;\n const originalUrl = server?.url;\n const changed = mode === \"add\" || (mode === \"edit\" && originalUrl !== url);\n if (!changed) return null;\n // For URL-based servers (sse/shttp), ensure URL is unique across both types\n const exists = existingServers.some(\n (s) => (s.type === \"sse\" || s.type === \"shttp\") && s.url === url,\n );\n if (exists) return t(I18nKey.SETTINGS$MCP_ERROR_URL_DUPLICATE);\n return null;\n };\n\n const validateEnvFormat = (envString: string): string | null => {\n if (!envString.trim()) return null;\n const lines = envString.split(\"\\n\");\n for (let i = 0; i < lines.length; i += 1) {\n const trimmed = lines[i].trim();\n if (trimmed) {\n const eq = trimmed.indexOf(\"=\");\n if (eq === -1) return t(I18nKey.SETTINGS$MCP_ERROR_ENV_INVALID_FORMAT);\n const key = trimmed.substring(0, eq).trim();\n if (!key) return t(I18nKey.SETTINGS$MCP_ERROR_ENV_INVALID_FORMAT);\n }\n }\n return null;\n };\n\n const validateTimeout = (timeoutStr: string): string | null => {\n if (!timeoutStr.trim()) return null; // Optional field\n\n const timeout = parseInt(timeoutStr.trim(), 10);\n if (Number.isNaN(timeout)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_INVALID_NUMBER);\n }\n if (timeout <= 0) {\n return t(I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_POSITIVE);\n }\n if (timeout > 3600) {\n return t(I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_MAX_EXCEEDED);\n }\n return null;\n };\n\n const validateStdioServer = (formData: FormData): string | null => {\n const name = formData.get(\"name\")?.toString().trim() || \"\";\n const command = formData.get(\"command\")?.toString().trim() || \"\";\n const envString = formData.get(\"env\")?.toString() || \"\";\n\n const nameError = validateName(name);\n if (nameError) return nameError;\n\n const uniquenessError = validateNameUniqueness(name);\n if (uniquenessError) return uniquenessError;\n\n const commandError = validateCommand(command);\n if (commandError) return commandError;\n\n // Validate environment variable format\n const envError = validateEnvFormat(envString);\n if (envError) return envError;\n\n return null;\n };\n\n const validateForm = (formData: FormData): string | null => {\n if (serverType === \"sse\" || serverType === \"shttp\") {\n const url = formData.get(\"url\")?.toString().trim() || \"\";\n const urlError = validateUrl(url);\n if (urlError) return urlError;\n const urlDupError = validateUrlUniqueness(url);\n if (urlDupError) return urlDupError;\n\n // Validate timeout for SHTTP servers only\n if (serverType === \"shttp\") {\n const timeoutStr = formData.get(\"timeout\")?.toString() || \"\";\n const timeoutError = validateTimeout(timeoutStr);\n if (timeoutError) return timeoutError;\n }\n\n return null;\n }\n\n if (serverType === \"stdio\") {\n return validateStdioServer(formData);\n }\n\n return null;\n };\n\n const parseEnvironmentVariables = (\n envString: string,\n ): Record<string, string> => {\n const env: Record<string, string> = {};\n const input = envString.trim();\n if (!input) return env;\n\n for (const line of input.split(\"\\n\")) {\n const trimmed = line.trim();\n const eq = trimmed.indexOf(\"=\");\n const key = eq >= 0 ? trimmed.substring(0, eq).trim() : \"\";\n if (trimmed && eq !== -1 && key) {\n env[key] = trimmed.substring(eq + 1).trim();\n }\n }\n return env;\n };\n\n const formatEnvironmentVariables = (env?: Record<string, string>): string => {\n if (!env) return \"\";\n return Object.entries(env)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"\\n\");\n };\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n\n const formData = new FormData(event.currentTarget);\n const validationError = validateForm(formData);\n\n if (validationError) {\n setError(validationError);\n return;\n }\n\n const baseConfig = {\n id: server?.id || `${serverType}-${Date.now()}`,\n type: serverType,\n };\n\n if (serverType === \"sse\" || serverType === \"shttp\") {\n const url = formData.get(\"url\")?.toString().trim();\n const apiKey = formData.get(\"api_key\")?.toString().trim();\n const timeoutStr = formData.get(\"timeout\")?.toString().trim();\n\n const serverConfig: MCPServerConfig = {\n ...baseConfig,\n url: url!,\n ...(apiKey && { api_key: apiKey }),\n };\n\n // Only add timeout for SHTTP servers\n if (serverType === \"shttp\" && timeoutStr) {\n const timeoutValue = parseInt(timeoutStr, 10);\n if (!Number.isNaN(timeoutValue)) {\n serverConfig.timeout = timeoutValue;\n }\n }\n\n onSubmit(serverConfig);\n } else if (serverType === \"stdio\") {\n const name = formData.get(\"name\")?.toString().trim();\n const command = formData.get(\"command\")?.toString().trim();\n const argsString = formData.get(\"args\")?.toString().trim();\n const envString = formData.get(\"env\")?.toString().trim();\n\n const args = argsString\n ? argsString\n .split(\"\\n\")\n .map((arg) => arg.trim())\n .filter(Boolean)\n : [];\n const env = parseEnvironmentVariables(envString || \"\");\n\n onSubmit({\n ...baseConfig,\n name: name!,\n command: command!,\n ...(args.length > 0 && { args }),\n ...(Object.keys(env).length > 0 && { env }),\n });\n }\n };\n\n const formTestId =\n mode === \"add\" ? \"add-mcp-server-form\" : \"edit-mcp-server-form\";\n\n return (\n <form\n data-testid={formTestId}\n onSubmit={handleSubmit}\n className=\"flex flex-col items-start gap-6\"\n >\n {mode === \"add\" && (\n <SettingsDropdownInput\n testId=\"server-type-dropdown\"\n name=\"server-type\"\n label={t(I18nKey.SETTINGS$MCP_SERVER_TYPE)}\n items={serverTypeOptions}\n selectedKey={serverType}\n onSelectionChange={(key) => setServerType(key as MCPServerType)}\n onInputChange={() => {}} // Prevent input changes\n isClearable={false}\n allowsCustomValue={false}\n required\n wrapperClassName=\"w-full min-w-0\"\n />\n )}\n\n {error && <p className=\"text-red-500 text-sm\">{error}</p>}\n\n {(serverType === \"sse\" || serverType === \"shttp\") && (\n <>\n <SettingsInput\n testId=\"url-input\"\n name=\"url\"\n type=\"url\"\n label={t(I18nKey.SETTINGS$MCP_URL)}\n className=\"w-full min-w-0\"\n required\n defaultValue={server?.url || \"\"}\n placeholder=\"https://api.example.com\"\n />\n\n <SettingsInput\n testId=\"api-key-input\"\n name=\"api_key\"\n type=\"password\"\n label={t(I18nKey.SETTINGS$MCP_API_KEY)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={server?.api_key || \"\"}\n placeholder={t(I18nKey.SETTINGS$MCP_API_KEY_PLACEHOLDER)}\n />\n\n {serverType === \"shttp\" && (\n <SettingsInput\n testId=\"timeout-input\"\n name=\"timeout\"\n type=\"number\"\n label={t(I18nKey.SETTINGS$MCP_TIMEOUT_LABEL)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={server?.timeout?.toString() || \"\"}\n placeholder=\"60\"\n min={1}\n max={3600}\n />\n )}\n </>\n )}\n\n {serverType === \"stdio\" && (\n <>\n <SettingsInput\n testId=\"name-input\"\n name=\"name\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_NAME)}\n className=\"w-full min-w-0\"\n required\n defaultValue={server?.name || \"\"}\n placeholder=\"my-mcp-server\"\n pattern=\"^[a-zA-Z0-9_-]+$\"\n />\n\n <SettingsInput\n testId=\"command-input\"\n name=\"command\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_COMMAND)}\n className=\"w-full min-w-0\"\n required\n defaultValue={server?.command || \"\"}\n placeholder=\"npx\"\n />\n\n <label className=\"flex flex-col gap-2.5 w-full min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm\">\n {t(I18nKey.SETTINGS$MCP_COMMAND_ARGUMENTS)}\n </span>\n <OptionalTag />\n </div>\n <textarea\n data-testid=\"args-input\"\n name=\"args\"\n rows={3}\n defaultValue={server?.args?.join(\"\\n\") || \"\"}\n placeholder=\"arg1&#10;arg2&#10;arg3\"\n className={cn(\n formControlMultilineFieldClassName,\n \"resize-none placeholder:italic\",\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n )}\n />\n <p className=\"text-xs text-tertiary-alt\">\n {t(I18nKey.SETTINGS$MCP_COMMAND_ARGUMENTS_HELP)}\n </p>\n </label>\n\n <label className=\"flex flex-col gap-2.5 w-full min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm\">\n {t(I18nKey.SETTINGS$MCP_ENVIRONMENT_VARIABLES)}\n </span>\n <OptionalTag />\n </div>\n <textarea\n data-testid=\"env-input\"\n name=\"env\"\n rows={4}\n defaultValue={formatEnvironmentVariables(server?.env)}\n placeholder=\"KEY1=value1&#10;KEY2=value2\"\n className={cn(\n formControlMultilineFieldClassName,\n \"resize-none placeholder:italic\",\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n )}\n />\n </label>\n </>\n )}\n\n <div\n className={cn(\n \"flex w-full items-center gap-2\",\n onDelete ? \"justify-between\" : \"justify-end\",\n )}\n >\n {onDelete ? (\n <BrandButton\n testId=\"mcp-custom-editor-delete\"\n type=\"button\"\n variant=\"secondary\"\n onClick={onDelete}\n isDisabled={isActionDisabled}\n startContent={\n <Trash2 aria-hidden className=\"size-4\" strokeWidth={2} />\n }\n >\n {t(I18nKey.BUTTON$DELETE)}\n </BrandButton>\n ) : null}\n <div className=\"flex items-center gap-2\">\n <BrandButton\n testId=\"cancel-button\"\n type=\"button\"\n variant=\"secondary\"\n onClick={onCancel}\n isDisabled={isActionDisabled}\n >\n {t(I18nKey.BUTTON$CANCEL)}\n </BrandButton>\n <BrandButton\n testId=\"submit-button\"\n type=\"submit\"\n variant=\"primary\"\n isDisabled={isActionDisabled}\n >\n {mode === \"add\" && t(I18nKey.SETTINGS$MCP_ADD_SERVER)}\n {mode === \"edit\" && t(I18nKey.SETTINGS$MCP_SAVE_SERVER)}\n </BrandButton>\n </div>\n </div>\n </form>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mcp-server-form.js","names":[],"sources":["../../../../../src/components/features/settings/mcp-settings/mcp-server-form.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Trash2 } from \"lucide-react\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { SettingsInput } from \"../settings-input\";\nimport { SettingsDropdownInput } from \"../settings-dropdown-input\";\nimport { BrandButton } from \"../brand-button\";\nimport { OptionalTag } from \"../optional-tag\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlMultilineFieldClassName } from \"#/utils/form-control-classes\";\nimport type { MCPServerConfig } from \"#/types/mcp-server\";\n\ntype MCPServerType = \"sse\" | \"stdio\" | \"shttp\";\n\nexport interface TestMessage {\n ok: boolean;\n text: string;\n}\n\ninterface MCPServerFormProps {\n mode: \"add\" | \"edit\";\n server?: MCPServerConfig;\n existingServers?: MCPServerConfig[];\n onSubmit: (server: MCPServerConfig) => void;\n onCancel: () => void;\n onDelete?: () => void;\n isActionDisabled?: boolean;\n onTest?: (server: MCPServerConfig) => void;\n isTestPending?: boolean;\n testMessage?: TestMessage | null;\n}\n\nexport function MCPServerForm({\n mode,\n server,\n existingServers,\n onSubmit,\n onCancel,\n onDelete,\n isActionDisabled = false,\n onTest,\n isTestPending = false,\n testMessage = null,\n}: MCPServerFormProps) {\n const { t } = useTranslation(\"openhands\");\n const [serverType, setServerType] = React.useState<MCPServerType>(\n server?.type || \"sse\",\n );\n const [error, setError] = React.useState<string | null>(null);\n const formRef = React.useRef<HTMLFormElement>(null);\n\n const serverTypeOptions = [\n { key: \"sse\", label: t(I18nKey.SETTINGS$MCP_SERVER_TYPE_SSE) },\n { key: \"stdio\", label: t(I18nKey.SETTINGS$MCP_SERVER_TYPE_STDIO) },\n { key: \"shttp\", label: t(I18nKey.SETTINGS$MCP_SERVER_TYPE_SHTTP) },\n ];\n\n const validateUrl = (url: string): string | null => {\n if (!url) return t(I18nKey.SETTINGS$MCP_ERROR_URL_REQUIRED);\n try {\n const urlObj = new URL(url);\n if (![\"http:\", \"https:\"].includes(urlObj.protocol)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_URL_INVALID_PROTOCOL);\n }\n } catch {\n return t(I18nKey.SETTINGS$MCP_ERROR_URL_INVALID);\n }\n return null;\n };\n\n const validateName = (name: string): string | null => {\n if (!name) return t(I18nKey.SETTINGS$MCP_ERROR_NAME_REQUIRED);\n if (!/^[a-zA-Z0-9_-]+$/.test(name)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_NAME_INVALID);\n }\n return null;\n };\n\n const validateNameUniqueness = (name: string): string | null => {\n if (!existingServers) return null;\n const shouldCheckUniqueness =\n mode === \"add\" || (mode === \"edit\" && server?.name !== name);\n if (!shouldCheckUniqueness) return null;\n\n const existingStdioNames = existingServers\n .filter((s) => s.type === \"stdio\")\n .map((s) => s.name)\n .filter(Boolean);\n if (existingStdioNames.includes(name)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_NAME_DUPLICATE);\n }\n return null;\n };\n\n const validateCommand = (command: string): string | null => {\n if (!command) return t(I18nKey.SETTINGS$MCP_ERROR_COMMAND_REQUIRED);\n if (command.includes(\" \")) {\n return t(I18nKey.SETTINGS$MCP_ERROR_COMMAND_NO_SPACES);\n }\n return null;\n };\n\n const validateUrlUniqueness = (url: string): string | null => {\n if (!existingServers) return null;\n const originalUrl = server?.url;\n const changed = mode === \"add\" || (mode === \"edit\" && originalUrl !== url);\n if (!changed) return null;\n // For URL-based servers (sse/shttp), ensure URL is unique across both types\n const exists = existingServers.some(\n (s) => (s.type === \"sse\" || s.type === \"shttp\") && s.url === url,\n );\n if (exists) return t(I18nKey.SETTINGS$MCP_ERROR_URL_DUPLICATE);\n return null;\n };\n\n const validateEnvFormat = (envString: string): string | null => {\n if (!envString.trim()) return null;\n const lines = envString.split(\"\\n\");\n for (let i = 0; i < lines.length; i += 1) {\n const trimmed = lines[i].trim();\n if (trimmed) {\n const eq = trimmed.indexOf(\"=\");\n if (eq === -1) return t(I18nKey.SETTINGS$MCP_ERROR_ENV_INVALID_FORMAT);\n const key = trimmed.substring(0, eq).trim();\n if (!key) return t(I18nKey.SETTINGS$MCP_ERROR_ENV_INVALID_FORMAT);\n }\n }\n return null;\n };\n\n const validateTimeout = (timeoutStr: string): string | null => {\n if (!timeoutStr.trim()) return null; // Optional field\n\n const timeout = parseInt(timeoutStr.trim(), 10);\n if (Number.isNaN(timeout)) {\n return t(I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_INVALID_NUMBER);\n }\n if (timeout <= 0) {\n return t(I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_POSITIVE);\n }\n if (timeout > 3600) {\n return t(I18nKey.SETTINGS$MCP_ERROR_TIMEOUT_MAX_EXCEEDED);\n }\n return null;\n };\n\n const validateStdioServer = (formData: FormData): string | null => {\n const name = formData.get(\"name\")?.toString().trim() || \"\";\n const command = formData.get(\"command\")?.toString().trim() || \"\";\n const envString = formData.get(\"env\")?.toString() || \"\";\n\n const nameError = validateName(name);\n if (nameError) return nameError;\n\n const uniquenessError = validateNameUniqueness(name);\n if (uniquenessError) return uniquenessError;\n\n const commandError = validateCommand(command);\n if (commandError) return commandError;\n\n // Validate environment variable format\n const envError = validateEnvFormat(envString);\n if (envError) return envError;\n\n return null;\n };\n\n const validateForm = (formData: FormData): string | null => {\n if (serverType === \"sse\" || serverType === \"shttp\") {\n const url = formData.get(\"url\")?.toString().trim() || \"\";\n const urlError = validateUrl(url);\n if (urlError) return urlError;\n const urlDupError = validateUrlUniqueness(url);\n if (urlDupError) return urlDupError;\n\n // Validate timeout for SHTTP servers only\n if (serverType === \"shttp\") {\n const timeoutStr = formData.get(\"timeout\")?.toString() || \"\";\n const timeoutError = validateTimeout(timeoutStr);\n if (timeoutError) return timeoutError;\n }\n\n return null;\n }\n\n if (serverType === \"stdio\") {\n return validateStdioServer(formData);\n }\n\n return null;\n };\n\n const parseEnvironmentVariables = (\n envString: string,\n ): Record<string, string> => {\n const env: Record<string, string> = {};\n const input = envString.trim();\n if (!input) return env;\n\n for (const line of input.split(\"\\n\")) {\n const trimmed = line.trim();\n const eq = trimmed.indexOf(\"=\");\n const key = eq >= 0 ? trimmed.substring(0, eq).trim() : \"\";\n if (trimmed && eq !== -1 && key) {\n env[key] = trimmed.substring(eq + 1).trim();\n }\n }\n return env;\n };\n\n const formatEnvironmentVariables = (env?: Record<string, string>): string => {\n if (!env) return \"\";\n return Object.entries(env)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"\\n\");\n };\n\n const buildConfig = (formData: FormData): MCPServerConfig => {\n const baseConfig = {\n id: server?.id || `${serverType}-${Date.now()}`,\n type: serverType,\n };\n\n if (serverType === \"sse\" || serverType === \"shttp\") {\n const url = formData.get(\"url\")?.toString().trim();\n const apiKey = formData.get(\"api_key\")?.toString().trim();\n const timeoutStr = formData.get(\"timeout\")?.toString().trim();\n\n const serverConfig: MCPServerConfig = {\n ...baseConfig,\n url: url!,\n ...(apiKey && { api_key: apiKey }),\n };\n\n // Only add timeout for SHTTP servers\n if (serverType === \"shttp\" && timeoutStr) {\n const timeoutValue = parseInt(timeoutStr, 10);\n if (!Number.isNaN(timeoutValue)) {\n serverConfig.timeout = timeoutValue;\n }\n }\n\n return serverConfig;\n }\n\n // stdio\n const name = formData.get(\"name\")?.toString().trim();\n const command = formData.get(\"command\")?.toString().trim();\n const argsString = formData.get(\"args\")?.toString().trim();\n const envString = formData.get(\"env\")?.toString().trim();\n\n const args = argsString\n ? argsString\n .split(\"\\n\")\n .map((arg) => arg.trim())\n .filter(Boolean)\n : [];\n const env = parseEnvironmentVariables(envString || \"\");\n\n return {\n ...baseConfig,\n name: name!,\n command: command!,\n ...(args.length > 0 && { args }),\n ...(Object.keys(env).length > 0 && { env }),\n };\n };\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n\n const formData = new FormData(event.currentTarget);\n const validationError = validateForm(formData);\n\n if (validationError) {\n setError(validationError);\n return;\n }\n\n onSubmit(buildConfig(formData));\n };\n\n const handleTestClick = () => {\n if (!onTest || !formRef.current) return;\n setError(null);\n const formData = new FormData(formRef.current);\n const validationError = validateForm(formData);\n if (validationError) {\n setError(validationError);\n return;\n }\n onTest(buildConfig(formData));\n };\n\n const formTestId =\n mode === \"add\" ? \"add-mcp-server-form\" : \"edit-mcp-server-form\";\n\n return (\n <form\n ref={formRef}\n data-testid={formTestId}\n onSubmit={handleSubmit}\n className=\"flex flex-col items-start gap-6\"\n >\n {mode === \"add\" && (\n <SettingsDropdownInput\n testId=\"server-type-dropdown\"\n name=\"server-type\"\n label={t(I18nKey.SETTINGS$MCP_SERVER_TYPE)}\n items={serverTypeOptions}\n selectedKey={serverType}\n onSelectionChange={(key) => setServerType(key as MCPServerType)}\n onInputChange={() => {}} // Prevent input changes\n isClearable={false}\n allowsCustomValue={false}\n required\n wrapperClassName=\"w-full min-w-0\"\n />\n )}\n\n {error && <p className=\"text-red-500 text-sm\">{error}</p>}\n\n {(serverType === \"sse\" || serverType === \"shttp\") && (\n <>\n <SettingsInput\n testId=\"url-input\"\n name=\"url\"\n type=\"url\"\n label={t(I18nKey.SETTINGS$MCP_URL)}\n className=\"w-full min-w-0\"\n required\n defaultValue={server?.url || \"\"}\n placeholder=\"https://api.example.com\"\n />\n\n <SettingsInput\n testId=\"api-key-input\"\n name=\"api_key\"\n type=\"password\"\n label={t(I18nKey.SETTINGS$MCP_API_KEY)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={server?.api_key || \"\"}\n placeholder={t(I18nKey.SETTINGS$MCP_API_KEY_PLACEHOLDER)}\n />\n\n {serverType === \"shttp\" && (\n <SettingsInput\n testId=\"timeout-input\"\n name=\"timeout\"\n type=\"number\"\n label={t(I18nKey.SETTINGS$MCP_TIMEOUT_LABEL)}\n className=\"w-full min-w-0\"\n showOptionalTag\n defaultValue={server?.timeout?.toString() || \"\"}\n placeholder=\"60\"\n min={1}\n max={3600}\n />\n )}\n </>\n )}\n\n {serverType === \"stdio\" && (\n <>\n <SettingsInput\n testId=\"name-input\"\n name=\"name\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_NAME)}\n className=\"w-full min-w-0\"\n required\n defaultValue={server?.name || \"\"}\n placeholder=\"my-mcp-server\"\n pattern=\"^[a-zA-Z0-9_-]+$\"\n />\n\n <SettingsInput\n testId=\"command-input\"\n name=\"command\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$MCP_COMMAND)}\n className=\"w-full min-w-0\"\n required\n defaultValue={server?.command || \"\"}\n placeholder=\"npx\"\n />\n\n <label className=\"flex flex-col gap-2.5 w-full min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm\">\n {t(I18nKey.SETTINGS$MCP_COMMAND_ARGUMENTS)}\n </span>\n <OptionalTag />\n </div>\n <textarea\n data-testid=\"args-input\"\n name=\"args\"\n rows={3}\n defaultValue={server?.args?.join(\"\\n\") || \"\"}\n placeholder=\"arg1&#10;arg2&#10;arg3\"\n className={cn(\n formControlMultilineFieldClassName,\n \"resize-none placeholder:italic\",\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n )}\n />\n <p className=\"text-xs text-tertiary-alt\">\n {t(I18nKey.SETTINGS$MCP_COMMAND_ARGUMENTS_HELP)}\n </p>\n </label>\n\n <label className=\"flex flex-col gap-2.5 w-full min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm\">\n {t(I18nKey.SETTINGS$MCP_ENVIRONMENT_VARIABLES)}\n </span>\n <OptionalTag />\n </div>\n <textarea\n data-testid=\"env-input\"\n name=\"env\"\n rows={4}\n defaultValue={formatEnvironmentVariables(server?.env)}\n placeholder=\"KEY1=value1&#10;KEY2=value2\"\n className={cn(\n formControlMultilineFieldClassName,\n \"resize-none placeholder:italic\",\n \"disabled:bg-[var(--oh-surface-raised)] disabled:border-[var(--oh-border-subtle)]\",\n )}\n />\n </label>\n </>\n )}\n\n {testMessage && (\n <p\n data-testid=\"mcp-test-message\"\n className={\n testMessage.ok\n ? \"text-sm text-green-500 whitespace-pre-wrap\"\n : \"text-sm text-red-500 whitespace-pre-wrap\"\n }\n >\n {testMessage.text}\n </p>\n )}\n\n <div\n className={cn(\n \"flex w-full items-center gap-2\",\n onDelete ? \"justify-between\" : \"justify-end\",\n )}\n >\n {onDelete ? (\n <BrandButton\n testId=\"mcp-custom-editor-delete\"\n type=\"button\"\n variant=\"secondary\"\n onClick={onDelete}\n isDisabled={isActionDisabled}\n startContent={\n <Trash2 aria-hidden className=\"size-4\" strokeWidth={2} />\n }\n >\n {t(I18nKey.BUTTON$DELETE)}\n </BrandButton>\n ) : null}\n <div className=\"flex items-center gap-2\">\n <BrandButton\n testId=\"cancel-button\"\n type=\"button\"\n variant=\"secondary\"\n onClick={onCancel}\n isDisabled={isActionDisabled}\n >\n {t(I18nKey.BUTTON$CANCEL)}\n </BrandButton>\n {onTest && (\n <BrandButton\n testId=\"mcp-test-connection\"\n type=\"button\"\n variant=\"secondary\"\n onClick={handleTestClick}\n isDisabled={isActionDisabled || isTestPending}\n >\n {isTestPending\n ? t(I18nKey.MCP$VERIFYING)\n : t(I18nKey.MCP$TEST_BUTTON)}\n </BrandButton>\n )}\n <BrandButton\n testId=\"submit-button\"\n type=\"submit\"\n variant=\"primary\"\n isDisabled={isActionDisabled || isTestPending}\n >\n {mode === \"add\" && t(I18nKey.SETTINGS$MCP_ADD_SERVER)}\n {mode === \"edit\" && t(I18nKey.SETTINGS$MCP_SAVE_SERVER)}\n </BrandButton>\n </div>\n </div>\n </form>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../hooks/use-scroll-to-bottom.cjs`);let n=require(`react`);n=e.__toESM(n,1);let r=require(`react/jsx-runtime`);var i=(0,n.createContext)(void 0);function a({children:e,value:a}){let o=t.useScrollToBottom(n.default.useRef(null)),s=a||o;return(0,r.jsx)(i.Provider,{value:s,children:e})}function o(){let e=(0,n.useContext)(i);if(e===void 0)throw Error(`useScrollContext must be used within a ScrollProvider`);return e}exports.ScrollProvider=a,exports.useScrollContext=o;
1
+ const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../hooks/use-scroll-to-bottom.cjs`);let n=require(`react`);n=e.__toESM(n,1);let r=require(`react/jsx-runtime`);var i=(0,n.createContext)(void 0);function a({children:e,value:a}){let o=t.useScrollToBottom(n.default.useRef(null)),s=a||o;return(0,r.jsx)(i.Provider,{value:s,children:e})}function o(){let e=(0,n.useContext)(i);if(e===void 0)throw Error(`useScrollContext must be used within a ScrollProvider`);return e}function s(){return(0,n.useContext)(i)}exports.ScrollProvider=a,exports.useOptionalScrollContext=s,exports.useScrollContext=o;
2
2
  //# sourceMappingURL=scroll-context.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-context.cjs","names":[],"sources":["../../src/context/scroll-context.tsx"],"sourcesContent":["import React, { createContext, useContext, ReactNode, RefObject } from \"react\";\nimport { useScrollToBottom } from \"#/hooks/use-scroll-to-bottom\";\n\ninterface ScrollContextType {\n scrollRef: RefObject<HTMLDivElement | null>;\n autoScroll: boolean;\n setAutoScroll: (value: boolean) => void;\n scrollDomToBottom: () => void;\n hitBottom: boolean;\n setHitBottom: (value: boolean) => void;\n onChatBodyScroll: (e: HTMLElement) => void;\n}\n\nexport const ScrollContext = createContext<ScrollContextType | undefined>(\n undefined,\n);\n\ninterface ScrollProviderProps {\n children: ReactNode;\n value?: ScrollContextType;\n}\n\nexport function ScrollProvider({ children, value }: ScrollProviderProps) {\n const scrollHook = useScrollToBottom(React.useRef<HTMLDivElement>(null));\n\n // Use provided value or default to the hook\n const contextValue = value || scrollHook;\n\n return (\n <ScrollContext.Provider value={contextValue}>\n {children}\n </ScrollContext.Provider>\n );\n}\n\nexport function useScrollContext() {\n const context = useContext(ScrollContext);\n if (context === undefined) {\n throw new Error(\"useScrollContext must be used within a ScrollProvider\");\n }\n return context;\n}\n"],"mappings":"+KAaA,IAAa,GAAA,EAAA,EAAA,eACX,IAAA,GACD,CAOD,SAAgB,EAAe,CAAE,WAAU,SAA8B,CACvE,IAAM,EAAa,EAAA,kBAAkB,EAAA,QAAM,OAAuB,KAAK,CAAC,CAGlE,EAAe,GAAS,EAE9B,OACE,EAAA,EAAA,KAAC,EAAc,SAAf,CAAwB,MAAO,EAC5B,WACsB,CAAA,CAI7B,SAAgB,GAAmB,CACjC,IAAM,GAAA,EAAA,EAAA,YAAqB,EAAc,CACzC,GAAI,IAAY,IAAA,GACd,MAAU,MAAM,wDAAwD,CAE1E,OAAO"}
1
+ {"version":3,"file":"scroll-context.cjs","names":[],"sources":["../../src/context/scroll-context.tsx"],"sourcesContent":["import React, { createContext, useContext, ReactNode, RefObject } from \"react\";\nimport { useScrollToBottom } from \"#/hooks/use-scroll-to-bottom\";\n\ninterface ScrollContextType {\n scrollRef: RefObject<HTMLDivElement | null>;\n autoScroll: boolean;\n setAutoScroll: (value: boolean) => void;\n scrollDomToBottom: () => void;\n hitBottom: boolean;\n setHitBottom: (value: boolean) => void;\n onChatBodyScroll: (e: HTMLElement) => void;\n}\n\nexport const ScrollContext = createContext<ScrollContextType | undefined>(\n undefined,\n);\n\ninterface ScrollProviderProps {\n children: ReactNode;\n value?: ScrollContextType;\n}\n\nexport function ScrollProvider({ children, value }: ScrollProviderProps) {\n const scrollHook = useScrollToBottom(React.useRef<HTMLDivElement>(null));\n\n // Use provided value or default to the hook\n const contextValue = value || scrollHook;\n\n return (\n <ScrollContext.Provider value={contextValue}>\n {children}\n </ScrollContext.Provider>\n );\n}\n\nexport function useScrollContext() {\n const context = useContext(ScrollContext);\n if (context === undefined) {\n throw new Error(\"useScrollContext must be used within a ScrollProvider\");\n }\n return context;\n}\n\n// Same as useScrollContext but returns undefined when no provider is mounted.\n// Use this in components that have valid render paths both inside and outside\n// the chat's ScrollProvider (e.g. GitControlBar in production vs. isolated\n// test mounts).\nexport function useOptionalScrollContext() {\n return useContext(ScrollContext);\n}\n"],"mappings":"+KAaA,IAAa,GAAA,EAAA,EAAA,eACX,IAAA,GACD,CAOD,SAAgB,EAAe,CAAE,WAAU,SAA8B,CACvE,IAAM,EAAa,EAAA,kBAAkB,EAAA,QAAM,OAAuB,KAAK,CAAC,CAGlE,EAAe,GAAS,EAE9B,OACE,EAAA,EAAA,KAAC,EAAc,SAAf,CAAwB,MAAO,EAC5B,WACsB,CAAA,CAI7B,SAAgB,GAAmB,CACjC,IAAM,GAAA,EAAA,EAAA,YAAqB,EAAc,CACzC,GAAI,IAAY,IAAA,GACd,MAAU,MAAM,wDAAwD,CAE1E,OAAO,EAOT,SAAgB,GAA2B,CACzC,OAAA,EAAA,EAAA,YAAkB,EAAc"}
@@ -15,4 +15,5 @@ interface ScrollProviderProps {
15
15
  }
16
16
  export declare function ScrollProvider({ children, value }: ScrollProviderProps): import("react/jsx-runtime").JSX.Element;
17
17
  export declare function useScrollContext(): ScrollContextType;
18
+ export declare function useOptionalScrollContext(): ScrollContextType | undefined;
18
19
  export {};
@@ -15,7 +15,10 @@ function s() {
15
15
  if (e === void 0) throw Error("useScrollContext must be used within a ScrollProvider");
16
16
  return e;
17
17
  }
18
+ function c() {
19
+ return r(a);
20
+ }
18
21
  //#endregion
19
- export { o as ScrollProvider, s as useScrollContext };
22
+ export { o as ScrollProvider, c as useOptionalScrollContext, s as useScrollContext };
20
23
 
21
24
  //# sourceMappingURL=scroll-context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-context.js","names":[],"sources":["../../src/context/scroll-context.tsx"],"sourcesContent":["import React, { createContext, useContext, ReactNode, RefObject } from \"react\";\nimport { useScrollToBottom } from \"#/hooks/use-scroll-to-bottom\";\n\ninterface ScrollContextType {\n scrollRef: RefObject<HTMLDivElement | null>;\n autoScroll: boolean;\n setAutoScroll: (value: boolean) => void;\n scrollDomToBottom: () => void;\n hitBottom: boolean;\n setHitBottom: (value: boolean) => void;\n onChatBodyScroll: (e: HTMLElement) => void;\n}\n\nexport const ScrollContext = createContext<ScrollContextType | undefined>(\n undefined,\n);\n\ninterface ScrollProviderProps {\n children: ReactNode;\n value?: ScrollContextType;\n}\n\nexport function ScrollProvider({ children, value }: ScrollProviderProps) {\n const scrollHook = useScrollToBottom(React.useRef<HTMLDivElement>(null));\n\n // Use provided value or default to the hook\n const contextValue = value || scrollHook;\n\n return (\n <ScrollContext.Provider value={contextValue}>\n {children}\n </ScrollContext.Provider>\n );\n}\n\nexport function useScrollContext() {\n const context = useContext(ScrollContext);\n if (context === undefined) {\n throw new Error(\"useScrollContext must be used within a ScrollProvider\");\n }\n return context;\n}\n"],"mappings":";;;;AAaA,IAAa,IAAgB,EAC3B,KAAA,EACD;AAOD,SAAgB,EAAe,EAAE,aAAU,YAA8B;CACvE,IAAM,IAAa,EAAkB,EAAM,OAAuB,KAAK,CAAC,EAGlE,IAAe,KAAS;AAE9B,QACE,kBAAC,EAAc,UAAf;EAAwB,OAAO;EAC5B;EACsB,CAAA;;AAI7B,SAAgB,IAAmB;CACjC,IAAM,IAAU,EAAW,EAAc;AACzC,KAAI,MAAY,KAAA,EACd,OAAU,MAAM,wDAAwD;AAE1E,QAAO"}
1
+ {"version":3,"file":"scroll-context.js","names":[],"sources":["../../src/context/scroll-context.tsx"],"sourcesContent":["import React, { createContext, useContext, ReactNode, RefObject } from \"react\";\nimport { useScrollToBottom } from \"#/hooks/use-scroll-to-bottom\";\n\ninterface ScrollContextType {\n scrollRef: RefObject<HTMLDivElement | null>;\n autoScroll: boolean;\n setAutoScroll: (value: boolean) => void;\n scrollDomToBottom: () => void;\n hitBottom: boolean;\n setHitBottom: (value: boolean) => void;\n onChatBodyScroll: (e: HTMLElement) => void;\n}\n\nexport const ScrollContext = createContext<ScrollContextType | undefined>(\n undefined,\n);\n\ninterface ScrollProviderProps {\n children: ReactNode;\n value?: ScrollContextType;\n}\n\nexport function ScrollProvider({ children, value }: ScrollProviderProps) {\n const scrollHook = useScrollToBottom(React.useRef<HTMLDivElement>(null));\n\n // Use provided value or default to the hook\n const contextValue = value || scrollHook;\n\n return (\n <ScrollContext.Provider value={contextValue}>\n {children}\n </ScrollContext.Provider>\n );\n}\n\nexport function useScrollContext() {\n const context = useContext(ScrollContext);\n if (context === undefined) {\n throw new Error(\"useScrollContext must be used within a ScrollProvider\");\n }\n return context;\n}\n\n// Same as useScrollContext but returns undefined when no provider is mounted.\n// Use this in components that have valid render paths both inside and outside\n// the chat's ScrollProvider (e.g. GitControlBar in production vs. isolated\n// test mounts).\nexport function useOptionalScrollContext() {\n return useContext(ScrollContext);\n}\n"],"mappings":";;;;AAaA,IAAa,IAAgB,EAC3B,KAAA,EACD;AAOD,SAAgB,EAAe,EAAE,aAAU,YAA8B;CACvE,IAAM,IAAa,EAAkB,EAAM,OAAuB,KAAK,CAAC,EAGlE,IAAe,KAAS;AAE9B,QACE,kBAAC,EAAc,UAAf;EAAwB,OAAO;EAC5B;EACsB,CAAA;;AAI7B,SAAgB,IAAmB;CACjC,IAAM,IAAU,EAAW,EAAc;AACzC,KAAI,MAAY,KAAA,EACd,OAAU,MAAM,wDAAwD;AAE1E,QAAO;;AAOT,SAAgB,IAA2B;AACzC,QAAO,EAAW,EAAc"}
@@ -1,4 +1,4 @@
1
- const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../stores/browser-store.cjs`),n=require(`../stores/command-store.cjs`),r=require(`../utils/conversation-local-storage.cjs`),i=require(`../stores/conversation-store.cjs`),ee=require(`../stores/conversation-state-store.cjs`),a=require(`../types/agent-server/type-guards.cjs`),o=require(`../stores/use-event-store.cjs`),te=require(`../node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs`),ne=require(`../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs`),re=require(`../node_modules/posthog-js/react/dist/esm/index.cjs`),s=require(`../hooks/use-websocket.cjs`),ie=require(`../constants/server-connection-error.cjs`),ae=require(`../stores/error-message-store.cjs`),oe=require(`../stores/optimistic-user-message-store.cjs`),se=require(`../services/canvas-ui.cjs`),c=require(`../utils/cache-utils.cjs`),l=require(`../utils/websocket-url.cjs`),ce=require(`../api/agent-server-client-options.cjs`),le=require(`../api/event-service/event-service.api.cjs`),u=require(`../utils/error-handler.cjs`),ue=require(`../hooks/mutation/use-read-conversation-file.cjs`),de=require(`../stores/metrics-store.cjs`),fe=require(`../hooks/query/use-conversation-history.cjs`),pe=require(`../hooks/chat/record-model-switch-message.cjs`),d=require(`../hooks/mutation/conversation-mutation-utils.cjs`);let f=require(`react`);f=e.__toESM(f,1);let me=require(`react/jsx-runtime`);var p=(0,f.createContext)(void 0);function m(e){return e.llm_message.content.filter(e=>e.type===`text`).map(e=>e.text).join(``)}function h({children:e,conversationId:h,conversationUrl:g,sessionApiKey:_,subConversations:v,subConversationIds:y}){let[b,x]=(0,f.useState)(`CONNECTING`),[S,C]=(0,f.useState)(`CONNECTING`),w=f.default.useRef(!1),T=f.default.useRef(!1),E=re.usePostHog(),D=ne.useQueryClient(),O=o.useEventStore(e=>e.addEvent),k=o.useEventStore(e=>e.addEvents),{setErrorMessage:A,removeErrorMessage:j,clearConnectionError:M}=ae.useErrorMessageStore(),N=oe.useOptimisticUserMessageStore(e=>e.consumeMatchingPendingMessage),{setExecutionStatus:P}=ee.useConversationStateStore(),{appendInput:F,appendOutput:I}=n.useCommandStore(),[L,R]=(0,f.useState)(!0),[z,B]=(0,f.useState)(null),{setPlanContent:V}=i.useConversationStore(),{mutate:H}=ue.useReadConversationFile(),U=(0,f.useRef)(0),W=(0,f.useRef)(null),he=e=>e?.toUpperCase().endsWith(`PLAN.MD`)??!1,G=(0,f.useCallback)(()=>{M()},[M]),K=(0,f.useCallback)(e=>{if(e.value.usage_to_metrics?.agent){let t=e.value.usage_to_metrics.agent,n={cost:t.accumulated_cost,max_budget_per_task:t.max_budget_per_task??null,usage:t.accumulated_token_usage?{prompt_tokens:t.accumulated_token_usage.prompt_tokens,completion_tokens:t.accumulated_token_usage.completion_tokens,cache_read_tokens:t.accumulated_token_usage.cache_read_tokens,cache_write_tokens:t.accumulated_token_usage.cache_write_tokens,context_window:t.accumulated_token_usage.context_window,per_turn_token:t.accumulated_token_usage.per_turn_token}:null};de.default.getState().setMetrics(n)}},[]),{data:q,isPending:J,isError:ge}=fe.useConversationHistory(h),_e=!!h&&J;(0,f.useLayoutEffect)(()=>{!q||q.events.length===0||k(q.events)},[q,k]);let Y=(0,f.useMemo)(()=>{if(J)return null;let e=q?.events??[],t=e[e.length-1];return!t||!(`timestamp`in t)||!t.timestamp?null:t.timestamp},[q,J]),X=(0,f.useMemo)(()=>!h||!g||J&&!ge?null:l.buildWebSocketUrl(h,g),[h,g,J,ge]),Z=(0,f.useMemo)(()=>{if(!v?.length)return null;let e=v[0];return!e?.id||!e.conversation_url?null:l.buildWebSocketUrl(e.id,e.conversation_url)},[v]),ve=(0,f.useMemo)(()=>Z?b===`CONNECTING`||S===`CONNECTING`?`CONNECTING`:b===`OPEN`&&S===`OPEN`?`OPEN`:b===`CLOSED`&&S===`CLOSED`?`CLOSED`:b===`CLOSING`||S===`CLOSING`?`CLOSING`:`CLOSED`:b,[b,S,Z]);(0,f.useEffect)(()=>{z!==null&&U.current>=z&&L&&R(!1)},[z,L,U]),(0,f.useEffect)(()=>{if(!L&&W.current){let{path:e,conversationId:t}=W.current;H({conversationId:t,filePath:e},{onSuccess:e=>{V(e)},onError:e=>{console.warn(`Failed to read conversation file:`,e)}}),W.current=null}},[L,H,V]),(0,f.useEffect)(()=>{w.current=!1,R(!!y?.length),B(null),U.current=0,W.current=null},[y]),(0,f.useEffect)(()=>{w.current=!1,T.current=!1,W.current=null},[h]);let ye=(0,f.useMemo)(()=>_e||L,[_e,L]),be=(0,f.useCallback)(e=>{try{let n=JSON.parse(e.data);if(a.isAgentServerEvent(n)){let e=!o.useEventStore.getState().eventIds.has(n.id)&&a.isSwitchLLMObservationEvent(n)?n:null;if(O(n),a.isDisplayableErrorEvent(n)){let e=n;u.trackError({message:e.detail,source:`conversation`,metadata:{eventId:e.id,errorCode:e.code},posthog:E}),A(e.detail)}else G();if(a.isAgentErrorEvent(n)&&u.trackError({message:n.error,source:`agent`,metadata:{eventId:n.id,toolName:n.tool_name,toolCallId:n.tool_call_id},posthog:E}),a.isUserMessageEvent(n)&&h&&(N(h,m(n)),r.setConversationState(h,{draftMessage:null})),a.isActionEvent(n)&&c.handleActionEventCacheInvalidation(n,h||`test-conversation-id`,D),a.isConversationStateUpdateEvent(n)&&(a.isFullStateConversationStateUpdateEvent(n)&&P(n.value.execution_status),a.isAgentStatusConversationStateUpdateEvent(n)&&P(n.value),a.isStatsConversationStateUpdateEvent(n)&&K(n)),a.isExecuteBashActionEvent(n)&&F(n.action.command),a.isExecuteBashObservationEvent(n)&&I(n.observation.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
2
- `)),a.isBrowserObservationEvent(n)){let{screenshot_data:e}=n.observation;if(e){let n=e.startsWith(`data:`)?e:`data:image/png;base64,${e}`;t.useBrowserStore.getState().setScreenshotSrc(n)}}a.isBrowserNavigateActionEvent(n)&&t.useBrowserStore.getState().setUrl(n.action.url),h&&e&&!e.observation.is_error&&(pe.recordModelSwitchMessage(h,e.observation.profile_name),e.observation.active_model&&d.updateConversationLlmModelInCache(D,h,e.observation.active_model),d.invalidateConversationQueries(D,h)),a.isCanvasUIActionEvent(n)&&se.handleCanvasUIAction(n.action)}}catch(e){console.warn(`Failed to parse WebSocket message as JSON:`,e)}},[O,A,N,D,h,P,F,I,K,G,E]),xe=(0,f.useCallback)(e=>{try{let t=JSON.parse(e.data);if(L&&(U.current+=1,z!==null&&U.current>=z&&R(!1)),a.isAgentServerEvent(t)){if(O({...t,isFromPlanningAgent:!0}),a.isDisplayableErrorEvent(t)){let e=t;u.trackError({message:e.detail,source:`planning_conversation`,metadata:{eventId:e.id,errorCode:e.code},posthog:E}),A(e.detail)}else G();if(a.isAgentErrorEvent(t)&&u.trackError({message:t.error,source:`planning_agent`,metadata:{eventId:t.id,toolName:t.tool_name,toolCallId:t.tool_call_id},posthog:E}),a.isUserMessageEvent(t)&&h&&(N(h,m(t)),r.setConversationState(h,{draftMessage:null})),a.isActionEvent(t)&&c.handleActionEventCacheInvalidation(t,v?.[0]?.id||`test-conversation-id`,D),a.isConversationStateUpdateEvent(t)&&(a.isFullStateConversationStateUpdateEvent(t)&&P(t.value.execution_status),a.isAgentStatusConversationStateUpdateEvent(t)&&P(t.value),a.isStatsConversationStateUpdateEvent(t)&&K(t)),a.isExecuteBashActionEvent(t)&&F(t.action.command),a.isExecuteBashObservationEvent(t)&&I(t.observation.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
3
- `)),a.isPlanningFileEditorObservationEvent(t)){let{path:e}=t.observation;if(he(e)){let t=v?.[0]?.id;t&&e&&(L?W.current={path:e,conversationId:t}:H({conversationId:t,filePath:e},{onSuccess:e=>{V(e)},onError:e=>{console.warn(`Failed to read conversation file:`,e)}}))}}}}catch(e){console.warn(`Failed to parse WebSocket message as JSON:`,e)}},[O,L,z,A,N,D,v,h,P,F,I,H,V,K,G,E]),Se=(0,f.useMemo)(()=>{let e=Y?{resend_mode:`since`,after_timestamp:Y}:{resend_mode:`all`};return _&&(e.session_api_key=_),{queryParams:e,reconnect:{enabled:!0},onOpen:()=>{x(`OPEN`),w.current=!0,M()},onClose:()=>{x(`CLOSED`)},onError:()=>{x(`CLOSED`),w.current&&A(ie.SERVER_CONNECTION_ERROR_MESSAGE,`connection`)},onMessage:be}},[be,A,M,_,Y]),Ce=(0,f.useMemo)(()=>{let e={resend_all:!0};_&&(e.session_api_key=_);let t=v?.[0];return{queryParams:e,reconnect:{enabled:!0},onOpen:async()=>{if(C(`OPEN`),T.current=!0,M(),t?.id&&t.conversation_url)try{let e=await le.default.getEventCount(t.id,t.conversation_url,t.session_api_key);B(e),e===0&&R(!1)}catch{R(!1)}},onClose:()=>{C(`CLOSED`)},onError:()=>{C(`CLOSED`),T.current&&A(ie.SERVER_CONNECTION_ERROR_MESSAGE,`connection`)},onMessage:xe}},[xe,A,M,_,v]),{socket:Q,reconnect:we}=s.useWebSocket(X||``,Se),{socket:$,reconnect:Te}=s.useWebSocket(Z||``,Ce),Ee=(0,f.useCallback)(()=>{if(j(),i.useConversationStore.getState().conversationMode===`plan`&&Z){Te();return}we()},[Z,we,Te,j]),De=(0,f.useCallback)(async e=>{let t=i.useConversationStore.getState().conversationMode===`plan`?$:Q;if(t?.readyState!==WebSocket.OPEN){if(!h){let e=Error(`No conversation ID available`);throw A(e.message),e}try{return await new te.ConversationClient(ce.getAgentServerClientOptions()).sendEvent(h,{role:`user`,content:e.content},{run:!0}),{queued:!0}}catch(e){throw A(e instanceof Error?e.message:`Failed to queue message for delivery`),e}}try{return t.send(JSON.stringify({...e,run:!0})),{queued:!1}}catch(e){throw A(e instanceof Error?e.message:`Failed to send message`),e}},[Q,$,A,h]);(0,f.useEffect)(()=>{Q&&X&&(()=>{switch(Q.readyState){case WebSocket.CONNECTING:x(`CONNECTING`);break;case WebSocket.OPEN:x(`OPEN`);break;case WebSocket.CLOSING:x(`CLOSING`);break;case WebSocket.CLOSED:x(`CLOSED`);break;default:x(`CLOSED`);break}})()},[Q,X]),(0,f.useEffect)(()=>{$&&Z&&(()=>{switch($.readyState){case WebSocket.CONNECTING:C(`CONNECTING`);break;case WebSocket.OPEN:C(`OPEN`);break;case WebSocket.CLOSING:C(`CLOSING`);break;case WebSocket.CLOSED:C(`CLOSED`);break;default:C(`CLOSED`);break}})()},[$,Z]);let Oe=(0,f.useMemo)(()=>({connectionState:ve,sendMessage:De,isLoadingHistory:ye,reconnect:Ee}),[ve,De,ye,Ee]);return(0,me.jsx)(p.Provider,{value:Oe,children:e})}var g=()=>(0,f.useContext)(p)||null;exports.ConversationWebSocketProvider=h,exports.useConversationWebSocket=g;
1
+ const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../stores/browser-store.cjs`),n=require(`../stores/command-store.cjs`),ee=require(`../utils/conversation-local-storage.cjs`),r=require(`../stores/conversation-store.cjs`),te=require(`../stores/conversation-state-store.cjs`),i=require(`../types/agent-server/type-guards.cjs`),a=require(`../stores/use-event-store.cjs`),ne=require(`../node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs`),re=require(`../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs`),ie=require(`../node_modules/posthog-js/react/dist/esm/index.cjs`),o=require(`../hooks/use-websocket.cjs`),ae=require(`../constants/server-connection-error.cjs`),oe=require(`../stores/error-message-store.cjs`),se=require(`../stores/optimistic-user-message-store.cjs`),ce=require(`../services/canvas-ui.cjs`),s=require(`../utils/cache-utils.cjs`),c=require(`../utils/websocket-url.cjs`),le=require(`../api/agent-server-client-options.cjs`),ue=require(`../api/event-service/event-service.api.cjs`),l=require(`../utils/error-handler.cjs`),de=require(`../hooks/mutation/use-read-conversation-file.cjs`),fe=require(`../stores/metrics-store.cjs`),pe=require(`../hooks/query/use-conversation-history.cjs`),me=require(`../hooks/chat/record-model-switch-message.cjs`),u=require(`../hooks/mutation/conversation-mutation-utils.cjs`);let d=require(`react`);d=e.__toESM(d,1);let he=require(`react/jsx-runtime`);var f=(0,d.createContext)(void 0);function p(e){return e.llm_message.content.filter(e=>e.type===`text`).map(e=>e.text).join(``)}function m({children:e,conversationId:m,conversationUrl:h,sessionApiKey:g,subConversations:_,subConversationIds:v}){let[y,b]=(0,d.useState)(`CONNECTING`),[x,S]=(0,d.useState)(`CONNECTING`),C=d.default.useRef(!1),w=d.default.useRef(!1),T=ie.usePostHog(),E=re.useQueryClient(),D=a.useEventStore(e=>e.addEvent),ge=a.useEventStore(e=>e.addEvents),_e=a.useEventStore(e=>e.clearEventsForConversation),{setErrorMessage:O,removeErrorMessage:k,clearConnectionError:A}=oe.useErrorMessageStore(),j=se.useOptimisticUserMessageStore(e=>e.consumeMatchingPendingMessage),{setExecutionStatus:M}=te.useConversationStateStore(),{appendInput:N,appendOutput:P}=n.useCommandStore(),[F,I]=(0,d.useState)(!0),[L,R]=(0,d.useState)(null),{setPlanContent:z}=r.useConversationStore(),{mutate:B}=de.useReadConversationFile(),V=(0,d.useRef)(0),H=(0,d.useRef)(null),ve=e=>e?.toUpperCase().endsWith(`PLAN.MD`)??!1,U=(0,d.useCallback)(()=>{A()},[A]),W=(0,d.useCallback)(e=>{if(e.value.usage_to_metrics?.agent){let t=e.value.usage_to_metrics.agent,n={cost:t.accumulated_cost,max_budget_per_task:t.max_budget_per_task??null,usage:t.accumulated_token_usage?{prompt_tokens:t.accumulated_token_usage.prompt_tokens,completion_tokens:t.accumulated_token_usage.completion_tokens,cache_read_tokens:t.accumulated_token_usage.cache_read_tokens,cache_write_tokens:t.accumulated_token_usage.cache_write_tokens,context_window:t.accumulated_token_usage.context_window,per_turn_token:t.accumulated_token_usage.per_turn_token}:null};fe.default.getState().setMetrics(n)}},[]),{data:G,isPending:K,isError:ye}=pe.useConversationHistory(m),be=!!m&&K;(0,d.useLayoutEffect)(()=>{let e=m??null;a.useEventStore.getState().loadedConversationId!==e&&_e(e)},[m,_e]),(0,d.useLayoutEffect)(()=>{if(!(!G||G.events.length===0)&&(ge(G.events),m))for(let e of G.events)i.isUserMessageEvent(e)&&j(m,p(e))},[G,ge,m,j]);let q=(0,d.useMemo)(()=>{if(K)return null;let e=G?.events??[],t=e[e.length-1];return!t||!(`timestamp`in t)||!t.timestamp?null:t.timestamp},[G,K]),J=(0,d.useMemo)(()=>!m||!h||K&&!ye?null:c.buildWebSocketUrl(m,h),[m,h,K,ye]),Y=(0,d.useMemo)(()=>{if(!_?.length)return null;let e=_[0];return!e?.id||!e.conversation_url?null:c.buildWebSocketUrl(e.id,e.conversation_url)},[_]),xe=(0,d.useMemo)(()=>Y?y===`CONNECTING`||x===`CONNECTING`?`CONNECTING`:y===`OPEN`&&x===`OPEN`?`OPEN`:y===`CLOSED`&&x===`CLOSED`?`CLOSED`:y===`CLOSING`||x===`CLOSING`?`CLOSING`:`CLOSED`:y,[y,x,Y]);(0,d.useEffect)(()=>{L!==null&&V.current>=L&&F&&I(!1)},[L,F,V]),(0,d.useEffect)(()=>{if(!F&&H.current){let{path:e,conversationId:t}=H.current;B({conversationId:t,filePath:e},{onSuccess:e=>{z(e)},onError:e=>{console.warn(`Failed to read conversation file:`,e)}}),H.current=null}},[F,B,z]),(0,d.useEffect)(()=>{C.current=!1,I(!!v?.length),R(null),V.current=0,H.current=null},[v]),(0,d.useEffect)(()=>{C.current=!1,w.current=!1,H.current=null},[m]);let X=(0,d.useMemo)(()=>be||F,[be,F]),Se=(0,d.useCallback)(e=>{try{let n=JSON.parse(e.data);if(i.isAgentServerEvent(n)){let e=!a.useEventStore.getState().eventIds.has(n.id)&&i.isSwitchLLMObservationEvent(n)?n:null;if(D(n),i.isDisplayableErrorEvent(n)){let e=n;l.trackError({message:e.detail,source:`conversation`,metadata:{eventId:e.id,errorCode:e.code},posthog:T}),O(e.detail)}else U();if(i.isAgentErrorEvent(n)&&l.trackError({message:n.error,source:`agent`,metadata:{eventId:n.id,toolName:n.tool_name,toolCallId:n.tool_call_id},posthog:T}),i.isUserMessageEvent(n)&&m&&(j(m,p(n)),ee.setConversationState(m,{draftMessage:null})),i.isActionEvent(n)&&s.handleActionEventCacheInvalidation(n,m||`test-conversation-id`,E),i.isConversationStateUpdateEvent(n)&&(i.isFullStateConversationStateUpdateEvent(n)&&M(n.value.execution_status),i.isAgentStatusConversationStateUpdateEvent(n)&&M(n.value),i.isStatsConversationStateUpdateEvent(n)&&W(n)),i.isExecuteBashActionEvent(n)&&N(n.action.command),i.isExecuteBashObservationEvent(n)&&P(n.observation.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
2
+ `)),i.isBrowserObservationEvent(n)){let{screenshot_data:e}=n.observation;if(e){let n=e.startsWith(`data:`)?e:`data:image/png;base64,${e}`;t.useBrowserStore.getState().setScreenshotSrc(n)}}i.isBrowserNavigateActionEvent(n)&&t.useBrowserStore.getState().setUrl(n.action.url),m&&e&&!e.observation.is_error&&(me.recordModelSwitchMessage(m,e.observation.profile_name),e.observation.active_model&&u.updateConversationLlmModelInCache(E,m,e.observation.active_model),u.invalidateConversationQueries(E,m)),i.isCanvasUIActionEvent(n)&&ce.handleCanvasUIAction(n.action)}}catch(e){console.warn(`Failed to parse WebSocket message as JSON:`,e)}},[D,O,j,E,m,M,N,P,W,U,T]),Ce=(0,d.useCallback)(e=>{try{let t=JSON.parse(e.data);if(F&&(V.current+=1,L!==null&&V.current>=L&&I(!1)),i.isAgentServerEvent(t)){if(D({...t,isFromPlanningAgent:!0}),i.isDisplayableErrorEvent(t)){let e=t;l.trackError({message:e.detail,source:`planning_conversation`,metadata:{eventId:e.id,errorCode:e.code},posthog:T}),O(e.detail)}else U();if(i.isAgentErrorEvent(t)&&l.trackError({message:t.error,source:`planning_agent`,metadata:{eventId:t.id,toolName:t.tool_name,toolCallId:t.tool_call_id},posthog:T}),i.isUserMessageEvent(t)&&m&&(j(m,p(t)),ee.setConversationState(m,{draftMessage:null})),i.isActionEvent(t)&&s.handleActionEventCacheInvalidation(t,_?.[0]?.id||`test-conversation-id`,E),i.isConversationStateUpdateEvent(t)&&(i.isFullStateConversationStateUpdateEvent(t)&&M(t.value.execution_status),i.isAgentStatusConversationStateUpdateEvent(t)&&M(t.value),i.isStatsConversationStateUpdateEvent(t)&&W(t)),i.isExecuteBashActionEvent(t)&&N(t.action.command),i.isExecuteBashObservationEvent(t)&&P(t.observation.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
3
+ `)),i.isPlanningFileEditorObservationEvent(t)){let{path:e}=t.observation;if(ve(e)){let t=_?.[0]?.id;t&&e&&(F?H.current={path:e,conversationId:t}:B({conversationId:t,filePath:e},{onSuccess:e=>{z(e)},onError:e=>{console.warn(`Failed to read conversation file:`,e)}}))}}}}catch(e){console.warn(`Failed to parse WebSocket message as JSON:`,e)}},[D,F,L,O,j,E,_,m,M,N,P,B,z,W,U,T]),we=(0,d.useMemo)(()=>{let e=q?{resend_mode:`since`,after_timestamp:q}:{resend_mode:`all`};return g&&(e.session_api_key=g),{queryParams:e,reconnect:{enabled:!0},onOpen:()=>{b(`OPEN`),C.current=!0,A()},onClose:()=>{b(`CLOSED`)},onError:()=>{b(`CLOSED`),C.current&&O(ae.SERVER_CONNECTION_ERROR_MESSAGE,`connection`)},onMessage:Se}},[Se,O,A,g,q]),Te=(0,d.useMemo)(()=>{let e={resend_all:!0};g&&(e.session_api_key=g);let t=_?.[0];return{queryParams:e,reconnect:{enabled:!0},onOpen:async()=>{if(S(`OPEN`),w.current=!0,A(),t?.id&&t.conversation_url)try{let e=await ue.default.getEventCount(t.id,t.conversation_url,t.session_api_key);R(e),e===0&&I(!1)}catch{I(!1)}},onClose:()=>{S(`CLOSED`)},onError:()=>{S(`CLOSED`),w.current&&O(ae.SERVER_CONNECTION_ERROR_MESSAGE,`connection`)},onMessage:Ce}},[Ce,O,A,g,_]),{socket:Z,reconnect:Ee}=o.useWebSocket(J||``,we),{socket:Q,reconnect:De}=o.useWebSocket(Y||``,Te),Oe=(0,d.useCallback)(()=>{if(k(),r.useConversationStore.getState().conversationMode===`plan`&&Y){De();return}Ee()},[Y,Ee,De,k]),$=(0,d.useCallback)(async e=>{let t=r.useConversationStore.getState().conversationMode===`plan`?Q:Z;if(t?.readyState!==WebSocket.OPEN){if(!m){let e=Error(`No conversation ID available`);throw O(e.message),e}try{return await new ne.ConversationClient(le.getAgentServerClientOptions()).sendEvent(m,{role:`user`,content:e.content},{run:!0}),{queued:!0}}catch(e){throw O(e instanceof Error?e.message:`Failed to queue message for delivery`),e}}try{return t.send(JSON.stringify({...e,run:!0})),{queued:!1}}catch(e){throw O(e instanceof Error?e.message:`Failed to send message`),e}},[Z,Q,O,m]);(0,d.useEffect)(()=>{Z&&J&&(()=>{switch(Z.readyState){case WebSocket.CONNECTING:b(`CONNECTING`);break;case WebSocket.OPEN:b(`OPEN`);break;case WebSocket.CLOSING:b(`CLOSING`);break;case WebSocket.CLOSED:b(`CLOSED`);break;default:b(`CLOSED`);break}})()},[Z,J]),(0,d.useEffect)(()=>{Q&&Y&&(()=>{switch(Q.readyState){case WebSocket.CONNECTING:S(`CONNECTING`);break;case WebSocket.OPEN:S(`OPEN`);break;case WebSocket.CLOSING:S(`CLOSING`);break;case WebSocket.CLOSED:S(`CLOSED`);break;default:S(`CLOSED`);break}})()},[Q,Y]);let ke=(0,d.useMemo)(()=>({connectionState:xe,sendMessage:$,isLoadingHistory:X,reconnect:Oe}),[xe,$,X,Oe]);return(0,he.jsx)(f.Provider,{value:ke,children:e})}var h=()=>(0,d.useContext)(f)||null;exports.ConversationWebSocketProvider=m,exports.useConversationWebSocket=h;
4
4
  //# sourceMappingURL=conversation-websocket-context.cjs.map