@openhands/agent-canvas 1.16.0 → 1.18.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 (1093) hide show
  1. package/README.md +1 -1
  2. package/README.windows.md +2 -2
  3. package/build/assets/{acp-providers-CX3Lh9gj.js → acp-providers-DcY_mKYa.js} +1 -1
  4. package/build/assets/active-backend-context-BnH4-L8h.js +2 -0
  5. package/build/assets/{agent-context-settings-DSZlXrLj.js → agent-context-settings-D3peZkjX.js} +1 -1
  6. package/build/assets/agent-profiles-service.api-DkeZaqIl.js +1 -0
  7. package/build/assets/agent-profiles-settings-7yMWYjGF.js +1 -0
  8. package/build/assets/agent-server-client-options-EHB23gyx.js +1 -0
  9. package/build/assets/agent-server-config-C_x8Otd9.js +1 -0
  10. package/build/assets/agent-server-conversation-service.api-jiCopc2E.js +88 -0
  11. package/build/assets/agent-settings-BF8hM6wb.js +2 -0
  12. package/build/assets/agent-settings-YPutBAeR.js +1 -0
  13. package/build/assets/alert-banner-eYyqvHL3.js +1 -0
  14. package/build/assets/{api-error-message-B-XdSk3b.js → api-error-message-BXo0lCI5.js} +1 -1
  15. package/build/assets/api-key-entry-screen-CCBvBD8u.js +1 -0
  16. package/build/assets/app-settings-BtYDs-Be.js +1 -0
  17. package/build/assets/automation-detail-BxXhb_m2.js +3 -0
  18. package/build/assets/{automation-export-D3a3of4G.js → automation-export-BJsfi7n2.js} +1 -1
  19. package/build/assets/automation-git-sync-B7o_Nbl-.js +1 -0
  20. package/build/assets/automation-setup-route-qaJ6lLCf.js +3 -0
  21. package/build/assets/{automation-templates-BRppNh99.js → automation-templates-Bb98r-kx.js} +1 -1
  22. package/build/assets/automations-list-DEPVNud3.js +1 -0
  23. package/build/assets/{back-nav-button-Cjl_hoxq.js → back-nav-button-B2yBiVMB.js} +1 -1
  24. package/build/assets/backend-form-modal-DxisQV_6.js +1 -0
  25. package/build/assets/backend-synced-settings-badge-DLEp6cq7.js +1 -0
  26. package/build/assets/badge-ehL-kgeO.js +1 -0
  27. package/build/assets/{base-modal-D_L0oEbG.js → base-modal-C1a0TsSx.js} +1 -1
  28. package/build/assets/bot-ByolqPEr.js +1 -0
  29. package/build/assets/{brand-button-BAfk4wGP.js → brand-button-CUMfjb99.js} +1 -1
  30. package/build/assets/browser-SE24Tk8g.js +46 -0
  31. package/build/assets/browser-tab-HjJxHA0V.js +1 -0
  32. package/build/assets/canvas-extension-page-BsUGBb1T.js +1 -0
  33. package/build/assets/canvas-extensions-C9Tm6s_E.js +1 -0
  34. package/build/assets/{canvas-extensions-runtime-2_x5Ezmi.js → canvas-extensions-runtime-B8kxM4rO.js} +1 -1
  35. package/build/assets/{chat-send-button-MUQqCZCS.js → chat-send-button-CGvc2wpE.js} +1 -1
  36. package/build/assets/check-Bo8s5Ylg.js +1 -0
  37. package/build/assets/chevron-down-Cr6Fn_wS.js +1 -0
  38. package/build/assets/chevron-right-CfdfRn-8.js +1 -0
  39. package/build/assets/circle-check-5pH3qCji.js +1 -0
  40. package/build/assets/circle-plus-check-toggle-BDX_ctNs.js +1 -0
  41. package/build/assets/{cloud-funnel-analytics-CztBCCPp.js → cloud-funnel-analytics-D5uJ_4JE.js} +1 -1
  42. package/build/assets/{cog-D-MPQW6G.js → cog-CAEugqtV.js} +1 -1
  43. package/build/assets/command-menu-CQxs4mtX.js +1 -0
  44. package/build/assets/commits-tab-D0xgjipP.js +1 -0
  45. package/build/assets/{condenser-settings-DmEOje-7.js → condenser-settings-D63NJRBT.js} +1 -1
  46. package/build/assets/confirmation-modal-78sd9Vny.js +1 -0
  47. package/build/assets/{context-menu-list-item-I86vKcmM.js → context-menu-list-item-Cm7-7Y-7.js} +1 -1
  48. package/build/assets/conversation-B_nweu5p.js +93 -0
  49. package/build/assets/conversation-edjzrv5w.js +1 -0
  50. package/build/assets/conversation-panel-edjzrv5w.js +1 -0
  51. package/build/assets/conversation-state-store-9D_3P7q4.js +1 -0
  52. package/build/assets/conversation-store-DC-JlJuq.js +6 -0
  53. package/build/assets/{conversation-tab-empty-state-FIbh_lc8.js → conversation-tab-empty-state-B3dpJXX0.js} +1 -1
  54. package/build/assets/copy-to-clipboard-button-B1ljgNxO.js +1 -0
  55. package/build/assets/device-verify-D5QRIS_x.js +1 -0
  56. package/build/assets/{dropdown-classes-Bc1djN0-.js → dropdown-classes-BGvOvW2_.js} +1 -1
  57. package/build/assets/edit-automation-modal-D_JWSmxT.js +1 -0
  58. package/build/assets/empty-state-FK_s1B60.js +1 -0
  59. package/build/assets/{entry.client-CqyPPjOq.js → entry.client-BMafTpjO.js} +2 -2
  60. package/build/assets/enum-filter-dropdown-UNaom12H.js +1 -0
  61. package/build/assets/environment-switch-overlay-COibRUA-.js +1 -0
  62. package/build/assets/error-state-Cf8LRuuY.js +1 -0
  63. package/build/assets/extensions-hub-C_6ahIua.js +1 -0
  64. package/build/assets/extensions-navigation-C5GfpzFe.js +1 -0
  65. package/build/assets/external-link-Bd7Tga-1.js +1 -0
  66. package/build/assets/files-tab-D5PPIWI1.js +1 -0
  67. package/build/assets/{form-control-classes-Bkh5FGrD.js → form-control-classes-Dbq-7YP_.js} +1 -1
  68. package/build/assets/format-model-name-Dfh9Udrx.js +1 -0
  69. package/build/assets/get-git-path-jU2zjqIB.js +1 -0
  70. package/build/assets/git-repo-dropdown-BoDDWXfX.js +1 -0
  71. package/build/assets/git-repo-dropdown-uxlFw2gn.js +1 -0
  72. package/build/assets/highlighted-source-view-C7pAXrT0.js +1 -0
  73. package/build/assets/home-BM5_Wz_R.js +1 -0
  74. package/build/assets/home-Ivfm7KC4.js +1 -0
  75. package/build/assets/home-automation-run-tooltip-B1N2uO9p.js +1 -0
  76. package/build/assets/home-store-DCbei3DX.js +1 -0
  77. package/build/assets/hooks-service-Dnmhqc0Z.js +1 -0
  78. package/build/assets/index-home-td9BN2T3.js +1 -0
  79. package/build/assets/info-BcajzHn1.js +1 -0
  80. package/build/assets/install-server-modal-B81I-5OE.js +1 -0
  81. package/build/assets/kebab-menu-item-content-SCJBwZnp.js +1 -0
  82. package/build/assets/{key-BmVyxs-2.js → key-O84CMFHb.js} +1 -1
  83. package/build/assets/launch-ZLxI4opd.js +1 -0
  84. package/build/assets/list-filter-B8PQk3RA.js +1 -0
  85. package/build/assets/{list-todo-apgLVjMw.js → list-todo-Caa8E1X_.js} +1 -1
  86. package/build/assets/llm-not-configured-banner-Dh_ajcM8.js +27 -0
  87. package/build/assets/llm-settings-CODhjQzy.js +1 -0
  88. package/build/assets/llm-settings-CZaXYgtw.js +1 -0
  89. package/build/assets/llm-subscription-service-CgIDc38n.js +1 -0
  90. package/build/assets/loader-circle-BxJgk73D.js +1 -0
  91. package/build/assets/{loading-spinner-BY9N3pOe.js → loading-spinner-BeLV0IXf.js} +1 -1
  92. package/build/assets/manage-backends-modal-cMXqCb-B.js +1 -0
  93. package/build/assets/manifest-bfeccb98.js +1 -0
  94. package/build/assets/manifest-subpage-layout-CVZgVKoY.js +1 -0
  95. package/build/assets/{map-provider-Cu3Zgumb.js → map-provider-iRs80q_6.js} +1 -1
  96. package/build/assets/markdown-renderer-DyFl9-mL.js +8 -0
  97. package/build/assets/mcp-CraxoXQv.js +1 -0
  98. package/build/assets/{mcp-marketplace-utils-AIBzzHTO.js → mcp-marketplace-utils-C7PYr293.js} +1 -1
  99. package/build/assets/mcp-page-CteH_K0N.js +9 -0
  100. package/build/assets/messages-Bk1xhbU2.js +41 -0
  101. package/build/assets/{modal-body-BxZjsju9.js → modal-body-C24WsdFb.js} +1 -1
  102. package/build/assets/{modal-classes-C8eycCwG.js → modal-classes-B0b9eiL8.js} +1 -1
  103. package/build/assets/modal-close-button-DfqfB2Nj.js +1 -0
  104. package/build/assets/{mouse-pointer-click-Co2uyaPA.js → mouse-pointer-click-BXlRN92t.js} +1 -1
  105. package/build/assets/onboarding-DXFBRqEy.js +1 -0
  106. package/build/assets/onboarding-modal-BT3Gx_sZ.js +1 -0
  107. package/build/assets/organization-service.api-B5CvmnYQ.js +1 -0
  108. package/build/assets/pencil-q-ihqDYv.js +1 -0
  109. package/build/assets/pin-BdroVQdN.js +1 -0
  110. package/build/assets/planner-tab-CstoOlAB.js +1 -0
  111. package/build/assets/plug-7ACOEbMs.js +1 -0
  112. package/build/assets/plugins-management-service-5rqVPEGN.js +1 -0
  113. package/build/assets/plus-C2e21TFC.js +1 -0
  114. package/build/assets/profiles-service.api-D1XKMgr0.js +1 -0
  115. package/build/assets/providers-XmZ9HM4Q.js +1 -0
  116. package/build/assets/proxy-XP6U1Dhv.js +1 -0
  117. package/build/assets/{puzzle-JM_QaRm0.js → puzzle-LJYnuxKe.js} +1 -1
  118. package/build/assets/react-BX7IV650.js +1 -0
  119. package/build/assets/recommended-automations-launcher-DEHRKIAg.js +1 -0
  120. package/build/assets/refresh-cw-BtdC3T8P.js +1 -0
  121. package/build/assets/root-CM6IZHlg.css +1 -0
  122. package/build/assets/root-DdFkodKW.js +2 -0
  123. package/build/assets/root-layout-DUquNZTU.js +2 -0
  124. package/build/assets/schema-field-Y3F8JvXd.js +1 -0
  125. package/build/assets/scroll-fade-state-Dt_fx2kf.js +1 -0
  126. package/build/assets/sdk-section-page-CNZTLwH9.js +1 -0
  127. package/build/assets/secret-form-9-BoGA40.js +1 -0
  128. package/build/assets/secrets-service-BOIsfD9j.js +1 -0
  129. package/build/assets/secrets-settings-CBJgFr42.js +1 -0
  130. package/build/assets/settings-D4hdToD4.js +1 -0
  131. package/build/assets/settings-dropdown-input-DBvsZ7-Q.js +1 -0
  132. package/build/assets/settings-index-DeQphyBK.js +1 -0
  133. package/build/assets/settings-input-dVuzapBA.js +1 -0
  134. package/build/assets/{settings-list-classes-BzeSZbF2.js → settings-list-classes-DhAPuXm6.js} +1 -1
  135. package/build/assets/settings-modal-tHiJ8iYV.js +1 -0
  136. package/build/assets/settings-nav-GAQjW1a-.js +16 -0
  137. package/build/assets/settings-service.api-C1vZH9Vh.js +1 -0
  138. package/build/assets/settings-switch-DDd1cQ8t.js +1 -0
  139. package/build/assets/{settings-utils-UYpEdPuD.js → settings-utils-BTaaRhLZ.js} +1 -1
  140. package/build/assets/shared-conversation-Cyg7m7ns.js +1 -0
  141. package/build/assets/shield-check-C3Rl0NF8.js +1 -0
  142. package/build/assets/{sidebar-layout-D6fS8-Gl.js → sidebar-layout-DH0E-5KW.js} +1 -1
  143. package/build/assets/sidebar-mobile-menu-toggle-CQ4iky__.js +1 -0
  144. package/build/assets/{sidebar-nav-link-DQQcMf1A.js → sidebar-nav-link-oLQiKUBu.js} +1 -1
  145. package/build/assets/{sidebar-onboarding-checklist-storage-BBkeI6Bp.js → sidebar-onboarding-checklist-storage-TfvNNnnr.js} +1 -1
  146. package/build/assets/sidebar-store-DAZVH-DR.js +1 -0
  147. package/build/assets/skill-card-pill-row-DfjIfj0K.js +1 -0
  148. package/build/assets/{skill-filter-w__3UCEE.js → skill-filter-DsNLmn76.js} +2 -2
  149. package/build/assets/{skill-icon-badge-RQkq8wvl.js → skill-icon-badge-0MK_68Nc.js} +1 -1
  150. package/build/assets/skill-scope-BE-H9TSZ.js +1 -0
  151. package/build/assets/skills-plugins-vzSdxSk_.js +1 -0
  152. package/build/assets/skills-settings-BiPOH9H9.js +1 -0
  153. package/build/assets/styled-tooltip-CejG0rqv.js +1 -0
  154. package/build/assets/task-list-tab-OkZSqnTp.js +1 -0
  155. package/build/assets/{terminal-CNElN42a.js → terminal-Dph60VFZ.js} +2 -2
  156. package/build/assets/toggle-switch-B2uXaAUS.js +1 -0
  157. package/build/assets/trash-2-Bb40zQzs.js +1 -0
  158. package/build/assets/trash-Ckh7yCaB.js +1 -0
  159. package/build/assets/triangle-alert-DEdu-b_L.js +1 -0
  160. package/build/assets/{typography-v1KN0tzi.js → typography-DgcLGdHk.js} +1 -1
  161. package/build/assets/usage-tab-MCmNRAnR.js +1 -0
  162. package/build/assets/use-acp-credential-form-ychoGqjC.js +1 -0
  163. package/build/assets/use-activate-agent-profile-8L8Xdghy.js +1 -0
  164. package/build/assets/use-agent-profiles-Bi8hSkze.js +1 -0
  165. package/build/assets/{use-automation-health-E6NZi9rb.js → use-automation-health-U99vvHxx.js} +1 -1
  166. package/build/assets/use-automation-permissions-Buus0R6h.js +1 -0
  167. package/build/assets/{use-automations-xijQKIl9.js → use-automations-Bq5hVuv0.js} +1 -1
  168. package/build/assets/{use-can-manage-org-profiles-CrJP5262.js → use-can-manage-org-profiles-MzIeEV8F.js} +1 -1
  169. package/build/assets/use-canvas-extensions-Ca9KoVEm.js +1 -0
  170. package/build/assets/{use-cloud-current-user-id-CDfAHpPX.js → use-cloud-current-user-id-B4ZLUZSa.js} +1 -1
  171. package/build/assets/use-config-l5tkDHyD.js +1 -0
  172. package/build/assets/use-create-conversation-i_PdFdIs.js +1 -0
  173. package/build/assets/use-create-secret-CjWq0J4O.js +1 -0
  174. package/build/assets/use-free-models-gCsJ5BV0.js +1 -0
  175. package/build/assets/{use-get-secrets-K3jmk-LH.js → use-get-secrets-CMTuWEp_.js} +1 -1
  176. package/build/assets/use-is-authed-A2Yinlt0.js +1 -0
  177. package/build/assets/{use-launch-skill-in-chat-BYjYihBP.js → use-launch-skill-in-chat-QbXDhiHr.js} +1 -1
  178. package/build/assets/use-llm-configured-Dl4zg8ht.js +1 -0
  179. package/build/assets/use-llm-profiles-SWsuFmFu.js +1 -0
  180. package/build/assets/use-manifest-capabilities-CdqYfUAC.js +1 -0
  181. package/build/assets/use-onboarding-completion-Xl63ZvzQ.js +1 -0
  182. package/build/assets/use-pinned-home-route-BXDIUaxQ.js +1 -0
  183. package/build/assets/use-plugins-marketplace-BIIaPiaB.js +1 -0
  184. package/build/assets/use-save-agent-profile-D-ZHHE94.js +1 -0
  185. package/build/assets/{use-save-settings-DYqkKv7T.js → use-save-settings-Dapkf4cC.js} +1 -1
  186. package/build/assets/use-settings-C2KKQKVC.js +1 -0
  187. package/build/assets/use-settings-nav-items-TOc0Rsfd.js +1 -0
  188. package/build/assets/use-tracking-j4uo9VEW.js +3 -0
  189. package/build/assets/{use-user-conversation-B9Gebw_g.js → use-user-conversation-5UFqMoO4.js} +1 -1
  190. package/build/assets/{useInfiniteQuery-C926xzY4.js → useInfiniteQuery-CtSRG7uW.js} +1 -1
  191. package/build/assets/{useMutation-B-qc391N.js → useMutation-Cszf8mKy.js} +1 -1
  192. package/build/assets/useQueries-pUohFMSP.js +1 -0
  193. package/build/assets/useQuery-DAAacS7O.js +1 -0
  194. package/build/assets/useTranslation-CCgUjPJF.js +1 -0
  195. package/build/assets/utils-BgLSZdyy.js +1 -0
  196. package/build/assets/{vendor~conversation-panel~conversation-C8Fn4XOf.js → vendor~conversation-panel~conversation-C22sJuWZ.js} +1 -1
  197. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~b0x1wrp2-Z0lly3FE.js +2 -0
  198. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~czjee3a3-BXXGJNDU.js +185 -0
  199. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ew9ih1s8-40UR63Gt.js +1 -0
  200. package/build/assets/{vendor~index-home~home~conversation-panel~conversation-hWywRBaR.js → vendor~index-home~home~conversation-panel~conversation-UTl7gUo9.js} +1 -1
  201. package/build/assets/vendor~root-layout-CcdIqs-C.js +1 -0
  202. package/build/assets/{vendor~root-layout~conversation-panel~conversation-BMbMgaGu.js → vendor~root-layout~conversation-panel~conversation-C3EBV3kp.js} +1 -1
  203. package/build/assets/vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-BCe0JJVy.js +1 -0
  204. package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation-j5MFqfSy.js → vendor~root-layout~index-home~home~conversation-panel~conversation-BGGbPcYh.js} +1 -1
  205. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~mcp~automations-list~aut~ibfbmr9f-CxhwKuAd.js +1 -0
  206. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~nj1hli3r-DP9wmsjo.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~inibp4qe-CnsDDzeE.js} +1 -1
  207. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-CUmIwQCN.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-3eJ4ExtV.js} +12 -6
  208. package/build/assets/{verification-settings-gw_q6vkL.js → verification-settings-DdBpaVPz.js} +1 -1
  209. package/build/assets/{wrench-CUEI1krB.js → wrench-B8Wg_nbp.js} +1 -1
  210. package/build/assets/x-CX8lVGwm.js +1 -0
  211. package/build/index.html +4 -4
  212. package/build/locales/ar/openhands.json +79 -22
  213. package/build/locales/ca/openhands.json +79 -22
  214. package/build/locales/de/openhands.json +79 -22
  215. package/build/locales/en/openhands.json +79 -22
  216. package/build/locales/es/openhands.json +79 -22
  217. package/build/locales/fr/openhands.json +79 -22
  218. package/build/locales/it/openhands.json +79 -22
  219. package/build/locales/ja/openhands.json +79 -22
  220. package/build/locales/ko-KR/openhands.json +79 -22
  221. package/build/locales/no/openhands.json +79 -22
  222. package/build/locales/pt/openhands.json +79 -22
  223. package/build/locales/tr/openhands.json +79 -22
  224. package/build/locales/uk/openhands.json +79 -22
  225. package/build/locales/zh-CN/openhands.json +79 -22
  226. package/build/locales/zh-TW/openhands.json +79 -22
  227. package/config/defaults.json +3 -3
  228. package/dist/api/agent-server-adapter.cjs +3 -3
  229. package/dist/api/agent-server-adapter.cjs.map +1 -1
  230. package/dist/api/agent-server-adapter.d.ts +72 -12
  231. package/dist/api/agent-server-adapter.js +234 -132
  232. package/dist/api/agent-server-adapter.js.map +1 -1
  233. package/dist/api/agent-server-config.cjs +1 -1
  234. package/dist/api/agent-server-config.cjs.map +1 -1
  235. package/dist/api/agent-server-config.d.ts +6 -0
  236. package/dist/api/agent-server-config.js +6 -3
  237. package/dist/api/agent-server-config.js.map +1 -1
  238. package/dist/api/automation-service/automation-service.api.cjs +1 -1
  239. package/dist/api/automation-service/automation-service.api.cjs.map +1 -1
  240. package/dist/api/automation-service/automation-service.api.d.ts +2 -2
  241. package/dist/api/automation-service/automation-service.api.js +7 -7
  242. package/dist/api/automation-service/automation-service.api.js.map +1 -1
  243. package/dist/api/cloud/organization-service.api.cjs.map +1 -1
  244. package/dist/api/cloud/organization-service.api.d.ts +9 -1
  245. package/dist/api/cloud/organization-service.api.js.map +1 -1
  246. package/dist/api/cloud/provider-connections-service.api.cjs +2 -0
  247. package/dist/api/cloud/provider-connections-service.api.cjs.map +1 -0
  248. package/dist/api/cloud/provider-connections-service.api.d.ts +5 -0
  249. package/dist/api/cloud/provider-connections-service.api.js +50 -0
  250. package/dist/api/cloud/provider-connections-service.api.js.map +1 -0
  251. package/dist/api/cloud/skills-service.api.cjs +1 -1
  252. package/dist/api/cloud/skills-service.api.cjs.map +1 -1
  253. package/dist/api/cloud/skills-service.api.d.ts +10 -0
  254. package/dist/api/cloud/skills-service.api.js +11 -1
  255. package/dist/api/cloud/skills-service.api.js.map +1 -1
  256. package/dist/api/config-service/config-service.api.cjs +1 -1
  257. package/dist/api/config-service/config-service.api.cjs.map +1 -1
  258. package/dist/api/config-service/config-service.api.js +6 -2
  259. package/dist/api/config-service/config-service.api.js.map +1 -1
  260. package/dist/api/config-service/config-service.types.d.ts +13 -0
  261. package/dist/api/conversation-metadata-store.cjs +1 -1
  262. package/dist/api/conversation-metadata-store.cjs.map +1 -1
  263. package/dist/api/conversation-metadata-store.d.ts +24 -0
  264. package/dist/api/conversation-metadata-store.js +10 -2
  265. package/dist/api/conversation-metadata-store.js.map +1 -1
  266. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
  267. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
  268. package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +20 -0
  269. package/dist/api/conversation-service/agent-server-conversation-service.api.js +126 -77
  270. package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
  271. package/dist/api/hooks-service.cjs +2 -0
  272. package/dist/api/hooks-service.cjs.map +1 -0
  273. package/dist/api/hooks-service.d.ts +13 -0
  274. package/dist/api/hooks-service.js +20 -0
  275. package/dist/api/hooks-service.js.map +1 -0
  276. package/dist/api/provider-connections-service/provider-connections-service.api.cjs +1 -1
  277. package/dist/api/provider-connections-service/provider-connections-service.api.cjs.map +1 -1
  278. package/dist/api/provider-connections-service/provider-connections-service.api.js +25 -16
  279. package/dist/api/provider-connections-service/provider-connections-service.api.js.map +1 -1
  280. package/dist/api/settings-service/settings-service.api.cjs +1 -1
  281. package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
  282. package/dist/api/settings-service/settings-service.api.d.ts +2 -0
  283. package/dist/api/settings-service/settings-service.api.js +18 -10
  284. package/dist/api/settings-service/settings-service.api.js.map +1 -1
  285. package/dist/api/skills-service.cjs +1 -1
  286. package/dist/api/skills-service.cjs.map +1 -1
  287. package/dist/api/skills-service.d.ts +7 -0
  288. package/dist/api/skills-service.js +11 -8
  289. package/dist/api/skills-service.js.map +1 -1
  290. package/dist/components/conversation-events/chat/event-message-components/critic-result-display.cjs +1 -1
  291. package/dist/components/conversation-events/chat/event-message-components/critic-result-display.js +5 -5
  292. package/dist/components/conversation-events/chat/event-message-components/finish-event-message.cjs +1 -1
  293. package/dist/components/conversation-events/chat/event-message-components/finish-event-message.cjs.map +1 -1
  294. package/dist/components/conversation-events/chat/event-message-components/finish-event-message.js +2 -1
  295. package/dist/components/conversation-events/chat/event-message-components/finish-event-message.js.map +1 -1
  296. package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.cjs +1 -1
  297. package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.cjs.map +1 -1
  298. package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.d.ts +1 -1
  299. package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.js +28 -28
  300. package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.js.map +1 -1
  301. package/dist/components/conversation-events/chat/event-message-components/thought-event-message.cjs +1 -1
  302. package/dist/components/conversation-events/chat/event-message-components/thought-event-message.cjs.map +1 -1
  303. package/dist/components/conversation-events/chat/event-message-components/thought-event-message.js +2 -1
  304. package/dist/components/conversation-events/chat/event-message-components/thought-event-message.js.map +1 -1
  305. package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.cjs +1 -1
  306. package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.cjs.map +1 -1
  307. package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.d.ts +1 -1
  308. package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.js +37 -37
  309. package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.js.map +1 -1
  310. package/dist/components/conversation-events/chat/event-message.cjs +2 -2
  311. package/dist/components/conversation-events/chat/event-message.cjs.map +1 -1
  312. package/dist/components/conversation-events/chat/event-message.js +79 -70
  313. package/dist/components/conversation-events/chat/event-message.js.map +1 -1
  314. package/dist/components/conversation-events/chat/messages.cjs +1 -1
  315. package/dist/components/conversation-events/chat/messages.cjs.map +1 -1
  316. package/dist/components/conversation-events/chat/messages.js +28 -27
  317. package/dist/components/conversation-events/chat/messages.js.map +1 -1
  318. package/dist/components/features/automations/automation-card.cjs +1 -1
  319. package/dist/components/features/automations/automation-card.cjs.map +1 -1
  320. package/dist/components/features/automations/automation-card.js +104 -97
  321. package/dist/components/features/automations/automation-card.js.map +1 -1
  322. package/dist/components/features/automations/automation-list-row.cjs +1 -1
  323. package/dist/components/features/automations/automation-list-row.cjs.map +1 -1
  324. package/dist/components/features/automations/automation-list-row.js +89 -77
  325. package/dist/components/features/automations/automation-list-row.js.map +1 -1
  326. package/dist/components/features/automations/build-automation-menu-items.cjs +1 -1
  327. package/dist/components/features/automations/build-automation-menu-items.cjs.map +1 -1
  328. package/dist/components/features/automations/build-automation-menu-items.d.ts +3 -1
  329. package/dist/components/features/automations/build-automation-menu-items.js +12 -11
  330. package/dist/components/features/automations/build-automation-menu-items.js.map +1 -1
  331. package/dist/components/features/automations/detail/configuration-section.d.ts +7 -1
  332. package/dist/components/features/automations/detail/detail-header.d.ts +10 -5
  333. package/dist/components/features/automations/detail/run-status-badge.cjs +1 -1
  334. package/dist/components/features/automations/detail/run-status-badge.cjs.map +1 -1
  335. package/dist/components/features/automations/detail/run-status-badge.d.ts +2 -2
  336. package/dist/components/features/automations/detail/run-status-badge.js +82 -53
  337. package/dist/components/features/automations/detail/run-status-badge.js.map +1 -1
  338. package/dist/components/features/automations/kebab-menu.cjs +1 -1
  339. package/dist/components/features/automations/kebab-menu.cjs.map +1 -1
  340. package/dist/components/features/automations/kebab-menu.js +9 -5
  341. package/dist/components/features/automations/kebab-menu.js.map +1 -1
  342. package/dist/components/features/automations/recommended-automations-launcher.cjs +1 -1
  343. package/dist/components/features/automations/recommended-automations-launcher.cjs.map +1 -1
  344. package/dist/components/features/automations/recommended-automations-launcher.js +12 -12
  345. package/dist/components/features/automations/recommended-automations-launcher.js.map +1 -1
  346. package/dist/components/features/automations/recommended-automations-section.cjs +1 -1
  347. package/dist/components/features/automations/recommended-automations-section.js +9 -9
  348. package/dist/components/features/backends/backend-selector.cjs +1 -1
  349. package/dist/components/features/backends/backend-selector.cjs.map +1 -1
  350. package/dist/components/features/backends/backend-selector.js +123 -112
  351. package/dist/components/features/backends/backend-selector.js.map +1 -1
  352. package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
  353. package/dist/components/features/backends/manage-backends-modal.cjs.map +1 -1
  354. package/dist/components/features/backends/manage-backends-modal.js +29 -29
  355. package/dist/components/features/backends/manage-backends-modal.js.map +1 -1
  356. package/dist/components/features/chat/change-agent-button.cjs +1 -1
  357. package/dist/components/features/chat/change-agent-button.js +4 -4
  358. package/dist/components/features/chat/chat-interface.cjs +2 -2
  359. package/dist/components/features/chat/chat-interface.cjs.map +1 -1
  360. package/dist/components/features/chat/chat-interface.js +137 -137
  361. package/dist/components/features/chat/chat-interface.js.map +1 -1
  362. package/dist/components/features/chat/chat-message.cjs +1 -1
  363. package/dist/components/features/chat/chat-message.cjs.map +1 -1
  364. package/dist/components/features/chat/chat-message.d.ts +2 -1
  365. package/dist/components/features/chat/chat-message.js +88 -79
  366. package/dist/components/features/chat/chat-message.js.map +1 -1
  367. package/dist/components/features/chat/components/chat-input-llm-profile-picker.cjs +1 -1
  368. package/dist/components/features/chat/components/chat-input-llm-profile-picker.cjs.map +1 -1
  369. package/dist/components/features/chat/components/chat-input-llm-profile-picker.js +62 -61
  370. package/dist/components/features/chat/components/chat-input-llm-profile-picker.js.map +1 -1
  371. package/dist/components/features/chat/components/context-window-meter.cjs +1 -1
  372. package/dist/components/features/chat/components/context-window-meter.js +4 -4
  373. package/dist/components/features/chat/confirmation-mode-enabled.cjs +1 -1
  374. package/dist/components/features/chat/confirmation-mode-enabled.js +4 -4
  375. package/dist/components/features/chat/generic-event-message.cjs +1 -1
  376. package/dist/components/features/chat/generic-event-message.cjs.map +1 -1
  377. package/dist/components/features/chat/generic-event-message.d.ts +2 -1
  378. package/dist/components/features/chat/generic-event-message.js +41 -22
  379. package/dist/components/features/chat/generic-event-message.js.map +1 -1
  380. package/dist/components/features/chat/interactive-chat-box.cjs +1 -1
  381. package/dist/components/features/chat/interactive-chat-box.cjs.map +1 -1
  382. package/dist/components/features/chat/interactive-chat-box.js +20 -19
  383. package/dist/components/features/chat/interactive-chat-box.js.map +1 -1
  384. package/dist/components/features/chat/model-messages.cjs +1 -1
  385. package/dist/components/features/chat/model-messages.cjs.map +1 -1
  386. package/dist/components/features/chat/model-messages.js +27 -26
  387. package/dist/components/features/chat/model-messages.js.map +1 -1
  388. package/dist/components/features/conversation/conversation-overview-git-section.cjs +1 -1
  389. package/dist/components/features/conversation/conversation-overview-git-section.js +4 -4
  390. package/dist/components/features/conversation/conversation-overview-skills-panel.cjs +1 -1
  391. package/dist/components/features/conversation/conversation-overview-skills-panel.js +4 -4
  392. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs +1 -1
  393. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs.map +1 -1
  394. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js +77 -78
  395. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js.map +1 -1
  396. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs +1 -1
  397. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs.map +1 -1
  398. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js +88 -88
  399. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js.map +1 -1
  400. package/dist/components/features/conversation-panel/advanced-conversation-options-modal.cjs +2 -0
  401. package/dist/components/features/conversation-panel/advanced-conversation-options-modal.cjs.map +1 -0
  402. package/dist/components/features/conversation-panel/advanced-conversation-options-modal.d.ts +21 -0
  403. package/dist/components/features/conversation-panel/advanced-conversation-options-modal.js +239 -0
  404. package/dist/components/features/conversation-panel/advanced-conversation-options-modal.js.map +1 -0
  405. package/dist/components/features/conversation-panel/budget-display.cjs +1 -1
  406. package/dist/components/features/conversation-panel/budget-display.cjs.map +1 -1
  407. package/dist/components/features/conversation-panel/budget-display.d.ts +1 -2
  408. package/dist/components/features/conversation-panel/budget-display.js +12 -19
  409. package/dist/components/features/conversation-panel/budget-display.js.map +1 -1
  410. package/dist/components/features/conversation-panel/conversation-active-tag-filters.cjs +2 -0
  411. package/dist/components/features/conversation-panel/conversation-active-tag-filters.cjs.map +1 -0
  412. package/dist/components/features/conversation-panel/conversation-active-tag-filters.d.ts +28 -0
  413. package/dist/components/features/conversation-panel/conversation-active-tag-filters.js +69 -0
  414. package/dist/components/features/conversation-panel/conversation-active-tag-filters.js.map +1 -0
  415. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.cjs +1 -1
  416. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.cjs.map +1 -1
  417. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.d.ts +2 -1
  418. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.js +19 -18
  419. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.js.map +1 -1
  420. package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.cjs +1 -1
  421. package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.cjs.map +1 -1
  422. package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.d.ts +2 -1
  423. package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.js +91 -80
  424. package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.js.map +1 -1
  425. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs +1 -1
  426. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs.map +1 -1
  427. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js +45 -44
  428. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js.map +1 -1
  429. package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.cjs +1 -1
  430. package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.cjs.map +1 -1
  431. package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.js +1 -1
  432. package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.js.map +1 -1
  433. package/dist/components/features/conversation-panel/conversation-card/conversation-card.cjs +1 -1
  434. package/dist/components/features/conversation-panel/conversation-card/conversation-card.cjs.map +1 -1
  435. package/dist/components/features/conversation-panel/conversation-card/conversation-card.d.ts +7 -1
  436. package/dist/components/features/conversation-panel/conversation-card/conversation-card.js +87 -81
  437. package/dist/components/features/conversation-panel/conversation-card/conversation-card.js.map +1 -1
  438. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.cjs +1 -1
  439. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.cjs.map +1 -1
  440. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.d.ts +2 -1
  441. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.js +1 -1
  442. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.js.map +1 -1
  443. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.cjs +1 -1
  444. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.cjs.map +1 -1
  445. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.d.ts +2 -1
  446. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.js +2 -1
  447. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.js.map +1 -1
  448. package/dist/components/features/conversation-panel/conversation-layouts-menu.cjs +2 -0
  449. package/dist/components/features/conversation-panel/conversation-layouts-menu.cjs.map +1 -0
  450. package/dist/components/features/conversation-panel/conversation-layouts-menu.d.ts +29 -0
  451. package/dist/components/features/conversation-panel/conversation-layouts-menu.js +177 -0
  452. package/dist/components/features/conversation-panel/conversation-layouts-menu.js.map +1 -0
  453. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs +1 -1
  454. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs.map +1 -1
  455. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.d.ts +37 -0
  456. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js +85 -45
  457. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js.map +1 -1
  458. package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
  459. package/dist/components/features/conversation-panel/conversation-panel.cjs.map +1 -1
  460. package/dist/components/features/conversation-panel/conversation-panel.js +296 -290
  461. package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
  462. package/dist/components/features/conversation-panel/edit-conversation-tags-modal.cjs +2 -0
  463. package/dist/components/features/conversation-panel/edit-conversation-tags-modal.cjs.map +1 -0
  464. package/dist/components/features/conversation-panel/edit-conversation-tags-modal.d.ts +22 -0
  465. package/dist/components/features/conversation-panel/edit-conversation-tags-modal.js +153 -0
  466. package/dist/components/features/conversation-panel/edit-conversation-tags-modal.js.map +1 -0
  467. package/dist/components/features/conversation-panel/hide-older-conversations-row.cjs +2 -0
  468. package/dist/components/features/conversation-panel/hide-older-conversations-row.cjs.map +1 -0
  469. package/dist/components/features/conversation-panel/hide-older-conversations-row.d.ts +6 -0
  470. package/dist/components/features/conversation-panel/hide-older-conversations-row.js +65 -0
  471. package/dist/components/features/conversation-panel/hide-older-conversations-row.js.map +1 -0
  472. package/dist/components/features/conversation-panel/menu-row.cjs +1 -1
  473. package/dist/components/features/conversation-panel/menu-row.cjs.map +1 -1
  474. package/dist/components/features/conversation-panel/menu-row.d.ts +11 -1
  475. package/dist/components/features/conversation-panel/menu-row.js +27 -16
  476. package/dist/components/features/conversation-panel/menu-row.js.map +1 -1
  477. package/dist/components/features/home/featured-automations/automation-health-indicator.cjs +1 -1
  478. package/dist/components/features/home/featured-automations/automation-health-indicator.cjs.map +1 -1
  479. package/dist/components/features/home/featured-automations/automation-health-indicator.js +1 -1
  480. package/dist/components/features/home/featured-automations/automation-health-indicator.js.map +1 -1
  481. package/dist/components/features/home/featured-automations/automation-run-activity-metrics.cjs +1 -1
  482. package/dist/components/features/home/featured-automations/automation-run-activity-metrics.cjs.map +1 -1
  483. package/dist/components/features/home/featured-automations/automation-run-activity-metrics.d.ts +4 -3
  484. package/dist/components/features/home/featured-automations/automation-run-activity-metrics.js +22 -25
  485. package/dist/components/features/home/featured-automations/automation-run-activity-metrics.js.map +1 -1
  486. package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.cjs +1 -1
  487. package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.cjs.map +1 -1
  488. package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.d.ts +1 -1
  489. package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.js +15 -15
  490. package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.js.map +1 -1
  491. package/dist/components/features/home/featured-automations/automation-run-health.cjs +1 -1
  492. package/dist/components/features/home/featured-automations/automation-run-health.cjs.map +1 -1
  493. package/dist/components/features/home/featured-automations/automation-run-health.d.ts +5 -3
  494. package/dist/components/features/home/featured-automations/automation-run-health.js +30 -23
  495. package/dist/components/features/home/featured-automations/automation-run-health.js.map +1 -1
  496. package/dist/components/features/home/featured-automations/build-home-automation-menu-items.d.ts +1 -2
  497. package/dist/components/features/home/featured-automations/build-pinned-automation-menu-items.d.ts +0 -1
  498. package/dist/components/features/home/featured-automations/home-automation-activity.d.ts +3 -2
  499. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.cjs +1 -1
  500. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.cjs.map +1 -1
  501. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.d.ts +1 -1
  502. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js +42 -42
  503. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js.map +1 -1
  504. package/dist/components/features/images/image-lightbox.cjs +2 -0
  505. package/dist/components/features/images/image-lightbox.cjs.map +1 -0
  506. package/dist/components/features/images/image-lightbox.d.ts +11 -0
  507. package/dist/components/features/images/image-lightbox.js +37 -0
  508. package/dist/components/features/images/image-lightbox.js.map +1 -0
  509. package/dist/components/features/images/image-preview.cjs +1 -1
  510. package/dist/components/features/images/image-preview.cjs.map +1 -1
  511. package/dist/components/features/images/image-preview.d.ts +2 -1
  512. package/dist/components/features/images/image-preview.js +33 -13
  513. package/dist/components/features/images/image-preview.js.map +1 -1
  514. package/dist/components/features/manifest/manifest-form-field.d.ts +3 -1
  515. package/dist/components/features/manifest/manifest-review-step.d.ts +3 -1
  516. package/dist/components/features/onboarding/steps/setup-llm-step.d.ts +3 -4
  517. package/dist/components/features/settings/cloud-settings-link.cjs +1 -1
  518. package/dist/components/features/settings/cloud-settings-link.cjs.map +1 -1
  519. package/dist/components/features/settings/cloud-settings-link.d.ts +3 -1
  520. package/dist/components/features/settings/cloud-settings-link.js +22 -19
  521. package/dist/components/features/settings/cloud-settings-link.js.map +1 -1
  522. package/dist/components/features/settings/integrations-settings-link.cjs +1 -1
  523. package/dist/components/features/settings/integrations-settings-link.cjs.map +1 -1
  524. package/dist/components/features/settings/integrations-settings-link.d.ts +3 -1
  525. package/dist/components/features/settings/integrations-settings-link.js +20 -17
  526. package/dist/components/features/settings/integrations-settings-link.js.map +1 -1
  527. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.cjs +1 -1
  528. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.js +3 -2
  529. package/dist/components/features/settings/llm-profiles/profile-row.cjs +1 -1
  530. package/dist/components/features/settings/llm-profiles/profile-row.js +1 -1
  531. package/dist/components/features/settings/llm-profiles/profiles-body.d.ts +2 -2
  532. package/dist/components/features/settings/sdk-settings/sdk-section-page.cjs +1 -1
  533. package/dist/components/features/settings/sdk-settings/sdk-section-page.cjs.map +1 -1
  534. package/dist/components/features/settings/sdk-settings/sdk-section-page.d.ts +8 -7
  535. package/dist/components/features/settings/sdk-settings/sdk-section-page.js +172 -142
  536. package/dist/components/features/settings/sdk-settings/sdk-section-page.js.map +1 -1
  537. package/dist/components/features/settings/secrets-settings/secret-form.cjs +1 -1
  538. package/dist/components/features/settings/secrets-settings/secret-form.cjs.map +1 -1
  539. package/dist/components/features/settings/secrets-settings/secret-form.js +38 -25
  540. package/dist/components/features/settings/secrets-settings/secret-form.js.map +1 -1
  541. package/dist/components/features/settings/settings-dropdown-input.cjs +1 -1
  542. package/dist/components/features/settings/settings-dropdown-input.js +6 -6
  543. package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
  544. package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
  545. package/dist/components/features/sidebar/sidebar-rail-body.d.ts +4 -1
  546. package/dist/components/features/sidebar/sidebar-rail-body.js +157 -139
  547. package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
  548. package/dist/components/features/sidebar/sidebar.cjs +1 -1
  549. package/dist/components/features/sidebar/sidebar.cjs.map +1 -1
  550. package/dist/components/features/sidebar/sidebar.js +28 -26
  551. package/dist/components/features/sidebar/sidebar.js.map +1 -1
  552. package/dist/components/features/sidebar/use-sidebar-onboarding-checklist.cjs +1 -1
  553. package/dist/components/features/sidebar/use-sidebar-onboarding-checklist.js +3 -3
  554. package/dist/components/features/skills/extensions-navigation.cjs +1 -1
  555. package/dist/components/features/skills/extensions-navigation.cjs.map +1 -1
  556. package/dist/components/features/skills/extensions-navigation.js +3 -3
  557. package/dist/components/features/skills/extensions-navigation.js.map +1 -1
  558. package/dist/components/providers/agent-server-ui-providers.cjs +1 -1
  559. package/dist/components/providers/agent-server-ui-providers.cjs.map +1 -1
  560. package/dist/components/providers/agent-server-ui-providers.js +33 -29
  561. package/dist/components/providers/agent-server-ui-providers.js.map +1 -1
  562. package/dist/components/shared/buttons/remove-button.cjs +1 -1
  563. package/dist/components/shared/buttons/remove-button.cjs.map +1 -1
  564. package/dist/components/shared/buttons/remove-button.d.ts +2 -1
  565. package/dist/components/shared/buttons/remove-button.js +2 -1
  566. package/dist/components/shared/buttons/remove-button.js.map +1 -1
  567. package/dist/components/shared/buttons/styled-tooltip.cjs +1 -1
  568. package/dist/components/shared/buttons/styled-tooltip.cjs.map +1 -1
  569. package/dist/components/shared/buttons/styled-tooltip.d.ts +2 -1
  570. package/dist/components/shared/buttons/styled-tooltip.js +2 -1
  571. package/dist/components/shared/buttons/styled-tooltip.js.map +1 -1
  572. package/dist/components/shared/filters/enum-filter-dropdown.cjs +1 -1
  573. package/dist/components/shared/filters/enum-filter-dropdown.cjs.map +1 -1
  574. package/dist/components/shared/filters/enum-filter-dropdown.d.ts +5 -1
  575. package/dist/components/shared/filters/enum-filter-dropdown.js +14 -14
  576. package/dist/components/shared/filters/enum-filter-dropdown.js.map +1 -1
  577. package/dist/components/shared/free-models-note.cjs +2 -0
  578. package/dist/components/shared/free-models-note.cjs.map +1 -0
  579. package/dist/components/shared/free-models-note.d.ts +3 -0
  580. package/dist/components/shared/free-models-note.js +20 -0
  581. package/dist/components/shared/free-models-note.js.map +1 -0
  582. package/dist/components/shared/modals/confirmation-modal.cjs +1 -1
  583. package/dist/components/shared/modals/confirmation-modal.cjs.map +1 -1
  584. package/dist/components/shared/modals/confirmation-modal.d.ts +2 -1
  585. package/dist/components/shared/modals/confirmation-modal.js +8 -8
  586. package/dist/components/shared/modals/confirmation-modal.js.map +1 -1
  587. package/dist/components/shared/modals/settings/model-selector.cjs +1 -1
  588. package/dist/components/shared/modals/settings/model-selector.cjs.map +1 -1
  589. package/dist/components/shared/modals/settings/model-selector.js +102 -112
  590. package/dist/components/shared/modals/settings/model-selector.js.map +1 -1
  591. package/dist/config/defaults.cjs +1 -1
  592. package/dist/config/defaults.cjs.map +1 -1
  593. package/dist/config/defaults.js +3 -3
  594. package/dist/config/defaults.js.map +1 -1
  595. package/dist/constants/acp-providers.cjs.map +1 -1
  596. package/dist/constants/acp-providers.d.ts +12 -0
  597. package/dist/constants/acp-providers.js.map +1 -1
  598. package/dist/constants/settings-nav.d.ts +8 -0
  599. package/dist/contexts/conversation-websocket-context.cjs +3 -3
  600. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  601. package/dist/contexts/conversation-websocket-context.d.ts +5 -0
  602. package/dist/contexts/conversation-websocket-context.js +194 -198
  603. package/dist/contexts/conversation-websocket-context.js.map +1 -1
  604. package/dist/contexts/websocket-provider-wrapper.cjs +1 -1
  605. package/dist/contexts/websocket-provider-wrapper.cjs.map +1 -1
  606. package/dist/contexts/websocket-provider-wrapper.js +31 -15
  607. package/dist/contexts/websocket-provider-wrapper.js.map +1 -1
  608. package/dist/hooks/chat/record-model-switch-message.cjs +1 -1
  609. package/dist/hooks/chat/record-model-switch-message.cjs.map +1 -1
  610. package/dist/hooks/chat/record-model-switch-message.d.ts +31 -0
  611. package/dist/hooks/chat/record-model-switch-message.js +25 -12
  612. package/dist/hooks/chat/record-model-switch-message.js.map +1 -1
  613. package/dist/hooks/chat/use-plan-mode-interceptor.cjs +2 -0
  614. package/dist/hooks/chat/use-plan-mode-interceptor.cjs.map +1 -0
  615. package/dist/hooks/chat/use-plan-mode-interceptor.d.ts +16 -0
  616. package/dist/hooks/chat/use-plan-mode-interceptor.js +43 -0
  617. package/dist/hooks/chat/use-plan-mode-interceptor.js.map +1 -0
  618. package/dist/hooks/chat/use-slash-command.cjs +1 -1
  619. package/dist/hooks/chat/use-slash-command.cjs.map +1 -1
  620. package/dist/hooks/chat/use-slash-command.js +63 -62
  621. package/dist/hooks/chat/use-slash-command.js.map +1 -1
  622. package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
  623. package/dist/hooks/mutation/use-create-conversation.cjs.map +1 -1
  624. package/dist/hooks/mutation/use-create-conversation.js +5 -1
  625. package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
  626. package/dist/hooks/mutation/use-read-conversation-file.cjs +1 -1
  627. package/dist/hooks/mutation/use-read-conversation-file.cjs.map +1 -1
  628. package/dist/hooks/mutation/use-read-conversation-file.js +11 -4
  629. package/dist/hooks/mutation/use-read-conversation-file.js.map +1 -1
  630. package/dist/hooks/mutation/use-save-settings.cjs +1 -1
  631. package/dist/hooks/mutation/use-save-settings.js +3 -3
  632. package/dist/hooks/mutation/use-switch-llm-profile.cjs +1 -1
  633. package/dist/hooks/mutation/use-switch-llm-profile.cjs.map +1 -1
  634. package/dist/hooks/mutation/use-switch-llm-profile.js +13 -25
  635. package/dist/hooks/mutation/use-switch-llm-profile.js.map +1 -1
  636. package/dist/hooks/mutation/use-update-conversation-tags.cjs +2 -0
  637. package/dist/hooks/mutation/use-update-conversation-tags.cjs.map +1 -0
  638. package/dist/hooks/mutation/use-update-conversation-tags.d.ts +8 -0
  639. package/dist/hooks/mutation/use-update-conversation-tags.js +45 -0
  640. package/dist/hooks/mutation/use-update-conversation-tags.js.map +1 -0
  641. package/dist/hooks/query/query-keys.cjs +1 -1
  642. package/dist/hooks/query/query-keys.cjs.map +1 -1
  643. package/dist/hooks/query/query-keys.d.ts +6 -0
  644. package/dist/hooks/query/query-keys.js +2 -2
  645. package/dist/hooks/query/query-keys.js.map +1 -1
  646. package/dist/hooks/query/use-automation-sdk-version.cjs +1 -1
  647. package/dist/hooks/query/use-automation-sdk-version.cjs.map +1 -1
  648. package/dist/hooks/query/use-automation-sdk-version.d.ts +0 -1
  649. package/dist/hooks/query/use-automation-sdk-version.js +30 -55
  650. package/dist/hooks/query/use-automation-sdk-version.js.map +1 -1
  651. package/dist/hooks/query/use-conversation-skills.cjs +1 -1
  652. package/dist/hooks/query/use-conversation-skills.cjs.map +1 -1
  653. package/dist/hooks/query/use-conversation-skills.d.ts +14 -5
  654. package/dist/hooks/query/use-conversation-skills.js +20 -4
  655. package/dist/hooks/query/use-conversation-skills.js.map +1 -1
  656. package/dist/hooks/query/use-free-models.cjs +2 -0
  657. package/dist/hooks/query/use-free-models.cjs.map +1 -0
  658. package/dist/hooks/query/use-free-models.d.ts +23 -0
  659. package/dist/hooks/query/use-free-models.js +67 -0
  660. package/dist/hooks/query/use-free-models.js.map +1 -0
  661. package/dist/hooks/query/use-local-git-info.cjs.map +1 -1
  662. package/dist/hooks/query/use-local-git-info.js.map +1 -1
  663. package/dist/hooks/query/use-provider-connections.cjs +1 -1
  664. package/dist/hooks/query/use-provider-connections.cjs.map +1 -1
  665. package/dist/hooks/query/use-provider-connections.d.ts +6 -3
  666. package/dist/hooks/query/use-provider-connections.js +7 -3
  667. package/dist/hooks/query/use-provider-connections.js.map +1 -1
  668. package/dist/hooks/query/use-provider-models.cjs +1 -1
  669. package/dist/hooks/query/use-provider-models.cjs.map +1 -1
  670. package/dist/hooks/query/use-provider-models.js +34 -25
  671. package/dist/hooks/query/use-provider-models.js.map +1 -1
  672. package/dist/hooks/query/use-search-providers.cjs +1 -1
  673. package/dist/hooks/query/use-search-providers.cjs.map +1 -1
  674. package/dist/hooks/query/use-search-providers.js +31 -19
  675. package/dist/hooks/query/use-search-providers.js.map +1 -1
  676. package/dist/hooks/query/use-sub-conversations.cjs +1 -1
  677. package/dist/hooks/query/use-sub-conversations.cjs.map +1 -1
  678. package/dist/hooks/query/use-sub-conversations.js +16 -16
  679. package/dist/hooks/query/use-sub-conversations.js.map +1 -1
  680. package/dist/hooks/use-acp-model-context.cjs +1 -1
  681. package/dist/hooks/use-acp-model-context.js +3 -3
  682. package/dist/hooks/use-agent-state.cjs +1 -1
  683. package/dist/hooks/use-agent-state.cjs.map +1 -1
  684. package/dist/hooks/use-agent-state.d.ts +17 -1
  685. package/dist/hooks/use-agent-state.js +19 -9
  686. package/dist/hooks/use-agent-state.js.map +1 -1
  687. package/dist/hooks/use-automation-permissions.cjs +2 -0
  688. package/dist/hooks/use-automation-permissions.cjs.map +1 -0
  689. package/dist/hooks/use-automation-permissions.d.ts +43 -0
  690. package/dist/hooks/use-automation-permissions.js +52 -0
  691. package/dist/hooks/use-automation-permissions.js.map +1 -0
  692. package/dist/hooks/use-chat-input-model-state.cjs +1 -1
  693. package/dist/hooks/use-chat-input-model-state.js +3 -3
  694. package/dist/hooks/use-handle-plan-click.cjs +1 -1
  695. package/dist/hooks/use-handle-plan-click.cjs.map +1 -1
  696. package/dist/hooks/use-handle-plan-click.d.ts +3 -1
  697. package/dist/hooks/use-handle-plan-click.js +85 -26
  698. package/dist/hooks/use-handle-plan-click.js.map +1 -1
  699. package/dist/hooks/use-home-automation-actions.cjs +1 -1
  700. package/dist/hooks/use-home-automation-actions.cjs.map +1 -1
  701. package/dist/hooks/use-home-automation-actions.d.ts +1 -2
  702. package/dist/hooks/use-home-automation-actions.js +1 -1
  703. package/dist/hooks/use-home-automation-actions.js.map +1 -1
  704. package/dist/hooks/use-llm-configured.cjs +1 -1
  705. package/dist/hooks/use-llm-configured.js +3 -3
  706. package/dist/hooks/use-manifest-preflight.d.ts +1 -1
  707. package/dist/hooks/use-unified-websocket-status.cjs +1 -1
  708. package/dist/hooks/use-unified-websocket-status.cjs.map +1 -1
  709. package/dist/hooks/use-unified-websocket-status.d.ts +7 -0
  710. package/dist/hooks/use-unified-websocket-status.js +5 -1
  711. package/dist/hooks/use-unified-websocket-status.js.map +1 -1
  712. package/dist/i18n/declaration.cjs +1 -1
  713. package/dist/i18n/declaration.cjs.map +1 -1
  714. package/dist/i18n/declaration.d.ts +71 -14
  715. package/dist/i18n/declaration.js +1 -1
  716. package/dist/i18n/declaration.js.map +1 -1
  717. package/dist/i18n/translation.cjs +2 -2
  718. package/dist/i18n/translation.cjs.map +1 -1
  719. package/dist/i18n/translation.js +1281 -312
  720. package/dist/i18n/translation.js.map +1 -1
  721. package/dist/locales/ar/openhands.json +79 -22
  722. package/dist/locales/ca/openhands.json +79 -22
  723. package/dist/locales/de/openhands.json +79 -22
  724. package/dist/locales/en/openhands.json +79 -22
  725. package/dist/locales/es/openhands.json +79 -22
  726. package/dist/locales/fr/openhands.json +79 -22
  727. package/dist/locales/it/openhands.json +79 -22
  728. package/dist/locales/ja/openhands.json +79 -22
  729. package/dist/locales/ko-KR/openhands.json +79 -22
  730. package/dist/locales/no/openhands.json +79 -22
  731. package/dist/locales/pt/openhands.json +79 -22
  732. package/dist/locales/tr/openhands.json +79 -22
  733. package/dist/locales/uk/openhands.json +79 -22
  734. package/dist/locales/zh-CN/openhands.json +79 -22
  735. package/dist/locales/zh-TW/openhands.json +79 -22
  736. package/dist/manifests/automation-insights.cjs.map +1 -1
  737. package/dist/manifests/automation-insights.d.ts +10 -2
  738. package/dist/manifests/automation-insights.js.map +1 -1
  739. package/dist/manifests/automation-setup.cjs +1 -1
  740. package/dist/manifests/automation-setup.cjs.map +1 -1
  741. package/dist/manifests/automation-setup.d.ts +9 -16
  742. package/dist/manifests/automation-setup.js +17 -7
  743. package/dist/manifests/automation-setup.js.map +1 -1
  744. package/dist/manifests/manifest-actions.d.ts +1 -1
  745. package/dist/manifests/manifest-capabilities.d.ts +3 -1
  746. package/dist/manifests/manifest-local-validation.cjs +2 -0
  747. package/dist/manifests/manifest-local-validation.cjs.map +1 -0
  748. package/dist/manifests/manifest-local-validation.d.ts +15 -11
  749. package/dist/manifests/manifest-local-validation.js +8 -0
  750. package/dist/manifests/manifest-local-validation.js.map +1 -0
  751. package/dist/manifests/manifest-template.cjs +2 -0
  752. package/dist/manifests/manifest-template.cjs.map +1 -0
  753. package/dist/manifests/manifest-template.d.ts +4 -4
  754. package/dist/manifests/manifest-template.js +12 -0
  755. package/dist/manifests/manifest-template.js.map +1 -0
  756. package/dist/manifests/manifest-validation.cjs +1 -1
  757. package/dist/manifests/manifest-validation.cjs.map +1 -1
  758. package/dist/manifests/manifest-validation.js +106 -28
  759. package/dist/manifests/manifest-validation.js.map +1 -1
  760. package/dist/manifests/types.cjs.map +1 -1
  761. package/dist/manifests/types.d.ts +39 -4
  762. package/dist/manifests/types.js.map +1 -1
  763. package/dist/node_modules/@openhands/extensions/automations/catalog/custom-automation/manifest.cjs +8 -0
  764. package/dist/node_modules/@openhands/extensions/automations/catalog/custom-automation/manifest.cjs.map +1 -0
  765. package/dist/node_modules/@openhands/extensions/automations/catalog/custom-automation/manifest.js +221 -0
  766. package/dist/node_modules/@openhands/extensions/automations/catalog/custom-automation/manifest.js.map +1 -0
  767. package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.cjs +1 -1
  768. package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.cjs.map +1 -1
  769. package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.js +1 -1
  770. package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.js.map +1 -1
  771. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs +1 -1
  772. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs.map +1 -1
  773. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js +1 -1
  774. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js.map +1 -1
  775. package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.cjs +1 -1
  776. package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.cjs.map +1 -1
  777. package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.js +1 -1
  778. package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.js.map +1 -1
  779. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs +1 -1
  780. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs.map +1 -1
  781. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js +22 -20
  782. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js.map +1 -1
  783. package/dist/node_modules/@openhands/extensions/automations/interface.cjs +1 -1
  784. package/dist/node_modules/@openhands/extensions/automations/interface.cjs.map +1 -1
  785. package/dist/node_modules/@openhands/extensions/automations/interface.js +2 -1
  786. package/dist/node_modules/@openhands/extensions/automations/interface.js.map +1 -1
  787. package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.cjs +1 -1
  788. package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.cjs.map +1 -1
  789. package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.js +24 -5
  790. package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.js.map +1 -1
  791. package/dist/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs +1 -1
  792. package/dist/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js +1 -1
  793. package/dist/node_modules/lucide-react/dist/esm/icons/circle-question-mark.cjs +2 -0
  794. package/dist/node_modules/lucide-react/dist/esm/icons/circle-question-mark.cjs.map +1 -0
  795. package/dist/node_modules/lucide-react/dist/esm/icons/circle-question-mark.js +21 -0
  796. package/dist/node_modules/lucide-react/dist/esm/icons/circle-question-mark.js.map +1 -0
  797. package/dist/node_modules/lucide-react/dist/esm/icons/shrink.cjs +2 -0
  798. package/dist/node_modules/lucide-react/dist/esm/icons/shrink.cjs.map +1 -0
  799. package/dist/node_modules/lucide-react/dist/esm/icons/shrink.js +23 -0
  800. package/dist/node_modules/lucide-react/dist/esm/icons/shrink.js.map +1 -0
  801. package/dist/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.cjs +2 -0
  802. package/dist/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.cjs.map +1 -0
  803. package/dist/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.js +43 -0
  804. package/dist/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.js.map +1 -0
  805. package/dist/node_modules/lucide-react/dist/esm/icons/tags.cjs +2 -0
  806. package/dist/node_modules/lucide-react/dist/esm/icons/tags.cjs.map +1 -0
  807. package/dist/node_modules/lucide-react/dist/esm/icons/tags.js +22 -0
  808. package/dist/node_modules/lucide-react/dist/esm/icons/tags.js.map +1 -0
  809. package/dist/package.cjs +1 -1
  810. package/dist/package.cjs.map +1 -1
  811. package/dist/package.js +4 -4
  812. package/dist/package.js.map +1 -1
  813. package/dist/routes/agent-settings.d.ts +2 -0
  814. package/dist/routes/app-settings.cjs +1 -1
  815. package/dist/routes/app-settings.cjs.map +1 -1
  816. package/dist/routes/app-settings.js +53 -48
  817. package/dist/routes/app-settings.js.map +1 -1
  818. package/dist/routes/llm-settings.cjs +1 -1
  819. package/dist/routes/llm-settings.cjs.map +1 -1
  820. package/dist/routes/llm-settings.d.ts +3 -1
  821. package/dist/routes/llm-settings.js +120 -127
  822. package/dist/routes/llm-settings.js.map +1 -1
  823. package/dist/routes/planner-tab.cjs +1 -1
  824. package/dist/routes/planner-tab.cjs.map +1 -1
  825. package/dist/routes/planner-tab.js +44 -28
  826. package/dist/routes/planner-tab.js.map +1 -1
  827. package/dist/services/telemetry.cjs +1 -1
  828. package/dist/services/telemetry.cjs.map +1 -1
  829. package/dist/services/telemetry.d.ts +5 -0
  830. package/dist/services/telemetry.js +122 -115
  831. package/dist/services/telemetry.js.map +1 -1
  832. package/dist/stores/conversation-panel-preferences-store.cjs +1 -1
  833. package/dist/stores/conversation-panel-preferences-store.cjs.map +1 -1
  834. package/dist/stores/conversation-panel-preferences-store.d.ts +32 -5
  835. package/dist/stores/conversation-panel-preferences-store.js +29 -12
  836. package/dist/stores/conversation-panel-preferences-store.js.map +1 -1
  837. package/dist/stores/conversation-state-store.cjs +1 -1
  838. package/dist/stores/conversation-state-store.cjs.map +1 -1
  839. package/dist/stores/conversation-state-store.d.ts +9 -3
  840. package/dist/stores/conversation-state-store.js +6 -3
  841. package/dist/stores/conversation-state-store.js.map +1 -1
  842. package/dist/stores/conversation-store.cjs +1 -1
  843. package/dist/stores/conversation-store.cjs.map +1 -1
  844. package/dist/stores/conversation-store.d.ts +2 -0
  845. package/dist/stores/conversation-store.js +3 -0
  846. package/dist/stores/conversation-store.js.map +1 -1
  847. package/dist/stores/free-models-store.cjs +2 -0
  848. package/dist/stores/free-models-store.cjs.map +1 -0
  849. package/dist/stores/free-models-store.d.ts +30 -0
  850. package/dist/stores/free-models-store.js +22 -0
  851. package/dist/stores/free-models-store.js.map +1 -0
  852. package/dist/stores/model-store.cjs +1 -1
  853. package/dist/stores/model-store.cjs.map +1 -1
  854. package/dist/stores/model-store.d.ts +7 -0
  855. package/dist/stores/model-store.js +4 -0
  856. package/dist/stores/model-store.js.map +1 -1
  857. package/dist/types/automation.cjs.map +1 -1
  858. package/dist/types/automation.d.ts +46 -1
  859. package/dist/types/automation.js.map +1 -1
  860. package/dist/ui/context-menu.d.ts +1 -1
  861. package/dist/ui/toggle-switch.cjs +1 -1
  862. package/dist/ui/toggle-switch.cjs.map +1 -1
  863. package/dist/ui/toggle-switch.d.ts +4 -1
  864. package/dist/ui/toggle-switch.js +4 -3
  865. package/dist/ui/toggle-switch.js.map +1 -1
  866. package/dist/utils/automation-catalog.cjs +1 -1
  867. package/dist/utils/automation-catalog.cjs.map +1 -1
  868. package/dist/utils/automation-catalog.d.ts +12 -1
  869. package/dist/utils/automation-catalog.js +42 -12
  870. package/dist/utils/automation-catalog.js.map +1 -1
  871. package/dist/utils/automation-run-display.cjs +2 -0
  872. package/dist/utils/automation-run-display.cjs.map +1 -0
  873. package/dist/utils/automation-run-display.d.ts +20 -0
  874. package/dist/utils/automation-run-display.js +85 -0
  875. package/dist/utils/automation-run-display.js.map +1 -0
  876. package/dist/utils/automation-schedule.cjs +1 -1
  877. package/dist/utils/automation-schedule.cjs.map +1 -1
  878. package/dist/utils/automation-schedule.d.ts +16 -0
  879. package/dist/utils/automation-schedule.js +2 -0
  880. package/dist/utils/automation-schedule.js.map +1 -1
  881. package/dist/utils/constants.cjs +1 -1
  882. package/dist/utils/constants.cjs.map +1 -1
  883. package/dist/utils/constants.d.ts +4 -0
  884. package/dist/utils/constants.js +23 -3
  885. package/dist/utils/constants.js.map +1 -1
  886. package/dist/utils/format-event-timestamp.cjs +2 -0
  887. package/dist/utils/format-event-timestamp.cjs.map +1 -0
  888. package/dist/utils/format-event-timestamp.d.ts +1 -0
  889. package/dist/utils/format-event-timestamp.js +13 -0
  890. package/dist/utils/format-event-timestamp.js.map +1 -0
  891. package/dist/utils/format-model-name.cjs +1 -1
  892. package/dist/utils/format-model-name.cjs.map +1 -1
  893. package/dist/utils/format-model-name.d.ts +27 -6
  894. package/dist/utils/format-model-name.js +14 -6
  895. package/dist/utils/format-model-name.js.map +1 -1
  896. package/dist/utils/git-diff-stats.cjs +2 -2
  897. package/dist/utils/git-diff-stats.cjs.map +1 -1
  898. package/dist/utils/git-diff-stats.d.ts +4 -0
  899. package/dist/utils/git-diff-stats.js +12 -2
  900. package/dist/utils/git-diff-stats.js.map +1 -1
  901. package/dist/utils/plan-file.cjs +4 -0
  902. package/dist/utils/plan-file.cjs.map +1 -0
  903. package/dist/utils/plan-file.d.ts +18 -0
  904. package/dist/utils/plan-file.js +58 -0
  905. package/dist/utils/plan-file.js.map +1 -0
  906. package/dist/utils/recommended-automation-rail.cjs +1 -1
  907. package/dist/utils/recommended-automation-rail.cjs.map +1 -1
  908. package/dist/utils/recommended-automation-rail.js +1 -0
  909. package/dist/utils/recommended-automation-rail.js.map +1 -1
  910. package/dist/utils/scroll-fade-state.cjs +1 -1
  911. package/dist/utils/scroll-fade-state.cjs.map +1 -1
  912. package/dist/utils/scroll-fade-state.d.ts +6 -0
  913. package/dist/utils/scroll-fade-state.js +8 -1
  914. package/dist/utils/scroll-fade-state.js.map +1 -1
  915. package/dist/utils/sdk-settings-schema.cjs +1 -1
  916. package/dist/utils/sdk-settings-schema.cjs.map +1 -1
  917. package/dist/utils/sdk-settings-schema.d.ts +1 -0
  918. package/dist/utils/sdk-settings-schema.js +25 -22
  919. package/dist/utils/sdk-settings-schema.js.map +1 -1
  920. package/dist/utils/utils.cjs +1 -1
  921. package/dist/utils/utils.cjs.map +1 -1
  922. package/dist/utils/utils.js +11 -11
  923. package/dist/utils/utils.js.map +1 -1
  924. package/package.json +4 -4
  925. package/scripts/check-sdk-version-sync.mjs +6 -6
  926. package/scripts/dev-safe.mjs +1 -1
  927. package/scripts/dev-with-automation.mjs +1 -1
  928. package/scripts/static-server.mjs +33 -1
  929. package/build/assets/active-backend-context-CrHTlgvN.js +0 -2
  930. package/build/assets/agent-profiles-settings-Dzgb7G9z.js +0 -1
  931. package/build/assets/agent-server-conversation-service.api-tnqNjbpE.js +0 -86
  932. package/build/assets/agent-settings-DLtsqaOs.js +0 -2
  933. package/build/assets/agent-settings-fFvR-XC2.js +0 -1
  934. package/build/assets/alert-banner-HP6mX-Vr.js +0 -1
  935. package/build/assets/api-key-entry-screen-qTzrmJcr.js +0 -1
  936. package/build/assets/app-settings-dbnneVaV.js +0 -1
  937. package/build/assets/automation-detail-BmwlCUAB.js +0 -3
  938. package/build/assets/automation-git-sync-CprN5DcU.js +0 -1
  939. package/build/assets/automation-setup-route-C40kXjMY.js +0 -1
  940. package/build/assets/automations-list-DuNcRawl.js +0 -1
  941. package/build/assets/backend-form-modal-lhGwzXFI.js +0 -1
  942. package/build/assets/backend-synced-settings-badge-DPkz30BE.js +0 -1
  943. package/build/assets/badge-BU3S0VtE.js +0 -1
  944. package/build/assets/bot-dMYHVfYM.js +0 -1
  945. package/build/assets/browser-DSAo0tz1.js +0 -46
  946. package/build/assets/browser-tab-C9vy56R5.js +0 -1
  947. package/build/assets/canvas-extension-page-dx1gFrfW.js +0 -1
  948. package/build/assets/canvas-extensions-8A-XhpgP.js +0 -1
  949. package/build/assets/check-CS0vmpQQ.js +0 -1
  950. package/build/assets/chevron-down-e1QBpjVy.js +0 -1
  951. package/build/assets/chevron-right-ZG4R5G4Q.js +0 -1
  952. package/build/assets/circle-check-DzWLNsbE.js +0 -1
  953. package/build/assets/circle-plus-check-toggle-BO_kFZt3.js +0 -1
  954. package/build/assets/command-menu--UIlGL72.js +0 -1
  955. package/build/assets/commits-tab-AnZwLvh-.js +0 -1
  956. package/build/assets/confirmation-modal-Dv1ktp8K.js +0 -1
  957. package/build/assets/conversation-BbGrAO4Z.js +0 -93
  958. package/build/assets/conversation-mYT6NAoj.js +0 -1
  959. package/build/assets/conversation-panel-mYT6NAoj.js +0 -1
  960. package/build/assets/conversation-state-store-B0ImPLHO.js +0 -1
  961. package/build/assets/conversation-store-Ca3ghXap.js +0 -6
  962. package/build/assets/copy-to-clipboard-button-Ca8iSkkA.js +0 -1
  963. package/build/assets/device-verify-Bhn2e_Ye.js +0 -1
  964. package/build/assets/edit-automation-modal-DadGbJ2u.js +0 -1
  965. package/build/assets/empty-state-BoGVDecT.js +0 -1
  966. package/build/assets/enum-filter-dropdown-Bgca129f.js +0 -1
  967. package/build/assets/environment-switch-overlay-BmBRT7gv.js +0 -1
  968. package/build/assets/error-state-Body8Ngd.js +0 -1
  969. package/build/assets/extensions-hub-CcDqq_vR.js +0 -1
  970. package/build/assets/extensions-navigation-Cr4yzYk4.js +0 -1
  971. package/build/assets/external-link-DKUlnCQV.js +0 -1
  972. package/build/assets/files-tab-D4o2VyE_.js +0 -1
  973. package/build/assets/format-model-name-CasAP3nd.js +0 -1
  974. package/build/assets/get-git-path-ChKDVHZp.js +0 -1
  975. package/build/assets/git-repo-dropdown-4ROKl2cB.js +0 -1
  976. package/build/assets/git-repo-dropdown-BkqzkMmM.js +0 -1
  977. package/build/assets/highlighted-source-view-BFRxGT_Q.js +0 -1
  978. package/build/assets/home-ChpSuepX.js +0 -1
  979. package/build/assets/home-DIsB440S.js +0 -1
  980. package/build/assets/home-automation-run-tooltip-BVNDWjAH.js +0 -1
  981. package/build/assets/home-store-CY9Ej0ux.js +0 -1
  982. package/build/assets/index-home-BdlrFIif.js +0 -1
  983. package/build/assets/info-B6RQawoW.js +0 -1
  984. package/build/assets/install-server-modal-Dpy89p4g.js +0 -1
  985. package/build/assets/kebab-menu-item-content-D8hSNGmm.js +0 -1
  986. package/build/assets/launch-IrTDEFCs.js +0 -1
  987. package/build/assets/list-filter-DsEK7NFC.js +0 -1
  988. package/build/assets/llm-not-configured-banner-CIFABh3K.js +0 -27
  989. package/build/assets/llm-settings-B9juXhIa.js +0 -1
  990. package/build/assets/llm-settings-De1d5dfr.js +0 -1
  991. package/build/assets/llm-subscription-service-BpJ0ouQo.js +0 -1
  992. package/build/assets/loader-circle-CC1au6hc.js +0 -1
  993. package/build/assets/manage-backends-modal-BrPV3oB-.js +0 -1
  994. package/build/assets/manifest-80fb1c29.js +0 -1
  995. package/build/assets/manifest-subpage-layout-CAOYzrYp.js +0 -1
  996. package/build/assets/markdown-renderer-BzTlxI8x.js +0 -8
  997. package/build/assets/mcp-BTs_SXfZ.js +0 -1
  998. package/build/assets/mcp-page-BEBYqH_K.js +0 -9
  999. package/build/assets/messages-DKV9cRc2.js +0 -41
  1000. package/build/assets/modal-close-button-DDzdRvCs.js +0 -1
  1001. package/build/assets/onboarding-DV_OXoeP.js +0 -1
  1002. package/build/assets/onboarding-modal-rkyBYkeQ.js +0 -1
  1003. package/build/assets/organization-service.api-DrYNkEN_.js +0 -1
  1004. package/build/assets/pencil-47jAZH_V.js +0 -1
  1005. package/build/assets/pin-By41Vl5J.js +0 -1
  1006. package/build/assets/planner-tab-C9uZmhme.js +0 -1
  1007. package/build/assets/plug-CG5HFcNG.js +0 -1
  1008. package/build/assets/plugins-management-service-BMJgC3Ga.js +0 -1
  1009. package/build/assets/plus-C7Slq-0I.js +0 -1
  1010. package/build/assets/profiles-service.api-ChoKrL0l.js +0 -1
  1011. package/build/assets/providers-BhMcY5nv.js +0 -1
  1012. package/build/assets/proxy-9Fe1v5na.js +0 -1
  1013. package/build/assets/recommended-automations-launcher-6ABrI9Cy.js +0 -1
  1014. package/build/assets/refresh-cw-3q3Frrii.js +0 -1
  1015. package/build/assets/root-Dc8YmC9F.js +0 -2
  1016. package/build/assets/root-VDaypvK4.css +0 -1
  1017. package/build/assets/root-layout-CXkhSPYh.js +0 -2
  1018. package/build/assets/schema-field-D-y9-LDb.js +0 -1
  1019. package/build/assets/scroll-fade-state-Dw-i4SGq.js +0 -1
  1020. package/build/assets/sdk-section-page-BlFiizlG.js +0 -1
  1021. package/build/assets/secret-form-BB7the8W.js +0 -1
  1022. package/build/assets/secrets-service-ByZVENbp.js +0 -1
  1023. package/build/assets/secrets-settings-B_GpxKW2.js +0 -1
  1024. package/build/assets/settings-C0EWuBtA.js +0 -1
  1025. package/build/assets/settings-dropdown-input-BcwylHs2.js +0 -1
  1026. package/build/assets/settings-index-5w5UW2K3.js +0 -1
  1027. package/build/assets/settings-input-Db-1g8Ql.js +0 -1
  1028. package/build/assets/settings-modal-DfJ3tcJQ.js +0 -1
  1029. package/build/assets/settings-service.api-DJ1r62Zr.js +0 -1
  1030. package/build/assets/settings-switch-CS-dJDmA.js +0 -1
  1031. package/build/assets/shared-conversation-CA5ISEDy.js +0 -1
  1032. package/build/assets/shield-check-D2aCRd16.js +0 -1
  1033. package/build/assets/sidebar-mobile-menu-toggle-C_fb0Jki.js +0 -1
  1034. package/build/assets/sidebar-store-DGqHkVLw.js +0 -1
  1035. package/build/assets/skill-card-pill-row-B27-xyig.js +0 -1
  1036. package/build/assets/skill-scope-B42H-XOc.js +0 -1
  1037. package/build/assets/skills-plugins-tgF8EiXC.js +0 -1
  1038. package/build/assets/skills-settings-BgJ9PaOe.js +0 -1
  1039. package/build/assets/styled-tooltip-C4jf5Fv9.js +0 -1
  1040. package/build/assets/task-list-tab-C5zcaktH.js +0 -1
  1041. package/build/assets/toggle-switch-ChOLXv2n.js +0 -1
  1042. package/build/assets/trash-2-D7K26eDO.js +0 -1
  1043. package/build/assets/trash-D-HYiVYM.js +0 -1
  1044. package/build/assets/triangle-alert-CtdXWHUI.js +0 -1
  1045. package/build/assets/usage-tab-CVDffLPt.js +0 -1
  1046. package/build/assets/use-acp-credential-form-XIQmpX6M.js +0 -1
  1047. package/build/assets/use-activate-agent-profile-BLfmvDiG.js +0 -1
  1048. package/build/assets/use-agent-profiles-Bd9Bvvp1.js +0 -1
  1049. package/build/assets/use-canvas-extensions-Bi693ujJ.js +0 -1
  1050. package/build/assets/use-config-A9QovgXO.js +0 -1
  1051. package/build/assets/use-create-conversation-Dx3l7mFZ.js +0 -1
  1052. package/build/assets/use-create-secret-B9cUFWRG.js +0 -1
  1053. package/build/assets/use-has-permission-B3C8rQmR.js +0 -1
  1054. package/build/assets/use-is-authed-nTBcM7dE.js +0 -1
  1055. package/build/assets/use-llm-configured-BV9nZ1_j.js +0 -1
  1056. package/build/assets/use-llm-profiles-BO-P4Oyo.js +0 -1
  1057. package/build/assets/use-manifest-capabilities-Cw_flwEz.js +0 -1
  1058. package/build/assets/use-onboarding-completion-D8U7k4Qb.js +0 -1
  1059. package/build/assets/use-pinned-home-route-CckOZrmb.js +0 -1
  1060. package/build/assets/use-plugins-marketplace-7i94Zu3Z.js +0 -1
  1061. package/build/assets/use-save-agent-profile-BUjSsDXK.js +0 -1
  1062. package/build/assets/use-settings-DSXLbvBl.js +0 -1
  1063. package/build/assets/use-settings-nav-items-CwRw-CmX.js +0 -16
  1064. package/build/assets/use-tracking-D53y3TH9.js +0 -3
  1065. package/build/assets/useQueries-DlbhlH9I.js +0 -1
  1066. package/build/assets/useQuery-BSTgq1rl.js +0 -1
  1067. package/build/assets/utils-CN5ZfZy1.js +0 -1
  1068. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~czjee3a3-DqZDXfg2.js +0 -186
  1069. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ew9ih1s8-rfV8mQ9m.js +0 -1
  1070. package/build/assets/vendor~root-layout-C9Ju9DQg.js +0 -1
  1071. package/build/assets/vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-BWir3rJs.js +0 -1
  1072. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~mcp~automations-list~aut~ibfbmr9f-cDuKr-WD.js +0 -1
  1073. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~iyia17eu-Chf7vmKB.js +0 -1
  1074. package/build/assets/x-DJdhbdmt.js +0 -1
  1075. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs +0 -2
  1076. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs.map +0 -1
  1077. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.d.ts +0 -35
  1078. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js +0 -247
  1079. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js.map +0 -1
  1080. package/dist/hooks/query/use-skills.cjs +0 -2
  1081. package/dist/hooks/query/use-skills.cjs.map +0 -1
  1082. package/dist/hooks/query/use-skills.d.ts +0 -7
  1083. package/dist/hooks/query/use-skills.js +0 -13
  1084. package/dist/hooks/query/use-skills.js.map +0 -1
  1085. package/dist/hooks/use-has-permission.cjs +0 -2
  1086. package/dist/hooks/use-has-permission.cjs.map +0 -1
  1087. package/dist/hooks/use-has-permission.d.ts +0 -1
  1088. package/dist/hooks/use-has-permission.js +0 -8
  1089. package/dist/hooks/use-has-permission.js.map +0 -1
  1090. package/dist/node_modules/lucide-react/dist/esm/icons/eye.cjs +0 -2
  1091. package/dist/node_modules/lucide-react/dist/esm/icons/eye.cjs.map +0 -1
  1092. package/dist/node_modules/lucide-react/dist/esm/icons/eye.js +0 -14
  1093. package/dist/node_modules/lucide-react/dist/esm/icons/eye.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"backend-selector.js","names":[],"sources":["../../../../src/components/features/backends/backend-selector.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useMatch, useNavigate } from \"react-router\";\nimport { Plus, Settings } from \"lucide-react\";\nimport { Dropdown } from \"#/ui/dropdown/dropdown\";\nimport { DropdownOption } from \"#/ui/dropdown/types\";\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\nimport { isNoBackend } from \"#/api/backend-registry/active-store\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { useAllCloudOrganizations } from \"#/hooks/query/use-cloud-organizations\";\nimport { useCloudCurrentUserId } from \"#/hooks/query/use-cloud-current-user-id\";\nimport {\n useBackendsHealth,\n type BackendHealth,\n} from \"#/hooks/query/use-backends-health\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport type { Backend } from \"#/api/backend-registry/types\";\n// Import the trigger helpers from the lightweight store, not the overlay\n// component, so the eagerly-mounted sidebar/backend-selector graph does not\n// pull in the overlay's render code (the overlay is lazy-loaded from\n// `routes/root-layout.tsx`).\nimport {\n ENVIRONMENT_SWITCH_SETACTIVE_DELAY_MS,\n triggerEnvironmentSwitch,\n} from \"#/components/features/backends/environment-switch-store\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { AddBackendModal } from \"./add-backend-modal\";\nimport { BackendStatusDot } from \"./backend-status-dot\";\nimport { ManageBackendsModal } from \"./manage-backends-modal\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlTransitionClassName } from \"#/utils/form-control-classes\";\nimport {\n dropdownFooterActionClassName,\n dropdownMenuListClassName,\n dropdownMenuRowIconWrapperClassName,\n} from \"#/utils/dropdown-classes\";\n\nconst VALUE_SEPARATOR = \"::\";\n\nfunction makeOptionValue(backendId: string, orgId: string | null): string {\n return orgId ? `${backendId}${VALUE_SEPARATOR}${orgId}` : backendId;\n}\n\nfunction parseOptionValue(value: string): {\n backendId: string;\n orgId: string | null;\n} {\n const [backendId, orgId] = value.split(VALUE_SEPARATOR);\n return { backendId, orgId: orgId ?? null };\n}\n\nfunction buildStatusPrefix(health: BackendHealth | undefined) {\n return <BackendStatusDot isConnected={health?.isConnected ?? null} />;\n}\n\nfunction buildNoBackendPrefix() {\n return <BackendStatusDot isConnected=\"unavailable\" />;\n}\n\nfunction buildOptions(\n registered: Backend[],\n personalWorkspaceLabel: string,\n cloudOrgs: ReturnType<typeof useAllCloudOrganizations>,\n currentUserIds: ReturnType<typeof useCloudCurrentUserId>,\n healthByBackendId: Record<string, BackendHealth>,\n): DropdownOption[] {\n const options: DropdownOption[] = [];\n\n const locals = registered.filter((b) => b.kind === \"local\");\n const clouds = registered.filter((b) => b.kind === \"cloud\");\n\n for (const b of locals) {\n options.push({\n value: makeOptionValue(b.id, null),\n label: b.name,\n prefix: buildStatusPrefix(healthByBackendId[b.id]),\n });\n }\n\n for (const b of clouds) {\n const entry = cloudOrgs[b.id];\n const prefix = buildStatusPrefix(healthByBackendId[b.id]);\n if (!entry || entry.orgs.length === 0) {\n options.push({\n value: makeOptionValue(b.id, null),\n label: b.name,\n prefix,\n });\n } else {\n // Personal-workspace rule (per the cloud contract): the org whose\n // id matches the calling user's id is the user's personal\n // workspace. We resolve `user_id` once per backend (via /me on any\n // one org) and apply it across all orgs of that backend.\n const userIdForBackend = currentUserIds[b.id]?.userId ?? null;\n\n for (const org of entry.orgs) {\n const isPersonal = !!userIdForBackend && userIdForBackend === org.id;\n const orgLabel = isPersonal ? personalWorkspaceLabel : org.name;\n options.push({\n value: makeOptionValue(b.id, org.id),\n label: `${b.name} – ${orgLabel}`,\n // All org rows for the same cloud backend share that backend's\n // single connectivity verdict — there is no per-org probe.\n prefix,\n });\n }\n }\n }\n\n return options;\n}\n\ninterface BackendSelectorProps {\n /** Render the menu above the trigger (e.g. when pinned to bottom of sidebar). */\n openUpward?: boolean;\n /** Hide the selector input trigger and only render the dropdown menu. */\n hideTrigger?: boolean;\n /** Whether the dropdown menu should start open on mount. */\n defaultOpen?: boolean;\n /** Callback fired after selecting a backend/org option. */\n onSelectOption?: () => void;\n /**\n * Override the internal Add Backend modal handling. When provided,\n * clicking \"Add Backend\" calls this instead of opening BackendSelector's\n * own modal. Useful when the selector is mounted inside an ephemeral\n * container (e.g. the collapsed-sidebar popover) and the modal must\n * survive the parent unmounting.\n */\n onOpenAddBackend?: () => void;\n /** Same as onOpenAddBackend but for the Manage Backends modal. */\n onOpenManageBackends?: () => void;\n /**\n * Whether the surrounding sidebar rail is in its collapsed variant. Passed\n * down from `SidebarRailBody` so the mobile drawer (which always renders\n * the expanded rail) can override the persisted desktop value.\n */\n sidebarCollapsed?: boolean;\n}\n\nexport function BackendSelector({\n openUpward = false,\n hideTrigger = false,\n defaultOpen = false,\n onSelectOption,\n onOpenAddBackend,\n onOpenManageBackends,\n sidebarCollapsed = false,\n}: BackendSelectorProps = {}) {\n const { t } = useTranslation(\"openhands\");\n const { backends, active, setActive } = useActiveBackendContext();\n const cloudOrgs = useAllCloudOrganizations();\n const currentUserIds = useCloudCurrentUserId();\n // Probe each registered backend every 10s.\n const healthByBackendId = useBackendsHealth(backends);\n const navigate = useNavigate();\n const settingsMatch = useMatch(\"/settings\");\n const settingsSubrouteMatch = useMatch(\"/settings/*\");\n const conversationMatch = useMatch(\"/conversations/:conversationId\");\n const automationDetailMatch = useMatch(\"/automations/:automationId\");\n const [addBackendModalOpen, setAddBackendModalOpen] = React.useState(false);\n const [manageBackendsModalOpen, setManageBackendsModalOpen] =\n React.useState(false);\n\n const personalWorkspaceLabel = t(I18nKey.BACKEND$PERSONAL_WORKSPACE);\n\n const options = React.useMemo(\n () =>\n buildOptions(\n backends,\n personalWorkspaceLabel,\n cloudOrgs,\n currentUserIds,\n healthByBackendId,\n ),\n [\n backends,\n personalWorkspaceLabel,\n cloudOrgs,\n currentUserIds,\n healthByBackendId,\n ],\n );\n\n const noBackendSelected = isNoBackend(active.backend);\n const noBackendLabel = t(I18nKey.BACKEND$NO_BACKEND_AVAILABLE);\n const activeValue = makeOptionValue(active.backend.id, active.orgId);\n const activeOption = noBackendSelected\n ? undefined\n : options.find((o) => o.value === activeValue);\n const isSettingsActive = Boolean(settingsMatch || settingsSubrouteMatch);\n const settingsLabel = t(I18nKey.SIDEBAR$SETTINGS);\n const isRightPanelShown = useConversationStore(\n (state) => state.isRightPanelShown,\n );\n // When the sidebar rail is expanded, `placement=\"left\"` hugs the main\n // canvas and reads awkwardly; prefer above the control. When the rail is\n // collapsed, keep left except on active conversation + open right drawer.\n const settingsTooltipPlacement =\n !sidebarCollapsed || (conversationMatch && isRightPanelShown)\n ? \"top\"\n : \"left\";\n\n const someCloudLoading = Object.values(cloudOrgs).some((c) => c.isLoading);\n\n // Self-heal a malformed `(cloudBackendId, null)` selection.\n //\n // Once a cloud backend's orgs resolve, the dropdown only renders\n // per-org rows for it — the `(backendId, null)` row disappears, so\n // selecting that shape would drift from what the dropdown can render\n // (UI says \"Local\", APIs hit cloud). When we detect the drift, snap\n // the selection onto Cloud's current org first, then fall back to the\n // personal workspace (or, lacking a /me result, the first org). The\n // selection is recorded locally only; the cloud request scope follows\n // from the X-Org-Id header sent by `callCloudProxy`, so the cloud UI's\n // org choice is never mutated as a side effect.\n React.useEffect(() => {\n if (noBackendSelected || active.backend.kind !== \"cloud\" || active.orgId)\n return;\n const { backend } = active;\n const entry = cloudOrgs[backend.id];\n if (!entry || entry.orgs.length === 0) return;\n\n const currentOrg = entry.currentOrgId\n ? entry.orgs.find((o) => o.id === entry.currentOrgId)\n : undefined;\n const userId = currentUserIds[backend.id]?.userId ?? null;\n const personal = userId\n ? entry.orgs.find((o) => o.id === userId)\n : undefined;\n const target = currentOrg ?? personal ?? entry.orgs[0];\n if (target) {\n setActive(backend.id, target.id);\n }\n }, [active, cloudOrgs, currentUserIds, setActive, noBackendSelected]);\n\n const openAddBackendModal = React.useCallback(() => {\n if (onOpenAddBackend) {\n onOpenAddBackend();\n onSelectOption?.();\n return;\n }\n setAddBackendModalOpen(true);\n }, [onOpenAddBackend, onSelectOption]);\n\n const openManageBackendsModal = React.useCallback(() => {\n if (onOpenManageBackends) {\n onOpenManageBackends();\n onSelectOption?.();\n return;\n }\n setManageBackendsModalOpen(true);\n }, [onOpenManageBackends, onSelectOption]);\n\n const isLockedToCloud = getLockedCloudHost() !== null;\n\n const preventDropdownMenuClose = React.useCallback(\n (event: React.SyntheticEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n },\n [],\n );\n\n const handleAddBackendClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openAddBackendModal();\n },\n [openAddBackendModal, preventDropdownMenuClose],\n );\n\n const handleAddBackendTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openAddBackendModal();\n },\n [openAddBackendModal, preventDropdownMenuClose],\n );\n\n const handleManageBackendsClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openManageBackendsModal();\n },\n [openManageBackendsModal, preventDropdownMenuClose],\n );\n\n const handleManageBackendsTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openManageBackendsModal();\n },\n [openManageBackendsModal, preventDropdownMenuClose],\n );\n\n const addBackendFooter = (\n <div className={dropdownMenuListClassName}>\n {isLockedToCloud ? null : (\n <button\n type=\"button\"\n data-testid=\"add-backend-menu-item\"\n onMouseDown={preventDropdownMenuClose}\n onTouchStart={preventDropdownMenuClose}\n onTouchEnd={handleAddBackendTouchEnd}\n onClick={handleAddBackendClick}\n className={cn(\n dropdownFooterActionClassName,\n \"cursor-pointer rounded-md\",\n )}\n >\n <span className={dropdownMenuRowIconWrapperClassName} aria-hidden>\n <Plus width={16} height={16} />\n </span>\n {t(I18nKey.BACKEND$ADD)}\n </button>\n )}\n <button\n type=\"button\"\n data-testid=\"manage-backends-menu-item\"\n onMouseDown={preventDropdownMenuClose}\n onTouchStart={preventDropdownMenuClose}\n onTouchEnd={handleManageBackendsTouchEnd}\n onClick={handleManageBackendsClick}\n className={cn(\n dropdownFooterActionClassName,\n \"cursor-pointer rounded-md\",\n )}\n >\n <span className={dropdownMenuRowIconWrapperClassName} aria-hidden>\n <Settings width={16} height={16} />\n </span>\n {t(\n isLockedToCloud\n ? I18nKey.BACKEND$RECONNECT_CLOUD\n : I18nKey.BACKEND$MANAGE,\n )}\n </button>\n </div>\n );\n\n const handleSelectBackend = React.useCallback(\n async (value: string) => {\n if (value === activeValue) return;\n\n const { backendId, orgId } = parseOptionValue(value);\n const target = backends.find((b) => b.id === backendId);\n if (!target) return;\n\n triggerEnvironmentSwitch(\n options.find((option) => option.value === value)?.label ?? target.name,\n );\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ENVIRONMENT_SWITCH_SETACTIVE_DELAY_MS);\n });\n\n // @spec BM-002 — Switching backends keeps the user on the same page\n if (conversationMatch) navigate(\"/conversations\");\n else if (automationDetailMatch) navigate(\"/automations\");\n\n setActive(target.id, orgId);\n onSelectOption?.();\n },\n [\n activeValue,\n backends,\n conversationMatch,\n automationDetailMatch,\n navigate,\n options,\n setActive,\n t,\n onSelectOption,\n ],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-2 w-full\">\n <div className=\"flex-1 min-w-0\">\n <Dropdown\n testId=\"backend-selector\"\n key={`${activeValue}-${activeOption?.label ?? \"\"}`}\n defaultValue={\n activeOption ?? {\n value: activeValue,\n label: noBackendSelected ? noBackendLabel : active.backend.name,\n prefix: noBackendSelected\n ? buildNoBackendPrefix()\n : buildStatusPrefix(healthByBackendId[active.backend.id]),\n }\n }\n footer={addBackendFooter}\n openUpward={openUpward}\n hideTrigger={hideTrigger}\n defaultOpen={defaultOpen}\n openOnHover={!hideTrigger}\n onChange={(item) => {\n if (!item) return;\n void handleSelectBackend(item.value);\n }}\n placeholder={\n noBackendSelected ? noBackendLabel : active.backend.name\n }\n loading={someCloudLoading}\n options={options}\n className=\"h-10 px-2 py-0 bg-transparent border-transparent hover:bg-[var(--oh-surface-raised)] focus-within:bg-[var(--oh-surface-raised)] focus-within:border-transparent focus-within:ring-0\"\n />\n </div>\n {!hideTrigger ? (\n <StyledTooltip\n content={settingsLabel}\n placement={settingsTooltipPlacement}\n offset={10}\n >\n <NavigationLink\n to=\"/settings\"\n data-testid=\"backend-selector-settings-link\"\n data-active={isSettingsActive}\n aria-label={settingsLabel}\n className={\n isSettingsActive\n ? cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md bg-tertiary text-white font-normal cursor-pointer\",\n formControlTransitionClassName,\n )\n : cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)] cursor-pointer\",\n formControlTransitionClassName,\n )\n }\n >\n <Settings width={16} height={16} />\n </NavigationLink>\n </StyledTooltip>\n ) : null}\n </div>\n {addBackendModalOpen ? (\n <AddBackendModal onClose={() => setAddBackendModalOpen(false)} />\n ) : null}\n {manageBackendsModalOpen ? (\n <ManageBackendsModal\n onClose={() => setManageBackendsModalOpen(false)}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"backend-selector.js","names":[],"sources":["../../../../src/components/features/backends/backend-selector.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useMatch, useNavigate } from \"react-router\";\nimport { Plus, Settings } from \"lucide-react\";\nimport { Dropdown } from \"#/ui/dropdown/dropdown\";\nimport { DropdownOption } from \"#/ui/dropdown/types\";\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\nimport { isNoBackend } from \"#/api/backend-registry/active-store\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { useAllCloudOrganizations } from \"#/hooks/query/use-cloud-organizations\";\nimport { useCloudCurrentUserId } from \"#/hooks/query/use-cloud-current-user-id\";\nimport {\n useBackendsHealth,\n type BackendHealth,\n} from \"#/hooks/query/use-backends-health\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport type { Backend } from \"#/api/backend-registry/types\";\n// Import the trigger helpers from the lightweight store, not the overlay\n// component, so the eagerly-mounted sidebar/backend-selector graph does not\n// pull in the overlay's render code (the overlay is lazy-loaded from\n// `routes/root-layout.tsx`).\nimport {\n ENVIRONMENT_SWITCH_SETACTIVE_DELAY_MS,\n triggerEnvironmentSwitch,\n} from \"#/components/features/backends/environment-switch-store\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { AddBackendModal } from \"./add-backend-modal\";\nimport { BackendStatusDot } from \"./backend-status-dot\";\nimport { ManageBackendsModal } from \"./manage-backends-modal\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlTransitionClassName } from \"#/utils/form-control-classes\";\nimport {\n dropdownFooterActionClassName,\n dropdownMenuListClassName,\n dropdownMenuRowIconWrapperClassName,\n} from \"#/utils/dropdown-classes\";\n\nconst VALUE_SEPARATOR = \"::\";\n\nfunction makeOptionValue(backendId: string, orgId: string | null): string {\n return orgId ? `${backendId}${VALUE_SEPARATOR}${orgId}` : backendId;\n}\n\nfunction parseOptionValue(value: string): {\n backendId: string;\n orgId: string | null;\n} {\n const [backendId, orgId] = value.split(VALUE_SEPARATOR);\n return { backendId, orgId: orgId ?? null };\n}\n\nfunction buildStatusPrefix(health: BackendHealth | undefined) {\n return <BackendStatusDot isConnected={health?.isConnected ?? null} />;\n}\n\nfunction buildNoBackendPrefix() {\n return <BackendStatusDot isConnected=\"unavailable\" />;\n}\n\nfunction buildOptions(\n registered: Backend[],\n personalWorkspaceLabel: string,\n cloudOrgs: ReturnType<typeof useAllCloudOrganizations>,\n currentUserIds: ReturnType<typeof useCloudCurrentUserId>,\n healthByBackendId: Record<string, BackendHealth>,\n): DropdownOption[] {\n const options: DropdownOption[] = [];\n\n const locals = registered.filter((b) => b.kind === \"local\");\n const clouds = registered.filter((b) => b.kind === \"cloud\");\n\n for (const b of locals) {\n options.push({\n value: makeOptionValue(b.id, null),\n label: b.name,\n prefix: buildStatusPrefix(healthByBackendId[b.id]),\n });\n }\n\n for (const b of clouds) {\n const entry = cloudOrgs[b.id];\n const prefix = buildStatusPrefix(healthByBackendId[b.id]);\n if (!entry || entry.orgs.length === 0) {\n options.push({\n value: makeOptionValue(b.id, null),\n label: b.name,\n prefix,\n });\n } else {\n // Personal-workspace rule (per the cloud contract): the org whose\n // id matches the calling user's id is the user's personal\n // workspace. We resolve `user_id` once per backend (via /me on any\n // one org) and apply it across all orgs of that backend.\n const userIdForBackend = currentUserIds[b.id]?.userId ?? null;\n\n for (const org of entry.orgs) {\n const isPersonal = !!userIdForBackend && userIdForBackend === org.id;\n const orgLabel = isPersonal ? personalWorkspaceLabel : org.name;\n options.push({\n value: makeOptionValue(b.id, org.id),\n label: `${b.name} – ${orgLabel}`,\n // All org rows for the same cloud backend share that backend's\n // single connectivity verdict — there is no per-org probe.\n prefix,\n });\n }\n }\n }\n\n return options;\n}\n\ninterface BackendSelectorProps {\n /** Render the menu above the trigger (e.g. when pinned to bottom of sidebar). */\n openUpward?: boolean;\n /** Hide the selector input trigger and only render the dropdown menu. */\n hideTrigger?: boolean;\n /** Whether the dropdown menu should start open on mount. */\n defaultOpen?: boolean;\n /** Callback fired after selecting a backend/org option. */\n onSelectOption?: () => void;\n /**\n * Override the internal Add Backend modal handling. When provided,\n * clicking \"Add Backend\" calls this instead of opening BackendSelector's\n * own modal. Useful when the selector is mounted inside an ephemeral\n * container (e.g. the collapsed-sidebar popover) and the modal must\n * survive the parent unmounting.\n */\n onOpenAddBackend?: () => void;\n /** Same as onOpenAddBackend but for the Manage Backends modal. */\n onOpenManageBackends?: () => void;\n /**\n * Whether the surrounding sidebar rail is in its collapsed variant. Passed\n * down from `SidebarRailBody` so the mobile drawer (which always renders\n * the expanded rail) can override the persisted desktop value.\n */\n sidebarCollapsed?: boolean;\n}\n\nexport function BackendSelector({\n openUpward = false,\n hideTrigger = false,\n defaultOpen = false,\n onSelectOption,\n onOpenAddBackend,\n onOpenManageBackends,\n sidebarCollapsed = false,\n}: BackendSelectorProps = {}) {\n const { t } = useTranslation(\"openhands\");\n const { backends, active, setActive } = useActiveBackendContext();\n const cloudOrgs = useAllCloudOrganizations();\n const currentUserIds = useCloudCurrentUserId();\n // Probe each registered backend every 10s.\n const healthByBackendId = useBackendsHealth(backends);\n const navigate = useNavigate();\n const settingsMatch = useMatch(\"/settings\");\n const settingsSubrouteMatch = useMatch(\"/settings/*\");\n const conversationMatch = useMatch(\"/conversations/:conversationId\");\n const automationDetailMatch = useMatch(\"/automations/:automationId\");\n const [addBackendModalOpen, setAddBackendModalOpen] = React.useState(false);\n const [manageBackendsModalOpen, setManageBackendsModalOpen] =\n React.useState(false);\n\n const personalWorkspaceLabel = t(I18nKey.BACKEND$PERSONAL_WORKSPACE);\n\n const options = React.useMemo(\n () =>\n buildOptions(\n backends,\n personalWorkspaceLabel,\n cloudOrgs,\n currentUserIds,\n healthByBackendId,\n ),\n [\n backends,\n personalWorkspaceLabel,\n cloudOrgs,\n currentUserIds,\n healthByBackendId,\n ],\n );\n\n const noBackendSelected = isNoBackend(active.backend);\n const noBackendLabel = t(I18nKey.BACKEND$NO_BACKEND_AVAILABLE);\n const activeValue = makeOptionValue(active.backend.id, active.orgId);\n const activeOption = noBackendSelected\n ? undefined\n : options.find((o) => o.value === activeValue);\n const isSettingsActive = Boolean(settingsMatch || settingsSubrouteMatch);\n const settingsLabel = t(I18nKey.SIDEBAR$SETTINGS);\n // `org` is consumed by the cloud settings loader so the page opens on the\n // org that is active here instead of the cloud's last-used org.\n const cloudSettingsOrgQuery = active.orgId\n ? `?org=${encodeURIComponent(active.orgId)}`\n : \"\";\n const isRightPanelShown = useConversationStore(\n (state) => state.isRightPanelShown,\n );\n // When the sidebar rail is expanded, `placement=\"left\"` hugs the main\n // canvas and reads awkwardly; prefer above the control. When the rail is\n // collapsed, keep left except on active conversation + open right drawer.\n const settingsTooltipPlacement =\n !sidebarCollapsed || (conversationMatch && isRightPanelShown)\n ? \"top\"\n : \"left\";\n\n const someCloudLoading = Object.values(cloudOrgs).some((c) => c.isLoading);\n\n // Self-heal a malformed `(cloudBackendId, null)` selection.\n //\n // Once a cloud backend's orgs resolve, the dropdown only renders\n // per-org rows for it — the `(backendId, null)` row disappears, so\n // selecting that shape would drift from what the dropdown can render\n // (UI says \"Local\", APIs hit cloud). When we detect the drift, snap\n // the selection onto Cloud's current org first, then fall back to the\n // personal workspace (or, lacking a /me result, the first org). The\n // selection is recorded locally only; the cloud request scope follows\n // from the X-Org-Id header sent by `callCloudProxy`, so the cloud UI's\n // org choice is never mutated as a side effect.\n React.useEffect(() => {\n if (noBackendSelected || active.backend.kind !== \"cloud\" || active.orgId)\n return;\n const { backend } = active;\n const entry = cloudOrgs[backend.id];\n if (!entry || entry.orgs.length === 0) return;\n\n const currentOrg = entry.currentOrgId\n ? entry.orgs.find((o) => o.id === entry.currentOrgId)\n : undefined;\n const userId = currentUserIds[backend.id]?.userId ?? null;\n const personal = userId\n ? entry.orgs.find((o) => o.id === userId)\n : undefined;\n const target = currentOrg ?? personal ?? entry.orgs[0];\n if (target) {\n setActive(backend.id, target.id);\n }\n }, [active, cloudOrgs, currentUserIds, setActive, noBackendSelected]);\n\n const openAddBackendModal = React.useCallback(() => {\n if (onOpenAddBackend) {\n onOpenAddBackend();\n onSelectOption?.();\n return;\n }\n setAddBackendModalOpen(true);\n }, [onOpenAddBackend, onSelectOption]);\n\n const openManageBackendsModal = React.useCallback(() => {\n if (onOpenManageBackends) {\n onOpenManageBackends();\n onSelectOption?.();\n return;\n }\n setManageBackendsModalOpen(true);\n }, [onOpenManageBackends, onSelectOption]);\n\n const isLockedToCloud = getLockedCloudHost() !== null;\n // A cookie-auth (OHE-hosted) Canvas has nothing to add, manage, or\n // reconnect — its single locked backend is owned by the main-app session.\n const hideBackendFooter =\n isLockedToCloud && active.backend.authMode === \"cookie\";\n\n const preventDropdownMenuClose = React.useCallback(\n (event: React.SyntheticEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n },\n [],\n );\n\n const handleAddBackendClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openAddBackendModal();\n },\n [openAddBackendModal, preventDropdownMenuClose],\n );\n\n const handleAddBackendTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openAddBackendModal();\n },\n [openAddBackendModal, preventDropdownMenuClose],\n );\n\n const handleManageBackendsClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openManageBackendsModal();\n },\n [openManageBackendsModal, preventDropdownMenuClose],\n );\n\n const handleManageBackendsTouchEnd = React.useCallback(\n (event: React.TouchEvent<HTMLButtonElement>) => {\n preventDropdownMenuClose(event);\n openManageBackendsModal();\n },\n [openManageBackendsModal, preventDropdownMenuClose],\n );\n\n const addBackendFooter = hideBackendFooter ? undefined : (\n <div className={dropdownMenuListClassName}>\n {isLockedToCloud ? null : (\n <button\n type=\"button\"\n data-testid=\"add-backend-menu-item\"\n onMouseDown={preventDropdownMenuClose}\n onTouchStart={preventDropdownMenuClose}\n onTouchEnd={handleAddBackendTouchEnd}\n onClick={handleAddBackendClick}\n className={cn(\n dropdownFooterActionClassName,\n \"cursor-pointer rounded-md\",\n )}\n >\n <span className={dropdownMenuRowIconWrapperClassName} aria-hidden>\n <Plus width={16} height={16} />\n </span>\n {t(I18nKey.BACKEND$ADD)}\n </button>\n )}\n <button\n type=\"button\"\n data-testid=\"manage-backends-menu-item\"\n onMouseDown={preventDropdownMenuClose}\n onTouchStart={preventDropdownMenuClose}\n onTouchEnd={handleManageBackendsTouchEnd}\n onClick={handleManageBackendsClick}\n className={cn(\n dropdownFooterActionClassName,\n \"cursor-pointer rounded-md\",\n )}\n >\n <span className={dropdownMenuRowIconWrapperClassName} aria-hidden>\n <Settings width={16} height={16} />\n </span>\n {t(\n isLockedToCloud\n ? I18nKey.BACKEND$RECONNECT_CLOUD\n : I18nKey.BACKEND$MANAGE,\n )}\n </button>\n </div>\n );\n\n const handleSelectBackend = React.useCallback(\n async (value: string) => {\n if (value === activeValue) return;\n\n const { backendId, orgId } = parseOptionValue(value);\n const target = backends.find((b) => b.id === backendId);\n if (!target) return;\n\n triggerEnvironmentSwitch(\n options.find((option) => option.value === value)?.label ?? target.name,\n );\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ENVIRONMENT_SWITCH_SETACTIVE_DELAY_MS);\n });\n\n // @spec BM-002 — Switching backends keeps the user on the same page\n if (conversationMatch) navigate(\"/conversations\");\n else if (automationDetailMatch) navigate(\"/automations\");\n\n setActive(target.id, orgId);\n onSelectOption?.();\n },\n [\n activeValue,\n backends,\n conversationMatch,\n automationDetailMatch,\n navigate,\n options,\n setActive,\n t,\n onSelectOption,\n ],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-2 w-full\">\n <div className=\"flex-1 min-w-0\">\n <Dropdown\n testId=\"backend-selector\"\n key={`${activeValue}-${activeOption?.label ?? \"\"}`}\n defaultValue={\n activeOption ?? {\n value: activeValue,\n label: noBackendSelected ? noBackendLabel : active.backend.name,\n prefix: noBackendSelected\n ? buildNoBackendPrefix()\n : buildStatusPrefix(healthByBackendId[active.backend.id]),\n }\n }\n footer={addBackendFooter}\n openUpward={openUpward}\n hideTrigger={hideTrigger}\n defaultOpen={defaultOpen}\n openOnHover={!hideTrigger}\n onChange={(item) => {\n if (!item) return;\n void handleSelectBackend(item.value);\n }}\n placeholder={\n noBackendSelected ? noBackendLabel : active.backend.name\n }\n loading={someCloudLoading}\n options={options}\n className=\"h-10 px-2 py-0 bg-transparent border-transparent hover:bg-[var(--oh-surface-raised)] focus-within:bg-[var(--oh-surface-raised)] focus-within:border-transparent focus-within:ring-0\"\n />\n </div>\n {!hideTrigger ? (\n <StyledTooltip\n content={settingsLabel}\n placement={settingsTooltipPlacement}\n offset={10}\n >\n {active.backend.kind === \"cloud\" ? (\n <a\n href={`${active.backend.host.replace(/\\/+$/, \"\")}/settings${cloudSettingsOrgQuery}`}\n target={isLockedToCloud ? undefined : \"_blank\"}\n rel={isLockedToCloud ? undefined : \"noopener noreferrer\"}\n data-testid=\"backend-selector-settings-link\"\n aria-label={settingsLabel}\n className={cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)] cursor-pointer\",\n formControlTransitionClassName,\n )}\n >\n <Settings width={16} height={16} />\n </a>\n ) : (\n <NavigationLink\n to=\"/settings\"\n data-testid=\"backend-selector-settings-link\"\n data-active={isSettingsActive}\n aria-label={settingsLabel}\n className={\n isSettingsActive\n ? cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md bg-tertiary text-white font-normal cursor-pointer\",\n formControlTransitionClassName,\n )\n : cn(\n \"inline-flex items-center justify-center shrink-0 w-9 h-9 rounded-md text-[var(--oh-muted)] hover:text-white hover:bg-[var(--oh-surface-raised)] cursor-pointer\",\n formControlTransitionClassName,\n )\n }\n >\n <Settings width={16} height={16} />\n </NavigationLink>\n )}\n </StyledTooltip>\n ) : null}\n </div>\n {addBackendModalOpen ? (\n <AddBackendModal onClose={() => setAddBackendModalOpen(false)} />\n ) : null}\n {manageBackendsModalOpen ? (\n <ManageBackendsModal\n onClose={() => setManageBackendsModalOpen(false)}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/react-i18next/dist/es/useTranslation.cjs"),n=require("../../../i18n/declaration.cjs"),r=require("../../../node_modules/lucide-react/dist/esm/icons/plus.cjs"),i=require("../../../utils/utils.cjs"),a=require("../../../api/agent-server-config.cjs"),o=require("../../../contexts/active-backend-context.cjs"),s=require("../../shared/modals/modal-backdrop.cjs"),c=require("../../shared/modals/modal-body.cjs"),l=require("../../../utils/modal-classes.cjs"),u=require("../../shared/modals/modal-close-button.cjs"),d=require("../settings/brand-button.cjs"),f=require("../../shared/modals/confirmation-modal.cjs"),p=require("../../../hooks/query/use-cloud-organizations.cjs"),m=require("../../../hooks/query/use-cloud-current-user-id.cjs"),h=require("../../../hooks/query/use-backends-health.cjs"),g=require("./device-flow-auth.cjs"),_=require("./backend-form-modal.cjs"),v=require("./backend-row.cjs");let y=require("react");y=e.__toESM(y,1);let b=require("react/jsx-runtime");function x(e,t,n,r){if(e.kind!==`cloud`)return;let i=t[e.id];if(!i||i.orgs.length===0)return;let a=n[e.id]?.userId??null;return i.orgs.map(e=>a&&a===e.id?r:e.name).join(`, `)}function S({onClose:e,recoveryMode:S=!1}){let{t:C}=t.useTranslation(`openhands`),{backends:w,active:T,removeBackend:E,setActive:D,updateBackend:O}=o.useActiveBackendContext(),k=h.useBackendsHealth(w,{probeDisabledOnce:!0}),A=p.useAllCloudOrganizations(),j=m.useCloudCurrentUserId(),M=C(n.I18nKey.BACKEND$PERSONAL_WORKSPACE),N=a.getLockedCloudHost(),P=N!==null,F=P&&T.backend.kind===`cloud`?T.backend:null,I=N??F?.host??``,L=C(P?n.I18nKey.BACKEND$RECONNECT_CLOUD_TITLE:n.I18nKey.BACKEND$MANAGE_TITLE),[R,z]=y.default.useState(null),[B,V]=y.default.useState(null),[H,U]=y.default.useState(!1),W=()=>{R&&(E(R.id),z(null))},G=y.default.useCallback(t=>{(T.backend.id!==t.id||T.orgId!==null)&&D(t.id),e()},[T.backend.id,T.orgId,e,D]),K=y.default.useCallback((e,t)=>{O(e.id,{apiKey:t})},[O]),q=y.default.useCallback(e=>{F&&O(F.id,{apiKey:e})},[F,O]);return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(s.ModalBackdrop,{onClose:S?void 0:e,closeOnEscape:!S,closeOnBackdropClick:!S,"aria-label":L,children:(0,b.jsxs)(`div`,{"data-testid":`manage-backends-modal`,className:i.cn(`relative flex flex-col bg-[var(--oh-surface)] border border-[var(--oh-border)] rounded-xl`,c.modalWidthClassName(`lg`),c.MODAL_MAX_WIDTH_VIEWPORT,`max-h-[70vh]`),children:[S?null:(0,b.jsx)(u.ModalCloseButton,{onClose:e,testId:`close-manage-backends-modal`}),(0,b.jsx)(`div`,{className:i.cn(`p-5`,!S&&`pr-12`),children:(0,b.jsx)(`h2`,{className:l.modalTitleLgClassName,children:L})}),(0,b.jsx)(`div`,{className:`flex min-h-0 flex-1 flex-col px-5`,children:(0,b.jsx)(`div`,{className:`flex-1 overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always`,"data-testid":`manage-backends-list`,children:w.length===0?(0,b.jsx)(`p`,{className:`px-3 py-6 text-center text-sm text-[var(--oh-text-secondary)]`,children:C(n.I18nKey.BACKEND$MANAGE_EMPTY)}):(0,b.jsx)(`ul`,{className:`divide-y divide-[var(--oh-border)]`,children:w.map(e=>(0,b.jsx)(v.BackendRow,{backend:e,health:k[e.id],orgLabel:x(e,A,j,M),onSelect:()=>G(e),onEdit:()=>V(e),onRemove:()=>z({id:e.id,name:e.name}),onLogin:t=>K(e,t)},e.id))})})}),(0,b.jsxs)(`div`,{className:`flex justify-end gap-2 p-5`,children:[P?F?(0,b.jsx)(g.DeviceFlowAuth,{host:I,onSuccess:q,testIdRoot:`manage-backends-reconnect-cloud`,idleButtonLabel:C(n.I18nKey.BACKEND$RECONNECT_CLOUD),className:`w-full sm:w-auto`,buttonClassName:`w-full sm:w-auto`,statusDisplay:`modal`}):null:(0,b.jsx)(d.BrandButton,{type:`button`,variant:S?`primary`:`secondary`,onClick:()=>U(!0),testId:`manage-backends-add`,startContent:(0,b.jsx)(r.Plus,{width:14,height:14}),children:C(n.I18nKey.BACKEND$ADD)}),S?null:(0,b.jsx)(d.BrandButton,{type:`button`,variant:`primary`,onClick:e,testId:`manage-backends-done`,children:C(n.I18nKey.HOME$DONE)})]})]})}),H?(0,b.jsx)(_.BackendFormModal,{mode:`add`,source:`manage_backends_modal`,onClose:()=>U(!1)}):null,B?(0,b.jsx)(_.BackendFormModal,{mode:`edit`,backend:B,onClose:()=>V(null)}):null,R?(0,b.jsx)(f.ConfirmationModal,{text:C(n.I18nKey.BACKEND$REMOVE_CONFIRMATION,{name:R.name}),onConfirm:W,onCancel:()=>z(null)}):null]})}exports.ManageBackendsModal=S;
