@openhands/agent-canvas 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (492) hide show
  1. package/README.md +1 -1
  2. package/README.windows.md +2 -2
  3. package/build/assets/{Trans-B7lYw4uD.js → Trans-Bwpzk1wT.js} +1 -1
  4. package/build/assets/{acp-providers-WUD4tfSq.js → acp-providers-C921BlYB.js} +1 -1
  5. package/build/assets/active-backend-context-BiwzkzDy.js +2 -0
  6. package/build/assets/agent-context-settings-DXNT_dcw.js +1 -0
  7. package/build/assets/agent-profiles-settings-BymJf3EP.js +1 -0
  8. package/build/assets/agent-server-conversation-service.api-CYSWw-2g.js +41 -0
  9. package/build/assets/agent-settings-BjgQQe-_.js +1 -0
  10. package/build/assets/{agent-settings-BGTyoT6X.js → agent-settings-WzqXk6B4.js} +2 -2
  11. package/build/assets/{alert-banner-eRyIwDyU.js → alert-banner-DR8EVyZM.js} +1 -1
  12. package/build/assets/api-error-message-e16L1kwH.js +1 -0
  13. package/build/assets/{api-key-entry-screen-JOx3SH1-.js → api-key-entry-screen-DI0I04O3.js} +1 -1
  14. package/build/assets/{app-settings-D53QZy5p.js → app-settings-DGistSFV.js} +1 -1
  15. package/build/assets/automation-C_eCrGyP.js +1 -0
  16. package/build/assets/automation-detail-DY6x2FW1.js +2 -0
  17. package/build/assets/automation-export-C09f-Lua.js +2 -0
  18. package/build/assets/automation-setup-route-CqKp0717.js +1 -0
  19. package/build/assets/automations-list-CqWJ7qXW.js +1 -0
  20. package/build/assets/{back-nav-button-C02hGa8t.js → back-nav-button-D4ngzpSh.js} +1 -1
  21. package/build/assets/backend-form-modal-B8D5hBzK.js +1 -0
  22. package/build/assets/{backend-synced-settings-badge-CQ9xtNWm.js → backend-synced-settings-badge-BnzI8Ysj.js} +1 -1
  23. package/build/assets/{badge-CzXbf7tR.js → badge-1Mf1iPcX.js} +1 -1
  24. package/build/assets/{base-modal-DkVyzFMt.js → base-modal-BBuy0WQQ.js} +1 -1
  25. package/build/assets/{brand-button-BUlDL-mz.js → brand-button-DGN6Y9o6.js} +1 -1
  26. package/build/assets/browser-D_ekTlTS.js +6 -0
  27. package/build/assets/{browser-tab-BijpUbdt.js → browser-tab-D4a4Ou_w.js} +1 -1
  28. package/build/assets/{chat-send-button-BKsVjhtA.js → chat-send-button-CgbcjD97.js} +1 -1
  29. package/build/assets/check-CPLXgluF.js +1 -0
  30. package/build/assets/chevron-down-CP4QHvyc.js +1 -0
  31. package/build/assets/circle-check-Dpy2_xSI.js +1 -0
  32. package/build/assets/{circle-plus-check-toggle-DdjUiOo1.js → circle-plus-check-toggle-yTAS-nX3.js} +1 -1
  33. package/build/assets/cloud-funnel-analytics-CEOl5Gxr.js +1 -0
  34. package/build/assets/{combobox-caret-Dl9UtvD6.js → combobox-caret-Bd2yySnF.js} +1 -1
  35. package/build/assets/command-menu-Bj6X4ckE.js +1 -0
  36. package/build/assets/condenser-settings-EAXQNR2E.js +1 -0
  37. package/build/assets/{confirmation-modal-CRBJSllP.js → confirmation-modal-NCUPr2-O.js} +1 -1
  38. package/build/assets/{context-menu-list-item-FGaafXGh.js → context-menu-list-item-CrCrYuPF.js} +1 -1
  39. package/build/assets/conversation-BzyIcSwr.js +1 -0
  40. package/build/assets/conversation-CUJ0Vo8g.js +90 -0
  41. package/build/assets/conversation-panel-BzyIcSwr.js +1 -0
  42. package/build/assets/conversation-state-store-F62HvuI1.js +1 -0
  43. package/build/assets/{conversation-tab-empty-state-CDjvNgpG.js → conversation-tab-empty-state-BCZ7rUMH.js} +1 -1
  44. package/build/assets/{copy-Drwu97Gx.js → copy-DCmZtz6n.js} +1 -1
  45. package/build/assets/{copy-to-clipboard-button-NbN1clVr.js → copy-to-clipboard-button-D_Lp6-Fl.js} +1 -1
  46. package/build/assets/{device-verify-CDm_WrVu.js → device-verify-DLmolX8Q.js} +1 -1
  47. package/build/assets/{dropdown-classes-CqA2BTCL.js → dropdown-classes-BB8rzqXL.js} +1 -1
  48. package/build/assets/{entry.client-BO2KQj0y.js → entry.client-BbIYOsIg.js} +2 -2
  49. package/build/assets/{enum-filter-dropdown-DSqPZnsD.js → enum-filter-dropdown-C08-srev.js} +1 -1
  50. package/build/assets/{environment-switch-overlay-mGl2pqqx.js → environment-switch-overlay-BepBBX66.js} +1 -1
  51. package/build/assets/{extensions-hub-Br3Lgynp.js → extensions-hub-R3KNv-5V.js} +1 -1
  52. package/build/assets/{extensions-navigation-BQmstKDZ.js → extensions-navigation-CfWFmI1I.js} +1 -1
  53. package/build/assets/{external-link-D9B2QMPf.js → external-link-BdBSg8rk.js} +1 -1
  54. package/build/assets/files-tab-DEq8MbHu.js +1 -0
  55. package/build/assets/{form-control-classes-CtVAktAy.js → form-control-classes-DAfsCJTe.js} +1 -1
  56. package/build/assets/{format-time-delta-DICE64sz.js → format-time-delta-CxfPJpzC.js} +1 -1
  57. package/build/assets/git-provider-icon-BZqqUPlm.js +1 -0
  58. package/build/assets/git-repo-dropdown-9WKINV6J.js +1 -0
  59. package/build/assets/git-repo-dropdown-DEpOwUez.js +1 -0
  60. package/build/assets/{highlighted-source-view-KMsA9c4a.js → highlighted-source-view-CX9oIoVT.js} +1 -1
  61. package/build/assets/home-CY0JaxiY.js +1 -0
  62. package/build/assets/home-CaNWlVvB.js +1 -0
  63. package/build/assets/home-store-Ch1ErdBc.js +1 -0
  64. package/build/assets/index-home-CaNWlVvB.js +1 -0
  65. package/build/assets/info-CmWQXtRQ.js +1 -0
  66. package/build/assets/install-server-modal-BWrudmZU.js +1 -0
  67. package/build/assets/{launch-DjkKw55l.js → launch-B1POpHuP.js} +1 -1
  68. package/build/assets/{list-todo-BpAf7aOT.js → list-todo-DtiL3lTp.js} +1 -1
  69. package/build/assets/llm-not-configured-banner-3tMsM4K6.js +27 -0
  70. package/build/assets/{llm-settings-D8zNkIlP.js → llm-settings-CXo8iPNW.js} +1 -1
  71. package/build/assets/llm-settings-D0W8mJDk.js +1 -0
  72. package/build/assets/{llm-subscription-service-COTgZc1C.js → llm-subscription-service-DBJbfd8Z.js} +1 -1
  73. package/build/assets/loader-circle-B4QDBARx.js +1 -0
  74. package/build/assets/{loading-spinner-DRFyh6Iy.js → loading-spinner-DfZ_bhV7.js} +1 -1
  75. package/build/assets/{manage-backends-modal-DiRWE3tJ.js → manage-backends-modal-CwyWsiag.js} +1 -1
  76. package/build/assets/manifest-39f4789d.js +1 -0
  77. package/build/assets/markdown-renderer-DgiLLhW6.js +8 -0
  78. package/build/assets/mcp-DXG9LWrI.js +9 -0
  79. package/build/assets/mcp-marketplace-utils-DFmhKc5s.js +1 -0
  80. package/build/assets/messages-kBjKaAeA.js +40 -0
  81. package/build/assets/{modal-body-C3bGicn4.js → modal-body-CMsDpalT.js} +1 -1
  82. package/build/assets/{modal-classes-DFFO6BMU.js → modal-classes-B6PDrxXo.js} +1 -1
  83. package/build/assets/{modal-close-button-vxkAIRyZ.js → modal-close-button-DyxBZaAb.js} +1 -1
  84. package/build/assets/{onboarding-DWuFieEA.js → onboarding-47hh2IHA.js} +1 -1
  85. package/build/assets/{onboarding-modal-C8m72Dpb.js → onboarding-modal-9BuvvROo.js} +1 -1
  86. package/build/assets/{organization-service.api-CQ73CB-S.js → organization-service.api-UDy63-oC.js} +1 -1
  87. package/build/assets/{pencil-DzW2GB2M.js → pencil-BjgtZmWp.js} +1 -1
  88. package/build/assets/{planner-tab-YG0bGxDY.js → planner-tab-BWk8885v.js} +1 -1
  89. package/build/assets/{plugins-management-service-ijhH8OSh.js → plugins-management-service-CjkgF2dd.js} +1 -1
  90. package/build/assets/plus-DrKuuvMe.js +1 -0
  91. package/build/assets/{profiles-service.api-C32pPm70.js → profiles-service.api-CukSFLzz.js} +1 -1
  92. package/build/assets/{providers-DuSn9s2i.js → providers-CqUWC85T.js} +1 -1
  93. package/build/assets/{proxy-BiyDhMBd.js → proxy-BBUG3sd2.js} +1 -1
  94. package/build/assets/{puzzle-DlqT0yvr.js → puzzle-BoNc6zZ8.js} +1 -1
  95. package/build/assets/recommended-automations-launcher-ejxy1P27.js +1 -0
  96. package/build/assets/{refresh-cw-Br5254f4.js → refresh-cw-BrM5ZAZD.js} +1 -1
  97. package/build/assets/root-5S-M8SYa.js +2 -0
  98. package/build/assets/root-DZ39lS5f.css +1 -0
  99. package/build/assets/root-layout-BPqoa0gv.js +3 -0
  100. package/build/assets/{schema-field-htfNouTG.js → schema-field-nImDoY6-.js} +1 -1
  101. package/build/assets/{sdk-section-page-D0K1dBQY.js → sdk-section-page-BxMrtUNV.js} +1 -1
  102. package/build/assets/search-Dc2qR4O2.js +1 -0
  103. package/build/assets/{secrets-service-Dbv5Zb8G.js → secrets-service-Dhjh3HhH.js} +1 -1
  104. package/build/assets/{secrets-settings-Da4SSaX9.js → secrets-settings-CPdxceT_.js} +1 -1
  105. package/build/assets/segmented-toggle-Do6oyepX.js +1 -0
  106. package/build/assets/{settings-F4a09IxY.js → settings-BRbnfKEm.js} +1 -1
  107. package/build/assets/{settings-dropdown-input-jOiv5Yrk.js → settings-dropdown-input-DYCULKpp.js} +1 -1
  108. package/build/assets/{settings-index-CyJBf5NA.js → settings-index-C9o2NBO0.js} +1 -1
  109. package/build/assets/settings-input-B-q2gkVy.js +1 -0
  110. package/build/assets/{settings-list-classes-VqMzkYYt.js → settings-list-classes-WpQi0q1L.js} +1 -1
  111. package/build/assets/{settings-modal-C-S1NpbC.js → settings-modal-CEK0AIx6.js} +1 -1
  112. package/build/assets/{settings-service.api-CTJRrvMu.js → settings-service.api-CZiPD8__.js} +1 -1
  113. package/build/assets/{settings-switch-B405oU_v.js → settings-switch-LqKdGxHL.js} +1 -1
  114. package/build/assets/shared-conversation-Bu-dQlgp.js +1 -0
  115. package/build/assets/{sidebar-layout-BGMuyC86.js → sidebar-layout-oHBGQmLh.js} +1 -1
  116. package/build/assets/{sidebar-mobile-menu-toggle-xiKoUfGa.js → sidebar-mobile-menu-toggle-ND-hgygu.js} +1 -1
  117. package/build/assets/{sidebar-nav-link-DA4_ct9G.js → sidebar-nav-link-CrujNA09.js} +1 -1
  118. package/build/assets/{sidebar-store-FRJ3rADB.js → sidebar-store-Bui-WNEr.js} +1 -1
  119. package/build/assets/{skill-card-pill-row-BMdhr_sd.js → skill-card-pill-row-CZBI7OqH.js} +1 -1
  120. package/build/assets/{skill-icon-badge-CGUkgcVH.js → skill-icon-badge-BOov_phZ.js} +1 -1
  121. package/build/assets/{skills-plugins-C5eJnyft.js → skills-plugins-D0PiHWAD.js} +1 -1
  122. package/build/assets/{skills-settings-pUxMr6WZ.js → skills-settings-B43KArIz.js} +2 -2
  123. package/build/assets/{styled-tooltip-B3kIdVyH.js → styled-tooltip-C7grwnOX.js} +1 -1
  124. package/build/assets/{task-list-tab-B3k4W1cK.js → task-list-tab-R3ac6m7O.js} +1 -1
  125. package/build/assets/{terminal-CBI_41Zc.js → terminal-yqkNdEAx.js} +1 -1
  126. package/build/assets/{toggle-switch-DYRr9CAR.js → toggle-switch-BeSrbgCg.js} +1 -1
  127. package/build/assets/{trash-2-gZPlx23R.js → trash-2-wW5TWcdN.js} +1 -1
  128. package/build/assets/{typography-B1UxuuEC.js → typography-iYhzLlHO.js} +1 -1
  129. package/build/assets/{use-acp-credential-form-CjSvKWFH.js → use-acp-credential-form-DUxbxmbq.js} +1 -1
  130. package/build/assets/{use-activate-agent-profile-DCRf47e-.js → use-activate-agent-profile-CDHA52tC.js} +1 -1
  131. package/build/assets/use-agent-profiles-TsOdIyw5.js +1 -0
  132. package/build/assets/{use-can-manage-org-profiles-vBiP7rHF.js → use-can-manage-org-profiles-Bt1M71u5.js} +1 -1
  133. package/build/assets/{use-cloud-current-user-id-BMq9gw93.js → use-cloud-current-user-id-DWt7HCgf.js} +1 -1
  134. package/build/assets/use-config-CxlEdf_v.js +1 -0
  135. package/build/assets/{use-create-conversation-CakhLF0X.js → use-create-conversation-nOJ6Um5h.js} +1 -1
  136. package/build/assets/{use-create-secret-RT4QtSS9.js → use-create-secret-Dj5ang9x.js} +1 -1
  137. package/build/assets/use-is-authed-BT7Iud4U.js +1 -0
  138. package/build/assets/{use-is-creating-conversation-CIAcnd8M.js → use-is-creating-conversation-CAggrM75.js} +1 -1
  139. package/build/assets/use-llm-profiles-2Wc2db8u.js +1 -0
  140. package/build/assets/{use-onboarding-completion-CJU4MNAY.js → use-onboarding-completion-gxQlcEy2.js} +1 -1
  141. package/build/assets/{use-plugins-marketplace-D-93nqtJ.js → use-plugins-marketplace-CVO7sXYR.js} +1 -1
  142. package/build/assets/use-save-agent-profile-D0wC5ExW.js +1 -0
  143. package/build/assets/{use-save-settings--C6LZXfI.js → use-save-settings-L3aMaDeS.js} +1 -1
  144. package/build/assets/{use-settings-DIAo5KFk.js → use-settings-8nt3DGxW.js} +1 -1
  145. package/build/assets/use-settings-nav-items-DHAAD-zk.js +16 -0
  146. package/build/assets/{use-skills-D_mLhYNa.js → use-skills-CE6miQ3r.js} +1 -1
  147. package/build/assets/use-tracking-BGboadaZ.js +68 -0
  148. package/build/assets/{use-user-conversation-DhcAEyJX.js → use-user-conversation-BIIpGUgM.js} +1 -1
  149. package/build/assets/useInfiniteQuery-BLRVmVPU.js +1 -0
  150. package/build/assets/{useMutation-DHLpZ6J0.js → useMutation-CaSHLnX0.js} +1 -1
  151. package/build/assets/{useQueries-B3T1a7qt.js → useQueries--d_WWAzc.js} +1 -1
  152. package/build/assets/{useQuery-B38jBavx.js → useQuery-DiPh8LRJ.js} +1 -1
  153. package/build/assets/utils-BgGG1znF.js +1 -0
  154. package/build/assets/{vendor~browser-CIoZCqGs.js → vendor~browser-IVYgIgG1.js} +1 -1
  155. package/build/assets/{vendor~entry.client-Di4qO77Y.js → vendor~entry.client-BcYIVQvB.js} +1 -1
  156. package/build/assets/{vendor~entry.client-BfviqoVc.js → vendor~entry.client-CXM9oiAk.js} +1 -1
  157. package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~g4xrpilz-CYPMCkX1.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~b0bpqexo-CbTboogo.js} +1 -1
  158. package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f9xdmd0z-DLMP7bZx.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~d4by102p-C2f0ZhS-.js} +1 -1
  159. package/build/assets/{vendor~files-tab-atebg0iG.js → vendor~files-tab-C7RmQJwN.js} +1 -1
  160. package/build/assets/{vendor~index-home~home~conversation-panel~conversation-G9DMrR7m.js → vendor~index-home~home~conversation-panel~conversation-Bqp1ZqJM.js} +1 -1
  161. package/build/assets/{vendor~root-layout~conversation-panel~conversation-DEhW1h3I.js → vendor~root-layout~conversation-panel~conversation-BCn8lzeG.js} +1 -1
  162. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~automation-setup-route-B_L-gcOG.js +1 -0
  163. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-sjx0x5ac.js +1 -0
  164. package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~automation-setup-route~onboarding-modal-D7IDevqN.js +1 -0
  165. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~bi2r7bko-VFnwct3q.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~dfc8ddxy-tTyxnjXT.js} +1 -1
  166. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hakxo2tj-ClV0p9g3.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gy8zbn65-CGt6bWRT.js} +1 -1
  167. package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~launch~skills-settings~a~eywn6ulz-BKxxr74w.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~dufan6ng-Dtdw8H0q.js} +17 -4
  168. package/build/assets/{verification-settings-Vr5cN4md.js → verification-settings-DBsnSXC3.js} +1 -1
  169. package/build/assets/x-omAzpXkl.js +1 -0
  170. package/build/index.html +4 -4
  171. package/build/locales/ar/openhands.json +37 -2
  172. package/build/locales/ca/openhands.json +37 -2
  173. package/build/locales/de/openhands.json +37 -2
  174. package/build/locales/en/openhands.json +38 -3
  175. package/build/locales/es/openhands.json +37 -2
  176. package/build/locales/fr/openhands.json +37 -2
  177. package/build/locales/it/openhands.json +37 -2
  178. package/build/locales/ja/openhands.json +37 -2
  179. package/build/locales/ko-KR/openhands.json +37 -2
  180. package/build/locales/no/openhands.json +37 -2
  181. package/build/locales/pt/openhands.json +37 -2
  182. package/build/locales/tr/openhands.json +37 -2
  183. package/build/locales/uk/openhands.json +37 -2
  184. package/build/locales/zh-CN/openhands.json +37 -2
  185. package/build/locales/zh-TW/openhands.json +37 -2
  186. package/config/defaults.json +1 -1
  187. package/dist/api/agent-server-adapter.cjs +3 -3
  188. package/dist/api/agent-server-adapter.cjs.map +1 -1
  189. package/dist/api/agent-server-adapter.d.ts +46 -6
  190. package/dist/api/agent-server-adapter.js +187 -168
  191. package/dist/api/agent-server-adapter.js.map +1 -1
  192. package/dist/api/agent-server-compatibility.cjs +1 -1
  193. package/dist/api/agent-server-compatibility.cjs.map +1 -1
  194. package/dist/api/agent-server-compatibility.d.ts +4 -0
  195. package/dist/api/agent-server-compatibility.js +41 -38
  196. package/dist/api/agent-server-compatibility.js.map +1 -1
  197. package/dist/api/automation-service/automation-service.api.cjs +1 -1
  198. package/dist/api/automation-service/automation-service.api.cjs.map +1 -1
  199. package/dist/api/automation-service/automation-service.api.d.ts +20 -0
  200. package/dist/api/automation-service/automation-service.api.js +99 -62
  201. package/dist/api/automation-service/automation-service.api.js.map +1 -1
  202. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs +2 -0
  203. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs.map +1 -0
  204. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.d.ts +12 -0
  205. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js +94 -0
  206. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js.map +1 -0
  207. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
  208. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
  209. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +31 -90
  210. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
  211. package/dist/components/features/automations/recommended-automations-launcher.d.ts +0 -7
  212. package/dist/components/features/automations/recommended-automations-section.d.ts +0 -6
  213. package/dist/components/features/backends/backend-form-modal.cjs +1 -1
  214. package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
  215. package/dist/components/features/backends/backend-form-modal.js +568 -358
  216. package/dist/components/features/backends/backend-form-modal.js.map +1 -1
  217. package/dist/components/features/backends/device-flow-auth.cjs +1 -1
  218. package/dist/components/features/backends/device-flow-auth.cjs.map +1 -1
  219. package/dist/components/features/backends/device-flow-auth.d.ts +9 -1
  220. package/dist/components/features/backends/device-flow-auth.js +56 -55
  221. package/dist/components/features/backends/device-flow-auth.js.map +1 -1
  222. package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
  223. package/dist/components/features/backends/manage-backends-modal.cjs.map +1 -1
  224. package/dist/components/features/backends/manage-backends-modal.js +1 -1
  225. package/dist/components/features/backends/manage-backends-modal.js.map +1 -1
  226. package/dist/components/features/chat/chat-interface.cjs +1 -1
  227. package/dist/components/features/chat/chat-interface.cjs.map +1 -1
  228. package/dist/components/features/chat/chat-interface.js +105 -105
  229. package/dist/components/features/chat/chat-interface.js.map +1 -1
  230. package/dist/components/features/chat/chat-message.cjs +1 -1
  231. package/dist/components/features/chat/chat-message.cjs.map +1 -1
  232. package/dist/components/features/chat/chat-message.d.ts +2 -1
  233. package/dist/components/features/chat/chat-message.js +59 -49
  234. package/dist/components/features/chat/chat-message.js.map +1 -1
  235. package/dist/components/features/chat/pending-user-messages.cjs +1 -1
  236. package/dist/components/features/chat/pending-user-messages.cjs.map +1 -1
  237. package/dist/components/features/chat/pending-user-messages.js +4 -1
  238. package/dist/components/features/chat/pending-user-messages.js.map +1 -1
  239. package/dist/components/features/chat/typing-indicator.cjs +1 -1
  240. package/dist/components/features/chat/typing-indicator.cjs.map +1 -1
  241. package/dist/components/features/chat/typing-indicator.d.ts +8 -1
  242. package/dist/components/features/chat/typing-indicator.js +94 -10
  243. package/dist/components/features/chat/typing-indicator.js.map +1 -1
  244. package/dist/components/features/command-menu/command-menu-items.d.ts +5 -1
  245. package/dist/components/features/files-tab/segmented-toggle.cjs +1 -1
  246. package/dist/components/features/files-tab/segmented-toggle.cjs.map +1 -1
  247. package/dist/components/features/files-tab/segmented-toggle.d.ts +2 -0
  248. package/dist/components/features/files-tab/segmented-toggle.js +17 -14
  249. package/dist/components/features/files-tab/segmented-toggle.js.map +1 -1
  250. package/dist/components/features/manifest/manifest-form-field.d.ts +27 -0
  251. package/dist/components/features/manifest/manifest-prerequisites-step.d.ts +11 -0
  252. package/dist/components/features/manifest/manifest-review-step.d.ts +14 -0
  253. package/dist/components/features/manifest/manifest-setup-dialog.d.ts +14 -0
  254. package/dist/components/features/settings/settings-input.cjs +1 -1
  255. package/dist/components/features/settings/settings-input.cjs.map +1 -1
  256. package/dist/components/features/settings/settings-input.d.ts +6 -0
  257. package/dist/components/features/settings/settings-input.js +13 -8
  258. package/dist/components/features/settings/settings-input.js.map +1 -1
  259. package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
  260. package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
  261. package/dist/components/features/sidebar/sidebar-rail-body.js +124 -123
  262. package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
  263. package/dist/config/defaults.cjs +1 -1
  264. package/dist/config/defaults.cjs.map +1 -1
  265. package/dist/config/defaults.js +1 -1
  266. package/dist/config/defaults.js.map +1 -1
  267. package/dist/hooks/query/query-keys.cjs.map +1 -1
  268. package/dist/hooks/query/query-keys.d.ts +4 -0
  269. package/dist/hooks/query/query-keys.js.map +1 -1
  270. package/dist/hooks/query/use-manifest-capabilities.d.ts +21 -0
  271. package/dist/hooks/query/use-manifest-prerequisites.d.ts +24 -0
  272. package/dist/hooks/use-llm-configured.cjs +1 -1
  273. package/dist/hooks/use-llm-configured.cjs.map +1 -1
  274. package/dist/hooks/use-llm-configured.js +2 -1
  275. package/dist/hooks/use-llm-configured.js.map +1 -1
  276. package/dist/hooks/use-manifest-preflight.d.ts +18 -0
  277. package/dist/hooks/use-tracking.cjs +1 -1
  278. package/dist/hooks/use-tracking.cjs.map +1 -1
  279. package/dist/hooks/use-tracking.d.ts +14 -0
  280. package/dist/hooks/use-tracking.js +19 -1
  281. package/dist/hooks/use-tracking.js.map +1 -1
  282. package/dist/i18n/declaration.cjs +1 -1
  283. package/dist/i18n/declaration.cjs.map +1 -1
  284. package/dist/i18n/declaration.d.ts +36 -1
  285. package/dist/i18n/declaration.js +1 -1
  286. package/dist/i18n/declaration.js.map +1 -1
  287. package/dist/i18n/translation.cjs +2 -2
  288. package/dist/i18n/translation.cjs.map +1 -1
  289. package/dist/i18n/translation.js +611 -16
  290. package/dist/i18n/translation.js.map +1 -1
  291. package/dist/icons/external-link.cjs +2 -0
  292. package/dist/icons/external-link.cjs.map +1 -0
  293. package/dist/icons/external-link.js +22 -0
  294. package/dist/icons/external-link.js.map +1 -0
  295. package/dist/icons/server.cjs +2 -0
  296. package/dist/icons/server.cjs.map +1 -0
  297. package/dist/icons/server.js +17 -0
  298. package/dist/icons/server.js.map +1 -0
  299. package/dist/locales/ar/openhands.json +37 -2
  300. package/dist/locales/ca/openhands.json +37 -2
  301. package/dist/locales/de/openhands.json +37 -2
  302. package/dist/locales/en/openhands.json +38 -3
  303. package/dist/locales/es/openhands.json +37 -2
  304. package/dist/locales/fr/openhands.json +37 -2
  305. package/dist/locales/it/openhands.json +37 -2
  306. package/dist/locales/ja/openhands.json +37 -2
  307. package/dist/locales/ko-KR/openhands.json +37 -2
  308. package/dist/locales/no/openhands.json +37 -2
  309. package/dist/locales/pt/openhands.json +37 -2
  310. package/dist/locales/tr/openhands.json +37 -2
  311. package/dist/locales/uk/openhands.json +37 -2
  312. package/dist/locales/zh-CN/openhands.json +37 -2
  313. package/dist/locales/zh-TW/openhands.json +37 -2
  314. package/dist/manifests/automation-interface.cjs +2 -0
  315. package/dist/manifests/automation-interface.cjs.map +1 -0
  316. package/dist/manifests/automation-interface.d.ts +44 -0
  317. package/dist/manifests/automation-interface.js +81 -0
  318. package/dist/manifests/automation-interface.js.map +1 -0
  319. package/dist/manifests/automation-setup.cjs +2 -0
  320. package/dist/manifests/automation-setup.cjs.map +1 -0
  321. package/dist/manifests/automation-setup.d.ts +52 -0
  322. package/dist/manifests/automation-setup.js +8 -0
  323. package/dist/manifests/automation-setup.js.map +1 -0
  324. package/dist/manifests/interface-validation.cjs +2 -0
  325. package/dist/manifests/interface-validation.cjs.map +1 -0
  326. package/dist/manifests/interface-validation.d.ts +27 -0
  327. package/dist/manifests/interface-validation.js +182 -0
  328. package/dist/manifests/interface-validation.js.map +1 -0
  329. package/dist/manifests/manifest-actions.d.ts +15 -0
  330. package/dist/manifests/manifest-capabilities.d.ts +25 -0
  331. package/dist/manifests/manifest-error-map.d.ts +40 -0
  332. package/dist/manifests/manifest-local-validation.d.ts +56 -0
  333. package/dist/manifests/manifest-registry.cjs +2 -0
  334. package/dist/manifests/manifest-registry.cjs.map +1 -0
  335. package/dist/manifests/manifest-registry.d.ts +15 -0
  336. package/dist/manifests/manifest-registry.js +26 -0
  337. package/dist/manifests/manifest-registry.js.map +1 -0
  338. package/dist/manifests/manifest-sources.cjs +2 -0
  339. package/dist/manifests/manifest-sources.cjs.map +1 -0
  340. package/dist/manifests/manifest-sources.d.ts +15 -0
  341. package/dist/manifests/manifest-sources.js +8 -0
  342. package/dist/manifests/manifest-sources.js.map +1 -0
  343. package/dist/manifests/manifest-template.d.ts +18 -0
  344. package/dist/manifests/manifest-validation.cjs +2 -0
  345. package/dist/manifests/manifest-validation.cjs.map +1 -0
  346. package/dist/manifests/manifest-validation.d.ts +30 -0
  347. package/dist/manifests/manifest-validation.js +145 -0
  348. package/dist/manifests/manifest-validation.js.map +1 -0
  349. package/dist/manifests/types.cjs +2 -0
  350. package/dist/manifests/types.cjs.map +1 -0
  351. package/dist/manifests/types.d.ts +227 -0
  352. package/dist/manifests/types.js +6 -0
  353. package/dist/manifests/types.js.map +1 -0
  354. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs +9 -0
  355. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs.map +1 -0
  356. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js +75 -0
  357. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js.map +1 -0
  358. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs +9 -0
  359. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs.map +1 -0
  360. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js +78 -0
  361. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js.map +1 -0
  362. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.cjs +17 -0
  363. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.cjs.map +1 -0
  364. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.js +89 -0
  365. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.js.map +1 -0
  366. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs +10 -0
  367. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs.map +1 -0
  368. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js +17 -0
  369. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js.map +1 -0
  370. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.cjs +9 -0
  371. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.cjs.map +1 -0
  372. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.js +15 -0
  373. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.js.map +1 -0
  374. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.cjs +9 -0
  375. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.cjs.map +1 -0
  376. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.js +18 -0
  377. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.js.map +1 -0
  378. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.cjs +9 -0
  379. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.cjs.map +1 -0
  380. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.js +14 -0
  381. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.js.map +1 -0
  382. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.cjs +9 -0
  383. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.cjs.map +1 -0
  384. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.js +14 -0
  385. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.js.map +1 -0
  386. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs +2 -0
  387. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs.map +1 -0
  388. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js +23 -0
  389. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js.map +1 -0
  390. package/dist/node_modules/@openhands/extensions/automations/index.cjs +2 -0
  391. package/dist/node_modules/@openhands/extensions/automations/index.cjs.map +1 -0
  392. package/dist/node_modules/@openhands/extensions/automations/index.js +18 -0
  393. package/dist/node_modules/@openhands/extensions/automations/index.js.map +1 -0
  394. package/dist/node_modules/@openhands/extensions/automations/interface.cjs +2 -0
  395. package/dist/node_modules/@openhands/extensions/automations/interface.cjs.map +1 -0
  396. package/dist/node_modules/@openhands/extensions/automations/interface.js +89 -0
  397. package/dist/node_modules/@openhands/extensions/automations/interface.js.map +1 -0
  398. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs +1 -1
  399. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs.map +1 -1
  400. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js +3 -3
  401. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js.map +1 -1
  402. package/dist/node_modules/@openhands/extensions/skills/index.cjs +17 -4
  403. package/dist/node_modules/@openhands/extensions/skills/index.cjs.map +1 -1
  404. package/dist/node_modules/@openhands/extensions/skills/index.js +5 -5
  405. package/dist/node_modules/@openhands/extensions/skills/index.js.map +1 -1
  406. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.cjs +2 -0
  407. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.cjs.map +1 -0
  408. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.js +29 -0
  409. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.js.map +1 -0
  410. package/dist/package.cjs +1 -1
  411. package/dist/package.cjs.map +1 -1
  412. package/dist/package.js +2 -2
  413. package/dist/package.js.map +1 -1
  414. package/dist/types/agent-server/core/events/conversation-state-event.d.ts +2 -19
  415. package/dist/types/agent-server/core/events/observation-event.d.ts +2 -18
  416. package/dist/types/automation.d.ts +7 -3
  417. package/dist/utils/api-error-message.d.ts +6 -2
  418. package/dist/utils/automation-catalog.cjs +2 -0
  419. package/dist/utils/automation-catalog.cjs.map +1 -0
  420. package/dist/utils/automation-catalog.d.ts +28 -0
  421. package/dist/utils/automation-catalog.js +5 -0
  422. package/dist/utils/automation-catalog.js.map +1 -0
  423. package/dist/utils/automation-timeout.d.ts +3 -2
  424. package/dist/utils/responder-deployment.d.ts +5 -1
  425. package/dist/utils/transcript-export/index.cjs +5 -5
  426. package/dist/utils/transcript-export/index.js +12 -12
  427. package/package.json +2 -2
  428. package/scripts/check-translation-completeness.cjs +1 -0
  429. package/scripts/dev-safe.mjs +15 -10
  430. package/scripts/dev-static.mjs +17 -0
  431. package/scripts/dev-with-automation.mjs +12 -14
  432. package/scripts/ingress.mjs +22 -0
  433. package/scripts/proxy-utils.mjs +157 -2
  434. package/scripts/runtime-services-info.mjs +6 -6
  435. package/scripts/static-build.mjs +0 -7
  436. package/scripts/static-server.mjs +10 -0
  437. package/build/assets/active-backend-context-mY7Gff5c.js +0 -2
  438. package/build/assets/agent-context-settings-BTUmWEzL.js +0 -1
  439. package/build/assets/agent-profiles-settings-Ilqid_R5.js +0 -1
  440. package/build/assets/agent-server-conversation-service.api-C_7YnjzP.js +0 -41
  441. package/build/assets/agent-settings-CxfT4ksO.js +0 -1
  442. package/build/assets/automation-BGP_I1RR.js +0 -1
  443. package/build/assets/automation-detail-nEflClmc.js +0 -2
  444. package/build/assets/automation-export-BO_kfqC8.js +0 -2
  445. package/build/assets/automations-list-BYncC7gv.js +0 -1
  446. package/build/assets/backend-form-modal-CKrBF80P.js +0 -1
  447. package/build/assets/browser-3QjrEr1D.js +0 -6
  448. package/build/assets/check-CrxQfJZ2.js +0 -1
  449. package/build/assets/chevron-down-D_LsyTA7.js +0 -1
  450. package/build/assets/circle-check-DZn9HkLE.js +0 -1
  451. package/build/assets/cloud-funnel-analytics-NlmDoeo2.js +0 -1
  452. package/build/assets/command-menu-CvLPs7dg.js +0 -1
  453. package/build/assets/condenser-settings-C4Y9CzQV.js +0 -1
  454. package/build/assets/conversation-D_ORtpKC.js +0 -1
  455. package/build/assets/conversation-Dpc5nmGi.js +0 -90
  456. package/build/assets/conversation-panel-D_ORtpKC.js +0 -1
  457. package/build/assets/conversation-state-store-CGRQemtx.js +0 -1
  458. package/build/assets/files-tab-4c9HFSLo.js +0 -1
  459. package/build/assets/git-provider-icon-0PqmIS_S.js +0 -1
  460. package/build/assets/home-D9JsyEmE.js +0 -1
  461. package/build/assets/home-TFhnmZLx.js +0 -1
  462. package/build/assets/index-home-D9JsyEmE.js +0 -1
  463. package/build/assets/install-server-modal-BgGRnqA0.js +0 -1
  464. package/build/assets/llm-not-configured-banner-Y4W9-sar.js +0 -27
  465. package/build/assets/llm-settings-nPwv7hKu.js +0 -1
  466. package/build/assets/loader-circle-CGD6-Vak.js +0 -1
  467. package/build/assets/manifest-1cf33a7b.js +0 -1
  468. package/build/assets/markdown-renderer-U40HF0Ak.js +0 -8
  469. package/build/assets/mcp-xDMaHzOw.js +0 -9
  470. package/build/assets/messages-CdNfZPgd.js +0 -40
  471. package/build/assets/plus-CTGLo3aa.js +0 -1
  472. package/build/assets/recommended-automations-launcher-Dru1yN46.js +0 -58
  473. package/build/assets/root-B5JXKp1P.css +0 -1
  474. package/build/assets/root-DOLLQteU.js +0 -2
  475. package/build/assets/root-layout-xmylWoew.js +0 -3
  476. package/build/assets/search-BrpWXWUi.js +0 -1
  477. package/build/assets/segmented-toggle-CZKOdIly.js +0 -1
  478. package/build/assets/settings-input-BEaTCem1.js +0 -1
  479. package/build/assets/shared-conversation-BvWtTwES.js +0 -1
  480. package/build/assets/use-agent-profiles-DmT9zxAN.js +0 -1
  481. package/build/assets/use-config-C959QcRC.js +0 -1
  482. package/build/assets/use-is-authed-BsS4XwSL.js +0 -1
  483. package/build/assets/use-llm-profiles-CdaxVpyY.js +0 -1
  484. package/build/assets/use-save-agent-profile-DGJ3-u0M.js +0 -1
  485. package/build/assets/use-settings-nav-items-DPK5sxvR.js +0 -16
  486. package/build/assets/use-tracking-COqZLobY.js +0 -1
  487. package/build/assets/utils-DsWhWn2F.js +0 -1
  488. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation-Acmf1sKj.js +0 -1
  489. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-CmzCY1BT.js +0 -1
  490. package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~onboarding-modal-C7Yh77RT.js +0 -1
  491. package/build/assets/x-Dx_JbpHA.js +0 -1
  492. /package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f1hl7voa-BrmgjeOw.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~emdr2jt4-BrmgjeOw.js} +0 -0
@@ -264,7 +264,9 @@ export async function assertPortsFree(portConfigs, host = "127.0.0.1") {
264
264
  const busy = results.filter(({ free }) => !free);
265
265
  if (busy.length === 0) return;
266
266
 
267
- const lines = busy.map(({ name, port }) => ` • ${name}: port ${port}`).join("\n");
267
+ const lines = busy
268
+ .map(({ name, port }) => ` • ${name}: port ${port}`)
269
+ .join("\n");
268
270
  throw new Error(
269
271
  `Cannot start: the following ports are already in use:\n\n${lines}\n\n` +
270
272
  `Another agent-canvas instance may already be running.\n` +
@@ -619,8 +621,7 @@ function buildConfigFromPorts(ports, cwd, env) {
619
621
  // ~/.openhands/agent-canvas/secret-key.txt. Persisting ensures dev mode
620
622
  // and Docker mode share the same encryption key when they mount the same
621
623
  // ~/.openhands directory (docker/entrypoint.sh reads/writes the same file).
622
- const secretKeyPath =
623
- env.OH_SECRET_KEY_PATH || DEFAULT_SECRET_KEY_PATH;
624
+ const secretKeyPath = env.OH_SECRET_KEY_PATH || DEFAULT_SECRET_KEY_PATH;
624
625
  const secretKey =
625
626
  env.OH_SECRET_KEY || getOrCreatePersistedApiKey(secretKeyPath, "secret");
626
627
  // Use the user-provided LOCAL_BACKEND_API_KEY or fall back to a key
@@ -958,10 +959,6 @@ async function main() {
958
959
  }
959
960
 
960
961
  const frontendCommand = buildNpmScriptCommand("dev:frontend");
961
- const runtimeServicesInfo = buildRuntimeServicesInfo({
962
- mode: "dev:safe",
963
- agentServerPort: config.backendPort,
964
- });
965
962
  frontend = spawnProcess(frontendCommand.command, frontendCommand.args, {
966
963
  cwd: config.cwd,
967
964
  env: {
@@ -971,9 +968,17 @@ async function main() {
971
968
  VITE_WORKING_DIR: config.workingDir,
972
969
  // Pass session API key so frontend can authenticate with agent-server
973
970
  VITE_SESSION_API_KEY: config.sessionApiKey,
974
- // Inform the frontend (and downstream, the agent's system prompt) about
975
- // which services are available in this dev stack.
976
- VITE_RUNTIME_SERVICES_INFO: JSON.stringify(runtimeServicesInfo),
971
+ // dev:minimal deliberately does NOT supply runtime-services info (the
972
+ // frontend here talks straight to the agent-server over
973
+ // VITE_BACKEND_BASE_URL — there is no ingress or static-server in front
974
+ // of it to append `runtime_services` to `/server_info`, and the
975
+ // frontend's own VITE_RUNTIME_SERVICES_INFO env var is no longer read).
976
+ // It is a bare agent-server + Vite stack with no companion services to
977
+ // advertise, so `fetchBackendRuntimeServicesInfo()` correctly returns
978
+ // null and conversations simply omit the <RUNTIME_SERVICES> block.
979
+ // Stacks with automation/ingress/frontend services should use
980
+ // `npm run dev` / `dev:static`, which pass runtime-services info through
981
+ // ingress/static-server instead.
977
982
  },
978
983
  });
979
984
 
@@ -61,6 +61,7 @@ import {
61
61
  buildAgentServerAutomationEnv,
62
62
  buildAutomationCommand,
63
63
  buildAutomationTelemetryEnv,
64
+ buildAutomationRuntimeServicesInfo,
64
65
  buildConfig,
65
66
  } from "./dev-with-automation.mjs";
66
67
 
@@ -379,6 +380,12 @@ function startStaticServer(config) {
379
380
  // is forwarded to the agent-server instead of falling back to the SPA
380
381
  // shell). Without this, /server_info on :3001 returns index.html.
381
382
  const staticServerScript = join(projectRoot, "scripts", "static-server.mjs");
383
+ const runtimeServicesInfo = JSON.stringify(
384
+ buildAutomationRuntimeServicesInfo({
385
+ ...config,
386
+ frontendKind: "static",
387
+ }),
388
+ );
382
389
  spawnService(
383
390
  "static",
384
391
  "node",
@@ -396,6 +403,8 @@ function startStaticServer(config) {
396
403
  ...(config.sessionApiKey
397
404
  ? ["--session-api-key", config.sessionApiKey]
398
405
  : []),
406
+ "--runtime-services-info",
407
+ runtimeServicesInfo,
399
408
  "--route",
400
409
  `/api/automation=http://localhost:${config.autoBackendPort}`,
401
410
  "--route",
@@ -428,6 +437,12 @@ function startIngress(config) {
428
437
  logService("ingress", `Starting on port ${config.ingressPort}...`, c.yellow);
429
438
 
430
439
  const ingressScript = join(projectRoot, "scripts", "ingress.mjs");
440
+ const runtimeServicesInfo = JSON.stringify(
441
+ buildAutomationRuntimeServicesInfo({
442
+ ...config,
443
+ frontendKind: "static",
444
+ }),
445
+ );
431
446
 
432
447
  spawnService(
433
448
  "ingress",
@@ -436,6 +451,8 @@ function startIngress(config) {
436
451
  ingressScript,
437
452
  "--port",
438
453
  config.ingressPort.toString(),
454
+ "--runtime-services-info",
455
+ runtimeServicesInfo,
439
456
  "--route",
440
457
  `/api/automation=http://localhost:${config.autoBackendPort}`,
441
458
  "--route",
@@ -958,12 +958,16 @@ function shutdown() {
958
958
 
959
959
  process.on("SIGINT", shutdown);
960
960
  process.on("SIGTERM", shutdown);
961
+ process.on("SIGHUP", shutdown);
961
962
 
962
963
  function startIngress(config) {
963
964
  logService("ingress", `Starting on port ${config.ingressPort}...`, c.yellow);
964
965
 
965
966
  const ingressScript = join(projectRoot, "scripts", "ingress.mjs");
966
967
  const frontendBackend = getFrontendBackend(config);
968
+ const runtimeServicesInfo = config.launchAgentServer
969
+ ? JSON.stringify(buildAutomationRuntimeServicesInfo(config))
970
+ : null;
967
971
 
968
972
  spawnService(
969
973
  "ingress",
@@ -972,6 +976,9 @@ function startIngress(config) {
972
976
  ingressScript,
973
977
  "--port",
974
978
  config.ingressPort.toString(),
979
+ ...(runtimeServicesInfo
980
+ ? ["--runtime-services-info", runtimeServicesInfo]
981
+ : []),
975
982
  ...buildRouteArgs(getLocalServiceRoutes(config)),
976
983
  ...(frontendBackend ? ["--default", frontendBackend] : []),
977
984
  ],
@@ -984,8 +991,8 @@ function startIngress(config) {
984
991
 
985
992
  /**
986
993
  * Build the JSON-serializable runtime services info for an automation
987
- * stack. Used by both the Vite dev server (dev mode) and static-build.mjs
988
- * (static mode) so the frontend can populate the agent's
994
+ * stack. Backend-serving processes append this to `/server_info` so any
995
+ * frontend connected to the backend can populate the agent's
989
996
  * `<RUNTIME_SERVICES>` system-prompt block.
990
997
  */
991
998
  export function buildAutomationRuntimeServicesInfo(config) {
@@ -1009,9 +1016,6 @@ function startVite(config) {
1009
1016
  logService("vite", `Starting on port ${config.vitePort}...`, c.magenta);
1010
1017
 
1011
1018
  const frontendCommand = buildNpmScriptCommand("dev:frontend");
1012
- const runtimeServicesInfo = config.launchAgentServer
1013
- ? buildAutomationRuntimeServicesInfo(config)
1014
- : null;
1015
1019
 
1016
1020
  const viteEnv = {
1017
1021
  // Full-stack mode points Vite at this launcher's ingress. Frontend-only
@@ -1023,12 +1027,6 @@ function startVite(config) {
1023
1027
  viteEnv.VITE_WORKING_DIR = config.viteWorkingDir;
1024
1028
  }
1025
1029
 
1026
- if (runtimeServicesInfo) {
1027
- // Inform the frontend (and downstream, the agent's system prompt) about
1028
- // which services are available in this dev stack.
1029
- viteEnv.VITE_RUNTIME_SERVICES_INFO = JSON.stringify(runtimeServicesInfo);
1030
- }
1031
-
1032
1030
  // In local mode, bake the session key into the frontend so the user
1033
1031
  // never has to paste it. In public mode, omit the key and set
1034
1032
  // VITE_AUTH_REQUIRED so the frontend shows the API key entry screen
@@ -1442,9 +1440,9 @@ function startStaticFrontend(config, staticDir) {
1442
1440
  logService("static", `Starting on port ${config.vitePort}...`, c.magenta);
1443
1441
  logService("static", `Serving from: ${staticDir}`, c.dim);
1444
1442
 
1445
- // Build the runtime-services info JSON so the pre-built frontend can
1446
- // populate the agent's <RUNTIME_SERVICES> system-prompt block without
1447
- // VITE_RUNTIME_SERVICES_INFO baked in at build time.
1443
+ // Build the runtime-services info JSON so static-server can append it to
1444
+ // /server_info. The static-server also injects the old window global for
1445
+ // compatibility with previously built frontend bundles.
1448
1446
  const runtimeServicesInfo = config.launchAgentServer
1449
1447
  ? JSON.stringify(buildAutomationRuntimeServicesInfo(config))
1450
1448
  : null;
@@ -13,6 +13,8 @@
13
13
  * INGRESS_PORT - Port to listen on (default: 8000)
14
14
  * INGRESS_ROUTES - JSON object of path prefix -> backend URL
15
15
  * INGRESS_DEFAULT - Default backend for unmatched routes
16
+ * INGRESS_RUNTIME_SERVICES_INFO - Runtime services JSON appended to
17
+ * /server_info
16
18
  *
17
19
  * Route matching:
18
20
  * - Routes are matched by longest prefix first
@@ -27,6 +29,8 @@ import {
27
29
  createProxyHandlers,
28
30
  createRouter,
29
31
  isBenignSocketError,
32
+ isServerInfoRequest,
33
+ proxyServerInfoRequest,
30
34
  } from "./proxy-utils.mjs";
31
35
 
32
36
  // ═══════════════════════════════════════════════════════════════════════════
@@ -39,6 +43,7 @@ function parseArgs() {
39
43
  port: 8000,
40
44
  routes: {},
41
45
  defaultBackend: null,
46
+ runtimeServicesInfo: null,
42
47
  };
43
48
 
44
49
  for (let i = 0; i < args.length; i++) {
@@ -57,6 +62,9 @@ function parseArgs() {
57
62
  case "--default":
58
63
  config.defaultBackend = args[++i];
59
64
  break;
65
+ case "--runtime-services-info":
66
+ config.runtimeServicesInfo = args[++i] || null;
67
+ break;
60
68
  case "-h":
61
69
  case "--help":
62
70
  showHelp();
@@ -80,12 +88,15 @@ OPTIONS:
80
88
  -p, --port <port> Port to listen on (default: 8000)
81
89
  -r, --route <path=url> Add a route (can be repeated)
82
90
  -d, --default <url> Default backend for unmatched routes
91
+ --runtime-services-info Runtime services JSON for /server_info
83
92
  -h, --help Show this help
84
93
 
85
94
  ENVIRONMENT VARIABLES:
86
95
  INGRESS_PORT Port to listen on
87
96
  INGRESS_ROUTES JSON object: {"path": "url", ...}
88
97
  INGRESS_DEFAULT Default backend URL
98
+ INGRESS_RUNTIME_SERVICES_INFO
99
+ Runtime services JSON for /server_info
89
100
 
90
101
  EXAMPLES:
91
102
  # Basic setup with agent server and automation
@@ -125,6 +136,8 @@ function buildConfig(args, env = process.env) {
125
136
  port: args.port || parseInt(env.INGRESS_PORT, 10) || 8000,
126
137
  routes,
127
138
  defaultBackend: args.defaultBackend || env.INGRESS_DEFAULT || null,
139
+ runtimeServicesInfo:
140
+ args.runtimeServicesInfo || env.INGRESS_RUNTIME_SERVICES_INFO || null,
128
141
  };
129
142
  }
130
143
 
@@ -146,6 +159,15 @@ export function startIngress(config) {
146
159
  return;
147
160
  }
148
161
 
162
+ if (
163
+ config.runtimeServicesInfo &&
164
+ isServerInfoRequest(req) &&
165
+ (req.method === "GET" || req.method === "HEAD")
166
+ ) {
167
+ proxyServerInfoRequest(req, res, backend, config.runtimeServicesInfo);
168
+ return;
169
+ }
170
+
149
171
  proxy.proxyHttp(req, res, backend);
150
172
  });
151
173
 
@@ -1,6 +1,9 @@
1
+ import { request as httpRequest } from "node:http";
2
+ import { request as httpsRequest } from "node:https";
1
3
  import { createProxyServer } from "httpxy";
2
4
 
3
5
  const DEFAULT_PROXY_TIMEOUT_MS = 120_000;
6
+ const SERVER_INFO_PATH = "/server_info";
4
7
  const BENIGN_SOCKET_ERRORS = new Set([
5
8
  "ECONNRESET",
6
9
  "EPIPE",
@@ -35,6 +38,152 @@ export function isBenignSocketError(err) {
35
38
  return Boolean(err && BENIGN_SOCKET_ERRORS.has(err.code));
36
39
  }
37
40
 
41
+ function parseBackendUrl(backendUrl) {
42
+ const url = new URL(backendUrl);
43
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
44
+ throw new Error("Invalid backend URL");
45
+ }
46
+ return {
47
+ hostname: url.hostname,
48
+ port: Number.parseInt(url.port, 10) || (url.protocol === "https:" ? 443 : 80),
49
+ protocol: url.protocol,
50
+ };
51
+ }
52
+
53
+ function writeInvalidBackendUrlResponse(req, res) {
54
+ const message = "Invalid backend URL";
55
+ console.error(`Proxy error for ${req.url}: ${message}`);
56
+ if (!res.headersSent) {
57
+ res.writeHead(502, { "Content-Type": "text/plain; charset=utf-8" });
58
+ res.end(`Bad Gateway: ${message}`);
59
+ } else {
60
+ res.destroy();
61
+ }
62
+ }
63
+
64
+ export function isServerInfoRequest(req) {
65
+ const pathname = new URL(req.url ?? "/", "http://localhost").pathname;
66
+ return pathname === SERVER_INFO_PATH;
67
+ }
68
+
69
+ export function proxyServerInfoRequest(
70
+ req,
71
+ res,
72
+ backendUrl,
73
+ runtimeServicesInfo,
74
+ ) {
75
+ let backend;
76
+ try {
77
+ backend = parseBackendUrl(backendUrl);
78
+ } catch {
79
+ writeInvalidBackendUrlResponse(req, res);
80
+ return;
81
+ }
82
+
83
+ const request = backend.protocol === "https:" ? httpsRequest : httpRequest;
84
+ const proxyReq = request(
85
+ {
86
+ hostname: backend.hostname,
87
+ port: backend.port,
88
+ path: req.url,
89
+ method: req.method,
90
+ headers: {
91
+ ...req.headers,
92
+ host: `${backend.hostname}:${backend.port}`,
93
+ },
94
+ },
95
+ (proxyRes) => {
96
+ const chunks = [];
97
+
98
+ proxyRes.on("data", (chunk) => {
99
+ chunks.push(Buffer.from(chunk));
100
+ });
101
+
102
+ proxyRes.on("error", (err) => {
103
+ if (!isBenignSocketError(err)) {
104
+ console.error(`Upstream response error for ${req.url}:`, err.message);
105
+ }
106
+ if (!res.headersSent) {
107
+ res.writeHead(502);
108
+ res.end(`Bad Gateway: ${err.message}`);
109
+ } else {
110
+ res.destroy();
111
+ }
112
+ });
113
+
114
+ proxyRes.on("end", () => {
115
+ const statusCode = proxyRes.statusCode ?? 502;
116
+ const headers = { ...proxyRes.headers };
117
+ const originalBody = Buffer.concat(chunks);
118
+
119
+ if (statusCode < 200 || statusCode >= 300 || req.method === "HEAD") {
120
+ res.writeHead(statusCode, headers);
121
+ res.end(req.method === "HEAD" ? "" : originalBody);
122
+ return;
123
+ }
124
+
125
+ try {
126
+ const serverInfo = JSON.parse(originalBody.toString("utf8"));
127
+ const runtimeServices =
128
+ typeof runtimeServicesInfo === "string"
129
+ ? JSON.parse(runtimeServicesInfo)
130
+ : runtimeServicesInfo;
131
+ const body = Buffer.from(
132
+ JSON.stringify({
133
+ ...serverInfo,
134
+ runtime_services: runtimeServices,
135
+ }),
136
+ "utf8",
137
+ );
138
+
139
+ delete headers["content-length"];
140
+ delete headers["transfer-encoding"];
141
+ headers["content-type"] = "application/json; charset=utf-8";
142
+ headers["cache-control"] = "no-store";
143
+ res.writeHead(statusCode, headers);
144
+ res.end(body);
145
+ } catch (err) {
146
+ console.warn(
147
+ `Could not append runtime_services to ${SERVER_INFO_PATH}: ${
148
+ err instanceof Error ? err.message : String(err)
149
+ }`,
150
+ );
151
+ res.writeHead(statusCode, headers);
152
+ res.end(originalBody);
153
+ }
154
+ });
155
+ },
156
+ );
157
+
158
+ proxyReq.on("error", (err) => {
159
+ if (!isBenignSocketError(err)) {
160
+ console.error(`Proxy error for ${req.url}:`, err.message);
161
+ }
162
+ if (!res.headersSent) {
163
+ res.writeHead(502);
164
+ res.end(`Bad Gateway: ${err.message}`);
165
+ } else {
166
+ res.destroy();
167
+ }
168
+ });
169
+
170
+ req.on("error", (err) => {
171
+ if (!isBenignSocketError(err)) {
172
+ console.error(`Client request error for ${req.url}:`, err.message);
173
+ }
174
+ proxyReq.destroy();
175
+ });
176
+
177
+ res.on("error", (err) => {
178
+ if (!isBenignSocketError(err)) {
179
+ console.error(`Client response error for ${req.url}:`, err.message);
180
+ }
181
+ proxyReq.destroy();
182
+ });
183
+
184
+ req.pipe(proxyReq, { end: true });
185
+ }
186
+
38
187
  function once(fn) {
39
188
  let called = false;
40
189
  return (...args) => {
@@ -97,7 +246,7 @@ export function createProxyHandlers({
97
246
  res.on("finish", finish);
98
247
  res.on("error", finish);
99
248
 
100
- proxy.web(req, res, { target }).catch((err) => {
249
+ const handleProxyError = (err) => {
101
250
  metrics.totalErrors += 1;
102
251
  if (!isBenignSocketError(err)) {
103
252
  console.error(
@@ -107,7 +256,13 @@ export function createProxyHandlers({
107
256
  }
108
257
  writeProxyError(res, err instanceof Error ? err.message : String(err));
109
258
  finish();
110
- });
259
+ };
260
+
261
+ try {
262
+ proxy.web(req, res, { target }).catch(handleProxyError);
263
+ } catch (err) {
264
+ handleProxyError(err);
265
+ }
111
266
  }
112
267
 
113
268
  function proxyWebSocket(req, socket, head, target) {
@@ -2,19 +2,19 @@
2
2
  * Single source of truth for the `<RUNTIME_SERVICES>` block.
3
3
  *
4
4
  * Builds a structured description of the services that are reachable from
5
- * inside the agent's sandbox. The frontend forwards it (verbatim, as a JSON
6
- * string) and renders it into the system prompt via
7
- * `AgentContext.system_message_suffix`, so the agent sees a
5
+ * inside the agent's sandbox. Agent Canvas backend-serving processes attach it
6
+ * to `/server_info.runtime_services`; the frontend renders that backend value
7
+ * into `AgentContext.system_message_suffix`, so the agent sees a
8
8
  * `<RUNTIME_SERVICES>` block listing what's available without having to probe.
9
9
  *
10
10
  * Two callers share this one definition:
11
11
  * - the dev launchers (scripts/dev-*.mjs), which know the stack as a set of
12
- * ports and bake the result into `VITE_RUNTIME_SERVICES_INFO` at build time;
12
+ * ports and pass the result to ingress/static-server for `/server_info`;
13
13
  * - docker/entrypoint.sh, which runs this file as a CLI (see the bottom of
14
14
  * this module) because in a container the URLs are *runtime* config — the
15
15
  * ports and base URLs are overridable at `docker run` and therefore cannot
16
- * be baked into the image at build time. The JSON it prints is injected
17
- * into index.html at serve time by scripts/static-server.mjs.
16
+ * be baked into the image at build time. The JSON it prints is passed to
17
+ * scripts/static-server.mjs and exposed through `/server_info`.
18
18
  *
19
19
  * URLs are written from the *agent's* point of view (i.e. as the agent should
20
20
  * curl/fetch them from inside its sandbox), which is deliberately not the
@@ -3,7 +3,6 @@ import { existsSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
 
5
5
  import {
6
- buildAutomationRuntimeServicesInfo,
7
6
  c,
8
7
  logError,
9
8
  logService,
@@ -45,12 +44,6 @@ export function buildFrontend(config, args = {}) {
45
44
  // Bake the session API key — used by the frontend for both agent-server
46
45
  // and automation auth via the `X-Session-API-Key` header.
47
46
  VITE_SESSION_API_KEY: config.sessionApiKey,
48
- // Bake a description of the runtime services in this dev stack so the
49
- // frontend can populate the agent's <RUNTIME_SERVICES> system-prompt
50
- // block when creating a conversation.
51
- VITE_RUNTIME_SERVICES_INFO: JSON.stringify(
52
- buildAutomationRuntimeServicesInfo(config),
53
- ),
54
47
  // Intentionally do NOT set VITE_BACKEND_BASE_URL: leaving it unset makes
55
48
  // the runtime fall back to window.location.origin, which keeps the build
56
49
  // portable across localhost, LAN hosts, and tunnels such as ngrok.
@@ -37,7 +37,9 @@ import sirv from "sirv";
37
37
  import {
38
38
  createProxyHandlers,
39
39
  createRouter,
40
+ isServerInfoRequest,
40
41
  matchesPathPrefix,
42
+ proxyServerInfoRequest,
41
43
  } from "./proxy-utils.mjs";
42
44
 
43
45
  // ─────────────────────────────────────────────────────────────────────────────
@@ -558,6 +560,14 @@ export function startStaticServer(config) {
558
560
  const server = createServer((req, res) => {
559
561
  const backend = route(req.url ?? "/");
560
562
  if (backend) {
563
+ if (
564
+ config.runtimeServicesInfo &&
565
+ isServerInfoRequest(req) &&
566
+ (req.method === "GET" || req.method === "HEAD")
567
+ ) {
568
+ proxyServerInfoRequest(req, res, backend, config.runtimeServicesInfo);
569
+ return;
570
+ }
561
571
  proxy.proxyHttp(req, res, backend);
562
572
  return;
563
573
  }
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor~module-BZXjBMvd.js","assets/rolldown-runtime-Cyuzqnbw.js"])))=>i.map(i=>d[i]);
2
- import{a as e}from"./rolldown-runtime-Cyuzqnbw.js";import{St as t,xt as n,yt as r}from"./vendor-styling-Bcgpimp9.js";import{r as i}from"./vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f9xdmd0z-DLMP7bZx.js";import{D as a,F as o,I as s,M as ee,O as te,P as ne,T as re,d as ie,k as ae,w as c,y as oe}from"./vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~g4xrpilz-CYPMCkX1.js";import{R as se,t as ce,z as l}from"./utils-DsWhWn2F.js";var u=e(t(),1),le=`__AGENT_CANVAS_BASE_PATH__`;function ue(e){let t=e?.trim();return!t||t===`/`?``:(t.startsWith(`/`)?t:`/${t}`).replace(/\/+$/,``)}function de(){let e=ue(void 0);if(e)return e;if(typeof window<`u`){let e=window[le];if(typeof e==`string`)return ue(e)}return``}function fe(e){let t=de();return t?`${t}${e.startsWith(`/`)?e:`/${e}`}`:e.startsWith(`/`)?e:`/${e}`}var d=`openhands`,pe=[{label:`English`,value:`en`},{label:`日本語`,value:`ja`},{label:`简体中文`,value:`zh-CN`},{label:`繁體中文`,value:`zh-TW`},{label:`한국어`,value:`ko-KR`},{label:`Norsk`,value:`no`},{label:`Arabic`,value:`ar`},{label:`Deutsch`,value:`de`},{label:`Français`,value:`fr`},{label:`Italiano`,value:`it`},{label:`Português`,value:`pt`},{label:`Español`,value:`es`},{label:`Català`,value:`ca`},{label:`Türkçe`,value:`tr`},{label:`Українська`,value:`uk`}],me=new WeakMap,he=e=>{if(!me.has(e)){let t=e.use(te).use(a).use(i).init({fallbackLng:`en`,debug:!1,supportedLngs:pe.map(e=>e.value),nonExplicitSupportedLngs:!1,ns:[d],defaultNS:d,fallbackNS:d,backend:{loadPath:fe(`/locales/{{lng}}/{{ns}}.json`)},interpolation:{escapeValue:!1}});me.set(e,t)}return e},ge=()=>he(ee()),_e=null,ve=null,f=()=>(_e||=ge(),_e),ye=()=>ve??f(),be=e=>(ve=e??f(),ve),xe=async(e=f())=>(await me.get(e),e),Se=e=>e?typeof e==`object`&&!Array.isArray(e)?{ns:d,...e}:e:{ns:d},p=new Proxy({},{get:(e,t)=>{let n=ye();if(t===`t`)return(e,t)=>n.t(e,Se(t));if(t===`exists`)return(e,t)=>n.exists(e,Se(t));let r=Reflect.get(n,t,n);return typeof r==`function`?r.bind(n):r},set:(e,t,n)=>{let r=ye();return Reflect.set(r,t,n,r)}}),Ce=e=>typeof e.response?.data==`object`&&e.response?.data!==null&&`error`in e.response.data&&typeof e.response?.data?.error==`string`,we=e=>typeof e.response?.data==`object`&&e.response?.data!==null&&`message`in e.response.data&&typeof e.response?.data?.message==`string`,Te=`Disconnected (check URL or network). Check that the backend URL is correct and the backend server is reachable. If the backend is on another origin, check that it allows this frontend origin.`,Ee=`Disconnected (request timed out). Check that the backend URL is correct and reachable.`,De=4;function Oe(e){return typeof e==`object`&&!!e}function ke(e){let t=[],n=new Set,r=e,i=0;for(;r!=null&&i<De&&!n.has(r);){if(n.add(r),r instanceof Error)r.message&&t.push(r.message),r=r.cause;else if(typeof r==`string`){r&&t.push(r);break}else if(Oe(r)){let e=r.message;typeof e==`string`&&e&&t.push(e),r=r.cause}else break;i+=1}return t}function m(e){if(!e)return!1;let t=e.toLowerCase();return t.includes(`disconnected (check cors or network)`)||t.includes(`disconnected (check url or network)`)||t.includes(`blocked by cors`)||t.includes(`failed to fetch`)||t.includes(`network error`)||t.includes(`load failed`)||t.includes(`networkerror when attempting to fetch resource`)||t.includes(`cors`)&&t.includes(`blocked`)}function Ae(e){return ke(e).some(m)}function je(e){if(!e)return!1;let t=e.toLowerCase();return t.includes(`request timeout`)||t.includes(`timeout after`)||t.includes(`backend request timed out`)}function Me(e){let t=ke(e);return t.some(m)?Te:t.some(je)?Ee:t[0]??null}function Ne(e){return typeof e==`object`&&!!e&&`isAxiosError`in e&&e.isAxiosError===!0}var Pe=e=>{let t=null,n=!1;return Ne(e)?(n=!0,t=Ce(e)&&e.response?.data.error?e.response?.data.error:we(e)&&e.response?.data.message?e.response?.data.message:e.message):t=e instanceof Error?e.message:typeof e==`string`?e:null,Me(n?t??e:e)??t??``},h=(e,t=5e3,n=1e4)=>{if(!e)return t;let r=e.length/(1e3/60)*1e3*1.5;return Math.min(Math.max(r,t),n)},g=r(),Fe={background:`var(--oh-color-tertiary)`,border:`1px solid var(--oh-border-input)`,color:`#fff`,borderRadius:`var(--oh-radius)`,maxWidth:`400px`,wordBreak:`break-word`,overflowWrap:`anywhere`,whiteSpace:`pre-wrap`},_={position:`top-right`,style:Fe},Ie={...Fe,color:`var(--oh-muted)`};function Le({message:e}){let t=u.useRef(null),[n,r]=u.useState(!1);return u.useLayoutEffect(()=>{let e=t.current;if(!e)return;let n=()=>{let t=Number.parseFloat(getComputedStyle(e).lineHeight);if(!Number.isFinite(t)||t<=0){r(!1);return}r(e.getBoundingClientRect().height>t*1.5)};n();let i=new ResizeObserver(n);return i.observe(e),()=>i.disconnect()},[e]),(0,g.jsxs)(`div`,{className:ce(`flex min-w-0 gap-2`,n?`items-start`:`items-center`),children:[(0,g.jsx)(re,{"aria-hidden":!0,className:`h-4 w-4 shrink-0`,strokeWidth:2,style:{color:se}}),(0,g.jsx)(`span`,{ref:t,className:`min-w-0 flex-1 text-sm leading-5 [word-break:break-word] [overflow-wrap:anywhere]`,children:e})]})}var Re={..._,icon:null,style:Ie},ze=e=>{let t=e||p.t(l.STATUS$ERROR);m(t)?t=p.t(l.ERROR$CORS_OR_NETWORK):je(t)&&(t=p.t(l.ERROR$BACKEND_REQUEST_TIMEOUT));let n=h(t,4e3);c((0,g.jsx)(Le,{message:t}),{...Re,duration:n})},Be=e=>{let t=h(e,5e3);c.success((0,g.jsx)(`span`,{className:`[word-break:break-word] [overflow-wrap:anywhere]`,children:e}),{..._,duration:t})},Ve=(e,t,n)=>{let r=h(`${e} ${t}`,5e3);c.success((0,g.jsxs)(`span`,{className:`[word-break:break-word] [overflow-wrap:anywhere]`,children:[e,` `,(0,g.jsx)(`a`,{className:`underline hover:no-underline`,href:n,children:t})]}),{..._,duration:r})},He=e=>{let t=h(e,6e3);c((0,g.jsx)(`span`,{className:`[word-break:break-word] [overflow-wrap:anywhere]`,children:e}),{..._,icon:`⚠️`,duration:t})},Ue=`openhands-backend-health`,We=500;function Ge(e){if(typeof e!=`object`||!e)return!1;let t=e;return Number.isInteger(t.consecutiveFailures)&&t.consecutiveFailures>=0&&t.consecutiveFailures<=5&&(t.lastError===null||typeof t.lastError==`string`)&&(t.lastFailureAt===null||typeof t.lastFailureAt==`number`)&&typeof t.disabled==`boolean`}function Ke(){if(typeof window>`u`)return{};try{let e=window.localStorage.getItem(Ue);if(!e)return{};let t=JSON.parse(e);if(typeof t!=`object`||!t)return{};let n={};for(let[e,r]of Object.entries(t))typeof e==`string`&&e.length>0&&Ge(r)&&(n[e]=r);return n}catch{return{}}}function qe(e){if(!(typeof window>`u`))try{if(Object.keys(e).length===0){window.localStorage.removeItem(Ue);return}window.localStorage.setItem(Ue,JSON.stringify(e))}catch{}}function Je(e){let t=Me(e)??`Unknown error`;return t.length>We?`${t.slice(0,We)}…`:t}var v=Ke(),Ye=new Set;function Xe(){Ye.forEach(e=>e())}function y(e){v=e,qe(e),Xe()}function Ze(){return v}function Qe(e){return v[e]??null}function $e(e){return Ye.add(e),()=>{Ye.delete(e)}}function et(e,t){let n=v[e],r=Math.min((n?.consecutiveFailures??0)+1,5),i=n?.disabled===!0||r>=5,a={consecutiveFailures:r,lastError:Je(t),lastFailureAt:Date.now(),disabled:i};y({...v,[e]:a})}function tt(e){if(!(e in v))return;let{[e]:t,...n}=v;y(n)}function nt(e){if(!(e in v))return;let{[e]:t,...n}=v;y(n)}function rt(e){if(!(e in v))return;let{[e]:t,...n}=v;y(n)}var it=`workspace/project`,at=`__AGENT_CANVAS_LOCK_TO_CLOUD__`,ot=`all-hands.dev`,b=`openhands.dev`,st=`app.${ot}`,ct=b,lt=`app.${b}`;function ut(e){return e?.trim()||null}function dt(e){if(!e)return null;let t=e.trim().replace(/\/$/,``);return t?/^https?:\/\//i.test(t)?t:typeof window<`u`?`${window.location.protocol}//${t}`:`http://${t}`:null}function ft(e){if(!e)return null;let t=e.trim().replace(/\/+$/,``);return t?/^https?:\/\//i.test(t)?t:`https://${t}`:null}function pt(e){let t=e.toLowerCase();return t===st||t===lt?ct:t===ot?b:t.endsWith(`.${ot}`)?`${t.slice(0,-13)}${b}`:t}function mt(e){let t=ft(e);if(!t)return null;try{let e=new URL(t),n=e.port?`:${e.port}`:``;return`${e.protocol}//${pt(e.hostname)}${n}`}catch{return t.toLowerCase()}}function ht(){let e=yt();return!e||typeof window>`u`||!bt(window.location.origin,e)?null:window.location.origin}function gt(){return dt(void 0)}function _t(){let e=ut(void 0);if(e)return e;if(typeof window<`u`){let e=window.__AGENT_CANVAS_SESSION_API_KEY__;if(typeof e==`string`)return ut(e)}return null}function vt(){return{baseUrl:St()??``,sessionApiKey:x()??``}}function yt(){let e=ft(void 0);if(e)return e;if(typeof window<`u`){let e=window[at];if(typeof e==`string`)return ft(e)}return null}function bt(e,t){let n=mt(e),r=mt(t);return!n||!r?!1:n===r}function xt(){return ht()?`cookie`:`api-key`}function St(){return gt()||(typeof window<`u`?window.location.origin:null)}function x(){return _t()}function Ct(){return it}function wt(e){return`${Ct().replace(/\/+$/,``)}/${e.replace(/-/g,``)}`}function Tt(){let e=x();return e?{"X-Session-API-Key":e}:{}}function S(){return typeof window<`u`&&window.__AGENT_CANVAS_AUTH_REQUIRED__===!0}function Et(){return S()?!x():!1}var Dt=`default-local`,Ot=`Local`,kt=`locked-cloud`,At=`OpenHands Cloud`;function jt(){if(!yt())return null;let e=ht();return e?{id:kt,name:At,host:e,apiKey:``,kind:`cloud`,authMode:`cookie`}:null}function C(){if(yt())return null;let e=St(),t=x();return!e||!t?null:{id:Dt,name:Ot,host:e,apiKey:t,kind:`local`}}var Mt=`openhands-backends`,w=`openhands-active-backend`;function Nt(e){return e===`local`||e===`cloud`}function Pt(e){return e===void 0||e===`api-key`||e===`cookie`}function Ft(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.id==`string`&&t.id.length>0&&typeof t.name==`string`&&typeof t.host==`string`&&typeof t.apiKey==`string`&&Nt(t.kind)&&Pt(t.authMode)&&(t.connectionRevision===void 0||typeof t.connectionRevision==`number`&&Number.isSafeInteger(t.connectionRevision)&&t.connectionRevision>=0)}function It(e){try{let{hostname:t}=new URL(e);return t===`localhost`||t===`127.0.0.1`||t===`::1`||t===`[::1]`}catch{return!1}}function Lt(e,t){return e.id!==`default-local`||e.kind!==`local`?!1:e.host===t.host||It(e.host)&&It(t.host)}function Rt(e){let t=C();if(!t)return e;let n=!1,r=e.map(e=>!Lt(e,t)||e.apiKey===t.apiKey?e:(n=!0,{...e,apiKey:t.apiKey}));return n?(T(r),r):e}function T(e){if(!(typeof window>`u`))try{window.localStorage.setItem(Mt,JSON.stringify(e))}catch{}}function zt(){if(typeof window>`u`)return[];try{let e=jt();if(e)return T([e]),Wt()?.backendId!==e.id&&Gt({backendId:e.id}),[e];let t=window.localStorage.getItem(Mt);if(t===null){let e=C();return e?(T([e]),[e]):[]}let n=JSON.parse(t);if(!Array.isArray(n))return[];let r=n.filter(Ft);if(r.length===0){let e=C();return e?(T([e]),[e]):[]}return Rt(r)}catch{return[]}}function Bt(e){if(!e)return null;try{let t=JSON.parse(e);if(typeof t!=`object`||!t||typeof t.backendId!=`string`)return null;let n=t.orgId;return{backendId:t.backendId,orgId:typeof n==`string`&&n.length>0?n:null}}catch{return null}}function Vt(e,t){try{return e?.getItem(t)??null}catch{return null}}function Ht(e,t,n){try{e?.setItem(t,n)}catch{}}function Ut(e,t){try{e?.removeItem(t)}catch{}}function Wt(){return typeof window>`u`?null:Bt(Vt(window.sessionStorage,w))||Bt(Vt(window.localStorage,w))}function Gt(e){if(typeof window>`u`)return;if(!e){Ut(window.sessionStorage,w),Ut(window.localStorage,w);return}let t=JSON.stringify({backendId:e.backendId,orgId:e.orgId??null});Ht(window.sessionStorage,w,t),Ht(window.localStorage,w,t)}var Kt=`no-backend`,qt={id:Kt,name:`No Backend Available`,host:``,apiKey:``,kind:`local`};function Jt(e){return e.id===Kt}function Yt(e){return e.find(e=>e.kind===`local`&&Qe(e.id)?.disabled!==!0)||(e.find(e=>e.kind===`local`)??e[0]??qt)}function Xt(e,t){let n=null,r=null;if(t){let i=e.find(e=>e.id===t.backendId);i&&(n=i,r=t.orgId??null)}return n||(n=Yt(e),r=null),{backends:e,selection:t,active:{backend:n,orgId:r}}}var E=Xt(zt(),Wt()),Zt=new Set;function Qt(){Zt.forEach(e=>e())}function $t(){return E.active}function en(){let e=E.active.backend;return e.kind===`local`&&!Jt(e)?e:null}function D(){return E.backends}function tn(){return E.selection}function O(){return E}function nn(e){Gt(e),E=Xt(E.backends,e),Qt()}function rn(e){T(e);let t=E.selection;t&&!e.some(e=>e.id===t.backendId)&&(t=null,Gt(null)),E=Xt(e,t),Qt()}function an(e){return Zt.add(e),()=>{Zt.delete(e)}}var on=(e,t)=>{(e?.response?.status===401||e?.status===401)&&t.invalidateQueries({queryKey:[`user`,`authenticated`]})},sn=e=>{if(!(e instanceof ae)||e.response?.status!==401&&e.status!==401)return!1;let t=$t().backend;if(t.kind!==`cloud`)return!1;let n=e.config?.url;return!n||n.startsWith(t.host.replace(/\/+$/,``))},cn=new Set,ln=()=>{let e=new ne({queryCache:new o({onSuccess:(e,t)=>{let n=t.meta?.backendId??t.options.meta?.backendId;typeof n==`string`&&tt(n)},onError:(t,n)=>{if(n.queryKey[0]===`user`&&n.queryKey[1]===`authenticated`||on(t,e),!(n.meta?.disableToast??n.options.meta?.disableToast)&&!sn(t)){let e=Pe(t);cn.has(e||``)||(ze(e||p.t(l.ERROR$GENERIC)),cn.add(e||``),setTimeout(()=>{cn.delete(e||``)},3e3))}}}),mutationCache:new s({onError:(t,n,r,i)=>{on(t,e),!(i?.meta?.disableToast??i?.options.meta?.disableToast)&&!sn(t)&&ze(Pe(t)||p.t(l.ERROR$GENERIC))}})});return e},un=null,dn=null,fn=()=>(un||=ln(),un),pn=()=>dn??fn(),mn=e=>(dn=e??fn(),dn),hn=new Proxy({},{get:(e,t)=>{let n=pn(),r=Reflect.get(n,t,n);return typeof r==`function`?r.bind(n):r},set:(e,t,n)=>{let r=pn();return Reflect.set(r,t,n,r)}});function gn(e){if(e&&!e.startsWith(`/`))try{let t=new URL(e),n=t.hostname,r=window.location.hostname??window.location.host?.split(`:`)[0];return r&&(n===`localhost`||n===`127.0.0.1`)&&r!==`localhost`&&r!==`127.0.0.1`?`${r}:${t.port}`:t.host}catch{return window.location.host}return window.location.host}function _n(e){if(e&&!e.startsWith(`/`))try{return(new URL(e).pathname.split(`/api/conversations`)[0]||``).replace(/\/$/,``)}catch{return``}return``}function vn(e){let t=gn(e),n=_n(e),r=window.location.protocol===`https:`,i=yn(e)===`https:`;return`${r||i?`https:`:`http:`}//${t}${n}`}function yn(e){if(!e||e.startsWith(`/`))return null;try{return new URL(e).protocol}catch{return null}}function bn(e){let t=gn(e),n=_n(e),r=window.location.protocol===`https:`,i=yn(e)===`https:`;return`${r||i?`wss:`:`ws:`}//${t}${n}/sockets/bash-events`}function xn(e,t){if(!e)return null;let n=gn(t),r=_n(t),i=window.location.protocol===`https:`,a=yn(t)===`https:`;return`${i||a?`wss:`:`ws:`}//${n}${r}/sockets/events/${e}`}var Sn=class extends Error{constructor(){super(`No backend is configured.`),this.name=`NoBackendAvailableError`}};function Cn(e){return e.replace(/\/+$/,``)}function wn(e,t){return e.host?Cn(e.host):e.conversationUrl?Cn(vn(e.conversationUrl)):Cn(t?.host??``)}function Tn(e={}){let t=en();if(!t&&!e.host&&!e.conversationUrl)throw new Sn;let n=e.sessionApiKey??e.apiKey??t?.apiKey??void 0;return{host:wn(e,t),...n?{apiKey:n}:{},workingDir:e.workingDir??Ct(),...e.timeout===void 0?{}:{timeout:e.timeout}}}function En(e){let{host:t,apiKey:n,timeout:r}=Tn(e);return{baseUrl:t,...n?{apiKey:n}:{},timeout:r??6e4}}var Dn={_comment:`Single source of truth for version pins, ports, paths, and defaults shared across the npm and Docker install paths. Read by scripts/dev-safe.mjs, scripts/dev-with-automation.mjs, docker/entrypoint.sh (via generated defaults.env), and .github/workflows/docker.yml.`,versions:{agentServer:`1.39.1`,agentCanvas:`1.8.0`,automation:`1.5.0`},compatibility:{minimumAgentServer:`1.28.0`},constraints:{_comment:`Temporary upper bound on the agent-client-protocol (acp) transitive dependency. openhands-sdk 1.35.0 requires agent-client-protocol>=0.10.1 with no upper bound, but acp 0.11.0 reordered the ACP prompt() arguments and breaks the SDK's ACP client (a PromptRequest validation error surfaces as 'ACP error: 2 validation errors for PromptRequest'). Pin acp <0.11 until a fixed openhands-sdk ships. Consumed by scripts/dev-safe.mjs (agent-server uvx install) and .github/workflows/mock-llm-e2e.yml (mock ACP server venv).`,agentClientProtocol:`agent-client-protocol<0.11`},images:{agentServer:`ghcr.io/openhands/agent-server`,agentCanvas:`ghcr.io/openhands/agent-canvas`},ports:{agentServer:18e3,automation:18001,proxy:8e3},paths:{stateSubdir:`agent-canvas`,conversations:`agent-canvas/conversations`,bashEvents:`agent-canvas/bash_events`,automationDb:`automation/automations.db`,canvasBasePath:`/canvas`},packages:{agentServer:`openhands-agent-server`,automation:`openhands-automation`,tools:`openhands-tools`,workspace:`openhands-workspace`},telemetry:{posthogApiKey:`phc_kBtz5nKmxVRRQ7HtPwr2QX9eMC5j65zE86QKocVNwb4U`,posthogHost:`https://us.i.posthog.com`}},On=5e3,kn=`unknown`,k=Dn.compatibility.minimumAgentServer,An=`AGENT_SERVER_UNSUPPORTED_VERSION`,jn=`AGENT_SERVER_UNKNOWN_VERSION`,A=null,Mn=e=>Array.isArray(e?.usable_tools)?e.usable_tools:null,j=class extends Error{details;noBackendConfigured;constructor(e,t){let n=t?.noBackendConfigured??!1;super(n?`No agent server backend is configured yet. Add a backend to get started.`:`Could not connect to the configured agent server. Make sure it is running and reachable, then reload the page.`),this.name=`AgentServerUnavailableError`,this.details=e??null,this.noBackendConfigured=n}},Nn=e=>e instanceof j||typeof e==`object`&&!!e&&`name`in e&&e.name===`AgentServerUnavailableError`,Pn=class extends j{code=An;actualVersion;requiredVersion=k;constructor(e){let t=`Agent Canvas requires agent-server ${k} or newer; this backend is running ${e}. Please upgrade the agent-server backend.`;super(t),this.name=`AgentServerUnsupportedVersionError`,this.message=t,this.actualVersion=e}},Fn=class extends j{code=jn;actualVersion;requiredVersion=k;constructor(e){let t=`Could not determine this backend's agent-server version.${e?` It reported "${e}".`:``} Agent Canvas requires agent-server ${k} or newer, but this backend did not return a valid version from /server_info. Restart or rebuild the agent-server backend, then try again.`;super(t),this.name=`AgentServerUnknownVersionError`,this.message=t,this.actualVersion=e}},In=e=>S()&&N(e,401);function M(){A=null}function Ln(e){let t=Mn(A);return Array.isArray(t)?t.includes(e):!0}function Rn(e){return e instanceof Error&&e.name===`HttpError`&&`status`in e&&typeof e.status==`number`}function N(e,t){return Rn(e)&&e.status===t}function zn(e){return typeof e==`string`&&e.trim()||null}function Bn(e){return zn(e.sdk_version)}function Vn(e){return zn(e.version)??Bn(e)}function Hn(e){let t=Vn(e);return!t||t.toLowerCase()===kn?null:t}function Un(e){let t=Hn(e);return!t||!Kn(t)?null:t}function Wn(e){return!A||e&&en()?.host!==e?null:Un(A)}function Gn(e,t){let n=Kn(e),r=Kn(t);if(!n||!r)return null;for(let e of[`major`,`minor`,`patch`]){if(n[e]>r[e])return 1;if(n[e]<r[e])return-1}return n.prerelease&&!r.prerelease?-1:!n.prerelease&&r.prerelease?1:n.prerelease&&r.prerelease?n.prerelease.localeCompare(r.prerelease):0}function Kn(e){let[t]=e.trim().replace(/^v/,``).split(`+`),[n,r]=t.split(`-`,2),i=n.split(`.`);if(i.length!==3)return null;let[a,o,s]=i.map(e=>Number(e));return[a,o,s].every(e=>Number.isInteger(e)&&e>=0)?{major:a,minor:o,patch:s,prerelease:r}:null}function qn(e){let t=Hn(e);if(!t)throw M(),new Fn(Vn(e));let n=Gn(t,k);if(n===null)throw M(),new Fn(t);if(n<0)throw M(),new Pn(t)}async function Jn(){let e=en();if(!e){if(M(),Jt($t().backend))throw new j(`No backend configured`,{noBackendConfigured:!0});return null}let t=Tn({host:e.host,sessionApiKey:e.apiKey||null,timeout:On}),n;try{n=await new oe(t).getServerInfo()}catch(e){throw M(),N(e,401)?e:new j(e instanceof Error?e.message:null)}if(qn(n),S())try{await new ie(t).getSettings()}catch(e){if(N(e,401))throw e;console.warn(`[agent-server] getSettings() probe failed (non-401):`,e)}return A=n,n}var Yn={WEB_CLIENT_CONFIG:[`web-client-config`],MAIN_APP_COOKIE_AUTH:[`main-app-cookie-auth`]},Xn={all:[`settings`],byScope:e=>[`settings`,e],personal:()=>[`settings`,`personal`]},Zn={all:[`llm-profiles`]},Qn={all:[`agent-profiles`]},$n={retry:!1},er={all:[`llm-subscription`],openaiStatus:[`llm-subscription`,`openai`,`status`],openaiModels:[`llm-subscription`,`openai`,`models`]},tr={all:[`local-workspaces`]},nr={marketplace:[`plugins-marketplace`],installed:[`plugins-installed`],local:[`plugins-local`]},rr={latestVersion:[`agent-canvas-latest-version`]},ir={staleTime:1e3*60*5,gcTime:1e3*60*15},ar={name:`@openhands/agent-canvas`,version:`1.8.0`,description:`Agent Canvas UI for OpenHands - run AI coding agents with a visual interface`,license:`MIT`,private:!1,type:`module`,repository:{type:`git`,url:`https://github.com/OpenHands/OpenHands`},homepage:`https://github.com/OpenHands/OpenHands#readme`,bugs:{url:`https://github.com/OpenHands/OpenHands/issues`},bin:{"agent-canvas":`bin/agent-canvas.mjs`},engines:{node:`>=22.12.0`},dependencies:{"@heroui/react":`2.8.10`,"@microlink/react-json-view":`1.31.20`,"@monaco-editor/react":`4.7.0`,"@openhands/extensions":`0.11.0`,"@openhands/typescript-client":`1.36.1`,"@react-router/node":`7.17.0`,"@react-router/serve":`7.17.0`,"@tailwindcss/vite":`4.2.4`,"@tanstack/react-query":`5.100.9`,"@types/shell-quote":`1.7.5`,"@uidotdev/usehooks":`2.4.1`,"@xterm/addon-fit":`0.11.0`,"@xterm/xterm":`6.0.0`,axios:`1.18.0`,"class-variance-authority":`0.7.1`,clsx:`2.1.1`,downshift:`9.3.2`,"framer-motion":`12.38.0`,httpxy:`0.5.3`,i18next:`26.0.8`,"i18next-browser-languagedetector":`8.2.1`,"i18next-http-backend":`4.0.0`,isbot:`5.1.39`,"lucide-react":`1.25.0`,"monaco-editor":`0.55.1`,"posthog-js":`1.372.6`,react:`19.2.5`,"react-dom":`19.2.5`,"react-hot-toast":`2.6.0`,"react-i18next":`17.0.6`,"react-icons":`5.6.0`,"react-markdown":`10.1.0`,"react-router":`7.17.0`,"react-syntax-highlighter":`16.1.1`,"rehype-raw":`7.0.0`,"rehype-sanitize":`6.0.0`,"remark-breaks":`4.0.0`,"remark-gfm":`4.0.1`,"shell-quote":`1.9.0`,sirv:`3.0.2`,"sirv-cli":`3.0.1`,"socket.io-client":`4.8.3`,"tailwind-merge":`3.5.0`,"tailwind-scrollbar":`4.0.2`,"unist-util-visit":`5.1.0`,uuid:`14.0.0`,vite:`8.0.16`,winston:`3.19.0`,"winston-daily-rotate-file":`5.0.0`,zustand:`5.0.12`},scripts:{dev:`node --env-file-if-exists=.env scripts/dev-with-automation.mjs`,"dev:static":`node --env-file-if-exists=.env scripts/dev-static.mjs`,"dev:extra-backend":`node --env-file-if-exists=.env scripts/dev-extra-backend.mjs`,"dev:minimal":`node --env-file-if-exists=.env scripts/dev-safe.mjs`,"dev:frontend":`npm run make-i18n && cross-env VITE_MOCK_API=false react-router dev`,"dev:mock":`npm run make-i18n && cross-env VITE_MOCK_API=true react-router dev`,build:`npm run build:app`,"build:mock":`npm run make-i18n && cross-env VITE_MOCK_API=true react-router build`,start:`npx sirv-cli build/ --single`,test:`npm run make-i18n && vitest run`,"test:e2e":`playwright test --pass-with-no-tests`,"test:e2e:live":`node --env-file-if-exists=.env tests/e2e/live/scripts/run-live-e2e.mjs`,"test:e2e:mock-llm":`playwright test --config=playwright.mock-llm.config.ts`,"test:e2e:mock-llm:docker":`playwright test --config=playwright.mock-llm-docker.config.ts`,"test:coverage":`npm run make-i18n && vitest run --coverage`,"test:mutation":`npm run make-i18n && stryker run`,"test:mutation:diff":`npm run make-i18n && node scripts/stryker-diff.mjs`,"test:mutation:incremental":`npm run make-i18n && stryker run --incremental`,dev_wsl:`VITE_WATCH_USE_POLLING=true vite`,preview:`vite preview`,"make-i18n":`node scripts/make-i18n-translations.cjs`,prelint:`npm run make-i18n`,lint:`npm run typecheck && eslint src && prettier --check src/**/*.{ts,tsx}`,"lint:fix":`eslint src --fix && prettier --write src/**/*.{ts,tsx}`,prepare:`husky`,typecheck:`react-router typegen && tsc`,"typecheck:staged":`react-router typegen && npx tsc --noEmit --skipLibCheck`,"check-translation-completeness":`node scripts/check-translation-completeness.cjs`,"build:app":`npm run make-i18n && react-router build`,"build:lib":`npm run make-i18n && react-router typegen && cross-env BUILD_LIB=true vite build && tsc -p tsconfig.lib.json`,"build:docker":`node scripts/docker-build.mjs`,"example:acp-docker:env":`node scripts/gen-acp-docker-env.mjs`,desktop:`npm run build:app && electron electron/main.mjs`,"build:desktop":`npm run build:app && node scripts/download-uv.mjs && node scripts/download-node.mjs && electron-builder --config electron-builder.config.mjs --publish never`,"build:desktop:universal":`npm run build:app && node scripts/download-uv.mjs && node scripts/download-node.mjs && cross-env ELECTRON_ARCH=universal electron-builder --config electron-builder.config.mjs --publish never`,"download-uv":`node scripts/download-uv.mjs`,"download-node":`node scripts/download-node.mjs`},"lint-staged":{"src/**/*.{ts,tsx,js}":[`eslint --fix`,`prettier --write`],"src/**/*.{ts,tsx}":[`node scripts/run-staged-typecheck.mjs`],"src/**/*":[`npm run check-translation-completeness`]},devDependencies:{"@eslint/eslintrc":`3.3.1`,"@eslint/js":`9.39.4`,"@mswjs/socket.io-binding":`0.2.0`,"@playwright/test":`1.59.1`,"@react-router/dev":`7.17.0`,"@stryker-mutator/core":`9.6.1`,"@stryker-mutator/vitest-runner":`9.6.1`,"@tailwindcss/typography":`0.5.19`,"@tanstack/eslint-plugin-query":`5.100.9`,"@testing-library/dom":`10.4.1`,"@testing-library/jest-dom":`6.9.1`,"@testing-library/react":`16.3.2`,"@testing-library/user-event":`14.6.1`,"@types/mdast":`4.0.4`,"@types/node":`25.6.0`,"@types/react":`19.2.14`,"@types/react-dom":`19.2.3`,"@types/react-syntax-highlighter":`15.5.13`,"@typescript-eslint/eslint-plugin":`8.59.2`,"@typescript-eslint/parser":`8.59.2`,"@vercel/react-router":`1.3.0`,"@vitest/coverage-v8":`4.1.5`,"cross-env":`10.1.0`,electron:`42.3.3`,"electron-builder":`26.8.1`,eslint:`9.39.4`,"eslint-config-prettier":`10.1.8`,"eslint-import-resolver-typescript":`4.4.4`,"eslint-plugin-i18next":`6.1.4`,"eslint-plugin-import-x":`4.16.2`,"eslint-plugin-jsx-a11y":`6.10.2`,"eslint-plugin-prettier":`5.5.5`,"eslint-plugin-react":`7.37.5`,"eslint-plugin-react-hooks":`7.1.1`,"eslint-plugin-unused-imports":`4.4.1`,globals:`16.5.0`,husky:`9.1.7`,jsdom:`29.1.1`,"lint-staged":`16.4.0`,msw:`2.14.2`,"postcss-prefix-selector":`2.1.1`,prettier:`3.8.3`,tailwindcss:`4.2.4`,typescript:`6.0.3`,"vite-plugin-svgr":`5.2.0`,vitest:`4.1.5`},packageManager:`npm@10.5.0`,volta:{node:`22.12.0`},msw:{workerDirectory:[`public`]},overrides:{"@vercel/static-config":{ajv:`8.20.0`},dompurify:`3.4.7`},main:`./dist/index.cjs`,module:`./dist/index.js`,types:`./dist/index.d.ts`,files:[`dist`,`bin`,`build`,`config`,`scripts`,`tools`],exports:{".":{types:`./dist/index.d.ts`,import:`./dist/index.js`,require:`./dist/index.cjs`},"./browser":{types:`./dist/components/browser/index.d.ts`,import:`./dist/components/browser/index.js`,require:`./dist/components/browser/index.cjs`},"./conversation":{types:`./dist/components/conversation/index.d.ts`,import:`./dist/components/conversation/index.js`,require:`./dist/components/conversation/index.cjs`},"./files":{types:`./dist/components/files/index.d.ts`,import:`./dist/components/files/index.js`,require:`./dist/components/files/index.cjs`},"./settings":{types:`./dist/components/settings/index.d.ts`,import:`./dist/components/settings/index.js`,require:`./dist/components/settings/index.cjs`},"./sidebar":{types:`./dist/components/sidebar/index.d.ts`,import:`./dist/components/sidebar/index.js`,require:`./dist/components/sidebar/index.cjs`},"./terminal":{types:`./dist/components/terminal/index.d.ts`,import:`./dist/components/terminal/index.js`,require:`./dist/components/terminal/index.cjs`},"./i18n":{types:`./dist/i18n/index.d.ts`,import:`./dist/i18n/index.js`,require:`./dist/i18n/index.cjs`},"./package.json":`./package.json`},peerDependencies:{react:`19.2.5`,"react-dom":`19.2.5`,"react-router":`7.17.0`}},or=`agent_canvas`,sr=ar.version,cr=`X-OpenHands-Client`,lr=`X-OpenHands-Client-Version`,ur=`X-OpenHands-Telemetry-Distinct-Id`,dr={[cr]:or,[lr]:sr};function fr(e){return e?.trim()||`unknown`}function pr(e){return e?.trim()||null}function P({backendKind:e,agentServerVersion:t,automationSdkVersion:n,backendVersion:r,connectionMethod:i}){let a=fr(t??r),o=fr(n),s=fr(r??t);return{backend_kind:e??null,agent_server_version:a,automation_sdk_version:o,backend_version:s,...i?{connection_method:i}:{}}}function mr(e=null){return{cloud_user_id:pr(e?.userId),cloud_user_email:pr(e?.email),cloud_org_id:pr(e?.orgId)}}var F=`openhands-telemetry-consent`,I=`openhands-telemetry-consent-pending-cloud-sync`,L=`openhands-telemetry-consent-pending-local-revocation`,hr=`openhands-telemetry-consent-change`,gr=`openhands-telemetry-first-use`,_r=`openhands-telemetry-session`,vr=`agent-canvas`,yr=`history_change`,br=`phc_BgzfxKdgsYMLFTmJqt424ZoyVHvKFfrwttLimzdYTKFK`,xr=`https://z.openhands.dev`,Sr=`https://us.posthog.com`,R=null,z=null,Cr,B={},V=!1,H,U=0,W=-1,wr=Object.freeze({client_source:or,client_version:sr,package_name:ar.name,package_version:ar.version}),Tr=P({}),Er=mr();function Dr(e){Tr=P(e)}function G(e){Er=mr(e)}function Or(e){return e?{...e,properties:{...Tr,...Er,...e.properties,...wr}}:null}function kr(e){V||X()!==`granted`?e.opt_out_capturing():e.opt_in_capturing()}function Ar(e,t=!1){e.reset(t),W=-1,kr(e)}function K(e){if(H===void 0||!$())return;let t=H?.distinctId,n=e.get_property(`$user_id`);if(n!=null&&n!==t&&Ar(e),H===null){W=U;return}(e.get_property(`$user_id`)!==H.distinctId||W!==U)&&(e.identify(H.distinctId,H.properties),W=U)}function jr(e,t){let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>e[n]===t[n])}function Mr(e){if(e===!1){if(V)return;V=!0,R?.opt_out_capturing(),Z();return}let t=V;if(V=!1,!R&&!z){let t=Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0));B={...B,...t}}t&&(R&&(kr(R),K(R)),Z())}function Nr(){return V?null:{apiKey:B.apiKey||br,apiHost:B.apiHost||xr,uiHost:B.uiHost||Sr}}function q(){return typeof window<`u`&&typeof localStorage<`u`}async function Pr(){if(!q())return null;if(R)return R;try{let{default:e}=await n(async()=>{let{default:e}=await import(`./vendor~module-BZXjBMvd.js`).then(e=>e.t);return{default:e}},__vite__mapDeps([0,1]));return e}catch{return null}}function J(){return!!(V||typeof process<`u`&&{}.DO_NOT_TRACK===`1`||typeof navigator<`u`&&(navigator.doNotTrack===`1`||typeof window<`u`&&window.doNotTrack===`1`))}function Fr(e){R||(Cr=e)}async function Y(e=!1){if(R)return R;if(z)return z;z=(async()=>{let t=Nr();if(!t)return null;let n=await Pr();if(!n)return null;let r=n.init(t.apiKey,{api_host:t.apiHost,ui_host:t.uiHost,opt_out_capturing_by_default:!e,persistence:`localStorage`,persistence_name:vr,consent_persistence_name:`${vr}-consent`,person_profiles:`always`,capture_pageview:yr,autocapture:!0,disable_session_recording:!0,bootstrap:Cr,before_send:Or},vr);return r?(R=r,Cr=void 0,V?R.opt_out_capturing():X()===`granted`?(R.opt_in_capturing(),K(R)):e||R.opt_out_capturing(),R):null})();try{return await z}finally{R||(z=null)}}function X(){if(!q())return`pending`;if(J())return`denied`;if(xt()===`cookie`)return`granted`;try{let e=localStorage.getItem(F);if(e===`granted`||e===`denied`)return e}catch{}return`pending`}function Ir(){if(!q())return null;try{let e=localStorage.getItem(I);return e===`granted`||e===`denied`?e:null}catch{return null}}function Lr(){if(!q())return null;try{return localStorage.getItem(L)}catch{return null}}function Rr(e){if(!q())return()=>{};let t=t=>{(t.key===F||t.key===I)&&e()};return window.addEventListener(hr,e),window.addEventListener(`storage`,t),()=>{window.removeEventListener(hr,e),window.removeEventListener(`storage`,t)}}function Z(){q()&&window.dispatchEvent(new Event(hr))}function zr(e){if(q())try{localStorage.setItem(I,e)}catch{}}function Br(e){if(!(!q()||!e))try{localStorage.setItem(L,e)}catch{}}function Vr(e){if(q())try{if(localStorage.getItem(L)!==e)return;localStorage.removeItem(L)}catch{}}function Hr(e){if(q())try{if(e!==void 0&&localStorage.getItem(I)!==e)return;localStorage.removeItem(I),Z()}catch{}}async function Ur(e,{syncToCloud:t=!0}={}){if(q())try{let t=X()===e;if(localStorage.setItem(F,e),V||t)return;let n=R??await Y();if(!n)return;e===`granted`?(n.opt_in_capturing(),K(n)):(Br(n.get_distinct_id?.()??null),n.get_property?.(`$user_id`)==null?n.opt_out_capturing():Ar(n))}catch{}finally{t&&zr(e),Z()}}async function Q(e,t={}){let n=e===null?null:{distinctId:e,properties:t};if(H===n||H!=null&&n!==null&&H.distinctId===n.distinctId&&jr(H.properties,t)||(H=n,U+=1,W=-1,!$()))return;let r=R??await Y();r&&$()&&K(r)}function $(){return X()===`granted`}function Wr(){if(!q())return!1;try{return localStorage.getItem(gr)===`true`}catch{return!1}}function Gr(){if(q())try{localStorage.setItem(gr,`true`)}catch{}}async function Kr(){if(J()||Wr())return;let e=await Y(!0);!e||J()||((e.has_opted_out_capturing?.()??!1)&&e.opt_in_capturing(),e.capture(`canvas_install`,{platform:typeof navigator<`u`?navigator.platform:`unknown`,user_agent:typeof navigator<`u`?navigator.userAgent:`unknown`,referrer:typeof document<`u`?document.referrer:``,url_origin:typeof window<`u`?window.location.origin:``,embedded:typeof window<`u`&&window.self!==window.top}),Gr(),X()!==`granted`&&e.opt_out_capturing())}function qr(){if(!q())return!1;try{return sessionStorage.getItem(_r)===`true`}catch{return!1}}function Jr(){if(q())try{sessionStorage.setItem(_r,`true`)}catch{}}async function Yr(){if(!$()||X()!==`granted`)return null;let e=await Y();return!e||!$()?null:(e.has_opted_out_capturing?.()&&e.opt_in_capturing(),K(e),e)}async function Xr(){if(qr())return;let e=await Yr();e&&(e.capture(`canvas_new_session`,{is_first_use:!Wr()}),Jr())}async function Zr(){return(await Yr())?.get_distinct_id?.()??null}async function Qr(){if(!q())return null;if(X()!==`granted`){let e=Lr();if(e)return e}return V||J()?null:(await Y())?.get_distinct_id?.()??null}async function $r(e,t={}){let n=await Yr();n&&n.capture(e,t)}async function ei(e,t={}){let n=await Yr();n&&n.captureException(e,t)}async function ti(){if(q()){try{Br(R?.get_distinct_id?.()??null),localStorage.removeItem(F),localStorage.removeItem(gr)}catch{}Hr();try{sessionStorage.removeItem(_r)}catch{}Tr=P({}),Er=mr(),H=null,U+=1,W=-1;try{R&&Ar(R,!0)}catch{try{R?.opt_out_capturing()}catch{}}finally{Z()}}}var ni=u.createContext(null);function ri(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():`backend-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function ii(e,t){let n=e.backend.kind===`cloud`,r=t.backend.kind===`cloud`;!n&&!r||(G(null),r&&(!n||e.backend.id!==t.backend.id)&&Q(null))}function ai({children:e}){let t=u.useSyncExternalStore(an,O,O),n=u.useCallback(()=>{M(),hn.invalidateQueries({queryKey:Yn.WEB_CLIENT_CONFIG})},[]),r=u.useCallback((e,t)=>{let r=O(),i=tn()?.backendId??null,a=tn()?.orgId??null,o=t??null;if(e===i&&o===a)return;let s=D(),ee=s.find(t=>t.id===e),te={backend:ee??s[0]??qt,orgId:ee?o:null};ii(r.active,te),nn({backendId:e,orgId:o}),n()},[n]),i=u.useCallback(e=>{let t=O().active,r={...e,id:ri()},i=[...D(),r];return ii(t,{backend:r,orgId:null}),rn(i),nn({backendId:r.id}),n(),r},[n]),a=u.useCallback((e,t)=>{let r=D().find(t=>t.id===e),i=O().active.backend.id,a=t.host!==void 0&&r!==void 0&&t.host!==r.host,o=t.apiKey!==void 0&&r!==void 0&&t.apiKey!==r.apiKey;rn(D().map(n=>n.id===e?{...n,...t,connectionRevision:a||o?(n.connectionRevision??0)+1:n.connectionRevision}:n)),(a||o)&&(nt(e),i===e&&(r?.kind===`cloud`&&(G(null),Q(null)),n()))},[n]),o=u.useCallback(e=>{let t=D().find(t=>t.id===e),r=t?.kind===`cloud`&&O().active.backend.id===t.id;rn(D().filter(t=>t.id!==e)),r&&(G(null),Q(null)),rt(e),n()},[n]),s=u.useMemo(()=>({backends:t.backends,active:t.active,setActive:r,addBackend:i,updateBackend:a,removeBackend:o}),[t,r,i,a,o]);return(0,g.jsx)(ni.Provider,{value:s,children:e})}function oi(){let e=u.useContext(ni);if(!e)throw Error(`useActiveBackendContext must be used inside <ActiveBackendProvider>`);return e}function si(){let e=u.useContext(ni);return e?e.active:{backend:C()??qt,orgId:null}}export{bn as $,$n as A,He as At,M as B,p as Bt,Xr as C,et as Ct,sr as D,ze as Dt,or as E,_ as Et,tr as F,m as Ft,Ln as G,Wn as H,xe as Ht,nr as I,pe as It,N as J,Nn as K,Yn as L,d as Lt,ir as M,Me as Mt,Zn as N,je as Nt,ur as O,Be as Ot,er as P,Ae as Pt,En as Q,Xn as R,f as Rt,Kr as S,Ze as St,dr as T,$e as Tt,Un as U,fe as Ut,Gn as V,be as Vt,In as W,Sn as X,Jn as Y,Tn as Z,Ur as _,xt as _t,Vr as a,mn as at,$r as b,Et as bt,Mr as c,D as ct,X as d,it as dt,vn as et,Zr as f,wt as ft,G as g,Ct as gt,Dr as h,Tt as ht,Hr as i,hn as it,rr as j,Pe as jt,Qn as k,Ve as kt,Ir as l,Jt as lt,Y as m,vt as mt,si as n,fn as nt,ti as o,$t as ot,Qr as p,St as pt,Rn as q,oi as r,pn as rt,Fr as s,en as st,ai as t,xn as tt,Lr as u,Ot as ut,Q as v,yt as vt,P as w,tt as wt,ei as x,bt as xt,Rr as y,S as yt,qn as z,ye as zt};
@@ -1 +0,0 @@
1
- import{yt as e}from"./vendor-styling-Bcgpimp9.js";import{U as t}from"./vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f9xdmd0z-DLMP7bZx.js";import{t as n}from"./sdk-section-page-D0K1dBQY.js";var r=e();function i(){return(0,r.jsx)(n,{settingsSources:[{settingsSource:`agent_settings`,sectionKeys:[`agent_context`]}],testId:`agent-context-settings-screen`})}var a=t(i);export{a as default};
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-Cyuzqnbw.js";import{St as t,bt as n,yt as r}from"./vendor-styling-Bcgpimp9.js";import{U as i}from"./vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f9xdmd0z-DLMP7bZx.js";import{n as a}from"./vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f1hl7voa-BrmgjeOw.js";import{t as o}from"./vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hakxo2tj-ClV0p9g3.js";import{t as s}from"./useMutation-DHLpZ6J0.js";import{Dt as c,Ot as l,jt as u,k as d}from"./active-backend-context-mY7Gff5c.js";import{t as f,z as p}from"./utils-DsWhWn2F.js";import{t as m}from"./back-nav-button-C02hGa8t.js";import{t as h}from"./loading-spinner-DRFyh6Iy.js";import{t as g}from"./brand-button-BUlDL-mz.js";import{i as _}from"./dropdown-classes-CqA2BTCL.js";import{t as v}from"./use-llm-profiles-CdaxVpyY.js";import{n as y,t as b}from"./use-agent-profiles-DmT9zxAN.js";import{i as x,n as S,t as C}from"./use-can-manage-org-profiles-vBiP7rHF.js";import{t as w}from"./u-edit-809W9D9T.js";import{t as T}from"./settings-dropdown-input-jOiv5Yrk.js";import{r as E}from"./typography-B1UxuuEC.js";import{o as D}from"./extension-module-card-classes-Bo43vY5V.js";import{i as O,n as k,o as A,r as j,t as M}from"./badge-CzXbf7tR.js";import{t as N}from"./u-check-circle-DBEvndTS.js";import{i as P,n as F,r as I,t as L}from"./settings-list-classes-VqMzkYYt.js";import{n as R}from"./settings-section-header-context-CnIIQAUn.js";import{t as z}from"./use-save-agent-profile-DGJ3-u0M.js";import{n as B}from"./use-activate-agent-profile-DCRf47e-.js";import{t as V}from"./merge-agent-profile-save-input-WcFmQVKK.js";import{i as H,t as U}from"./agent-settings-BGTyoT6X.js";var W=e(t(),1),G=e(n(),1),K=r();function q({onEdit:e,onSetActive:t,onDelete:n,isActive:r,isActivating:i,onClose:a,anchorRef:s}){let{t:c}=o(`openhands`),l=(0,W.useRef)(null),u=(0,W.useRef)([]),d=s?.current??null,[m,h]=(0,W.useState)();(0,W.useLayoutEffect)(()=>{if(!d)return;let e=()=>{let e=d.getBoundingClientRect();e&&h({position:`fixed`,zIndex:9999,top:e.bottom+8,right:window.innerWidth-e.right,width:`max-content`})};return e(),window.addEventListener(`resize`,e),window.addEventListener(`scroll`,e,!0),()=>{window.removeEventListener(`resize`,e),window.removeEventListener(`scroll`,e,!0)}},[d]),(0,W.useEffect)(()=>{u.current[0]?.focus()},[]),(0,W.useEffect)(()=>{let e=e=>{let t=e.target;l.current&&!l.current.contains(t)&&a()},t=e=>{e.key===`Escape`&&a()};return document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[a]);let g=e=>{e(),a()},v=(0,W.useCallback)((e,t)=>{if(e.key===`Tab`){a();return}let n=u.current.filter(Boolean).length;if(e.key===`ArrowDown`){e.preventDefault();let r=(t+1)%n;u.current[r]?.focus()}else if(e.key===`ArrowUp`){e.preventDefault();let r=(t-1+n)%n;u.current[r]?.focus()}},[a]),y=r||i,b=!!d,S=(0,K.jsxs)(`div`,{ref:l,className:f(`absolute right-0 top-full z-10 mt-2 w-[160px] rounded-md border border-[var(--oh-border-subtle)] bg-tertiary px-1 py-1 shadow-lg`,_,b&&`!static !top-auto !bottom-auto !left-auto !right-auto !mt-0`),role:`menu`,"aria-orientation":`vertical`,"data-testid":`agent-profile-actions-menu`,children:[(0,K.jsx)(k,{index:0,icon:(0,K.jsx)(w,{width:16,height:16}),label:c(p.SETTINGS$PROFILE_EDIT),onClick:()=>g(e),onKeyDown:v,menuItemsRef:u,testId:`agent-profile-edit`}),(0,K.jsx)(k,{index:1,icon:(0,K.jsx)(N,{width:16,height:16}),label:c(p.SETTINGS$PROFILE_SET_ACTIVE),onClick:()=>g(t),onKeyDown:v,menuItemsRef:u,disabled:y,testId:`agent-profile-set-active`}),(0,K.jsx)(k,{index:2,icon:(0,K.jsx)(x,{width:16,height:16}),label:c(p.BUTTON$DELETE),onClick:()=>g(n),onKeyDown:v,menuItemsRef:u,testId:`agent-profile-delete`})]});return b?typeof document>`u`||!m?null:G.createPortal((0,K.jsx)(`div`,{style:m,children:S}),document.body):S}function J({profile:e,isActive:t,canManage:n,onActivate:r,onEdit:i,onDelete:a,isActivating:s}){let{t:c}=o(`openhands`),[l,u]=(0,W.useState)(!1),d=(0,W.useRef)(null),m=e.agent_kind===`openhands`?e.llm_profile_ref:c(p.SETTINGS$AGENT_TYPE_ACP);return(0,K.jsxs)(`div`,{"data-testid":`agent-profile-row`,className:f(P,`justify-between gap-3`),children:[(0,K.jsxs)(`div`,{className:`flex min-w-0 flex-1 items-center gap-3`,children:[(0,K.jsx)(`span`,{className:`min-w-0 max-w-full truncate text-sm font-medium text-white`,title:e.name,children:e.name}),m?(0,K.jsx)(`span`,{className:`min-w-0 max-w-full truncate text-sm text-[var(--oh-muted)]`,title:m,children:m}):null,t&&(0,K.jsx)(M,{className:`shrink-0 whitespace-nowrap px-2.5 py-1 text-xs`,"data-testid":`agent-profile-active-badge`,children:c(p.SETTINGS$PROFILE_ACTIVE)})]}),n&&(0,K.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,K.jsx)(S,{ref:d,onClick:()=>u(e=>!e),ariaLabel:c(p.SETTINGS$PROFILE_MENU),testId:`agent-profile-menu-trigger`,className:I}),l&&(0,K.jsx)(q,{anchorRef:d,onEdit:()=>i(e),onSetActive:()=>r(e),onDelete:()=>a(e),isActive:t,isActivating:s,onClose:()=>u(!1)})]})]})}function Y({isLoading:e,loadError:t,profiles:n,activeId:r,canManage:i,onActivate:a,onEdit:s,onDelete:c,isActivating:l}){let{t:u}=o(`openhands`);return e?(0,K.jsx)(`div`,{className:`flex justify-center p-4`,children:(0,K.jsx)(h,{size:`large`})}):t?(0,K.jsx)(`div`,{"data-testid":`agent-profiles-load-error`,className:D,children:(0,K.jsx)(`p`,{className:`text-sm text-red-400`,children:u(p.SETTINGS$PROFILES_LOAD_ERROR)})}):n.length===0?(0,K.jsx)(`div`,{"data-testid":`agent-profiles-empty`,className:D,children:(0,K.jsx)(`p`,{className:`text-sm text-[var(--oh-muted)]`,children:u(p.SETTINGS$PROFILES_EMPTY)})}):(0,K.jsx)(`div`,{className:f(L,F),children:n.map(e=>(0,K.jsx)(J,{profile:e,isActive:!!e.id&&e.id===r,canManage:i,onActivate:a,onEdit:s,onDelete:c,isActivating:l},e.name))})}function X(){let e=a();return s({mutationFn:e=>y.deleteProfile(e),onSuccess:async()=>{await e.invalidateQueries({queryKey:d.all})},meta:{disableToast:!0}})}function Z({profile:e,onClose:t}){let{t:n}=o(`openhands`),r=X(),i=(0,W.useRef)(null);if(!e)return null;let a=async()=>{try{await r.mutateAsync(e.name),l(n(p.SETTINGS$PROFILE_DELETED,{name:e.name})),t()}catch(e){c(e instanceof Error?e.message:n(p.ERROR$GENERIC))}},s=()=>{r.isPending||t()},u=(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(g,{ref:i,type:`button`,variant:`tertiary`,onClick:s,isDisabled:r.isPending,children:n(p.BUTTON$CANCEL)}),(0,K.jsx)(g,{testId:`delete-agent-profile-confirm`,type:`button`,variant:`danger`,onClick:a,isDisabled:r.isPending,"aria-busy":r.isPending,children:r.isPending?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(h,{size:`small`}),(0,K.jsx)(`span`,{className:`sr-only`,children:n(p.BUTTON$DELETE)})]}):n(p.BUTTON$DELETE)})]});return(0,K.jsx)(j,{isOpen:!0,title:n(p.SETTINGS$PROFILE_DELETE_TITLE),footer:u,onClose:s,initialFocusRef:i,children:(0,K.jsx)(`p`,{className:`text-sm break-all`,children:n(p.SETTINGS$PROFILE_DELETE_CONFIRMATION,{name:e.name})})})}function Q({onAddProfile:e,onEditProfile:t}){let{t:n}=o(`openhands`),{data:r,isLoading:i,error:a}=b(),s=B(),c=C(),[u,d]=(0,W.useState)(null),f=r?.profiles??[],m=r?.active_agent_profile_id??null;return(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,K.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,K.jsx)(`h2`,{className:`text-base font-medium text-white`,children:n(p.SETTINGS$AVAILABLE_PROFILES)}),e&&c?(0,K.jsx)(g,{testId:`add-agent-profile`,type:`button`,variant:`secondary`,className:`ml-auto`,onClick:e,children:n(p.SETTINGS$ADD_AGENT_PROFILE)}):null]}),(0,K.jsx)(Y,{isLoading:i,loadError:a??null,profiles:f,activeId:m,canManage:c,onActivate:async e=>{if(e.id)try{await s.mutateAsync(e.id),l(n(p.SETTINGS$PROFILE_ACTIVATED,{name:e.name}))}catch(e){console.error(`Failed to activate agent profile:`,e)}},onEdit:e=>t?.(e),onDelete:d,isActivating:s.isPending})]}),(0,K.jsx)(Z,{profile:u,onClose:()=>d(null)})]})}function $(){let e=a();return s({mutationFn:({name:e,newName:t})=>y.renameProfile(e,t),onSuccess:async()=>{await e.invalidateQueries({queryKey:d.all})},meta:{disableToast:!0}})}function ee(e){return e.agent_kind===`acp`?{agent_kind:`acp`,acp_server:e.acp_server,acp_command:e.acp_command?H(e.acp_command):[],acp_args:e.acp_args??[],acp_model:e.acp_model??``}:{agent_kind:`openhands`,enable_sub_agents:e.enable_sub_agents,tool_concurrency_limit:e.tool_concurrency_limit}}function te(){let{t:e}=o(`openhands`),{setHideSectionHeader:t}=R(),n=z(),r=$(),{data:i}=b(),{data:a,isLoading:s}=v(),[d,f]=(0,W.useState)(`list`),[h,_]=(0,W.useState)(``),[x,S]=(0,W.useState)(null),[C,w]=(0,W.useState)(null),[D,k]=(0,W.useState)(``),[j,M]=(0,W.useState)(null),[N,P]=(0,W.useState)(!1);(0,W.useEffect)(()=>(t(d!==`list`),()=>t(!1)),[d,t]);let F=a?.profiles??[],I=a?.active_profile??F[0]?.name??``,L=(0,W.useMemo)(()=>new Set(i?.profiles?.map(e=>e.name)??[]),[i]),B=(0,W.useMemo)(()=>!(!A(h,{isRequired:!0})||d===`create`&&L.has(h)||d===`edit`&&h!==x?.name&&L.has(h)),[h,d,L,x?.name]),H=(0,W.useCallback)(()=>{_(``),S(null),w({agent_kind:`openhands`}),k(I),M(null),f(`create`)},[I]),G=(0,W.useCallback)(async t=>{try{let e=(await y.getProfile(t.name,`encrypted`)).profile;S(e),w(ee(e)),e.agent_kind===`openhands`?k(s||F.some(t=>t.name===e.llm_profile_ref)?e.llm_profile_ref:I):k(``),_(e.name),M(null),f(`edit`)}catch(t){console.error(`Failed to fetch agent profile:`,t),c(e(p.ERROR$GENERIC))}},[e,F,s,I]),q=(0,W.useCallback)(()=>{f(`list`),S(null),_(``),w(null),M(null)},[]),J=(0,W.useCallback)(async()=>{if(!j||!B)return;let t;try{let n=j.buildAgentProfileFields();if(n.agent_kind===`openhands`){if(!D){c(e(p.SETTINGS$AGENT_PROFILE_LLM_REQUIRED));return}t={...n,llm_profile_ref:D}}else t=n}catch(t){c(t instanceof Error?t.message:e(p.ERROR$GENERIC));return}let i=h.trim(),a=x?.name,o=d===`edit`&&a&&a!==i;P(!0);try{if(j.credentials.isDirty){if(!await j.credentials.save({silent:!0}))return;j.credentials.reset()}o&&await r.mutateAsync({name:a,newName:i});let s=V(d===`edit`?x:null,t);await n.mutateAsync({name:i,profile:s}),l(e(d===`create`?p.SETTINGS$PROFILE_CREATED:p.SETTINGS$PROFILE_UPDATED,{name:i})),q()}catch(t){c(u(t)||e(p.ERROR$GENERIC))}finally{P(!1)}},[j,B,D,h,d,x,n,r,e,q]);if(d===`list`)return(0,K.jsx)(Q,{onAddProfile:H,onEditProfile:G});let Y=e(d===`edit`?p.SETTINGS$EDIT_AGENT_PROFILE:p.SETTINGS$ADD_AGENT_PROFILE),X=d===`edit`&&x?e(p.SETTINGS$PROFILE_LOADED,{name:x.name}):e(p.SETTINGS$PROFILE_SAVE_HINT),Z=j?.agentType!==`acp`;return(0,K.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,K.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,K.jsx)(m,{testId:`back-to-agent-profiles`,onClick:q,children:e(p.BUTTON$BACK)}),(0,K.jsx)(E.H2,{testId:`agent-profile-editor-title`,children:Y}),(0,K.jsx)(`p`,{"data-testid":`agent-profile-editor-description`,className:`text-sm leading-5 text-tertiary-light`,children:X})]}),(0,K.jsx)(O,{testId:`agent-profile-name-input`,value:h,onChange:_,isRequired:!0}),(0,K.jsx)(U,{embedded:!0,agentSettingsOverride:C,onSaveControlChange:M},d===`edit`?`edit-${x?.id}`:`new-profile`),Z&&(F.length>0?(0,K.jsx)(T,{testId:`agent-profile-llm-selector`,name:`agent-profile-llm`,label:e(p.SETTINGS$AGENT_PROFILE_LLM_LABEL),items:F.map(e=>({key:e.name,label:e.model?`${e.name} (${e.model})`:e.name})),selectedKey:D,onSelectionChange:e=>e&&k(String(e))}):(0,K.jsx)(`p`,{"data-testid":`agent-profile-no-llm`,className:`text-sm text-red-400`,children:e(p.SETTINGS$AGENT_PROFILE_NO_LLM)})),(0,K.jsxs)(`div`,{className:`flex justify-start gap-3 pt-4`,children:[(0,K.jsx)(g,{testId:`cancel-agent-profile-btn`,type:`button`,variant:`secondary`,onClick:q,children:e(p.BUTTON$CANCEL)}),(0,K.jsx)(g,{testId:`save-agent-profile-btn`,type:`button`,variant:`primary`,onClick:J,isDisabled:!B||N||!j?.isValid,"aria-busy":N,children:e(N?p.SETTINGS$SAVING:p.BUTTON$SAVE)})]})]})}var ne={hideTitle:!1},re=i(function(){return(0,K.jsx)(te,{})});export{re as default,ne as handle};