1
+ const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/react-i18next/dist/es/useTranslation.cjs"),n=require("../../../i18n/declaration.cjs"),r=require("../../../node_modules/lucide-react/dist/esm/icons/plus.cjs"),i=require("../../../utils/utils.cjs"),a=require("../../../api/agent-server-config.cjs"),o=require("../../../contexts/active-backend-context.cjs"),s=require("../../shared/modals/modal-backdrop.cjs"),c=require("../../shared/modals/modal-body.cjs"),l=require("../../../utils/modal-classes.cjs"),u=require("../../shared/modals/modal-close-button.cjs"),d=require("../settings/brand-button.cjs"),f=require("../../../hooks/query/use-cloud-organizations.cjs"),p=require("../../../hooks/query/use-cloud-current-user-id.cjs"),m=require("../../shared/modals/confirmation-modal.cjs"),h=require("../../../hooks/query/use-backends-health.cjs"),g=require("./device-flow-auth.cjs"),_=require("./backend-form-modal.cjs"),v=require("./backend-row.cjs");let y=require("react");y=e.__toESM(y,1);let b=require("react/jsx-runtime");function x(e,t,n,r){if(e.kind!==`cloud`)return;let i=t[e.id];if(!i||i.orgs.length===0)return;let a=n[e.id]?.userId??null;return i.orgs.map(e=>a&&a===e.id?r:e.name).join(`, `)}function S({onClose:e,recoveryMode:S=!1}){let{t:C}=t.useTranslation(`openhands`),{backends:w,active:T,removeBackend:E,setActive:D,updateBackend:O}=o.useActiveBackendContext(),k=h.useBackendsHealth(w,{probeDisabledOnce:!0}),A=f.useAllCloudOrganizations(),j=p.useCloudCurrentUserId(),M=C(n.I18nKey.BACKEND$PERSONAL_WORKSPACE),N=a.getLockedCloudHost(),P=N!==null,F=T.backend.authMode===`cookie`,I=P&&!F&&T.backend.kind===`cloud`?T.backend:null,L=N??I?.host??``,R=C(P&&!F?n.I18nKey.BACKEND$RECONNECT_CLOUD_TITLE:n.I18nKey.BACKEND$MANAGE_TITLE),[z,B]=y.default.useState(null),[V,H]=y.default.useState(null),[U,W]=y.default.useState(!1),G=()=>{z&&(E(z.id),B(null))},K=y.default.useCallback(t=>{(T.backend.id!==t.id||T.orgId!==null)&&D(t.id),e()},[T.backend.id,T.orgId,e,D]),q=y.default.useCallback((e,t)=>{O(e.id,{apiKey:t})},[O]),J=y.default.useCallback(e=>{I&&O(I.id,{apiKey:e})},[I,O]);return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(s.ModalBackdrop,{onClose:S?void 0:e,closeOnEscape:!S,closeOnBackdropClick:!S,"aria-label":R,children:(0,b.jsxs)(`div`,{"data-testid":`manage-backends-modal`,className:i.cn(`relative flex flex-col bg-[var(--oh-surface)] border border-[var(--oh-border)] rounded-xl`,c.modalWidthClassName(`lg`),c.MODAL_MAX_WIDTH_VIEWPORT,`max-h-[70vh]`),children:[S?null:(0,b.jsx)(u.ModalCloseButton,{onClose:e,testId:`close-manage-backends-modal`}),(0,b.jsx)(`div`,{className:i.cn(`p-5`,!S&&`pr-12`),children:(0,b.jsx)(`h2`,{className:l.modalTitleLgClassName,children:R})}),(0,b.jsx)(`div`,{className:`flex min-h-0 flex-1 flex-col px-5`,children:(0,b.jsx)(`div`,{className:`flex-1 overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always`,"data-testid":`manage-backends-list`,children:w.length===0?(0,b.jsx)(`p`,{className:`px-3 py-6 text-center text-sm text-[var(--oh-text-secondary)]`,children:C(n.I18nKey.BACKEND$MANAGE_EMPTY)}):(0,b.jsx)(`ul`,{className:`divide-y divide-[var(--oh-border)]`,children:w.map(e=>(0,b.jsx)(v.BackendRow,{backend:e,health:k[e.id],orgLabel:x(e,A,j,M),onSelect:()=>K(e),onEdit:()=>H(e),onRemove:()=>B({id:e.id,name:e.name}),onLogin:e.authMode===`cookie`?void 0:t=>q(e,t)},e.id))})})}),(0,b.jsxs)(`div`,{className:`flex justify-end gap-2 p-5`,children:[P?I?(0,b.jsx)(g.DeviceFlowAuth,{host:L,onSuccess:J,testIdRoot:`manage-backends-reconnect-cloud`,idleButtonLabel:C(n.I18nKey.BACKEND$RECONNECT_CLOUD),className:`w-full sm:w-auto`,buttonClassName:`w-full sm:w-auto`,statusDisplay:`modal`}):null:(0,b.jsx)(d.BrandButton,{type:`button`,variant:S?`primary`:`secondary`,onClick:()=>W(!0),testId:`manage-backends-add`,startContent:(0,b.jsx)(r.Plus,{width:14,height:14}),children:C(n.I18nKey.BACKEND$ADD)}),S?null:(0,b.jsx)(d.BrandButton,{type:`button`,variant:`primary`,onClick:e,testId:`manage-backends-done`,children:C(n.I18nKey.HOME$DONE)})]})]})}),U?(0,b.jsx)(_.BackendFormModal,{mode:`add`,source:`manage_backends_modal`,onClose:()=>W(!1)}):null,V?(0,b.jsx)(_.BackendFormModal,{mode:`edit`,backend:V,onClose:()=>H(null)}):null,z?(0,b.jsx)(m.ConfirmationModal,{text:C(n.I18nKey.BACKEND$REMOVE_CONFIRMATION,{name:z.name}),onConfirm:G,onCancel:()=>B(null)}):null]})}exports.ManageBackendsModal=S;
2
2
  //# sourceMappingURL=manage-backends-modal.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"manage-backends-modal.cjs","names":[],"sources":["../../../../src/components/features/backends/manage-backends-modal.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Plus } from \"lucide-react\";\n\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\nimport { type Backend } from \"#/api/backend-registry/types\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\nimport { ConfirmationModal } from \"#/components/shared/modals/confirmation-modal\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport {\n MODAL_MAX_WIDTH_VIEWPORT,\n modalWidthClassName,\n} from \"#/components/shared/modals/modal-body\";\nimport { ModalCloseButton } from \"#/components/shared/modals/modal-close-button\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { useBackendsHealth } from \"#/hooks/query/use-backends-health\";\nimport { useAllCloudOrganizations } from \"#/hooks/query/use-cloud-organizations\";\nimport { useCloudCurrentUserId } from \"#/hooks/query/use-cloud-current-user-id\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { modalTitleLgClassName } from \"#/utils/modal-classes\";\nimport { BackendFormModal } from \"./backend-form-modal\";\nimport { BackendRow } from \"./backend-row\";\nimport { DeviceFlowAuth } from \"./device-flow-auth\";\n\ninterface ManageBackendsModalProps {\n onClose: () => void;\n /**\n * Recovery mode is used by the root unavailable-backend gate. There is no\n * app shell behind the modal, so dismiss controls would be misleading.\n */\n recoveryMode?: boolean;\n}\n\ninterface PendingRemoval {\n id: string;\n name: string;\n}\n\n/**\n * Resolve the connected organization label for a backend row, mirroring the\n * per-org labelling used by the backend selector. Cloud API keys are bound to\n * a single org (legacy keys may expose several, joined here); local backends\n * and unresolved/errored lookups yield no label.\n */\nfunction resolveBackendOrgLabel(\n backend: Backend,\n cloudOrgs: ReturnType<typeof useAllCloudOrganizations>,\n currentUserIds: ReturnType<typeof useCloudCurrentUserId>,\n personalWorkspaceLabel: string,\n): string | undefined {\n if (backend.kind !== \"cloud\") return undefined;\n const entry = cloudOrgs[backend.id];\n if (!entry || entry.orgs.length === 0) return undefined;\n const userId = currentUserIds[backend.id]?.userId ?? null;\n return entry.orgs\n .map((org) =>\n !!userId && userId === org.id ? personalWorkspaceLabel : org.name,\n )\n .join(\", \");\n}\n\nexport function ManageBackendsModal({\n onClose,\n recoveryMode = false,\n}: ManageBackendsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const { backends, active, removeBackend, setActive, updateBackend } =\n useActiveBackendContext();\n const healthByBackendId = useBackendsHealth(backends, {\n probeDisabledOnce: true,\n });\n const cloudOrgs = useAllCloudOrganizations();\n const currentUserIds = useCloudCurrentUserId();\n const personalWorkspaceLabel = t(I18nKey.BACKEND$PERSONAL_WORKSPACE);\n const lockedCloudHost = getLockedCloudHost();\n const isLockedToCloud = lockedCloudHost !== null;\n const lockedCloudBackend =\n isLockedToCloud && active.backend.kind === \"cloud\" ? active.backend : null;\n const lockedCloudReconnectHost =\n lockedCloudHost ?? lockedCloudBackend?.host ?? \"\";\n const modalTitle = isLockedToCloud\n ? t(I18nKey.BACKEND$RECONNECT_CLOUD_TITLE)\n : t(I18nKey.BACKEND$MANAGE_TITLE);\n const [pendingRemoval, setPendingRemoval] =\n React.useState<PendingRemoval | null>(null);\n const [editingBackend, setEditingBackend] = React.useState<Backend | null>(\n null,\n );\n const [showAddForm, setShowAddForm] = React.useState(false);\n\n const handleConfirmRemoval = () => {\n if (!pendingRemoval) return;\n removeBackend(pendingRemoval.id);\n setPendingRemoval(null);\n };\n\n const handleSelectBackend = React.useCallback(\n (backend: Backend) => {\n if (active.backend.id !== backend.id || active.orgId !== null) {\n setActive(backend.id);\n }\n onClose();\n },\n [active.backend.id, active.orgId, onClose, setActive],\n );\n\n const handleCloudLogin = React.useCallback(\n (backend: Backend, apiKey: string) => {\n updateBackend(backend.id, { apiKey });\n },\n [updateBackend],\n );\n\n const handleLockedCloudReconnect = React.useCallback(\n (apiKey: string) => {\n if (!lockedCloudBackend) return;\n updateBackend(lockedCloudBackend.id, { apiKey });\n },\n [lockedCloudBackend, updateBackend],\n );\n\n return (\n <>\n <ModalBackdrop\n onClose={recoveryMode ? undefined : onClose}\n closeOnEscape={!recoveryMode}\n closeOnBackdropClick={!recoveryMode}\n aria-label={modalTitle}\n >\n <div\n data-testid=\"manage-backends-modal\"\n className={cn(\n \"relative flex flex-col bg-[var(--oh-surface)] border border-[var(--oh-border)] rounded-xl\",\n modalWidthClassName(\"lg\"),\n MODAL_MAX_WIDTH_VIEWPORT,\n \"max-h-[70vh]\",\n )}\n >\n {recoveryMode ? null : (\n <ModalCloseButton\n onClose={onClose}\n testId=\"close-manage-backends-modal\"\n />\n )}\n <div className={cn(\"p-5\", !recoveryMode && \"pr-12\")}>\n <h2 className={modalTitleLgClassName}>{modalTitle}</h2>\n </div>\n\n <div className=\"flex min-h-0 flex-1 flex-col px-5\">\n <div\n className=\"flex-1 overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\"\n data-testid=\"manage-backends-list\"\n >\n {backends.length === 0 ? (\n <p className=\"px-3 py-6 text-center text-sm text-[var(--oh-text-secondary)]\">\n {t(I18nKey.BACKEND$MANAGE_EMPTY)}\n </p>\n ) : (\n <ul className=\"divide-y divide-[var(--oh-border)]\">\n {backends.map((backend) => (\n <BackendRow\n key={backend.id}\n backend={backend}\n health={healthByBackendId[backend.id]}\n orgLabel={resolveBackendOrgLabel(\n backend,\n cloudOrgs,\n currentUserIds,\n personalWorkspaceLabel,\n )}\n onSelect={() => handleSelectBackend(backend)}\n onEdit={() => setEditingBackend(backend)}\n onRemove={() =>\n setPendingRemoval({\n id: backend.id,\n name: backend.name,\n })\n }\n onLogin={(apiKey) => handleCloudLogin(backend, apiKey)}\n />\n ))}\n </ul>\n )}\n </div>\n </div>\n\n <div className=\"flex justify-end gap-2 p-5\">\n {isLockedToCloud ? (\n lockedCloudBackend ? (\n <DeviceFlowAuth\n host={lockedCloudReconnectHost}\n onSuccess={handleLockedCloudReconnect}\n testIdRoot=\"manage-backends-reconnect-cloud\"\n idleButtonLabel={t(I18nKey.BACKEND$RECONNECT_CLOUD)}\n className=\"w-full sm:w-auto\"\n buttonClassName=\"w-full sm:w-auto\"\n statusDisplay=\"modal\"\n />\n ) : null\n ) : (\n <BrandButton\n type=\"button\"\n variant={recoveryMode ? \"primary\" : \"secondary\"}\n onClick={() => setShowAddForm(true)}\n testId=\"manage-backends-add\"\n startContent={<Plus width={14} height={14} />}\n >\n {t(I18nKey.BACKEND$ADD)}\n </BrandButton>\n )}\n {recoveryMode ? null : (\n <BrandButton\n type=\"button\"\n variant=\"primary\"\n onClick={onClose}\n testId=\"manage-backends-done\"\n >\n {t(I18nKey.HOME$DONE)}\n </BrandButton>\n )}\n </div>\n </div>\n </ModalBackdrop>\n\n {showAddForm ? (\n <BackendFormModal\n mode=\"add\"\n source=\"manage_backends_modal\"\n onClose={() => setShowAddForm(false)}\n />\n ) : null}\n\n {editingBackend ? (\n <BackendFormModal\n mode=\"edit\"\n backend={editingBackend}\n onClose={() => setEditingBackend(null)}\n />\n ) : null}\n\n {pendingRemoval ? (\n <ConfirmationModal\n text={t(I18nKey.BACKEND$REMOVE_CONFIRMATION, {\n name: pendingRemoval.name,\n })}\n onConfirm={handleConfirmRemoval}\n onCancel={() => setPendingRemoval(null)}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"manage-backends-modal.cjs","names":[],"sources":["../../../../src/components/features/backends/manage-backends-modal.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Plus } from \"lucide-react\";\n\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\nimport { type Backend } from \"#/api/backend-registry/types\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\nimport { ConfirmationModal } from \"#/components/shared/modals/confirmation-modal\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport {\n MODAL_MAX_WIDTH_VIEWPORT,\n modalWidthClassName,\n} from \"#/components/shared/modals/modal-body\";\nimport { ModalCloseButton } from \"#/components/shared/modals/modal-close-button\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { useBackendsHealth } from \"#/hooks/query/use-backends-health\";\nimport { useAllCloudOrganizations } from \"#/hooks/query/use-cloud-organizations\";\nimport { useCloudCurrentUserId } from \"#/hooks/query/use-cloud-current-user-id\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { modalTitleLgClassName } from \"#/utils/modal-classes\";\nimport { BackendFormModal } from \"./backend-form-modal\";\nimport { BackendRow } from \"./backend-row\";\nimport { DeviceFlowAuth } from \"./device-flow-auth\";\n\ninterface ManageBackendsModalProps {\n onClose: () => void;\n /**\n * Recovery mode is used by the root unavailable-backend gate. There is no\n * app shell behind the modal, so dismiss controls would be misleading.\n */\n recoveryMode?: boolean;\n}\n\ninterface PendingRemoval {\n id: string;\n name: string;\n}\n\n/**\n * Resolve the connected organization label for a backend row, mirroring the\n * per-org labelling used by the backend selector. Cloud API keys are bound to\n * a single org (legacy keys may expose several, joined here); local backends\n * and unresolved/errored lookups yield no label.\n */\nfunction resolveBackendOrgLabel(\n backend: Backend,\n cloudOrgs: ReturnType<typeof useAllCloudOrganizations>,\n currentUserIds: ReturnType<typeof useCloudCurrentUserId>,\n personalWorkspaceLabel: string,\n): string | undefined {\n if (backend.kind !== \"cloud\") return undefined;\n const entry = cloudOrgs[backend.id];\n if (!entry || entry.orgs.length === 0) return undefined;\n const userId = currentUserIds[backend.id]?.userId ?? null;\n return entry.orgs\n .map((org) =>\n !!userId && userId === org.id ? personalWorkspaceLabel : org.name,\n )\n .join(\", \");\n}\n\nexport function ManageBackendsModal({\n onClose,\n recoveryMode = false,\n}: ManageBackendsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const { backends, active, removeBackend, setActive, updateBackend } =\n useActiveBackendContext();\n const healthByBackendId = useBackendsHealth(backends, {\n probeDisabledOnce: true,\n });\n const cloudOrgs = useAllCloudOrganizations();\n const currentUserIds = useCloudCurrentUserId();\n const personalWorkspaceLabel = t(I18nKey.BACKEND$PERSONAL_WORKSPACE);\n const lockedCloudHost = getLockedCloudHost();\n const isLockedToCloud = lockedCloudHost !== null;\n // Cookie-auth (OHE-hosted) backends have no API key to refresh — re-auth is\n // the main-app login, so the device-flow reconnect controls don't apply.\n const isCookieAuthBackend = active.backend.authMode === \"cookie\";\n const lockedCloudBackend =\n isLockedToCloud && !isCookieAuthBackend && active.backend.kind === \"cloud\"\n ? active.backend\n : null;\n const lockedCloudReconnectHost =\n lockedCloudHost ?? lockedCloudBackend?.host ?? \"\";\n const modalTitle =\n isLockedToCloud && !isCookieAuthBackend\n ? t(I18nKey.BACKEND$RECONNECT_CLOUD_TITLE)\n : t(I18nKey.BACKEND$MANAGE_TITLE);\n const [pendingRemoval, setPendingRemoval] =\n React.useState<PendingRemoval | null>(null);\n const [editingBackend, setEditingBackend] = React.useState<Backend | null>(\n null,\n );\n const [showAddForm, setShowAddForm] = React.useState(false);\n\n const handleConfirmRemoval = () => {\n if (!pendingRemoval) return;\n removeBackend(pendingRemoval.id);\n setPendingRemoval(null);\n };\n\n const handleSelectBackend = React.useCallback(\n (backend: Backend) => {\n if (active.backend.id !== backend.id || active.orgId !== null) {\n setActive(backend.id);\n }\n onClose();\n },\n [active.backend.id, active.orgId, onClose, setActive],\n );\n\n const handleCloudLogin = React.useCallback(\n (backend: Backend, apiKey: string) => {\n updateBackend(backend.id, { apiKey });\n },\n [updateBackend],\n );\n\n const handleLockedCloudReconnect = React.useCallback(\n (apiKey: string) => {\n if (!lockedCloudBackend) return;\n updateBackend(lockedCloudBackend.id, { apiKey });\n },\n [lockedCloudBackend, updateBackend],\n );\n\n return (\n <>\n <ModalBackdrop\n onClose={recoveryMode ? undefined : onClose}\n closeOnEscape={!recoveryMode}\n closeOnBackdropClick={!recoveryMode}\n aria-label={modalTitle}\n >\n <div\n data-testid=\"manage-backends-modal\"\n className={cn(\n \"relative flex flex-col bg-[var(--oh-surface)] border border-[var(--oh-border)] rounded-xl\",\n modalWidthClassName(\"lg\"),\n MODAL_MAX_WIDTH_VIEWPORT,\n \"max-h-[70vh]\",\n )}\n >\n {recoveryMode ? null : (\n <ModalCloseButton\n onClose={onClose}\n testId=\"close-manage-backends-modal\"\n />\n )}\n <div className={cn(\"p-5\", !recoveryMode && \"pr-12\")}>\n <h2 className={modalTitleLgClassName}>{modalTitle}</h2>\n </div>\n\n <div className=\"flex min-h-0 flex-1 flex-col px-5\">\n <div\n className=\"flex-1 overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\"\n data-testid=\"manage-backends-list\"\n >\n {backends.length === 0 ? (\n <p className=\"px-3 py-6 text-center text-sm text-[var(--oh-text-secondary)]\">\n {t(I18nKey.BACKEND$MANAGE_EMPTY)}\n </p>\n ) : (\n <ul className=\"divide-y divide-[var(--oh-border)]\">\n {backends.map((backend) => (\n <BackendRow\n key={backend.id}\n backend={backend}\n health={healthByBackendId[backend.id]}\n orgLabel={resolveBackendOrgLabel(\n backend,\n cloudOrgs,\n currentUserIds,\n personalWorkspaceLabel,\n )}\n onSelect={() => handleSelectBackend(backend)}\n onEdit={() => setEditingBackend(backend)}\n onRemove={() =>\n setPendingRemoval({\n id: backend.id,\n name: backend.name,\n })\n }\n onLogin={\n backend.authMode === \"cookie\"\n ? undefined\n : (apiKey) => handleCloudLogin(backend, apiKey)\n }\n />\n ))}\n </ul>\n )}\n </div>\n </div>\n\n <div className=\"flex justify-end gap-2 p-5\">\n {isLockedToCloud ? (\n lockedCloudBackend ? (\n <DeviceFlowAuth\n host={lockedCloudReconnectHost}\n onSuccess={handleLockedCloudReconnect}\n testIdRoot=\"manage-backends-reconnect-cloud\"\n idleButtonLabel={t(I18nKey.BACKEND$RECONNECT_CLOUD)}\n className=\"w-full sm:w-auto\"\n buttonClassName=\"w-full sm:w-auto\"\n statusDisplay=\"modal\"\n />\n ) : null\n ) : (\n <BrandButton\n type=\"button\"\n variant={recoveryMode ? \"primary\" : \"secondary\"}\n onClick={() => setShowAddForm(true)}\n testId=\"manage-backends-add\"\n startContent={<Plus width={14} height={14} />}\n >\n {t(I18nKey.BACKEND$ADD)}\n </BrandButton>\n )}\n {recoveryMode ? null : (\n <BrandButton\n type=\"button\"\n variant=\"primary\"\n onClick={onClose}\n testId=\"manage-backends-done\"\n >\n {t(I18nKey.HOME$DONE)}\n </BrandButton>\n )}\n </div>\n </div>\n </ModalBackdrop>\n\n {showAddForm ? (\n <BackendFormModal\n mode=\"add\"\n source=\"manage_backends_modal\"\n onClose={() => setShowAddForm(false)}\n />\n ) : null}\n\n {editingBackend ? (\n <BackendFormModal\n mode=\"edit\"\n backend={editingBackend}\n onClose={() => setEditingBackend(null)}\n />\n ) : null}\n\n {pendingRemoval ? (\n <ConfirmationModal\n text={t(I18nKey.BACKEND$REMOVE_CONFIRMATION, {\n name: pendingRemoval.name,\n })}\n onConfirm={handleConfirmRemoval}\n onCancel={() => setPendingRemoval(null)}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":"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"}
@@ -9,9 +9,9 @@ import { MODAL_MAX_WIDTH_VIEWPORT as s, modalWidthClassName as c } from "../../s
9
9
  import { modalTitleLgClassName as l } from "../../../utils/modal-classes.js";
10
10
  import { ModalCloseButton as u } from "../../shared/modals/modal-close-button.js";
11
11
  import { BrandButton as d } from "../settings/brand-button.js";
12
- import { ConfirmationModal as f } from "../../shared/modals/confirmation-modal.js";
13
- import { useAllCloudOrganizations as p } from "../../../hooks/query/use-cloud-organizations.js";
14
- import { useCloudCurrentUserId as m } from "../../../hooks/query/use-cloud-current-user-id.js";
12
+ import { useAllCloudOrganizations as f } from "../../../hooks/query/use-cloud-organizations.js";
13
+ import { useCloudCurrentUserId as p } from "../../../hooks/query/use-cloud-current-user-id.js";
14
+ import { ConfirmationModal as m } from "../../shared/modals/confirmation-modal.js";
15
15
  import { useBackendsHealth as h } from "../../../hooks/query/use-backends-health.js";
16
16
  import { DeviceFlowAuth as g } from "./device-flow-auth.js";
17
17
  import { BackendFormModal as _ } from "./backend-form-modal.js";
@@ -27,26 +27,26 @@ function C(e, t, n, r) {
27
27
  return i.orgs.map((e) => a && a === e.id ? r : e.name).join(", ");
28
28
  }
29
29
  function w({ onClose: w, recoveryMode: T = !1 }) {
30
- let { t: E } = e("openhands"), { backends: D, active: O, removeBackend: k, setActive: A, updateBackend: j } = a(), M = h(D, { probeDisabledOnce: !0 }), N = p(), P = m(), F = E(t.BACKEND$PERSONAL_WORKSPACE), I = i(), L = I !== null, R = L && O.backend.kind === "cloud" ? O.backend : null, z = I ?? R?.host ?? "", B = E(L ? t.BACKEND$RECONNECT_CLOUD_TITLE : t.BACKEND$MANAGE_TITLE), [V, H] = y.useState(null), [U, W] = y.useState(null), [G, K] = y.useState(!1), q = () => {
31
- V && (k(V.id), H(null));
32
- }, J = y.useCallback((e) => {
30
+ let { t: E } = e("openhands"), { backends: D, active: O, removeBackend: k, setActive: A, updateBackend: j } = a(), M = h(D, { probeDisabledOnce: !0 }), N = f(), P = p(), F = E(t.BACKEND$PERSONAL_WORKSPACE), I = i(), L = I !== null, R = O.backend.authMode === "cookie", z = L && !R && O.backend.kind === "cloud" ? O.backend : null, B = I ?? z?.host ?? "", V = E(L && !R ? t.BACKEND$RECONNECT_CLOUD_TITLE : t.BACKEND$MANAGE_TITLE), [H, U] = y.useState(null), [W, G] = y.useState(null), [K, q] = y.useState(!1), J = () => {
31
+ H && (k(H.id), U(null));
32
+ }, Y = y.useCallback((e) => {
33
33
  (O.backend.id !== e.id || O.orgId !== null) && A(e.id), w();
34
34
  }, [
35
35
  O.backend.id,
36
36
  O.orgId,
37
37
  w,
38
38
  A
39
- ]), Y = y.useCallback((e, t) => {
39
+ ]), X = y.useCallback((e, t) => {
40
40
  j(e.id, { apiKey: t });
41
- }, [j]), X = y.useCallback((e) => {
42
- R && j(R.id, { apiKey: e });
43
- }, [R, j]);
41
+ }, [j]), Z = y.useCallback((e) => {
42
+ z && j(z.id, { apiKey: e });
43
+ }, [z, j]);
44
44
  return /* @__PURE__ */ S(b, { children: [
45
45
  /* @__PURE__ */ x(o, {
46
46
  onClose: T ? void 0 : w,
47
47
  closeOnEscape: !T,
48
48
  closeOnBackdropClick: !T,
49
- "aria-label": B,
49
+ "aria-label": V,
50
50
  children: /* @__PURE__ */ S("div", {
51
51
  "data-testid": "manage-backends-modal",
52
52
  className: r("relative flex flex-col bg-[var(--oh-surface)] border border-[var(--oh-border)] rounded-xl", c("lg"), s, "max-h-[70vh]"),
@@ -59,7 +59,7 @@ function w({ onClose: w, recoveryMode: T = !1 }) {
59
59
  className: r("p-5", !T && "pr-12"),
60
60
  children: /* @__PURE__ */ x("h2", {
61
61
  className: l,
62
- children: B
62
+ children: V
63
63
  })
64
64
  }),
65
65
  /* @__PURE__ */ x("div", {
@@ -76,22 +76,22 @@ function w({ onClose: w, recoveryMode: T = !1 }) {
76
76
  backend: e,
77
77
  health: M[e.id],
78
78
  orgLabel: C(e, N, P, F),
79
- onSelect: () => J(e),
80
- onEdit: () => W(e),
81
- onRemove: () => H({
79
+ onSelect: () => Y(e),
80
+ onEdit: () => G(e),
81
+ onRemove: () => U({
82
82
  id: e.id,
83
83
  name: e.name
84
84
  }),
85
- onLogin: (t) => Y(e, t)
85
+ onLogin: e.authMode === "cookie" ? void 0 : (t) => X(e, t)
86
86
  }, e.id))
87
87
  })
88
88
  })
89
89
  }),
90
90
  /* @__PURE__ */ S("div", {
91
91
  className: "flex justify-end gap-2 p-5",
92
- children: [L ? R ? /* @__PURE__ */ x(g, {
93
- host: z,
94
- onSuccess: X,
92
+ children: [L ? z ? /* @__PURE__ */ x(g, {
93
+ host: B,
94
+ onSuccess: Z,
95
95
  testIdRoot: "manage-backends-reconnect-cloud",
96
96
  idleButtonLabel: E(t.BACKEND$RECONNECT_CLOUD),
97
97
  className: "w-full sm:w-auto",
@@ -100,7 +100,7 @@ function w({ onClose: w, recoveryMode: T = !1 }) {
100
100
  }) : null : /* @__PURE__ */ x(d, {
101
101
  type: "button",
102
102
  variant: T ? "primary" : "secondary",
103
- onClick: () => K(!0),
103
+ onClick: () => q(!0),
104
104
  testId: "manage-backends-add",
105
105
  startContent: /* @__PURE__ */ x(n, {
106
106
  width: 14,
@@ -118,20 +118,20 @@ function w({ onClose: w, recoveryMode: T = !1 }) {
118
118
  ]
119
119
  })
120
120
  }),
121
- G ? /* @__PURE__ */ x(_, {
121
+ K ? /* @__PURE__ */ x(_, {
122
122
  mode: "add",
123
123
  source: "manage_backends_modal",
124
- onClose: () => K(!1)
124
+ onClose: () => q(!1)
125
125
  }) : null,
126
- U ? /* @__PURE__ */ x(_, {
126
+ W ? /* @__PURE__ */ x(_, {
127
127
  mode: "edit",
128
- backend: U,
129
- onClose: () => W(null)
128
+ backend: W,
129
+ onClose: () => G(null)
130
130
  }) : null,
131
- V ? /* @__PURE__ */ x(f, {
132
- text: E(t.BACKEND$REMOVE_CONFIRMATION, { name: V.name }),
133
- onConfirm: q,
134
- onCancel: () => H(null)
131
+ H ? /* @__PURE__ */ x(m, {
132
+ text: E(t.BACKEND$REMOVE_CONFIRMATION, { name: H.name }),
133
+ onConfirm: J,
134
+ onCancel: () => U(null)
135
135
  }) : null
136
136
  ] });
137
137
  }
@@ -1 +1 @@
1
- {"version":3,"file":"manage-backends-modal.js","names":[],"sources":["../../../../src/components/features/backends/manage-backends-modal.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Plus } from \"lucide-react\";\n\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\nimport { type Backend } from \"#/api/backend-registry/types\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\nimport { ConfirmationModal } from \"#/components/shared/modals/confirmation-modal\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport {\n MODAL_MAX_WIDTH_VIEWPORT,\n modalWidthClassName,\n} from \"#/components/shared/modals/modal-body\";\nimport { ModalCloseButton } from \"#/components/shared/modals/modal-close-button\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { useBackendsHealth } from \"#/hooks/query/use-backends-health\";\nimport { useAllCloudOrganizations } from \"#/hooks/query/use-cloud-organizations\";\nimport { useCloudCurrentUserId } from \"#/hooks/query/use-cloud-current-user-id\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { modalTitleLgClassName } from \"#/utils/modal-classes\";\nimport { BackendFormModal } from \"./backend-form-modal\";\nimport { BackendRow } from \"./backend-row\";\nimport { DeviceFlowAuth } from \"./device-flow-auth\";\n\ninterface ManageBackendsModalProps {\n onClose: () => void;\n /**\n * Recovery mode is used by the root unavailable-backend gate. There is no\n * app shell behind the modal, so dismiss controls would be misleading.\n */\n recoveryMode?: boolean;\n}\n\ninterface PendingRemoval {\n id: string;\n name: string;\n}\n\n/**\n * Resolve the connected organization label for a backend row, mirroring the\n * per-org labelling used by the backend selector. Cloud API keys are bound to\n * a single org (legacy keys may expose several, joined here); local backends\n * and unresolved/errored lookups yield no label.\n */\nfunction resolveBackendOrgLabel(\n backend: Backend,\n cloudOrgs: ReturnType<typeof useAllCloudOrganizations>,\n currentUserIds: ReturnType<typeof useCloudCurrentUserId>,\n personalWorkspaceLabel: string,\n): string | undefined {\n if (backend.kind !== \"cloud\") return undefined;\n const entry = cloudOrgs[backend.id];\n if (!entry || entry.orgs.length === 0) return undefined;\n const userId = currentUserIds[backend.id]?.userId ?? null;\n return entry.orgs\n .map((org) =>\n !!userId && userId === org.id ? personalWorkspaceLabel : org.name,\n )\n .join(\", \");\n}\n\nexport function ManageBackendsModal({\n onClose,\n recoveryMode = false,\n}: ManageBackendsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const { backends, active, removeBackend, setActive, updateBackend } =\n useActiveBackendContext();\n const healthByBackendId = useBackendsHealth(backends, {\n probeDisabledOnce: true,\n });\n const cloudOrgs = useAllCloudOrganizations();\n const currentUserIds = useCloudCurrentUserId();\n const personalWorkspaceLabel = t(I18nKey.BACKEND$PERSONAL_WORKSPACE);\n const lockedCloudHost = getLockedCloudHost();\n const isLockedToCloud = lockedCloudHost !== null;\n const lockedCloudBackend =\n isLockedToCloud && active.backend.kind === \"cloud\" ? active.backend : null;\n const lockedCloudReconnectHost =\n lockedCloudHost ?? lockedCloudBackend?.host ?? \"\";\n const modalTitle = isLockedToCloud\n ? t(I18nKey.BACKEND$RECONNECT_CLOUD_TITLE)\n : t(I18nKey.BACKEND$MANAGE_TITLE);\n const [pendingRemoval, setPendingRemoval] =\n React.useState<PendingRemoval | null>(null);\n const [editingBackend, setEditingBackend] = React.useState<Backend | null>(\n null,\n );\n const [showAddForm, setShowAddForm] = React.useState(false);\n\n const handleConfirmRemoval = () => {\n if (!pendingRemoval) return;\n removeBackend(pendingRemoval.id);\n setPendingRemoval(null);\n };\n\n const handleSelectBackend = React.useCallback(\n (backend: Backend) => {\n if (active.backend.id !== backend.id || active.orgId !== null) {\n setActive(backend.id);\n }\n onClose();\n },\n [active.backend.id, active.orgId, onClose, setActive],\n );\n\n const handleCloudLogin = React.useCallback(\n (backend: Backend, apiKey: string) => {\n updateBackend(backend.id, { apiKey });\n },\n [updateBackend],\n );\n\n const handleLockedCloudReconnect = React.useCallback(\n (apiKey: string) => {\n if (!lockedCloudBackend) return;\n updateBackend(lockedCloudBackend.id, { apiKey });\n },\n [lockedCloudBackend, updateBackend],\n );\n\n return (\n <>\n <ModalBackdrop\n onClose={recoveryMode ? undefined : onClose}\n closeOnEscape={!recoveryMode}\n closeOnBackdropClick={!recoveryMode}\n aria-label={modalTitle}\n >\n <div\n data-testid=\"manage-backends-modal\"\n className={cn(\n \"relative flex flex-col bg-[var(--oh-surface)] border border-[var(--oh-border)] rounded-xl\",\n modalWidthClassName(\"lg\"),\n MODAL_MAX_WIDTH_VIEWPORT,\n \"max-h-[70vh]\",\n )}\n >\n {recoveryMode ? null : (\n <ModalCloseButton\n onClose={onClose}\n testId=\"close-manage-backends-modal\"\n />\n )}\n <div className={cn(\"p-5\", !recoveryMode && \"pr-12\")}>\n <h2 className={modalTitleLgClassName}>{modalTitle}</h2>\n </div>\n\n <div className=\"flex min-h-0 flex-1 flex-col px-5\">\n <div\n className=\"flex-1 overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\"\n data-testid=\"manage-backends-list\"\n >\n {backends.length === 0 ? (\n <p className=\"px-3 py-6 text-center text-sm text-[var(--oh-text-secondary)]\">\n {t(I18nKey.BACKEND$MANAGE_EMPTY)}\n </p>\n ) : (\n <ul className=\"divide-y divide-[var(--oh-border)]\">\n {backends.map((backend) => (\n <BackendRow\n key={backend.id}\n backend={backend}\n health={healthByBackendId[backend.id]}\n orgLabel={resolveBackendOrgLabel(\n backend,\n cloudOrgs,\n currentUserIds,\n personalWorkspaceLabel,\n )}\n onSelect={() => handleSelectBackend(backend)}\n onEdit={() => setEditingBackend(backend)}\n onRemove={() =>\n setPendingRemoval({\n id: backend.id,\n name: backend.name,\n })\n }\n onLogin={(apiKey) => handleCloudLogin(backend, apiKey)}\n />\n ))}\n </ul>\n )}\n </div>\n </div>\n\n <div className=\"flex justify-end gap-2 p-5\">\n {isLockedToCloud ? (\n lockedCloudBackend ? (\n <DeviceFlowAuth\n host={lockedCloudReconnectHost}\n onSuccess={handleLockedCloudReconnect}\n testIdRoot=\"manage-backends-reconnect-cloud\"\n idleButtonLabel={t(I18nKey.BACKEND$RECONNECT_CLOUD)}\n className=\"w-full sm:w-auto\"\n buttonClassName=\"w-full sm:w-auto\"\n statusDisplay=\"modal\"\n />\n ) : null\n ) : (\n <BrandButton\n type=\"button\"\n variant={recoveryMode ? \"primary\" : \"secondary\"}\n onClick={() => setShowAddForm(true)}\n testId=\"manage-backends-add\"\n startContent={<Plus width={14} height={14} />}\n >\n {t(I18nKey.BACKEND$ADD)}\n </BrandButton>\n )}\n {recoveryMode ? null : (\n <BrandButton\n type=\"button\"\n variant=\"primary\"\n onClick={onClose}\n testId=\"manage-backends-done\"\n >\n {t(I18nKey.HOME$DONE)}\n </BrandButton>\n )}\n </div>\n </div>\n </ModalBackdrop>\n\n {showAddForm ? (\n <BackendFormModal\n mode=\"add\"\n source=\"manage_backends_modal\"\n onClose={() => setShowAddForm(false)}\n />\n ) : null}\n\n {editingBackend ? (\n <BackendFormModal\n mode=\"edit\"\n backend={editingBackend}\n onClose={() => setEditingBackend(null)}\n />\n ) : null}\n\n {pendingRemoval ? (\n <ConfirmationModal\n text={t(I18nKey.BACKEND$REMOVE_CONFIRMATION, {\n name: pendingRemoval.name,\n })}\n onConfirm={handleConfirmRemoval}\n onCancel={() => setPendingRemoval(null)}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"manage-backends-modal.js","names":[],"sources":["../../../../src/components/features/backends/manage-backends-modal.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Plus } from \"lucide-react\";\n\nimport { getLockedCloudHost } from \"#/api/agent-server-config\";\nimport { type Backend } from \"#/api/backend-registry/types\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\nimport { ConfirmationModal } from \"#/components/shared/modals/confirmation-modal\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport {\n MODAL_MAX_WIDTH_VIEWPORT,\n modalWidthClassName,\n} from \"#/components/shared/modals/modal-body\";\nimport { ModalCloseButton } from \"#/components/shared/modals/modal-close-button\";\nimport { useActiveBackendContext } from \"#/contexts/active-backend-context\";\nimport { useBackendsHealth } from \"#/hooks/query/use-backends-health\";\nimport { useAllCloudOrganizations } from \"#/hooks/query/use-cloud-organizations\";\nimport { useCloudCurrentUserId } from \"#/hooks/query/use-cloud-current-user-id\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { modalTitleLgClassName } from \"#/utils/modal-classes\";\nimport { BackendFormModal } from \"./backend-form-modal\";\nimport { BackendRow } from \"./backend-row\";\nimport { DeviceFlowAuth } from \"./device-flow-auth\";\n\ninterface ManageBackendsModalProps {\n onClose: () => void;\n /**\n * Recovery mode is used by the root unavailable-backend gate. There is no\n * app shell behind the modal, so dismiss controls would be misleading.\n */\n recoveryMode?: boolean;\n}\n\ninterface PendingRemoval {\n id: string;\n name: string;\n}\n\n/**\n * Resolve the connected organization label for a backend row, mirroring the\n * per-org labelling used by the backend selector. Cloud API keys are bound to\n * a single org (legacy keys may expose several, joined here); local backends\n * and unresolved/errored lookups yield no label.\n */\nfunction resolveBackendOrgLabel(\n backend: Backend,\n cloudOrgs: ReturnType<typeof useAllCloudOrganizations>,\n currentUserIds: ReturnType<typeof useCloudCurrentUserId>,\n personalWorkspaceLabel: string,\n): string | undefined {\n if (backend.kind !== \"cloud\") return undefined;\n const entry = cloudOrgs[backend.id];\n if (!entry || entry.orgs.length === 0) return undefined;\n const userId = currentUserIds[backend.id]?.userId ?? null;\n return entry.orgs\n .map((org) =>\n !!userId && userId === org.id ? personalWorkspaceLabel : org.name,\n )\n .join(\", \");\n}\n\nexport function ManageBackendsModal({\n onClose,\n recoveryMode = false,\n}: ManageBackendsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const { backends, active, removeBackend, setActive, updateBackend } =\n useActiveBackendContext();\n const healthByBackendId = useBackendsHealth(backends, {\n probeDisabledOnce: true,\n });\n const cloudOrgs = useAllCloudOrganizations();\n const currentUserIds = useCloudCurrentUserId();\n const personalWorkspaceLabel = t(I18nKey.BACKEND$PERSONAL_WORKSPACE);\n const lockedCloudHost = getLockedCloudHost();\n const isLockedToCloud = lockedCloudHost !== null;\n // Cookie-auth (OHE-hosted) backends have no API key to refresh — re-auth is\n // the main-app login, so the device-flow reconnect controls don't apply.\n const isCookieAuthBackend = active.backend.authMode === \"cookie\";\n const lockedCloudBackend =\n isLockedToCloud && !isCookieAuthBackend && active.backend.kind === \"cloud\"\n ? active.backend\n : null;\n const lockedCloudReconnectHost =\n lockedCloudHost ?? lockedCloudBackend?.host ?? \"\";\n const modalTitle =\n isLockedToCloud && !isCookieAuthBackend\n ? t(I18nKey.BACKEND$RECONNECT_CLOUD_TITLE)\n : t(I18nKey.BACKEND$MANAGE_TITLE);\n const [pendingRemoval, setPendingRemoval] =\n React.useState<PendingRemoval | null>(null);\n const [editingBackend, setEditingBackend] = React.useState<Backend | null>(\n null,\n );\n const [showAddForm, setShowAddForm] = React.useState(false);\n\n const handleConfirmRemoval = () => {\n if (!pendingRemoval) return;\n removeBackend(pendingRemoval.id);\n setPendingRemoval(null);\n };\n\n const handleSelectBackend = React.useCallback(\n (backend: Backend) => {\n if (active.backend.id !== backend.id || active.orgId !== null) {\n setActive(backend.id);\n }\n onClose();\n },\n [active.backend.id, active.orgId, onClose, setActive],\n );\n\n const handleCloudLogin = React.useCallback(\n (backend: Backend, apiKey: string) => {\n updateBackend(backend.id, { apiKey });\n },\n [updateBackend],\n );\n\n const handleLockedCloudReconnect = React.useCallback(\n (apiKey: string) => {\n if (!lockedCloudBackend) return;\n updateBackend(lockedCloudBackend.id, { apiKey });\n },\n [lockedCloudBackend, updateBackend],\n );\n\n return (\n <>\n <ModalBackdrop\n onClose={recoveryMode ? undefined : onClose}\n closeOnEscape={!recoveryMode}\n closeOnBackdropClick={!recoveryMode}\n aria-label={modalTitle}\n >\n <div\n data-testid=\"manage-backends-modal\"\n className={cn(\n \"relative flex flex-col bg-[var(--oh-surface)] border border-[var(--oh-border)] rounded-xl\",\n modalWidthClassName(\"lg\"),\n MODAL_MAX_WIDTH_VIEWPORT,\n \"max-h-[70vh]\",\n )}\n >\n {recoveryMode ? null : (\n <ModalCloseButton\n onClose={onClose}\n testId=\"close-manage-backends-modal\"\n />\n )}\n <div className={cn(\"p-5\", !recoveryMode && \"pr-12\")}>\n <h2 className={modalTitleLgClassName}>{modalTitle}</h2>\n </div>\n\n <div className=\"flex min-h-0 flex-1 flex-col px-5\">\n <div\n className=\"flex-1 overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\"\n data-testid=\"manage-backends-list\"\n >\n {backends.length === 0 ? (\n <p className=\"px-3 py-6 text-center text-sm text-[var(--oh-text-secondary)]\">\n {t(I18nKey.BACKEND$MANAGE_EMPTY)}\n </p>\n ) : (\n <ul className=\"divide-y divide-[var(--oh-border)]\">\n {backends.map((backend) => (\n <BackendRow\n key={backend.id}\n backend={backend}\n health={healthByBackendId[backend.id]}\n orgLabel={resolveBackendOrgLabel(\n backend,\n cloudOrgs,\n currentUserIds,\n personalWorkspaceLabel,\n )}\n onSelect={() => handleSelectBackend(backend)}\n onEdit={() => setEditingBackend(backend)}\n onRemove={() =>\n setPendingRemoval({\n id: backend.id,\n name: backend.name,\n })\n }\n onLogin={\n backend.authMode === \"cookie\"\n ? undefined\n : (apiKey) => handleCloudLogin(backend, apiKey)\n }\n />\n ))}\n </ul>\n )}\n </div>\n </div>\n\n <div className=\"flex justify-end gap-2 p-5\">\n {isLockedToCloud ? (\n lockedCloudBackend ? (\n <DeviceFlowAuth\n host={lockedCloudReconnectHost}\n onSuccess={handleLockedCloudReconnect}\n testIdRoot=\"manage-backends-reconnect-cloud\"\n idleButtonLabel={t(I18nKey.BACKEND$RECONNECT_CLOUD)}\n className=\"w-full sm:w-auto\"\n buttonClassName=\"w-full sm:w-auto\"\n statusDisplay=\"modal\"\n />\n ) : null\n ) : (\n <BrandButton\n type=\"button\"\n variant={recoveryMode ? \"primary\" : \"secondary\"}\n onClick={() => setShowAddForm(true)}\n testId=\"manage-backends-add\"\n startContent={<Plus width={14} height={14} />}\n >\n {t(I18nKey.BACKEND$ADD)}\n </BrandButton>\n )}\n {recoveryMode ? null : (\n <BrandButton\n type=\"button\"\n variant=\"primary\"\n onClick={onClose}\n testId=\"manage-backends-done\"\n >\n {t(I18nKey.HOME$DONE)}\n </BrandButton>\n )}\n </div>\n </div>\n </ModalBackdrop>\n\n {showAddForm ? (\n <BackendFormModal\n mode=\"add\"\n source=\"manage_backends_modal\"\n onClose={() => setShowAddForm(false)}\n />\n ) : null}\n\n {editingBackend ? (\n <BackendFormModal\n mode=\"edit\"\n backend={editingBackend}\n onClose={() => setEditingBackend(null)}\n />\n ) : null}\n\n {pendingRemoval ? (\n <ConfirmationModal\n text={t(I18nKey.BACKEND$REMOVE_CONFIRMATION, {\n name: pendingRemoval.name,\n })}\n onConfirm={handleConfirmRemoval}\n onCancel={() => setPendingRemoval(null)}\n />\n ) : null}\n </>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/react-i18next/dist/es/useTranslation.cjs"),n=require("../../../i18n/declaration.cjs"),r=require("../../../types/agent-state.cjs"),i=require("../../../utils/utils.cjs"),a=require("../../../hooks/use-conversation-id.cjs"),o=require("../../../stores/conversation-store.cjs"),s=require("../../../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs"),c=require("../../../hooks/query/use-active-conversation.cjs"),l=require("../../../hooks/use-agent-state.cjs"),u=require("../../../utils/form-control-classes.cjs"),d=require("../../shared/buttons/styled-tooltip.cjs"),f=require("../../../hooks/use-unified-websocket-status.cjs"),p=require("../../../hooks/query/use-sub-conversation-task-polling.cjs"),m=require("../../../ui/typography.cjs"),h=require("../../../ui/combobox-caret.cjs"),g=require("../../../icons/lesson-plan.cjs"),_=require("../../../icons/code-pill.cjs"),v=require("./change-agent-context-menu.cjs"),y=require("../../../hooks/use-handle-plan-click.cjs");let b=require("react");b=e.__toESM(b,1);let x=require("react/jsx-runtime");function S(){let[e,S]=(0,b.useState)(!1),{conversationMode:C,setConversationMode:w,subConversationTaskId:T}=o.useConversationStore(),{conversationId:E}=a.useOptionalConversationId(),D=!E,O=f.useUnifiedWebSocketStatus()===`OPEN`,{curAgentState:k}=l.useAgentState(),{t:A}=t.useTranslation(`openhands`),j=k===r.AgentState.RUNNING,{data:M}=c.useActiveConversation(),N=s.useQueryClient(),P=(0,b.useRef)(null),{taskStatus:F,subConversationId:I}=p.useSubConversationTaskPolling(T,M?.id||null);(0,b.useEffect)(()=>{F===`READY`&&I&&M?.id&&T&&P.current!==T&&(P.current=T,N.invalidateQueries({queryKey:[`user`,`conversation`,M.id]}))},[F,I,M?.id,T,N]);let{handlePlanClick:L,isCreatingConversation:R}=y.useHandlePlanClick();(0,b.useEffect)(()=>{(j||!O)&&e&&S(!1)},[j,e,O]);let z=D||j||R||!O;(0,b.useEffect)(()=>{if(z)return;let e=e=>{if(e.shiftKey&&e.key===`Tab`){e.preventDefault(),e.stopPropagation();let t=C===`code`?`plan`:`code`;t===`plan`?L(e):w(t)}};return document.addEventListener(`keydown`,e),()=>{document.removeEventListener(`keydown`,e)}},[z,C,w,L]);let B=t=>{t.preventDefault(),t.stopPropagation(),S(!e)},V=e=>{e.preventDefault(),e.stopPropagation(),w(`code`)},H=C===`code`,U=(0,b.useMemo)(()=>A(H?n.I18nKey.COMMON$CODE:n.I18nKey.COMMON$PLAN),[H,A]),W=(0,b.useMemo)(()=>H?(0,x.jsx)(_.CodePillIcon,{className:`h-[11px] w-[11px] shrink-0`}):(0,x.jsx)(g.default,{width:18,height:18,color:`currentColor`}),[H]),G=(0,x.jsxs)(`div`,{className:`relative`,children:[(0,x.jsxs)(`button`,{type:`button`,onClick:B,disabled:z,className:i.cn(`flex items-center rounded-[100px]`,u.formControlTransitionClassName,H?`border border-transparent text-[var(--oh-muted)]`:`border border-[#597FF4] bg-[#4A67BD]`,!z&&H&&i.cn(`cursor-pointer`,`hover:text-white hover:bg-white/10`),!z&&!H&&`cursor-pointer text-white hover:bg-[#597FF4]`,z&&i.cn(`opacity-50 cursor-not-allowed`,H&&`border-transparent`)),children:[(0,x.jsxs)(`div`,{className:`flex items-center gap-1 pl-1.5`,children:[W,(0,x.jsx)(m.Typography.Text,{className:`text-2.75 not-italic font-normal leading-5`,children:U})]}),(0,x.jsx)(h.ComboboxCaretInline,{isOpen:e})]}),e&&(0,x.jsx)(v.ChangeAgentContextMenu,{activeMode:C,onClose:()=>S(!1),onCodeClick:V,onPlanClick:L})]});return D?(0,x.jsx)(d.StyledTooltip,{content:A(n.I18nKey.CHANGE_AGENT$SWITCH_AFTER_CONVERSATION),placement:`top`,children:G}):G}exports.ChangeAgentButton=S;
1
+ const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/react-i18next/dist/es/useTranslation.cjs"),n=require("../../../i18n/declaration.cjs"),r=require("../../../types/agent-state.cjs"),i=require("../../../utils/utils.cjs"),a=require("../../../hooks/use-conversation-id.cjs"),o=require("../../../stores/conversation-store.cjs"),s=require("../../../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs"),c=require("../../../hooks/query/use-active-conversation.cjs"),l=require("../../../hooks/use-agent-state.cjs"),u=require("../../shared/buttons/styled-tooltip.cjs"),d=require("../../../utils/form-control-classes.cjs"),f=require("../../../hooks/use-unified-websocket-status.cjs"),p=require("../../../hooks/query/use-sub-conversation-task-polling.cjs"),m=require("../../../ui/typography.cjs"),h=require("../../../ui/combobox-caret.cjs"),g=require("../../../icons/lesson-plan.cjs"),_=require("../../../icons/code-pill.cjs"),v=require("./change-agent-context-menu.cjs"),y=require("../../../hooks/use-handle-plan-click.cjs");let b=require("react");b=e.__toESM(b,1);let x=require("react/jsx-runtime");function S(){let[e,S]=(0,b.useState)(!1),{conversationMode:C,setConversationMode:w,subConversationTaskId:T}=o.useConversationStore(),{conversationId:E}=a.useOptionalConversationId(),D=!E,O=f.useUnifiedWebSocketStatus()===`OPEN`,{curAgentState:k}=l.useAgentState(),{t:A}=t.useTranslation(`openhands`),j=k===r.AgentState.RUNNING,{data:M}=c.useActiveConversation(),N=s.useQueryClient(),P=(0,b.useRef)(null),{taskStatus:F,subConversationId:I}=p.useSubConversationTaskPolling(T,M?.id||null);(0,b.useEffect)(()=>{F===`READY`&&I&&M?.id&&T&&P.current!==T&&(P.current=T,N.invalidateQueries({queryKey:[`user`,`conversation`,M.id]}))},[F,I,M?.id,T,N]);let{handlePlanClick:L,isCreatingConversation:R}=y.useHandlePlanClick();(0,b.useEffect)(()=>{(j||!O)&&e&&S(!1)},[j,e,O]);let z=D||j||R||!O;(0,b.useEffect)(()=>{if(z)return;let e=e=>{if(e.shiftKey&&e.key===`Tab`){e.preventDefault(),e.stopPropagation();let t=C===`code`?`plan`:`code`;t===`plan`?L(e):w(t)}};return document.addEventListener(`keydown`,e),()=>{document.removeEventListener(`keydown`,e)}},[z,C,w,L]);let B=t=>{t.preventDefault(),t.stopPropagation(),S(!e)},V=e=>{e.preventDefault(),e.stopPropagation(),w(`code`)},H=C===`code`,U=(0,b.useMemo)(()=>A(H?n.I18nKey.COMMON$CODE:n.I18nKey.COMMON$PLAN),[H,A]),W=(0,b.useMemo)(()=>H?(0,x.jsx)(_.CodePillIcon,{className:`h-[11px] w-[11px] shrink-0`}):(0,x.jsx)(g.default,{width:18,height:18,color:`currentColor`}),[H]),G=(0,x.jsxs)(`div`,{className:`relative`,children:[(0,x.jsxs)(`button`,{type:`button`,onClick:B,disabled:z,className:i.cn(`flex items-center rounded-[100px]`,d.formControlTransitionClassName,H?`border border-transparent text-[var(--oh-muted)]`:`border border-[#597FF4] bg-[#4A67BD]`,!z&&H&&i.cn(`cursor-pointer`,`hover:text-white hover:bg-white/10`),!z&&!H&&`cursor-pointer text-white hover:bg-[#597FF4]`,z&&i.cn(`opacity-50 cursor-not-allowed`,H&&`border-transparent`)),children:[(0,x.jsxs)(`div`,{className:`flex items-center gap-1 pl-1.5`,children:[W,(0,x.jsx)(m.Typography.Text,{className:`text-2.75 not-italic font-normal leading-5`,children:U})]}),(0,x.jsx)(h.ComboboxCaretInline,{isOpen:e})]}),e&&(0,x.jsx)(v.ChangeAgentContextMenu,{activeMode:C,onClose:()=>S(!1),onCodeClick:V,onPlanClick:L})]});return D?(0,x.jsx)(u.StyledTooltip,{content:A(n.I18nKey.CHANGE_AGENT$SWITCH_AFTER_CONVERSATION),placement:`top`,children:G}):G}exports.ChangeAgentButton=S;
2
2
  //# sourceMappingURL=change-agent-button.cjs.map
@@ -7,8 +7,8 @@ import { useConversationStore as a } from "../../../stores/conversation-store.js
7
7
  import { useQueryClient as o } from "../../../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js";
8
8
  import { useActiveConversation as s } from "../../../hooks/query/use-active-conversation.js";
9
9
  import { useAgentState as c } from "../../../hooks/use-agent-state.js";
10
- import { formControlTransitionClassName as l } from "../../../utils/form-control-classes.js";
11
- import { StyledTooltip as u } from "../../shared/buttons/styled-tooltip.js";
10
+ import { StyledTooltip as l } from "../../shared/buttons/styled-tooltip.js";
11
+ import { formControlTransitionClassName as u } from "../../../utils/form-control-classes.js";
12
12
  import { useUnifiedWebSocketStatus as d } from "../../../hooks/use-unified-websocket-status.js";
13
13
  import { useSubConversationTaskPolling as f } from "../../../hooks/query/use-sub-conversation-task-polling.js";
14
14
  import { Typography as p } from "../../../ui/typography.js";
@@ -76,7 +76,7 @@ function T() {
76
76
  type: "button",
77
77
  onClick: W,
78
78
  disabled: U,
79
- className: r("flex items-center rounded-[100px]", l, K ? "border border-transparent text-[var(--oh-muted)]" : "border border-[#597FF4] bg-[#4A67BD]", !U && K && r("cursor-pointer", "hover:text-white hover:bg-white/10"), !U && !K && "cursor-pointer text-white hover:bg-[#597FF4]", U && r("opacity-50 cursor-not-allowed", K && "border-transparent")),
79
+ className: r("flex items-center rounded-[100px]", u, K ? "border border-transparent text-[var(--oh-muted)]" : "border border-[#597FF4] bg-[#4A67BD]", !U && K && r("cursor-pointer", "hover:text-white hover:bg-white/10"), !U && !K && "cursor-pointer text-white hover:bg-[#597FF4]", U && r("opacity-50 cursor-not-allowed", K && "border-transparent")),
80
80
  children: [/* @__PURE__ */ w("div", {
81
81
  className: "flex items-center gap-1 pl-1.5",
82
82
  children: [J, /* @__PURE__ */ C(p.Text, {
@@ -91,7 +91,7 @@ function T() {
91
91
  onPlanClick: V
92
92
  })]
93
93
  });
94
- return j ? /* @__PURE__ */ C(u, {
94
+ return j ? /* @__PURE__ */ C(l, {
95
95
  content: P(t.CHANGE_AGENT$SWITCH_AFTER_CONVERSATION),
96
96
  placement: "top",
97
97
  children: Y
@@ -1,4 +1,4 @@
1
- const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/react-i18next/dist/es/useTranslation.cjs"),n=require("../../../i18n/declaration.cjs"),r=require("../../../types/agent-state.cjs"),i=require("../../../utils/utils.cjs"),a=require("../../../hooks/use-conversation-id.cjs"),o=require("../../../stores/conversation-store.cjs"),s=require("../../../utils/custom-toast-handlers.cjs");require("../../../constants/server-connection-error.cjs");const c=require("../../../stores/error-message-store.cjs"),l=require("../../../stores/optimistic-user-message-store.cjs"),u=require("../../../stores/goal-store.cjs"),d=require("../../../stores/model-store.cjs"),f=require("../../../contexts/conversation-websocket-context.cjs"),p=require("../../../hooks/use-send-message.cjs"),m=require("../../../hooks/query/use-active-conversation.cjs"),h=require("../../../hooks/use-agent-state.cjs"),ee=require("../../../utils/convert-image-to-base-64.cjs"),te=require("../../../utils/file-validation.cjs"),g=require("../../../utils/pending-task-message-link.cjs"),ne=require("../../../hooks/query/use-task-polling.cjs"),re=require("../../../hooks/use-tracking.cjs"),ie=require("../../../utils/acp-error-codes.cjs"),ae=require("../../../services/chat-service.cjs"),oe=require("./btw-messages.cjs"),se=require("./goal-status-banner.cjs"),ce=require("./model-messages.cjs"),le=require("./components/resolve-picker-kind.cjs"),ue=require("../../../hooks/use-is-archived-conversation.cjs"),de=require("../../shared/loading-spinner.cjs"),fe=require("../../../hooks/use-scroll-to-bottom.cjs"),pe=require("../../../context/scroll-context.cjs"),me=require("./interactive-chat-box.cjs"),he=require("../../../hooks/use-filtered-events.cjs"),ge=require("../../../hooks/use-load-older-events.cjs"),_e=require("../../../hooks/use-auto-refresh-files-on-edit.cjs"),ve=require("./chat-markdown-path-code.cjs"),ye=require("./typing-indicator.cjs"),be=require("./chat-suggestions.cjs"),xe=require("../../../stores/initial-query-store.cjs"),Se=require("../../../hooks/use-handle-build-plan-click.cjs"),Ce=require("../../shared/buttons/scroll-to-bottom-button.cjs"),we=require("./chat-messages-skeleton.cjs"),Te=require("./error-message-banner.cjs"),Ee=require("./skill-install-restart-banner.cjs"),De=require("../../../hooks/use-llm-configured.cjs"),Oe=require("../home/llm-not-configured-banner.cjs"),ke=require("../../conversation-events/chat/messages.cjs"),Ae=require("./pending-user-messages.cjs"),je=require("../../../hooks/mutation/use-unified-upload-files.cjs"),Me=require("./confirmation-mode-enabled.cjs"),Ne=require("./chat-status-indicator.cjs"),Pe=require("../../../hooks/mutation/use-new-conversation-command.cjs");let _=require("react");_=e.__toESM(_,1);let v=require("react/jsx-runtime"),Fe=require("react-router");function Ie(e,t){return e?`github`:t?`replay`:`direct`}function y(){_e.useAutoRefreshFilesOnEdit();let{trackInitialQuerySubmitted:e,trackUserMessageSent:y}=re.useTracking(),{setMessageToSend:b,conversationMode:x,planContent:S}=o.useConversationStore(),{errorMessage:C,errorCode:w,errorClassification:Le,removeErrorMessage:Re,setErrorMessage:T}=c.useErrorMessageStore(),ze=(0,Fe.useNavigate)(),{isTask:E,taskStatus:D,taskDetail:Be}=ne.useTaskPolling(),O=E,k=f.useConversationWebSocket(),{send:Ve}=p.useSendMessage(),{renderableEvents:A,allConversationEvents:j,totalEvents:M,hasSubstantiveAgentActions:N,userEventsExist:P}=he.useFilteredEvents(),He=l.useOptimisticUserMessageStore(e=>e.enqueuePendingMessage),Ue=l.useOptimisticUserMessageStore(e=>e.markPendingMessageError),F=l.useOptimisticUserMessageStore(e=>e.pendingMessages),{t:I}=t.useTranslation(`openhands`),L=_.default.useRef(null),{scrollDomToBottom:R,onChatBodyScroll:z,hitBottom:B,autoScroll:V,setAutoScroll:We,setHitBottom:Ge}=fe.useScrollToBottom(L),{mutate:Ke,isPending:qe}=Pe.useNewConversationCommand(),{curAgentState:H}=h.useAgentState(),{handleBuildPlanClick:Je}=Se.useHandleBuildPlanClick(),{data:Ye}=m.useActiveConversation(),Xe=Ye?.sandbox_status??null,U=ue.useIsArchivedConversation(),{isConfigured:Ze,isLoading:Qe}=De.useLlmConfigured(),W=!Qe&&!Ze,$e=H===r.AgentState.RUNNING||H===r.AgentState.LOADING;_.default.useEffect(()=>{if($e||x!==`plan`||!S)return;let e=e=>{(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&(e.preventDefault(),e.stopPropagation(),Je(e),R())};return document.addEventListener(`keydown`,e),()=>{document.removeEventListener(`keydown`,e)}},[$e,x,S,Je,R]);let{selectedRepository:et,replayJson:tt}=xe.useInitialQueryStore(),{conversationId:G}=a.useOptionalConversationId(),nt=u.useGoalStore(e=>{let t=G?e.statusByConversation[G]:void 0;return t?.active?`${t.iteration}:${t.status}`:null}),{mutateAsync:rt}=je.useUnifiedUploadFiles(),{isLoading:K,hasMore:q,loadOlder:it}=ge.useLoadOlderEvents(G),J=_.default.useRef(null),Y=_.default.useCallback(e=>{if(O||K||!q)return;let t=e.scrollTop<=80,r=e.scrollHeight<=e.clientHeight+80;!t&&!r||(J.current={scrollHeight:e.scrollHeight,scrollTop:e.scrollTop},it().catch(e=>{J.current=null,T(e instanceof Error&&e.message?e.message:I(n.I18nKey.ERROR$GENERIC))}))},[q,K,O,it,T,I]),at=_.default.useCallback(e=>{e.deltaY<0&&e.currentTarget.scrollTop<=0&&Y(e.currentTarget)},[Y]),X=_.default.useMemo(()=>G?F.some(e=>g.matchesPendingConversationId(G,e.conversationId)):!1,[F,G]),ot=d.useModelStore(e=>G?(e.entriesByConversation[G]?.length??0)>0:!1),st=le.hasConversationStarted({isLoadingHistory:k?.isLoadingHistory===!0,hasUserEvents:P,hasPendingUserMessages:X,hasSubstantiveAgentActions:N,hasModelEntries:ot}),ct=j.length>0||X||!k?.isLoadingHistory,lt=!!G,Z=!ct&&!E,ut=async(t,r,i)=>{if(t.trim()===`/new`){if(!G){s.displayErrorToast(I(n.I18nKey.CONVERSATION$CLEAR_NO_ID));return}if(M===0){s.displayErrorToast(I(n.I18nKey.CONVERSATION$CLEAR_EMPTY));return}if(qe)return;Ke();return}let a=[...r],o=[...i];M===0?e({entryPoint:Ie(et!==null,tt!==null),queryCharacterLength:t.length,replayJsonSize:tt?.length}):y({sessionMessageCount:M,currentMessageLength:t.length});let c=te.validateFiles([...a,...o]);if(!c.isValid){s.displayErrorToast(`Error: ${c.errorMessage}`);return}let l=a.map(e=>ee.convertImageToBase64(e)),u=await Promise.all(l),d=new Date().toISOString(),{skipped_files:f,uploaded_files:p}=o.length>0?await rt({conversationId:G,files:o}):{skipped_files:[],uploaded_files:[]};f.forEach(e=>s.displayErrorToast(e.reason));let m=`${I(n.I18nKey.CHAT_INTERFACE$AUGMENTED_PROMPT_FILES_TITLE)}: ${p.join(`
1
+ const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/react-i18next/dist/es/useTranslation.cjs"),n=require("../../../i18n/declaration.cjs"),r=require("../../../types/agent-state.cjs"),i=require("../../../utils/utils.cjs"),a=require("../../../hooks/use-conversation-id.cjs"),o=require("../../../stores/conversation-store.cjs"),s=require("../../../utils/custom-toast-handlers.cjs");require("../../../constants/server-connection-error.cjs");const c=require("../../../stores/error-message-store.cjs"),l=require("../../../stores/optimistic-user-message-store.cjs"),u=require("../../../stores/goal-store.cjs"),d=require("../../../stores/model-store.cjs"),f=require("../../../contexts/conversation-websocket-context.cjs"),p=require("../../../hooks/use-send-message.cjs"),m=require("../../../hooks/query/use-active-conversation.cjs"),h=require("../../../hooks/use-agent-state.cjs"),ee=require("../../../utils/convert-image-to-base-64.cjs"),te=require("../../../utils/file-validation.cjs"),ne=require("../../../utils/pending-task-message-link.cjs"),re=require("../../../hooks/query/use-task-polling.cjs"),ie=require("../../../hooks/use-tracking.cjs"),ae=require("../../../utils/acp-error-codes.cjs"),oe=require("../../../services/chat-service.cjs"),se=require("./btw-messages.cjs"),ce=require("./goal-status-banner.cjs"),le=require("./model-messages.cjs"),ue=require("./components/resolve-picker-kind.cjs"),de=require("../../../hooks/use-is-archived-conversation.cjs"),g=require("../../shared/loading-spinner.cjs"),fe=require("../../../hooks/use-scroll-to-bottom.cjs"),pe=require("../../../context/scroll-context.cjs"),me=require("./interactive-chat-box.cjs"),he=require("../../../hooks/use-filtered-events.cjs"),ge=require("../../../hooks/use-load-older-events.cjs"),_e=require("../../../hooks/use-auto-refresh-files-on-edit.cjs"),ve=require("./chat-markdown-path-code.cjs"),ye=require("./typing-indicator.cjs"),be=require("./chat-suggestions.cjs"),xe=require("../../../stores/initial-query-store.cjs"),Se=require("../../../hooks/use-handle-build-plan-click.cjs"),Ce=require("../../shared/buttons/scroll-to-bottom-button.cjs"),we=require("./chat-messages-skeleton.cjs"),Te=require("./error-message-banner.cjs"),Ee=require("./skill-install-restart-banner.cjs"),De=require("../../../hooks/use-llm-configured.cjs"),Oe=require("../home/llm-not-configured-banner.cjs"),ke=require("../../conversation-events/chat/messages.cjs"),Ae=require("./pending-user-messages.cjs"),je=require("../../../hooks/mutation/use-unified-upload-files.cjs"),Me=require("./confirmation-mode-enabled.cjs"),Ne=require("./chat-status-indicator.cjs"),Pe=require("../../../hooks/mutation/use-new-conversation-command.cjs");let _=require("react");_=e.__toESM(_,1);let v=require("react/jsx-runtime"),Fe=require("react-router");function Ie(e,t){return e?`github`:t?`replay`:`direct`}function y(){_e.useAutoRefreshFilesOnEdit();let{trackInitialQuerySubmitted:e,trackUserMessageSent:y}=ie.useTracking(),{setMessageToSend:b,conversationMode:x,planContent:S}=o.useConversationStore(),{errorMessage:C,errorCode:w,errorClassification:Le,removeErrorMessage:Re,setErrorMessage:T}=c.useErrorMessageStore(),ze=(0,Fe.useNavigate)(),{isTask:E,taskStatus:D,taskDetail:Be}=re.useTaskPolling(),O=E,k=f.useConversationWebSocket(),{send:Ve}=p.useSendMessage(),{renderableEvents:A,allConversationEvents:j,totalEvents:M,hasSubstantiveAgentActions:N,userEventsExist:P}=he.useFilteredEvents(),He=l.useOptimisticUserMessageStore(e=>e.enqueuePendingMessage),Ue=l.useOptimisticUserMessageStore(e=>e.markPendingMessageError),F=l.useOptimisticUserMessageStore(e=>e.pendingMessages),{t:I}=t.useTranslation(`openhands`),L=_.default.useRef(null),{scrollDomToBottom:R,onChatBodyScroll:z,hitBottom:B,autoScroll:V,setAutoScroll:We,setHitBottom:Ge}=fe.useScrollToBottom(L),{mutate:Ke,isPending:qe}=Pe.useNewConversationCommand(),{curAgentState:H}=h.useAgentState(),{isPlanningAgentRunning:Je}=h.usePlanningAgentState(),{handleBuildPlanClick:Ye}=Se.useHandleBuildPlanClick(),{data:Xe}=m.useActiveConversation(),Ze=Xe?.sandbox_status??null,U=de.useIsArchivedConversation(),{isConfigured:Qe,isLoading:$e}=De.useLlmConfigured(),W=!$e&&!Qe,et=H===r.AgentState.RUNNING||H===r.AgentState.LOADING;_.default.useEffect(()=>{if(et||x!==`plan`||!S)return;let e=e=>{(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&(e.preventDefault(),e.stopPropagation(),Ye(e),R())};return document.addEventListener(`keydown`,e),()=>{document.removeEventListener(`keydown`,e)}},[et,x,S,Ye,R]);let{selectedRepository:tt,replayJson:nt}=xe.useInitialQueryStore(),{conversationId:G}=a.useOptionalConversationId(),rt=u.useGoalStore(e=>{let t=G?e.statusByConversation[G]:void 0;return t?.active?`${t.iteration}:${t.status}`:null}),{mutateAsync:it}=je.useUnifiedUploadFiles(),{isLoading:K,hasMore:q,loadOlder:at}=ge.useLoadOlderEvents(G),J=_.default.useRef(null),Y=_.default.useCallback(e=>{if(O||K||!q)return;let t=e.scrollTop<=80,r=e.scrollHeight<=e.clientHeight+80;!t&&!r||(J.current={scrollHeight:e.scrollHeight,scrollTop:e.scrollTop},at().catch(e=>{J.current=null,T(e instanceof Error&&e.message?e.message:I(n.I18nKey.ERROR$GENERIC))}))},[q,K,O,at,T,I]),ot=_.default.useCallback(e=>{e.deltaY<0&&e.currentTarget.scrollTop<=0&&Y(e.currentTarget)},[Y]),X=_.default.useMemo(()=>G?F.some(e=>ne.matchesPendingConversationId(G,e.conversationId)):!1,[F,G]),st=d.useModelStore(e=>G?(e.entriesByConversation[G]?.length??0)>0:!1),ct=ue.hasConversationStarted({isLoadingHistory:k?.isLoadingHistory===!0,hasUserEvents:P,hasPendingUserMessages:X,hasSubstantiveAgentActions:N,hasModelEntries:st}),lt=j.length>0||X||!k?.isLoadingHistory,ut=!!G,Z=!lt&&!E,dt=async(t,r,i)=>{if(t.trim()===`/new`){if(!G){s.displayErrorToast(I(n.I18nKey.CONVERSATION$CLEAR_NO_ID));return}if(M===0){s.displayErrorToast(I(n.I18nKey.CONVERSATION$CLEAR_EMPTY));return}if(qe)return;Ke();return}let a=[...r],o=[...i];M===0?e({entryPoint:Ie(tt!==null,nt!==null),queryCharacterLength:t.length,replayJsonSize:nt?.length}):y({sessionMessageCount:M,currentMessageLength:t.length});let c=te.validateFiles([...a,...o]);if(!c.isValid){s.displayErrorToast(`Error: ${c.errorMessage}`);return}let l=a.map(e=>ee.convertImageToBase64(e)),u=await Promise.all(l),d=new Date().toISOString(),{skipped_files:f,uploaded_files:p}=o.length>0?await it({conversationId:G,files:o}):{skipped_files:[],uploaded_files:[]};f.forEach(e=>s.displayErrorToast(e.reason));let m=`${I(n.I18nKey.CHAT_INTERFACE$AUGMENTED_PROMPT_FILES_TITLE)}: ${p.join(`
2
2
 
3
- `)}`,h=p.length>0?`${t}\n\n${m}`:t,g=He({conversationId:G,text:t,content:h,imageUrls:u,fileUrls:p,timestamp:d});R(),b(``);try{await Ve(ae.createChatMessage(h,u,p,d))}catch(e){Ue(g,e instanceof Error?e.message:I(n.I18nKey.CHAT_INTERFACE$FAILED_TO_SEND_MESSAGE))}};_.default.useEffect(()=>{if(J.current&&L.current){let{scrollHeight:e,scrollTop:t}=J.current,n=L.current,r=n.scrollHeight-e;r>0&&(n.scrollTop=t+r),J.current=null;return}V&&R()},[A.length,X,nt,R]);let dt=_.default.useRef(Y);_.default.useEffect(()=>{dt.current=Y}),_.default.useEffect(()=>{let e=L.current;e&&dt.current(e)},[A.length,q]);let ft={scrollRef:L,autoScroll:V,setAutoScroll:We,scrollDomToBottom:R,hitBottom:B,setHitBottom:Ge,onChatBodyScroll:z},Q=H===r.AgentState.LOADING||H===r.AgentState.INIT,pt=H===r.AgentState.STOPPED,$=H===r.AgentState.PAUSED,mt=i.getStatusColor({isPausing:$,isTask:E,taskStatus:D,isStartingStatus:Q,isStopStatus:pt,curAgentState:H}),ht=i.getStatusText({isPausing:$,isTask:E,taskStatus:D,taskDetail:Be,isStartingStatus:Q,isStopStatus:pt,curAgentState:H,errorMessage:C,t:I});return(0,v.jsx)(ve.WorkspaceFilesForChatProvider,{children:(0,v.jsx)(pe.ScrollProvider,{value:ft,children:(0,v.jsxs)(`div`,{className:`relative flex h-full flex-col justify-between px-4`,"data-testid":`chat-interface`,children:[!N&&!X&&!P&&!ot&&!Z&&!O&&M===0&&!U&&!W&&(0,v.jsx)(be.ChatSuggestions,{onSuggestionsClick:e=>b(e)}),(0,v.jsxs)(`div`,{ref:L,"data-testid":`chat-scroll-container`,onScroll:e=>{z(e.currentTarget),Y(e.currentTarget)},onWheel:at,className:`custom-scrollbar-always flex min-h-0 grow flex-col gap-2 overflow-x-hidden overflow-y-auto px-0 pt-4 pb-8 md:px-4`,children:[Z&&lt&&(0,v.jsx)(we.ChatMessagesSkeleton,{}),Z&&!lt&&(0,v.jsx)(`div`,{className:`flex justify-center`,"data-testid":`loading-spinner`,children:(0,v.jsx)(de.LoadingSpinner,{size:`small`})}),K&&(0,v.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-3 text-sm text-neutral-400`,"data-testid":`loading-older-events`,children:[(0,v.jsx)(de.LoadingSpinner,{size:`small`}),(0,v.jsx)(`span`,{children:I(n.I18nKey.CHAT_INTERFACE$FETCHING_OLDER_MESSAGES)})]}),(0,v.jsx)(ce.ModelMessages,{conversationId:G,anchorEventId:null}),ct&&A.length>0&&(0,v.jsx)(ke.Messages,{messages:A,allEvents:j}),(0,v.jsx)(Ae.PendingUserMessages,{}),(0,v.jsx)(se.GoalStatusBanner,{conversationId:G})]}),(0,v.jsxs)(`div`,{className:`flex shrink-0 flex-col gap-[6px] pb-4`,children:[(0,v.jsx)(Ee.SkillInstallRestartBanner,{conversationId:G}),(0,v.jsx)(oe.BtwMessages,{conversationId:G}),C&&(0,v.jsx)(Te.ErrorMessageBanner,{message:C,code:w,classification:Le,onDismiss:Re,onRetry:C===`Unable to connect to server`?()=>k?.reconnect():void 0,onReauth:ie.isAcpAuthErrorCode(w)?()=>ze(`/settings/agents`):void 0}),W&&!U&&(0,v.jsx)(Oe.LlmNotConfiguredBanner,{}),U?(0,v.jsxs)(`div`,{"data-testid":`archived-conversation-banner`,className:`mx-1 px-4 py-3 rounded-lg bg-[var(--oh-surface)] border border-[var(--oh-border-subtle)]`,children:[(0,v.jsx)(`p`,{className:`text-xs font-semibold text-[var(--oh-foreground)]`,children:I(Xe===`ERROR`?n.I18nKey.CHAT_INTERFACE$ERROR_SANDBOX_TITLE:n.I18nKey.CHAT_INTERFACE$ARCHIVED_SANDBOX_TITLE)}),(0,v.jsx)(`p`,{className:`text-xs text-[var(--oh-muted)] mt-0.5`,children:I(Xe===`ERROR`?n.I18nKey.CHAT_INTERFACE$ERROR_SANDBOX_DESCRIPTION:n.I18nKey.CHAT_INTERFACE$ARCHIVED_SANDBOX_DESCRIPTION)})]}):(0,v.jsxs)(`div`,{className:`relative`,children:[(0,v.jsx)(`div`,{className:`pointer-events-none absolute inset-x-0 bottom-full mb-1 z-20`,children:(0,v.jsxs)(`div`,{className:`flex justify-between relative`,children:[(0,v.jsxs)(`div`,{className:`flex items-end gap-1 pointer-events-auto`,children:[(0,v.jsx)(Me.default,{}),Q&&(0,v.jsx)(Ne.default,{statusColor:mt,status:ht})]}),B?H===r.AgentState.RUNNING&&(0,v.jsx)(`div`,{className:`pointer-events-none absolute inset-x-9 bottom-0 flex justify-center`,children:(0,v.jsx)(ye.TypingIndicator,{events:j})}):(0,v.jsx)(`div`,{className:`absolute left-1/2 transform -translate-x-1/2 bottom-0 pointer-events-auto`,children:(0,v.jsx)(Ce.ScrollToBottomButton,{onClick:R})})]})}),(0,v.jsx)(me.InteractiveChatBox,{onSubmit:ut,disabled:qe||W,hasStartedConversation:st})]})]})]})})})}exports.ChatInterface=y;
3
+ `)}`,h=p.length>0?`${t}\n\n${m}`:t,ne=He({conversationId:G,text:t,content:h,imageUrls:u,fileUrls:p,timestamp:d});R(),b(``);try{await Ve(oe.createChatMessage(h,u,p,d))}catch(e){Ue(ne,e instanceof Error?e.message:I(n.I18nKey.CHAT_INTERFACE$FAILED_TO_SEND_MESSAGE))}};_.default.useEffect(()=>{if(J.current&&L.current){let{scrollHeight:e,scrollTop:t}=J.current,n=L.current,r=n.scrollHeight-e;r>0&&(n.scrollTop=t+r),J.current=null;return}V&&R()},[A.length,X,rt,R]);let ft=_.default.useRef(Y);_.default.useEffect(()=>{ft.current=Y}),_.default.useEffect(()=>{let e=L.current;e&&ft.current(e)},[A.length,q]);let pt={scrollRef:L,autoScroll:V,setAutoScroll:We,scrollDomToBottom:R,hitBottom:B,setHitBottom:Ge,onChatBodyScroll:z},Q=H===r.AgentState.LOADING||H===r.AgentState.INIT,mt=H===r.AgentState.STOPPED,$=H===r.AgentState.PAUSED,ht=i.getStatusColor({isPausing:$,isTask:E,taskStatus:D,isStartingStatus:Q,isStopStatus:mt,curAgentState:H}),gt=i.getStatusText({isPausing:$,isTask:E,taskStatus:D,taskDetail:Be,isStartingStatus:Q,isStopStatus:mt,curAgentState:H,errorMessage:C,t:I});return(0,v.jsx)(ve.WorkspaceFilesForChatProvider,{children:(0,v.jsx)(pe.ScrollProvider,{value:pt,children:(0,v.jsxs)(`div`,{className:`relative flex h-full flex-col justify-between px-4`,"data-testid":`chat-interface`,children:[!N&&!X&&!P&&!st&&!Z&&!O&&M===0&&!U&&!W&&(0,v.jsx)(be.ChatSuggestions,{onSuggestionsClick:e=>b(e)}),(0,v.jsxs)(`div`,{ref:L,"data-testid":`chat-scroll-container`,onScroll:e=>{z(e.currentTarget),Y(e.currentTarget)},onWheel:ot,className:`custom-scrollbar-always flex min-h-0 grow flex-col gap-2 overflow-x-hidden overflow-y-auto px-0 pt-4 pb-8 md:px-4`,children:[Z&&ut&&(0,v.jsx)(we.ChatMessagesSkeleton,{}),Z&&!ut&&(0,v.jsx)(`div`,{className:`flex justify-center`,"data-testid":`loading-spinner`,children:(0,v.jsx)(g.LoadingSpinner,{size:`small`})}),K&&(0,v.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-3 text-sm text-neutral-400`,"data-testid":`loading-older-events`,children:[(0,v.jsx)(g.LoadingSpinner,{size:`small`}),(0,v.jsx)(`span`,{children:I(n.I18nKey.CHAT_INTERFACE$FETCHING_OLDER_MESSAGES)})]}),(0,v.jsx)(le.ModelMessages,{conversationId:G,anchorEventId:null}),lt&&A.length>0&&(0,v.jsx)(ke.Messages,{messages:A,allEvents:j}),(0,v.jsx)(Ae.PendingUserMessages,{}),(0,v.jsx)(ce.GoalStatusBanner,{conversationId:G})]}),(0,v.jsxs)(`div`,{className:`flex shrink-0 flex-col gap-[6px] pb-4`,children:[(0,v.jsx)(Ee.SkillInstallRestartBanner,{conversationId:G}),(0,v.jsx)(se.BtwMessages,{conversationId:G}),C&&(0,v.jsx)(Te.ErrorMessageBanner,{message:C,code:w,classification:Le,onDismiss:Re,onRetry:C===`Unable to connect to server`?()=>k?.reconnect():void 0,onReauth:ae.isAcpAuthErrorCode(w)?()=>ze(`/settings/agents`):void 0}),W&&!U&&(0,v.jsx)(Oe.LlmNotConfiguredBanner,{}),U?(0,v.jsxs)(`div`,{"data-testid":`archived-conversation-banner`,className:`mx-1 px-4 py-3 rounded-lg bg-[var(--oh-surface)] border border-[var(--oh-border-subtle)]`,children:[(0,v.jsx)(`p`,{className:`text-xs font-semibold text-[var(--oh-foreground)]`,children:I(Ze===`ERROR`?n.I18nKey.CHAT_INTERFACE$ERROR_SANDBOX_TITLE:n.I18nKey.CHAT_INTERFACE$ARCHIVED_SANDBOX_TITLE)}),(0,v.jsx)(`p`,{className:`text-xs text-[var(--oh-muted)] mt-0.5`,children:I(Ze===`ERROR`?n.I18nKey.CHAT_INTERFACE$ERROR_SANDBOX_DESCRIPTION:n.I18nKey.CHAT_INTERFACE$ARCHIVED_SANDBOX_DESCRIPTION)})]}):(0,v.jsxs)(`div`,{className:`relative`,children:[(0,v.jsx)(`div`,{className:`pointer-events-none absolute inset-x-0 bottom-full mb-1 z-20`,children:(0,v.jsxs)(`div`,{className:`flex justify-between relative`,children:[(0,v.jsxs)(`div`,{className:`flex items-end gap-1 pointer-events-auto`,children:[(0,v.jsx)(Me.default,{}),Q&&(0,v.jsx)(Ne.default,{statusColor:ht,status:gt})]}),B?(H===r.AgentState.RUNNING||Je)&&(0,v.jsx)(`div`,{className:`pointer-events-none absolute inset-x-9 bottom-0 flex justify-center`,children:(0,v.jsx)(ye.TypingIndicator,{events:j})}):(0,v.jsx)(`div`,{className:`absolute left-1/2 transform -translate-x-1/2 bottom-0 pointer-events-auto`,children:(0,v.jsx)(Ce.ScrollToBottomButton,{onClick:R})})]})}),(0,v.jsx)(me.InteractiveChatBox,{onSubmit:dt,disabled:qe||W,hasStartedConversation:ct})]})]})]})})})}exports.ChatInterface=y;
4
4
  //# sourceMappingURL=chat-interface.cjs.map