@openhands/agent-canvas 1.8.0 → 1.10.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 (1282) hide show
  1. package/README.md +1 -1
  2. package/README.windows.md +2 -2
  3. package/build/assets/{acp-providers-WUD4tfSq.js → acp-providers-DLe_gVDY.js} +1 -1
  4. package/build/assets/active-backend-context-B0wI7OzM.js +2 -0
  5. package/build/assets/agent-context-settings-CaQtdNA-.js +1 -0
  6. package/build/assets/agent-profiles-settings-CvuErjp6.js +1 -0
  7. package/build/assets/agent-server-conversation-service.api-km_8sOVf.js +41 -0
  8. package/build/assets/{agent-settings-BGTyoT6X.js → agent-settings-UE-U4Xii.js} +2 -2
  9. package/build/assets/agent-settings-nmO-KSXr.js +1 -0
  10. package/build/assets/alert-banner-BMaOtTCG.js +1 -0
  11. package/build/assets/{api-key-entry-screen-JOx3SH1-.js → api-key-entry-screen-Cy66vT4D.js} +1 -1
  12. package/build/assets/{app-settings-D53QZy5p.js → app-settings-9ok42bV6.js} +1 -1
  13. package/build/assets/automation-C_eCrGyP.js +1 -0
  14. package/build/assets/automation-detail-fuITm6i3.js +3 -0
  15. package/build/assets/automation-export-CRq40mux.js +2 -0
  16. package/build/assets/automation-setup-route-EXDazOHW.js +1 -0
  17. package/build/assets/automation-templates-BArZsaxP.js +1 -0
  18. package/build/assets/automations-list-CG4HKOTn.js +1 -0
  19. package/build/assets/{back-nav-button-C02hGa8t.js → back-nav-button-BZB6H7xz.js} +1 -1
  20. package/build/assets/backend-form-modal-B_lXjOGa.js +1 -0
  21. package/build/assets/{backend-synced-settings-badge-CQ9xtNWm.js → backend-synced-settings-badge-B_NXJ3u1.js} +1 -1
  22. package/build/assets/{badge-CzXbf7tR.js → badge-C64c-7PO.js} +1 -1
  23. package/build/assets/{base-modal-DkVyzFMt.js → base-modal-C0RQPug5.js} +1 -1
  24. package/build/assets/bot-DuN83i3p.js +1 -0
  25. package/build/assets/{brand-button-BUlDL-mz.js → brand-button-DJmFCyMK.js} +1 -1
  26. package/build/assets/browser-D3gd2n83.js +6 -0
  27. package/build/assets/{browser-tab-BijpUbdt.js → browser-tab-BicAWuJ1.js} +1 -1
  28. package/build/assets/{chat-send-button-BKsVjhtA.js → chat-send-button-CCrH1E8u.js} +1 -1
  29. package/build/assets/check-DLOKoFU9.js +1 -0
  30. package/build/assets/{checkmark-CxdXtM3b.js → checkmark-XZyokq_Y.js} +1 -1
  31. package/build/assets/chevron-down-CnIbtM6i.js +1 -0
  32. package/build/assets/circle-check-CxCYJrpZ.js +1 -0
  33. package/build/assets/{circle-plus-check-toggle-DdjUiOo1.js → circle-plus-check-toggle-CB_sNERY.js} +1 -1
  34. package/build/assets/{close-CDAVqnTn.js → close-ScPlnwyq.js} +1 -1
  35. package/build/assets/cloud-funnel-analytics-XynamQGU.js +1 -0
  36. package/build/assets/{combobox-caret-Dl9UtvD6.js → combobox-caret-Bwiifgjs.js} +1 -1
  37. package/build/assets/command-menu-CA3IjGNc.js +1 -0
  38. package/build/assets/condenser-settings-cNGy75gq.js +1 -0
  39. package/build/assets/{confirmation-modal-CRBJSllP.js → confirmation-modal-BATFmFyP.js} +1 -1
  40. package/build/assets/context-menu-list-item-DhJCcBA0.js +1 -0
  41. package/build/assets/conversation-B6t6EiVp.js +1 -0
  42. package/build/assets/conversation-Csdxh9Xt.js +90 -0
  43. package/build/assets/conversation-panel-B6t6EiVp.js +1 -0
  44. package/build/assets/conversation-state-store-C2QzhPaK.js +1 -0
  45. package/build/assets/{conversation-store-C6hSXHw0.js → conversation-store-B8Eahyeg.js} +1 -1
  46. package/build/assets/{conversation-tab-empty-state-CDjvNgpG.js → conversation-tab-empty-state-D3fb5xIA.js} +1 -1
  47. package/build/assets/{copy-Drwu97Gx.js → copy-DaHuDtG4.js} +1 -1
  48. package/build/assets/{copy-z7idLzWO.js → copy-Drmhc2jD.js} +1 -1
  49. package/build/assets/{copy-to-clipboard-button-NbN1clVr.js → copy-to-clipboard-button-c4MQwKGj.js} +1 -1
  50. package/build/assets/{device-verify-CDm_WrVu.js → device-verify-oFpQoLgm.js} +1 -1
  51. package/build/assets/{dist-hOnv1nn2.js → dist-Bl64nBZL.js} +1 -1
  52. package/build/assets/{dropdown-classes-CqA2BTCL.js → dropdown-classes-f91ARMV1.js} +1 -1
  53. package/build/assets/entry.client-BCzY2Bf3.js +2 -0
  54. package/build/assets/enum-filter-dropdown-HG3q3rkV.js +1 -0
  55. package/build/assets/{environment-switch-overlay-mGl2pqqx.js → environment-switch-overlay-CquZXolz.js} +1 -1
  56. package/build/assets/{extensions-hub-Br3Lgynp.js → extensions-hub-BeweE0PW.js} +1 -1
  57. package/build/assets/{extensions-navigation-BQmstKDZ.js → extensions-navigation-Dd58NlUF.js} +1 -1
  58. package/build/assets/{external-link-D9B2QMPf.js → external-link-zWbg5KXS.js} +1 -1
  59. package/build/assets/file-text-RecuaId_.js +1 -0
  60. package/build/assets/files-tab-CLLG55-q.js +1 -0
  61. package/build/assets/{folder-C86qXV7M.js → folder-C1ou4_DT.js} +1 -1
  62. package/build/assets/{form-control-classes-CtVAktAy.js → form-control-classes-pHtZUI6K.js} +1 -1
  63. package/build/assets/format-relative-time-6-3uvOXe.js +1 -0
  64. package/build/assets/format-time-delta-BIR5Os7T.js +1 -0
  65. package/build/assets/git-provider-icon-wg7ShB98.js +1 -0
  66. package/build/assets/git-repo-dropdown-CWnaUyxL.js +1 -0
  67. package/build/assets/git-repo-dropdown-TzOuG5Ef.js +1 -0
  68. package/build/assets/{highlighted-source-view-KMsA9c4a.js → highlighted-source-view-DBtI3por.js} +1 -1
  69. package/build/assets/home-BpZQkDWM.js +1 -0
  70. package/build/assets/home-OEx0XtfP.js +1 -0
  71. package/build/assets/home-store-DM4qw1lF.js +1 -0
  72. package/build/assets/{iconBase-B2rQun3J.js → iconBase-C2sR-uAp.js} +1 -1
  73. package/build/assets/index-home-OEx0XtfP.js +1 -0
  74. package/build/assets/info-C9lpK5pw.js +1 -0
  75. package/build/assets/install-server-modal-DnjZrJUy.js +1 -0
  76. package/build/assets/kebab-menu-item-content-By16Tm_0.js +1 -0
  77. package/build/assets/{launch-DjkKw55l.js → launch-C9uijypN.js} +1 -1
  78. package/build/assets/{link-external-BDBCz-_z.js → link-external-BNZzCM1I.js} +1 -1
  79. package/build/assets/list-filter-C86CBRDE.js +1 -0
  80. package/build/assets/{list-todo-BpAf7aOT.js → list-todo-CheUtB7F.js} +1 -1
  81. package/build/assets/llm-not-configured-banner-DrBrhfN0.js +27 -0
  82. package/build/assets/{llm-settings-D8zNkIlP.js → llm-settings-CRsLqxgu.js} +1 -1
  83. package/build/assets/llm-settings-RBm_3kNm.js +1 -0
  84. package/build/assets/{llm-subscription-service-COTgZc1C.js → llm-subscription-service-DwjJ8-_X.js} +1 -1
  85. package/build/assets/loader-circle-C5AnEN8r.js +1 -0
  86. package/build/assets/{loading-spinner-DRFyh6Iy.js → loading-spinner-6Yj-YyoS.js} +1 -1
  87. package/build/assets/{manage-backends-modal-DiRWE3tJ.js → manage-backends-modal-DrwErS0N.js} +1 -1
  88. package/build/assets/manifest-c352d453.js +1 -0
  89. package/build/assets/manifest-subpage-layout-CtqVwIvJ.js +1 -0
  90. package/build/assets/markdown-renderer-lsvsp7jn.js +8 -0
  91. package/build/assets/mcp-DD4hPTRE.js +9 -0
  92. package/build/assets/mcp-marketplace-utils-BMnYz0Gc.js +1 -0
  93. package/build/assets/messages-Dt77e0qi.js +40 -0
  94. package/build/assets/{modal-backdrop-X-vKo61e.js → modal-backdrop-BSzNhM4r.js} +1 -1
  95. package/build/assets/{modal-body-C3bGicn4.js → modal-body-BHGCSAtj.js} +1 -1
  96. package/build/assets/{modal-classes-DFFO6BMU.js → modal-classes-DSTLuxkA.js} +1 -1
  97. package/build/assets/{modal-close-button-vxkAIRyZ.js → modal-close-button-dheWZ2ys.js} +1 -1
  98. package/build/assets/mouse-pointer-click-Px-dXWcS.js +1 -0
  99. package/build/assets/{navigation-context-BOGzIng3.js → navigation-context-CQZwH_tC.js} +1 -1
  100. package/build/assets/navigation-link-Bxo3-4vo.js +1 -0
  101. package/build/assets/onboarding-5CZvRBbh.js +1 -0
  102. package/build/assets/onboarding-modal-CD2ehuxt.js +1 -0
  103. package/build/assets/{openhands-logo-CmYvJXBa.js → openhands-logo-BS-Epajy.js} +1 -1
  104. package/build/assets/{organization-service.api-CQ73CB-S.js → organization-service.api-Dsuoep0g.js} +1 -1
  105. package/build/assets/{pencil-DzW2GB2M.js → pencil-Bl3GWhgq.js} +1 -1
  106. package/build/assets/{planner-tab-YG0bGxDY.js → planner-tab-DeO7Thb0.js} +1 -1
  107. package/build/assets/{plugins-management-service-ijhH8OSh.js → plugins-management-service-C9f75R6X.js} +1 -1
  108. package/build/assets/plus-CtzlyAoF.js +1 -0
  109. package/build/assets/{profiles-service.api-C32pPm70.js → profiles-service.api-Dl20_2IM.js} +1 -1
  110. package/build/assets/{providers-DuSn9s2i.js → providers-CeuhK46N.js} +1 -1
  111. package/build/assets/{proxy-BiyDhMBd.js → proxy-CIGI9zQC.js} +1 -1
  112. package/build/assets/{puzzle-DlqT0yvr.js → puzzle-B3v361yY.js} +1 -1
  113. package/build/assets/recommended-automations-launcher-6xmbf7lh.js +1 -0
  114. package/build/assets/{refresh-cw-Br5254f4.js → refresh-cw-B9GhC3QC.js} +1 -1
  115. package/build/assets/root-BQPNqNvD.js +2 -0
  116. package/build/assets/root-BeuHFY2s.css +1 -0
  117. package/build/assets/root-layout-Dl_2CDoq.js +3 -0
  118. package/build/assets/{schema-field-htfNouTG.js → schema-field-z2vSLuLo.js} +1 -1
  119. package/build/assets/{sdk-section-page-D0K1dBQY.js → sdk-section-page-BnCXAytf.js} +1 -1
  120. package/build/assets/{search-7DRiGm4Z.js → search-BatSpWed.js} +1 -1
  121. package/build/assets/search-CYaiKHRp.js +1 -0
  122. package/build/assets/{secrets-service-Dbv5Zb8G.js → secrets-service-DGUNlwQd.js} +1 -1
  123. package/build/assets/{secrets-settings-Da4SSaX9.js → secrets-settings-DUmML_dK.js} +1 -1
  124. package/build/assets/segmented-toggle-eSofF7gn.js +1 -0
  125. package/build/assets/settings-CWFxymAf.js +1 -0
  126. package/build/assets/{settings-F4a09IxY.js → settings-Co-M5bK9.js} +1 -1
  127. package/build/assets/{settings-dropdown-input-jOiv5Yrk.js → settings-dropdown-input-Cx4g7Xfl.js} +1 -1
  128. package/build/assets/{settings-gear-TYXnELES.js → settings-gear-DaJj6Pde.js} +1 -1
  129. package/build/assets/{settings-index-CyJBf5NA.js → settings-index-BECdgecg.js} +1 -1
  130. package/build/assets/settings-input-BQY115xH.js +1 -0
  131. package/build/assets/settings-like-page-layout-classes-Cw4Yzv_P.js +1 -0
  132. package/build/assets/{settings-list-classes-VqMzkYYt.js → settings-list-classes-C9cLrrcc.js} +1 -1
  133. package/build/assets/{settings-modal-C-S1NpbC.js → settings-modal-ChBJNTdd.js} +1 -1
  134. package/build/assets/{settings-section-header-context-CnIIQAUn.js → settings-section-header-context-BOJ_Fbak.js} +1 -1
  135. package/build/assets/settings-service.api-Dz9cZyvx.js +1 -0
  136. package/build/assets/{settings-switch-B405oU_v.js → settings-switch-BIodMVz9.js} +1 -1
  137. package/build/assets/shared-conversation-CSF0aTuE.js +1 -0
  138. package/build/assets/{sidebar-layout-BGMuyC86.js → sidebar-layout-DEycoFd_.js} +1 -1
  139. package/build/assets/sidebar-mobile-menu-toggle-DeRvTupV.js +1 -0
  140. package/build/assets/{sidebar-nav-link-DA4_ct9G.js → sidebar-nav-link-BjpQ-NVc.js} +1 -1
  141. package/build/assets/{sidebar-store-FRJ3rADB.js → sidebar-store-B04sX8aP.js} +1 -1
  142. package/build/assets/{skill-card-pill-row-BMdhr_sd.js → skill-card-pill-row-BH6fPGba.js} +1 -1
  143. package/build/assets/{skill-icon-badge-CGUkgcVH.js → skill-icon-badge-D4uznfjU.js} +1 -1
  144. package/build/assets/skill-scope-DH_AUUUP.js +1 -0
  145. package/build/assets/{skills-CYFLsN5U.js → skills-B0IliMxw.js} +1 -1
  146. package/build/assets/{skills-plugins-C5eJnyft.js → skills-plugins-vfvOk34h.js} +1 -1
  147. package/build/assets/skills-settings-DnbIu2eO.js +2 -0
  148. package/build/assets/sparkles-g7y3r-Ut.js +1 -0
  149. package/build/assets/{styled-tooltip-B3kIdVyH.js → styled-tooltip-CQ9JEFiO.js} +1 -1
  150. package/build/assets/{switch-skeleton-BQoOhQTB.js → switch-skeleton-DwOoCqaL.js} +1 -1
  151. package/build/assets/{syntax-highlighter-B92AFGMy.js → syntax-highlighter-BGDg_7w9.js} +1 -1
  152. package/build/assets/{task-list-tab-B3k4W1cK.js → task-list-tab-DeF_uXdw.js} +1 -1
  153. package/build/assets/{terminal-cMS3RgVE.js → terminal-BUpID2wS.js} +1 -1
  154. package/build/assets/{terminal-CBI_41Zc.js → terminal-DRc4rup7.js} +1 -1
  155. package/build/assets/{toggle-switch-DYRr9CAR.js → toggle-switch--8n8NeV_.js} +1 -1
  156. package/build/assets/{trash-2-gZPlx23R.js → trash-2-CzDVN-Iw.js} +1 -1
  157. package/build/assets/{typography-B1UxuuEC.js → typography-BSbUhJPn.js} +1 -1
  158. package/build/assets/{u-check-circle-DBEvndTS.js → u-check-circle-BKn1spCL.js} +1 -1
  159. package/build/assets/{u-edit-809W9D9T.js → u-edit-DAkcF52u.js} +1 -1
  160. package/build/assets/{u-robot-CJtSzy5X.js → u-robot-BvAOA2ZD.js} +1 -1
  161. package/build/assets/{use-acp-credential-form-CjSvKWFH.js → use-acp-credential-form-BGKFi1VL.js} +1 -1
  162. package/build/assets/{use-activate-agent-profile-DCRf47e-.js → use-activate-agent-profile-2nvALjC-.js} +1 -1
  163. package/build/assets/use-agent-profiles-BlQA67MW.js +1 -0
  164. package/build/assets/{use-breakpoint-DA7JqsRN.js → use-breakpoint-DWtihr9g.js} +1 -1
  165. package/build/assets/{use-can-manage-org-profiles-vBiP7rHF.js → use-can-manage-org-profiles-Clw5Dh1s.js} +1 -1
  166. package/build/assets/{use-click-outside-element-DKqpqEEm.js → use-click-outside-element-W6Os4Nlb.js} +1 -1
  167. package/build/assets/{use-cloud-current-user-id-BMq9gw93.js → use-cloud-current-user-id-B8AQSQFM.js} +1 -1
  168. package/build/assets/use-config-C3zGuUQI.js +1 -0
  169. package/build/assets/{use-create-conversation-CakhLF0X.js → use-create-conversation-FaP0kUpg.js} +1 -1
  170. package/build/assets/{use-create-secret-RT4QtSS9.js → use-create-secret-CgQ3pXd6.js} +1 -1
  171. package/build/assets/use-is-authed-Bka89Xmm.js +1 -0
  172. package/build/assets/{use-is-creating-conversation-CIAcnd8M.js → use-is-creating-conversation-CVefC9Ns.js} +1 -1
  173. package/build/assets/{use-launch-skill-in-chat-DKzCTMt0.js → use-launch-skill-in-chat-BcKNjxxd.js} +1 -1
  174. package/build/assets/use-llm-profiles-C-tDO6UB.js +1 -0
  175. package/build/assets/use-manifest-capabilities-DLP5wCxp.js +1 -0
  176. package/build/assets/{use-onboarding-completion-CJU4MNAY.js → use-onboarding-completion-BiCdXvlU.js} +1 -1
  177. package/build/assets/{use-plugins-marketplace-D-93nqtJ.js → use-plugins-marketplace-DRFNLBlr.js} +1 -1
  178. package/build/assets/use-save-agent-profile-CaGVAudI.js +1 -0
  179. package/build/assets/{use-save-settings--C6LZXfI.js → use-save-settings-C9B8Y-h3.js} +1 -1
  180. package/build/assets/{use-settings-DIAo5KFk.js → use-settings-3RcgdUuZ.js} +1 -1
  181. package/build/assets/use-settings-nav-items-y-Oyc93G.js +16 -0
  182. package/build/assets/use-tracking-CTtkLAmx.js +3 -0
  183. package/build/assets/{use-user-conversation-DhcAEyJX.js → use-user-conversation-Bei82QsZ.js} +1 -1
  184. package/build/assets/useInfiniteQuery-DbCv0Jzd.js +1 -0
  185. package/build/assets/{useMutation-DHLpZ6J0.js → useMutation-ChpkYxI5.js} +1 -1
  186. package/build/assets/{useQueries-B3T1a7qt.js → useQueries-Cjv3E8_1.js} +1 -1
  187. package/build/assets/useQuery-BCnzy4LX.js +1 -0
  188. package/build/assets/utils-BX9XJ0IE.js +1 -0
  189. package/build/assets/{vendor-markdown-BML7QbqS.js → vendor-markdown-j0kYzV48.js} +1 -1
  190. package/build/assets/{vendor-styling-Bcgpimp9.js → vendor-styling-Ck5D_A2Q.js} +6 -6
  191. package/build/assets/{vendor~browser-jaN4ilxM.js → vendor~browser-C6uXH-dw.js} +2 -2
  192. package/build/assets/vendor~browser-DJ1pl_wn.js +47 -0
  193. package/build/assets/{vendor~browser-tab-_-VCXq8n.js → vendor~browser-tab-C5uuAxZX.js} +1 -1
  194. package/build/assets/vendor~entry.client-CgNUwtQL.js +1 -0
  195. package/build/assets/{vendor~entry.client-Di4qO77Y.js → vendor~entry.client-zSIea5EO.js} +2 -2
  196. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~cy4jtuc2-rfV8mQ9m.js +1 -0
  197. package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~g4xrpilz-CYPMCkX1.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~kv3pap4j-oGvLV0dO.js} +4 -4
  198. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~lq5hicxx-cHFhpUBq.js +26 -0
  199. package/build/assets/{vendor~files-tab-atebg0iG.js → vendor~files-tab-C87pjSpi.js} +1 -1
  200. package/build/assets/{vendor~index-home~home~conversation-panel~conversation-G9DMrR7m.js → vendor~index-home~home~conversation-panel~conversation-DiXf0dkj.js} +1 -1
  201. package/build/assets/{vendor~conversation-panel~conversation~alert-banner-BNzz5FuZ.js → vendor~index-home~home~conversation-panel~conversation~alert-banner-B3qC_oj8.js} +1 -1
  202. package/build/assets/{vendor~launch-ChXCOGw8.js → vendor~launch-CHwEQG6e.js} +1 -1
  203. package/build/assets/vendor~module-DyG7x7JT.js +2 -0
  204. package/build/assets/{vendor~root-layout~conversation-panel~conversation-DEhW1h3I.js → vendor~root-layout~conversation-panel~conversation-DEzjR4K7.js} +1 -1
  205. package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-DRblkyXD.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-DOuig0C0.js} +1 -1
  206. package/build/assets/vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-U-xdsAEx.js +1 -0
  207. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~automation-setup-route-CjECvSl5.js +1 -0
  208. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-CQR5Sa0H.js +1 -0
  209. package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~automation-templates~automation-set~bxsimjx0-D7IDevqN.js +1 -0
  210. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hakxo2tj-ClV0p9g3.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gxu4j2ea-Cwhh3zLe.js} +1 -1
  211. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~bi2r7bko-VFnwct3q.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hjcjabwg-CuQhkiS7.js} +1 -1
  212. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~9pstowjp-BOVIFA_g.js +73 -0
  213. package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~launch~skills-settings~a~eywn6ulz-BKxxr74w.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~ht43enc2-C0JXQb_q.js} +175 -54
  214. package/build/assets/{verification-settings-Vr5cN4md.js → verification-settings-nD61Ijph.js} +1 -1
  215. package/build/assets/wrench-DRitTfwe.js +1 -0
  216. package/build/assets/x-RYDBg-e2.js +1 -0
  217. package/build/assets/{x-mark-jcTkPiOB.js → x-mark-BopmFoBq.js} +1 -1
  218. package/build/assets/zap-tbKDzCe3.js +1 -0
  219. package/build/index.html +4 -4
  220. package/build/locales/ar/openhands.json +106 -5
  221. package/build/locales/ca/openhands.json +106 -5
  222. package/build/locales/de/openhands.json +106 -5
  223. package/build/locales/en/openhands.json +107 -6
  224. package/build/locales/es/openhands.json +106 -5
  225. package/build/locales/fr/openhands.json +106 -5
  226. package/build/locales/it/openhands.json +106 -5
  227. package/build/locales/ja/openhands.json +106 -5
  228. package/build/locales/ko-KR/openhands.json +106 -5
  229. package/build/locales/no/openhands.json +106 -5
  230. package/build/locales/pt/openhands.json +106 -5
  231. package/build/locales/tr/openhands.json +106 -5
  232. package/build/locales/uk/openhands.json +106 -5
  233. package/build/locales/zh-CN/openhands.json +106 -5
  234. package/build/locales/zh-TW/openhands.json +106 -5
  235. package/build/mockServiceWorker.js +21 -9
  236. package/config/defaults.json +3 -3
  237. package/dist/api/agent-server-adapter.cjs +3 -3
  238. package/dist/api/agent-server-adapter.cjs.map +1 -1
  239. package/dist/api/agent-server-adapter.d.ts +46 -6
  240. package/dist/api/agent-server-adapter.js +187 -168
  241. package/dist/api/agent-server-adapter.js.map +1 -1
  242. package/dist/api/agent-server-compatibility.cjs +1 -1
  243. package/dist/api/agent-server-compatibility.cjs.map +1 -1
  244. package/dist/api/agent-server-compatibility.d.ts +4 -0
  245. package/dist/api/agent-server-compatibility.js +41 -38
  246. package/dist/api/agent-server-compatibility.js.map +1 -1
  247. package/dist/api/automation-service/automation-service.api.cjs +1 -1
  248. package/dist/api/automation-service/automation-service.api.cjs.map +1 -1
  249. package/dist/api/automation-service/automation-service.api.d.ts +25 -0
  250. package/dist/api/automation-service/automation-service.api.js +110 -62
  251. package/dist/api/automation-service/automation-service.api.js.map +1 -1
  252. package/dist/api/backend-registry/active-store.cjs +1 -1
  253. package/dist/api/backend-registry/active-store.cjs.map +1 -1
  254. package/dist/api/backend-registry/active-store.js +36 -31
  255. package/dist/api/backend-registry/active-store.js.map +1 -1
  256. package/dist/api/backend-registry/url-selection.cjs +2 -0
  257. package/dist/api/backend-registry/url-selection.cjs.map +1 -0
  258. package/dist/api/backend-registry/url-selection.d.ts +31 -0
  259. package/dist/api/backend-registry/url-selection.js +29 -0
  260. package/dist/api/backend-registry/url-selection.js.map +1 -0
  261. package/dist/api/mcp-service/mcp-redacted-credentials.cjs +1 -1
  262. package/dist/api/mcp-service/mcp-redacted-credentials.cjs.map +1 -1
  263. package/dist/api/mcp-service/mcp-redacted-credentials.d.ts +3 -2
  264. package/dist/api/mcp-service/mcp-redacted-credentials.js +32 -27
  265. package/dist/api/mcp-service/mcp-redacted-credentials.js.map +1 -1
  266. package/dist/api/mcp-service/mcp-service.api.cjs +1 -1
  267. package/dist/api/mcp-service/mcp-service.api.cjs.map +1 -1
  268. package/dist/api/mcp-service/mcp-service.api.js +19 -19
  269. package/dist/api/mcp-service/mcp-service.api.js.map +1 -1
  270. package/dist/api/settings-service/settings-service.api.cjs +1 -1
  271. package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
  272. package/dist/api/settings-service/settings-service.api.d.ts +10 -0
  273. package/dist/api/settings-service/settings-service.api.js +90 -100
  274. package/dist/api/settings-service/settings-service.api.js.map +1 -1
  275. package/dist/api/skills-service.cjs +1 -1
  276. package/dist/api/skills-service.cjs.map +1 -1
  277. package/dist/api/skills-service.js +1 -0
  278. package/dist/api/skills-service.js.map +1 -1
  279. package/dist/assets/chevron-left.d.ts +1 -1
  280. package/dist/assets/chevron-right.d.ts +1 -1
  281. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs +2 -0
  282. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs.map +1 -0
  283. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.d.ts +12 -0
  284. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js +94 -0
  285. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js.map +1 -0
  286. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
  287. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
  288. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +31 -90
  289. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
  290. package/dist/components/conversation-events/chat/event-message-components/collapsible-thinking.d.ts +2 -1
  291. package/dist/components/conversation-events/chat/event-message-components/critic-result-display.d.ts +2 -1
  292. package/dist/components/conversation-events/chat/event-message-components/error-event-message.d.ts +2 -1
  293. package/dist/components/conversation-events/chat/event-message-components/event-group.d.ts +1 -1
  294. package/dist/components/conversation-events/chat/event-message-components/finish-event-message.d.ts +1 -1
  295. package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.d.ts +1 -1
  296. package/dist/components/conversation-events/chat/event-message-components/observation-pair-event-message.d.ts +2 -1
  297. package/dist/components/conversation-events/chat/event-message-components/skill-item-expanded.d.ts +1 -1
  298. package/dist/components/conversation-events/chat/event-message-components/skill-ready-content-list.d.ts +2 -1
  299. package/dist/components/conversation-events/chat/event-message-components/thought-event-message.d.ts +1 -1
  300. package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.d.ts +2 -1
  301. package/dist/components/conversation-events/chat/event-message.d.ts +2 -1
  302. package/dist/components/conversation-events/chat/task-tracking/task-item.d.ts +1 -1
  303. package/dist/components/conversation-events/chat/task-tracking/task-list-section.d.ts +1 -1
  304. package/dist/components/features/alerts/alert-banner.d.ts +1 -1
  305. package/dist/components/features/analytics/telemetry-consent-banner.d.ts +2 -1
  306. package/dist/components/features/automations/add-automation-modal.d.ts +1 -1
  307. package/dist/components/features/automations/automation-card-skeleton.d.ts +1 -1
  308. package/dist/components/features/automations/automation-card.d.ts +9 -1
  309. package/dist/components/features/automations/automation-group.d.ts +9 -1
  310. package/dist/components/features/automations/automation-health-badge.d.ts +8 -0
  311. package/dist/components/features/automations/automation-list-row.d.ts +3 -1
  312. package/dist/components/features/automations/automation-run-insights.d.ts +17 -0
  313. package/dist/components/features/automations/automation-view-toggle.d.ts +1 -1
  314. package/dist/components/features/automations/backend-not-configured.d.ts +1 -1
  315. package/dist/components/features/automations/create-instructions.d.ts +2 -2
  316. package/dist/components/features/automations/dashboard/automations-dashboard-controls.d.ts +18 -0
  317. package/dist/components/features/automations/dashboard/automations-filtered-empty-state.d.ts +9 -0
  318. package/dist/components/features/automations/dashboard/use-automation-sub-page-nav.d.ts +12 -0
  319. package/dist/components/features/automations/delete-confirmation-modal.d.ts +1 -1
  320. package/dist/components/features/automations/detail/active-status-badge.d.ts +1 -1
  321. package/dist/components/features/automations/detail/activity-log-item.d.ts +1 -1
  322. package/dist/components/features/automations/detail/activity-log-section.d.ts +3 -1
  323. package/dist/components/features/automations/detail/activity-section.d.ts +1 -1
  324. package/dist/components/features/automations/detail/back-link.d.ts +1 -1
  325. package/dist/components/features/automations/detail/branch-badge.d.ts +1 -1
  326. package/dist/components/features/automations/detail/config-field.d.ts +1 -1
  327. package/dist/components/features/automations/detail/configuration-section.d.ts +1 -1
  328. package/dist/components/features/automations/detail/debug-automation-button.d.ts +1 -1
  329. package/dist/components/features/automations/detail/detail-header.d.ts +1 -1
  330. package/dist/components/features/automations/detail/detail-skeleton.d.ts +1 -1
  331. package/dist/components/features/automations/detail/edit-automation-modal.d.ts +1 -1
  332. package/dist/components/features/automations/detail/not-found-state.d.ts +1 -1
  333. package/dist/components/features/automations/detail/plugin-chip.d.ts +1 -1
  334. package/dist/components/features/automations/detail/plugins-section.d.ts +1 -1
  335. package/dist/components/features/automations/detail/prompt-section.d.ts +2 -1
  336. package/dist/components/features/automations/detail/run-logs-modal.d.ts +1 -1
  337. package/dist/components/features/automations/detail/run-status-badge.d.ts +10 -1
  338. package/dist/components/features/automations/detail/section-card.d.ts +1 -1
  339. package/dist/components/features/automations/empty-state.d.ts +1 -1
  340. package/dist/components/features/automations/error-state.d.ts +1 -1
  341. package/dist/components/features/automations/import-automation-modal.d.ts +1 -1
  342. package/dist/components/features/automations/kebab-menu-item-content.d.ts +1 -1
  343. package/dist/components/features/automations/kebab-menu.d.ts +1 -1
  344. package/dist/components/features/automations/metadata-chip.d.ts +1 -1
  345. package/dist/components/features/automations/recommended-automations-launcher.d.ts +1 -8
  346. package/dist/components/features/automations/recommended-automations-section.d.ts +1 -7
  347. package/dist/components/features/automations/responder-deployment-modal.d.ts +1 -1
  348. package/dist/components/features/automations/search-input.d.ts +1 -1
  349. package/dist/components/features/automations/status-badge.d.ts +1 -1
  350. package/dist/components/features/automations/turn-off-confirmation-modal.d.ts +8 -0
  351. package/dist/components/features/automations/view-menu-item-content.d.ts +1 -1
  352. package/dist/components/features/backends/add-backend-modal.d.ts +1 -1
  353. package/dist/components/features/backends/api-key-entry-screen.d.ts +2 -1
  354. package/dist/components/features/backends/backend-form-modal.cjs +1 -1
  355. package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
  356. package/dist/components/features/backends/backend-form-modal.d.ts +3 -3
  357. package/dist/components/features/backends/backend-form-modal.js +568 -358
  358. package/dist/components/features/backends/backend-form-modal.js.map +1 -1
  359. package/dist/components/features/backends/backend-row.d.ts +1 -1
  360. package/dist/components/features/backends/backend-selector.d.ts +2 -1
  361. package/dist/components/features/backends/backend-status-dot.d.ts +2 -1
  362. package/dist/components/features/backends/backend-version.d.ts +1 -1
  363. package/dist/components/features/backends/device-flow-auth.cjs +1 -1
  364. package/dist/components/features/backends/device-flow-auth.cjs.map +1 -1
  365. package/dist/components/features/backends/device-flow-auth.d.ts +9 -1
  366. package/dist/components/features/backends/device-flow-auth.js +56 -55
  367. package/dist/components/features/backends/device-flow-auth.js.map +1 -1
  368. package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
  369. package/dist/components/features/backends/manage-backends-modal.cjs.map +1 -1
  370. package/dist/components/features/backends/manage-backends-modal.d.ts +2 -1
  371. package/dist/components/features/backends/manage-backends-modal.js +1 -1
  372. package/dist/components/features/backends/manage-backends-modal.js.map +1 -1
  373. package/dist/components/features/browser/browser-chrome-bar.d.ts +1 -1
  374. package/dist/components/features/browser/browser-snapshot.d.ts +1 -1
  375. package/dist/components/features/browser/browser.d.ts +1 -1
  376. package/dist/components/features/browser/empty-browser-message.d.ts +1 -1
  377. package/dist/components/features/chat/btw-messages.d.ts +1 -1
  378. package/dist/components/features/chat/change-agent-button.d.ts +2 -1
  379. package/dist/components/features/chat/change-agent-context-menu.d.ts +1 -1
  380. package/dist/components/features/chat/chat-action-tooltip.d.ts +1 -1
  381. package/dist/components/features/chat/chat-add-file-button.d.ts +2 -1
  382. package/dist/components/features/chat/chat-interface.cjs +1 -1
  383. package/dist/components/features/chat/chat-interface.cjs.map +1 -1
  384. package/dist/components/features/chat/chat-interface.d.ts +2 -1
  385. package/dist/components/features/chat/chat-interface.js +105 -105
  386. package/dist/components/features/chat/chat-interface.js.map +1 -1
  387. package/dist/components/features/chat/chat-message.cjs +1 -1
  388. package/dist/components/features/chat/chat-message.cjs.map +1 -1
  389. package/dist/components/features/chat/chat-message.d.ts +2 -1
  390. package/dist/components/features/chat/chat-message.js +59 -49
  391. package/dist/components/features/chat/chat-message.js.map +1 -1
  392. package/dist/components/features/chat/chat-messages-skeleton.d.ts +2 -1
  393. package/dist/components/features/chat/chat-play-button.d.ts +1 -1
  394. package/dist/components/features/chat/chat-send-button.d.ts +1 -1
  395. package/dist/components/features/chat/chat-status-indicator.d.ts +1 -1
  396. package/dist/components/features/chat/chat-stop-button.d.ts +1 -1
  397. package/dist/components/features/chat/chat-suggestions.d.ts +1 -1
  398. package/dist/components/features/chat/components/chat-input-actions.d.ts +2 -1
  399. package/dist/components/features/chat/components/chat-input-container.d.ts +1 -1
  400. package/dist/components/features/chat/components/chat-input-field.d.ts +1 -1
  401. package/dist/components/features/chat/components/chat-input-grip.d.ts +1 -1
  402. package/dist/components/features/chat/components/chat-input-llm-profile-picker.d.ts +3 -2
  403. package/dist/components/features/chat/components/chat-input-model.d.ts +3 -2
  404. package/dist/components/features/chat/components/chat-input-profile-picker.d.ts +1 -1
  405. package/dist/components/features/chat/components/chat-input-row.d.ts +1 -1
  406. package/dist/components/features/chat/components/hidden-file-input.d.ts +1 -1
  407. package/dist/components/features/chat/components/slash-command-menu.d.ts +2 -1
  408. package/dist/components/features/chat/confirmation-mode-enabled.d.ts +1 -1
  409. package/dist/components/features/chat/custom-chat-input.d.ts +1 -1
  410. package/dist/components/features/chat/drag-over.d.ts +1 -1
  411. package/dist/components/features/chat/error-message-banner.d.ts +2 -1
  412. package/dist/components/features/chat/error-message.d.ts +2 -1
  413. package/dist/components/features/chat/generic-event-message.d.ts +1 -1
  414. package/dist/components/features/chat/git-control-bar-branch-button.d.ts +1 -1
  415. package/dist/components/features/chat/git-control-bar-pr-button.d.ts +1 -1
  416. package/dist/components/features/chat/git-control-bar-pull-button.d.ts +1 -1
  417. package/dist/components/features/chat/git-control-bar-push-button.d.ts +1 -1
  418. package/dist/components/features/chat/git-control-bar-repo-button.d.ts +1 -1
  419. package/dist/components/features/chat/git-control-bar-tooltip-wrapper.d.ts +1 -1
  420. package/dist/components/features/chat/git-control-bar.d.ts +1 -1
  421. package/dist/components/features/chat/git-external-link-icon.d.ts +1 -1
  422. package/dist/components/features/chat/goal-status-banner.d.ts +1 -1
  423. package/dist/components/features/chat/goal-status-content.d.ts +1 -1
  424. package/dist/components/features/chat/got-it-button.d.ts +1 -1
  425. package/dist/components/features/chat/interactive-chat-box.d.ts +1 -1
  426. package/dist/components/features/chat/model-messages.d.ts +2 -1
  427. package/dist/components/features/chat/mono-component.d.ts +1 -1
  428. package/dist/components/features/chat/open-repository-modal.d.ts +2 -1
  429. package/dist/components/features/chat/pasted-image-upload-as-file-button.d.ts +1 -1
  430. package/dist/components/features/chat/path-component.d.ts +1 -1
  431. package/dist/components/features/chat/pending-stop-icon.d.ts +1 -1
  432. package/dist/components/features/chat/pending-user-messages.cjs +1 -1
  433. package/dist/components/features/chat/pending-user-messages.cjs.map +1 -1
  434. package/dist/components/features/chat/pending-user-messages.d.ts +2 -1
  435. package/dist/components/features/chat/pending-user-messages.js +4 -1
  436. package/dist/components/features/chat/pending-user-messages.js.map +1 -1
  437. package/dist/components/features/chat/plan-preview.d.ts +1 -1
  438. package/dist/components/features/chat/remove-file-button.d.ts +1 -1
  439. package/dist/components/features/chat/skill-install-restart-banner.d.ts +1 -1
  440. package/dist/components/features/chat/success-indicator.d.ts +1 -1
  441. package/dist/components/features/chat/task-tracking/status-badge.d.ts +1 -1
  442. package/dist/components/features/chat/task-tracking/status-icon.d.ts +1 -1
  443. package/dist/components/features/chat/task-tracking/task-item.d.ts +1 -1
  444. package/dist/components/features/chat/task-tracking/task-list-section.d.ts +1 -1
  445. package/dist/components/features/chat/tool-visualizers/primitives/code-block.d.ts +2 -1
  446. package/dist/components/features/chat/tool-visualizers/primitives/diff-view.d.ts +2 -1
  447. package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.d.ts +2 -1
  448. package/dist/components/features/chat/tool-visualizers/primitives/key-value-grid.d.ts +1 -1
  449. package/dist/components/features/chat/tool-visualizers/primitives/output-pane.d.ts +2 -1
  450. package/dist/components/features/chat/typing-indicator.cjs +1 -1
  451. package/dist/components/features/chat/typing-indicator.cjs.map +1 -1
  452. package/dist/components/features/chat/typing-indicator.d.ts +8 -1
  453. package/dist/components/features/chat/typing-indicator.js +94 -10
  454. package/dist/components/features/chat/typing-indicator.js.map +1 -1
  455. package/dist/components/features/chat/uploaded-file.d.ts +1 -1
  456. package/dist/components/features/chat/uploaded-files.d.ts +1 -1
  457. package/dist/components/features/chat/uploaded-image.d.ts +2 -1
  458. package/dist/components/features/chat/user-message-body.d.ts +2 -2
  459. package/dist/components/features/chat/waiting-for-runtime-message.d.ts +1 -1
  460. package/dist/components/features/chat/workspace-mode-icon.d.ts +1 -1
  461. package/dist/components/features/chat/workspace-mode-selector.d.ts +1 -1
  462. package/dist/components/features/command-menu/command-menu-items.d.ts +5 -1
  463. package/dist/components/features/command-menu/command-menu-trigger.d.ts +2 -1
  464. package/dist/components/features/context-menu/archived-disabled-tooltip.d.ts +1 -1
  465. package/dist/components/features/context-menu/context-menu-icon-text-with-description.d.ts +1 -1
  466. package/dist/components/features/context-menu/context-menu-icon-text.d.ts +1 -1
  467. package/dist/components/features/context-menu/context-menu-list-item.cjs +1 -1
  468. package/dist/components/features/context-menu/context-menu-list-item.cjs.map +1 -1
  469. package/dist/components/features/context-menu/context-menu-list-item.d.ts +2 -1
  470. package/dist/components/features/context-menu/context-menu-list-item.js +2 -1
  471. package/dist/components/features/context-menu/context-menu-list-item.js.map +1 -1
  472. package/dist/components/features/controls/agent-loading.d.ts +1 -1
  473. package/dist/components/features/controls/agent-status.d.ts +1 -1
  474. package/dist/components/features/controls/git-tools-submenu.d.ts +1 -1
  475. package/dist/components/features/controls/macros-submenu.d.ts +1 -1
  476. package/dist/components/features/controls/server-status-context-menu-icon-text.d.ts +1 -1
  477. package/dist/components/features/controls/server-status-context-menu.d.ts +1 -1
  478. package/dist/components/features/controls/server-status.d.ts +1 -1
  479. package/dist/components/features/controls/tools-context-menu-icon-text.d.ts +1 -1
  480. package/dist/components/features/controls/tools-context-menu.d.ts +1 -1
  481. package/dist/components/features/controls/tools.d.ts +2 -1
  482. package/dist/components/features/conversation/conversation-loading.d.ts +1 -1
  483. package/dist/components/features/conversation/conversation-main/chat-interface-wrapper.d.ts +1 -1
  484. package/dist/components/features/conversation/conversation-main/conversation-main.d.ts +1 -1
  485. package/dist/components/features/conversation/conversation-main/conversation-mobile-panel-page.d.ts +2 -1
  486. package/dist/components/features/conversation/conversation-name-context-menu-icon-text.d.ts +1 -1
  487. package/dist/components/features/conversation/conversation-name-context-menu.d.ts +1 -1
  488. package/dist/components/features/conversation/conversation-name-with-status.d.ts +2 -1
  489. package/dist/components/features/conversation/conversation-name.d.ts +2 -1
  490. package/dist/components/features/conversation/conversation-tab-empty-state.d.ts +1 -1
  491. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content-crossfade.d.ts +1 -1
  492. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.d.ts +1 -1
  493. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/suspense-pending-fallback.d.ts +1 -1
  494. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/tab-container.d.ts +1 -1
  495. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/tab-content-area.d.ts +1 -1
  496. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/tab-wrapper.d.ts +1 -1
  497. package/dist/components/features/conversation/conversation-tabs/conversation-tab-nav.d.ts +1 -1
  498. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.d.ts +1 -1
  499. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.d.ts +1 -1
  500. package/dist/components/features/conversation/conversation-tabs/drawer-vscode-link.d.ts +1 -1
  501. package/dist/components/features/conversation/metrics-modal/context-window-section.d.ts +1 -1
  502. package/dist/components/features/conversation/metrics-modal/cost-section.d.ts +1 -1
  503. package/dist/components/features/conversation/metrics-modal/empty-state.d.ts +1 -1
  504. package/dist/components/features/conversation/metrics-modal/metric-row.d.ts +1 -1
  505. package/dist/components/features/conversation/metrics-modal/metrics-modal-header.d.ts +1 -1
  506. package/dist/components/features/conversation/metrics-modal/metrics-modal.d.ts +1 -1
  507. package/dist/components/features/conversation/metrics-modal/usage-section.d.ts +1 -1
  508. package/dist/components/features/conversation/right-panel-toggle.d.ts +1 -1
  509. package/dist/components/features/conversation/transcript-export-modal.d.ts +2 -1
  510. package/dist/components/features/conversation-panel/budget-display.d.ts +2 -1
  511. package/dist/components/features/conversation-panel/budget-progress-bar.d.ts +1 -1
  512. package/dist/components/features/conversation-panel/budget-usage-text.d.ts +2 -1
  513. package/dist/components/features/conversation-panel/cloud-new-conversation-menu.d.ts +1 -1
  514. package/dist/components/features/conversation-panel/compact-conversation-row.cjs +1 -1
  515. package/dist/components/features/conversation-panel/compact-conversation-row.cjs.map +1 -1
  516. package/dist/components/features/conversation-panel/compact-conversation-row.d.ts +2 -1
  517. package/dist/components/features/conversation-panel/compact-conversation-row.js +38 -37
  518. package/dist/components/features/conversation-panel/compact-conversation-row.js.map +1 -1
  519. package/dist/components/features/conversation-panel/confirm-delete-modal.d.ts +1 -1
  520. package/dist/components/features/conversation-panel/confirm-stop-modal.d.ts +1 -1
  521. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.d.ts +1 -1
  522. package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.d.ts +1 -1
  523. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.d.ts +1 -1
  524. package/dist/components/features/conversation-panel/conversation-card/conversation-card-header.d.ts +1 -1
  525. package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.d.ts +1 -1
  526. package/dist/components/features/conversation-panel/conversation-card/conversation-card-skeleton.d.ts +1 -1
  527. package/dist/components/features/conversation-panel/conversation-card/conversation-card-title.d.ts +1 -1
  528. package/dist/components/features/conversation-panel/conversation-card/conversation-card.d.ts +2 -1
  529. package/dist/components/features/conversation-panel/conversation-card/conversation-repo-link.d.ts +1 -1
  530. package/dist/components/features/conversation-panel/conversation-card/conversation-status-badges.d.ts +1 -1
  531. package/dist/components/features/conversation-panel/conversation-card/no-repository.d.ts +1 -1
  532. package/dist/components/features/conversation-panel/conversation-group-folder-list.d.ts +1 -1
  533. package/dist/components/features/conversation-panel/conversation-group-folder-row.d.ts +1 -1
  534. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.d.ts +1 -1
  535. package/dist/components/features/conversation-panel/conversation-panel-new-thread-picker.d.ts +1 -1
  536. package/dist/components/features/conversation-panel/conversation-panel-pinned-section.d.ts +1 -1
  537. package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
  538. package/dist/components/features/conversation-panel/conversation-panel.cjs.map +1 -1
  539. package/dist/components/features/conversation-panel/conversation-panel.d.ts +2 -1
  540. package/dist/components/features/conversation-panel/conversation-panel.js +221 -220
  541. package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
  542. package/dist/components/features/conversation-panel/conversation-status-dot.d.ts +1 -1
  543. package/dist/components/features/conversation-panel/exit-conversation-modal.d.ts +1 -1
  544. package/dist/components/features/conversation-panel/hook-event-item.d.ts +1 -1
  545. package/dist/components/features/conversation-panel/hook-matcher-content.d.ts +1 -1
  546. package/dist/components/features/conversation-panel/hooks-empty-state.d.ts +1 -1
  547. package/dist/components/features/conversation-panel/hooks-loading-state.d.ts +1 -1
  548. package/dist/components/features/conversation-panel/hooks-modal-header.d.ts +1 -1
  549. package/dist/components/features/conversation-panel/hooks-modal.d.ts +1 -1
  550. package/dist/components/features/conversation-panel/local-new-conversation-menu.d.ts +1 -1
  551. package/dist/components/features/conversation-panel/menu-heading.d.ts +1 -1
  552. package/dist/components/features/conversation-panel/menu-row.d.ts +1 -1
  553. package/dist/components/features/conversation-panel/menu-separator.d.ts +1 -1
  554. package/dist/components/features/conversation-panel/new-conversation-button.d.ts +2 -1
  555. package/dist/components/features/conversation-panel/plugins-modal.d.ts +1 -1
  556. package/dist/components/features/conversation-panel/runtime-waiting-state.d.ts +1 -1
  557. package/dist/components/features/conversation-panel/skill-content.d.ts +1 -1
  558. package/dist/components/features/conversation-panel/skill-item.d.ts +1 -1
  559. package/dist/components/features/conversation-panel/skill-triggers.d.ts +1 -1
  560. package/dist/components/features/conversation-panel/skills-empty-state.d.ts +1 -1
  561. package/dist/components/features/conversation-panel/skills-loading-state.d.ts +1 -1
  562. package/dist/components/features/conversation-panel/skills-modal-header.d.ts +1 -1
  563. package/dist/components/features/conversation-panel/skills-modal-section.d.ts +1 -1
  564. package/dist/components/features/conversation-panel/skills-modal.d.ts +1 -1
  565. package/dist/components/features/conversation-panel/start-task-card/start-task-card-footer.d.ts +1 -1
  566. package/dist/components/features/conversation-panel/start-task-card/start-task-card-header.d.ts +1 -1
  567. package/dist/components/features/conversation-panel/start-task-card/start-task-card.d.ts +1 -1
  568. package/dist/components/features/conversation-panel/start-task-card/start-task-status-badge.d.ts +1 -1
  569. package/dist/components/features/conversation-panel/start-task-card/start-task-status-indicator.d.ts +1 -1
  570. package/dist/components/features/conversation-panel/system-message-modal/empty-tools-state.d.ts +1 -1
  571. package/dist/components/features/conversation-panel/system-message-modal/system-message-content.d.ts +1 -1
  572. package/dist/components/features/conversation-panel/system-message-modal/system-message-header.d.ts +1 -1
  573. package/dist/components/features/conversation-panel/system-message-modal/tab-button.d.ts +1 -1
  574. package/dist/components/features/conversation-panel/system-message-modal/tab-content.d.ts +1 -1
  575. package/dist/components/features/conversation-panel/system-message-modal/tab-navigation.d.ts +1 -1
  576. package/dist/components/features/conversation-panel/system-message-modal/toggle-button.d.ts +1 -1
  577. package/dist/components/features/conversation-panel/system-message-modal/tool-item.d.ts +1 -1
  578. package/dist/components/features/conversation-panel/system-message-modal/tool-parameters.d.ts +1 -1
  579. package/dist/components/features/conversation-panel/system-message-modal/tools-list.d.ts +1 -1
  580. package/dist/components/features/conversation-panel/system-message-modal.d.ts +1 -1
  581. package/dist/components/features/diff-viewer/commit-list.d.ts +2 -1
  582. package/dist/components/features/diff-viewer/commit-row.d.ts +2 -1
  583. package/dist/components/features/diff-viewer/diff-drawer-icon.d.ts +1 -1
  584. package/dist/components/features/diff-viewer/editor-container.d.ts +1 -1
  585. package/dist/components/features/diff-viewer/empty-changes-message.d.ts +1 -1
  586. package/dist/components/features/diff-viewer/file-diff-viewer.d.ts +2 -1
  587. package/dist/components/features/diff-viewer/loading-spinner.d.ts +1 -1
  588. package/dist/components/features/files/file-item.d.ts +1 -1
  589. package/dist/components/features/files/file-list.d.ts +2 -1
  590. package/dist/components/features/files-tab/file-content-viewer.d.ts +1 -1
  591. package/dist/components/features/files-tab/file-quick-row.d.ts +1 -1
  592. package/dist/components/features/files-tab/file-tree-view.d.ts +1 -1
  593. package/dist/components/features/files-tab/highlighted-source-view.d.ts +1 -1
  594. package/dist/components/features/files-tab/no-file-selected-message.d.ts +1 -1
  595. package/dist/components/features/files-tab/segmented-toggle.cjs +1 -1
  596. package/dist/components/features/files-tab/segmented-toggle.cjs.map +1 -1
  597. package/dist/components/features/files-tab/segmented-toggle.d.ts +3 -1
  598. package/dist/components/features/files-tab/segmented-toggle.js +17 -14
  599. package/dist/components/features/files-tab/segmented-toggle.js.map +1 -1
  600. package/dist/components/features/files-tab/tree-node.d.ts +1 -1
  601. package/dist/components/features/home/featured-automations/automation-health-indicator.d.ts +11 -0
  602. package/dist/components/features/home/featured-automations/automation-run-activity-metrics.d.ts +18 -0
  603. package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.d.ts +14 -0
  604. package/dist/components/features/home/featured-automations/automation-run-health.d.ts +25 -0
  605. package/dist/components/features/home/featured-automations/build-home-automation-menu-items.d.ts +39 -0
  606. package/dist/components/features/home/featured-automations/build-pinned-automation-menu-items.d.ts +22 -0
  607. package/dist/components/features/home/featured-automations/home-automation-activity.d.ts +23 -0
  608. package/dist/components/features/home/featured-automations/home-automation-menu.d.ts +13 -0
  609. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.d.ts +12 -0
  610. package/dist/components/features/home/featured-automations/pinned-automation-card.d.ts +21 -0
  611. package/dist/components/features/home/featured-automations/pinned-automations-dashboard.d.ts +6 -0
  612. package/dist/components/features/home/featured-automations/running-automations-list.d.ts +6 -0
  613. package/dist/components/features/home/git-branch-dropdown/branch-dropdown-menu.d.ts +1 -1
  614. package/dist/components/features/home/git-branch-dropdown/git-branch-dropdown.d.ts +2 -1
  615. package/dist/components/features/home/git-provider-dropdown/git-provider-dropdown.d.ts +2 -1
  616. package/dist/components/features/home/git-repo-dropdown/git-repo-dropdown.d.ts +2 -1
  617. package/dist/components/features/home/home-chat-launcher.d.ts +1 -1
  618. package/dist/components/features/home/home-git-control-bar-preview.d.ts +1 -1
  619. package/dist/components/features/home/home-header/guide-message.d.ts +1 -1
  620. package/dist/components/features/home/home-header/home-header-title.d.ts +1 -1
  621. package/dist/components/features/home/home-header/home-header.d.ts +1 -1
  622. package/dist/components/features/home/llm-not-configured-banner.d.ts +1 -1
  623. package/dist/components/features/home/new-conversation/create-conversation-button.d.ts +1 -1
  624. package/dist/components/features/home/new-conversation/new-conversation.d.ts +1 -1
  625. package/dist/components/features/home/new-conversation.d.ts +1 -1
  626. package/dist/components/features/home/open-launcher-button.d.ts +1 -1
  627. package/dist/components/features/home/open-repository-dialog.d.ts +1 -1
  628. package/dist/components/features/home/open-workspace-dialog.d.ts +1 -1
  629. package/dist/components/features/home/repo-selection-form.d.ts +2 -1
  630. package/dist/components/features/home/shared/clear-button.d.ts +2 -1
  631. package/dist/components/features/home/shared/dropdown-item.d.ts +1 -1
  632. package/dist/components/features/home/shared/empty-state.d.ts +2 -1
  633. package/dist/components/features/home/shared/error-message.d.ts +2 -1
  634. package/dist/components/features/home/shared/generic-dropdown-menu.d.ts +1 -1
  635. package/dist/components/features/home/shared/loading-spinner.d.ts +2 -1
  636. package/dist/components/features/home/shared/toggle-button.d.ts +1 -1
  637. package/dist/components/features/home/tasks/task-card.d.ts +1 -1
  638. package/dist/components/features/home/tasks/task-group.d.ts +1 -1
  639. package/dist/components/features/home/tasks/task-issue-number.d.ts +1 -1
  640. package/dist/components/features/home/tasks/task-item-title.d.ts +1 -1
  641. package/dist/components/features/home/tasks/task-suggestions-skeleton.d.ts +1 -1
  642. package/dist/components/features/home/tasks/task-suggestions.d.ts +1 -1
  643. package/dist/components/features/home/workspace-dropdown/folder-browser-modal.d.ts +2 -1
  644. package/dist/components/features/home/workspace-dropdown/manage-workspaces-modal.d.ts +2 -1
  645. package/dist/components/features/home/workspace-dropdown/workspace-dropdown.d.ts +2 -1
  646. package/dist/components/features/home/workspace-selection-form.d.ts +2 -1
  647. package/dist/components/features/images/image-carousel.d.ts +2 -1
  648. package/dist/components/features/images/image-preview.d.ts +1 -1
  649. package/dist/components/features/images/thumbnail.d.ts +1 -1
  650. package/dist/components/features/launch/plugin-launch-modal.d.ts +2 -1
  651. package/dist/components/features/launch/plugin-launch-parameter-input.d.ts +1 -1
  652. package/dist/components/features/launch/plugin-launch-plugin-section.d.ts +1 -1
  653. package/dist/components/features/manifest/manifest-form-field.d.ts +27 -0
  654. package/dist/components/features/manifest/manifest-icons.d.ts +13 -0
  655. package/dist/components/features/manifest/manifest-overview-tiles.d.ts +19 -0
  656. package/dist/components/features/manifest/manifest-prerequisites-step.d.ts +11 -0
  657. package/dist/components/features/manifest/manifest-review-step.d.ts +14 -0
  658. package/dist/components/features/manifest/manifest-setup-dialog.d.ts +14 -0
  659. package/dist/components/features/manifest/manifest-subpage-layout.d.ts +23 -0
  660. package/dist/components/features/markdown/anchor.d.ts +1 -1
  661. package/dist/components/features/markdown/blockquote.d.ts +1 -1
  662. package/dist/components/features/markdown/code.d.ts +1 -1
  663. package/dist/components/features/markdown/headings.d.ts +6 -6
  664. package/dist/components/features/markdown/horizontal-rule.d.ts +1 -1
  665. package/dist/components/features/markdown/list.d.ts +3 -3
  666. package/dist/components/features/markdown/markdown-renderer.d.ts +1 -1
  667. package/dist/components/features/markdown/markdown-table-scroll.d.ts +1 -1
  668. package/dist/components/features/markdown/paragraph.d.ts +1 -1
  669. package/dist/components/features/markdown/plan-components.d.ts +36 -36
  670. package/dist/components/features/markdown/table.d.ts +3 -3
  671. package/dist/components/features/mcp-logo-badge.d.ts +1 -1
  672. package/dist/components/features/mcp-page/custom-server-editor.cjs +1 -1
  673. package/dist/components/features/mcp-page/custom-server-editor.cjs.map +1 -1
  674. package/dist/components/features/mcp-page/custom-server-editor.d.ts +2 -1
  675. package/dist/components/features/mcp-page/custom-server-editor.js +5 -0
  676. package/dist/components/features/mcp-page/custom-server-editor.js.map +1 -1
  677. package/dist/components/features/mcp-page/install-server-modal.cjs +1 -1
  678. package/dist/components/features/mcp-page/install-server-modal.cjs.map +1 -1
  679. package/dist/components/features/mcp-page/install-server-modal.d.ts +2 -1
  680. package/dist/components/features/mcp-page/install-server-modal.js +117 -118
  681. package/dist/components/features/mcp-page/install-server-modal.js.map +1 -1
  682. package/dist/components/features/mcp-page/installed-server-card.d.ts +2 -1
  683. package/dist/components/features/mcp-page/installed-servers-section.d.ts +1 -1
  684. package/dist/components/features/mcp-page/marketplace-card.d.ts +1 -1
  685. package/dist/components/features/mcp-page/marketplace-section.d.ts +1 -1
  686. package/dist/components/features/mcp-page/mcp-logo-stack-badge.d.ts +1 -1
  687. package/dist/components/features/mcp-page/mcp-section-filter-dropdown.d.ts +1 -1
  688. package/dist/components/features/mcp-page/mcp-server-health.d.ts +2 -1
  689. package/dist/components/features/mcp-page/mcp-toolbar.d.ts +1 -1
  690. package/dist/components/features/mcp-page/save-as-secret-toggle.d.ts +1 -1
  691. package/dist/components/features/onboarding/onboarding-host.d.ts +1 -1
  692. package/dist/components/features/onboarding/onboarding-modal.d.ts +2 -1
  693. package/dist/components/features/onboarding/onboarding-progress-bar.d.ts +1 -1
  694. package/dist/components/features/onboarding/steps/check-backend-step.d.ts +2 -1
  695. package/dist/components/features/onboarding/steps/choose-agent-step.d.ts +3 -2
  696. package/dist/components/features/onboarding/steps/say-hello-step.d.ts +2 -1
  697. package/dist/components/features/onboarding/steps/setup-acp-secrets-step.d.ts +2 -1
  698. package/dist/components/features/onboarding/steps/setup-llm-step.d.ts +2 -1
  699. package/dist/components/features/plugins/add-plugin-modal.d.ts +2 -1
  700. package/dist/components/features/plugins/plugin-card.d.ts +2 -1
  701. package/dist/components/features/plugins/plugin-detail-modal.d.ts +1 -1
  702. package/dist/components/features/plugins/plugin-files-section.d.ts +2 -1
  703. package/dist/components/features/plugins/plugin-picker-card.d.ts +1 -1
  704. package/dist/components/features/plugins/plugin-picker-modal.d.ts +1 -1
  705. package/dist/components/features/plugins/plugin-picker-trigger.d.ts +1 -1
  706. package/dist/components/features/plugins/plugin-picker.d.ts +1 -1
  707. package/dist/components/features/plugins/plugins-toolbar.d.ts +1 -1
  708. package/dist/components/features/settings/acp-auth-status-banner.d.ts +1 -1
  709. package/dist/components/features/settings/acp-conflict-warnings.d.ts +2 -1
  710. package/dist/components/features/settings/acp-credentials-section.d.ts +1 -1
  711. package/dist/components/features/settings/acp-secret-field.d.ts +2 -1
  712. package/dist/components/features/settings/agent-canvas-update-card.d.ts +1 -1
  713. package/dist/components/features/settings/agent-profiles/agent-profile-actions-menu.d.ts +1 -1
  714. package/dist/components/features/settings/agent-profiles/agent-profile-row.d.ts +1 -1
  715. package/dist/components/features/settings/agent-profiles/agent-profiles-body.d.ts +1 -1
  716. package/dist/components/features/settings/agent-profiles/agent-profiles-local-view.d.ts +1 -1
  717. package/dist/components/features/settings/agent-profiles/agent-profiles-manager.d.ts +1 -1
  718. package/dist/components/features/settings/agent-profiles/delete-agent-profile-modal.d.ts +1 -1
  719. package/dist/components/features/settings/agent-server-onboarding.d.ts +2 -1
  720. package/dist/components/features/settings/api-key-modal-base.d.ts +1 -1
  721. package/dist/components/features/settings/app-settings/app-settings-inputs-skeleton.d.ts +1 -1
  722. package/dist/components/features/settings/app-settings/language-input.d.ts +1 -1
  723. package/dist/components/features/settings/app-settings/theme-input.d.ts +2 -1
  724. package/dist/components/features/settings/backend-synced-settings-badge.d.ts +1 -1
  725. package/dist/components/features/settings/banner-message.d.ts +1 -1
  726. package/dist/components/features/settings/cloud-settings-link.d.ts +1 -1
  727. package/dist/components/features/settings/input-skeleton.d.ts +1 -1
  728. package/dist/components/features/settings/integrations-settings-link.d.ts +1 -1
  729. package/dist/components/features/settings/key-status-icon.d.ts +1 -1
  730. package/dist/components/features/settings/llm-profiles/delete-profile-modal.d.ts +1 -1
  731. package/dist/components/features/settings/llm-profiles/llm-profiles-manager.d.ts +1 -1
  732. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.d.ts +2 -1
  733. package/dist/components/features/settings/llm-profiles/profile-actions-menu-item.d.ts +1 -1
  734. package/dist/components/features/settings/llm-profiles/profile-actions-menu.d.ts +1 -1
  735. package/dist/components/features/settings/llm-profiles/profile-row.d.ts +1 -1
  736. package/dist/components/features/settings/llm-profiles/profiles-body.d.ts +1 -1
  737. package/dist/components/features/settings/llm-profiles/rename-profile-modal.d.ts +1 -1
  738. package/dist/components/features/settings/llm-settings/llm-settings-inputs-skeleton.d.ts +1 -1
  739. package/dist/components/features/settings/llm-settings/openai-subscription-auth-card.d.ts +2 -1
  740. package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs +1 -1
  741. package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs.map +1 -1
  742. package/dist/components/features/settings/mcp-settings/mcp-server-form.d.ts +2 -1
  743. package/dist/components/features/settings/mcp-settings/mcp-server-form.js +2 -1
  744. package/dist/components/features/settings/mcp-settings/mcp-server-form.js.map +1 -1
  745. package/dist/components/features/settings/mcp-settings/mcp-server-list-item.d.ts +1 -1
  746. package/dist/components/features/settings/mcp-settings/mcp-server-list.d.ts +1 -1
  747. package/dist/components/features/settings/mobile-header.d.ts +1 -1
  748. package/dist/components/features/settings/optional-tag.d.ts +1 -1
  749. package/dist/components/features/settings/sdk-settings/field-help.d.ts +1 -1
  750. package/dist/components/features/settings/sdk-settings/schema-field.d.ts +2 -1
  751. package/dist/components/features/settings/sdk-settings/sdk-section-page.d.ts +1 -1
  752. package/dist/components/features/settings/sdk-settings/view-toggle.d.ts +1 -1
  753. package/dist/components/features/settings/secrets-settings/secret-form.d.ts +2 -1
  754. package/dist/components/features/settings/secrets-settings/secret-list-item.d.ts +2 -2
  755. package/dist/components/features/settings/settings-desktop-sidebar.d.ts +1 -1
  756. package/dist/components/features/settings/settings-dropdown-input.d.ts +1 -1
  757. package/dist/components/features/settings/settings-input.cjs +1 -1
  758. package/dist/components/features/settings/settings-input.cjs.map +1 -1
  759. package/dist/components/features/settings/settings-input.d.ts +6 -0
  760. package/dist/components/features/settings/settings-input.js +13 -8
  761. package/dist/components/features/settings/settings-input.js.map +1 -1
  762. package/dist/components/features/settings/settings-layout.d.ts +1 -1
  763. package/dist/components/features/settings/settings-mobile-drawer.d.ts +1 -1
  764. package/dist/components/features/settings/settings-mobile-hub.d.ts +1 -1
  765. package/dist/components/features/settings/settings-nav-divider.d.ts +1 -1
  766. package/dist/components/features/settings/settings-nav-header.d.ts +1 -1
  767. package/dist/components/features/settings/settings-nav-link.d.ts +1 -1
  768. package/dist/components/features/settings/settings-navigation.d.ts +1 -1
  769. package/dist/components/features/settings/settings-switch.d.ts +1 -1
  770. package/dist/components/features/settings/subtext-skeleton.d.ts +1 -1
  771. package/dist/components/features/settings/switch-skeleton.d.ts +1 -1
  772. package/dist/components/features/settings/upgrade-banner.d.ts +1 -1
  773. package/dist/components/features/settings/upgrade-button.d.ts +1 -1
  774. package/dist/components/features/sidebar/avatar.d.ts +1 -1
  775. package/dist/components/features/sidebar/sidebar-collapsed-icon-slot.d.ts +1 -1
  776. package/dist/components/features/sidebar/sidebar-conversation-list.d.ts +1 -1
  777. package/dist/components/features/sidebar/sidebar-mobile-menu-bar.d.ts +1 -1
  778. package/dist/components/features/sidebar/sidebar-mobile-menu-toggle.d.ts +1 -1
  779. package/dist/components/features/sidebar/sidebar-mobile-nav-context.d.ts +1 -1
  780. package/dist/components/features/sidebar/sidebar-nav-link.d.ts +1 -1
  781. package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
  782. package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
  783. package/dist/components/features/sidebar/sidebar-rail-body.d.ts +1 -1
  784. package/dist/components/features/sidebar/sidebar-rail-body.js +124 -123
  785. package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
  786. package/dist/components/features/sidebar/sidebar.d.ts +2 -1
  787. package/dist/components/features/sidebar/user-avatar.d.ts +1 -1
  788. package/dist/components/features/skills/add-skill-modal.d.ts +2 -1
  789. package/dist/components/features/skills/extensions-mobile-hub.d.ts +1 -1
  790. package/dist/components/features/skills/extensions-navigation.d.ts +1 -1
  791. package/dist/components/features/skills/skill-card-pill-row.d.ts +1 -1
  792. package/dist/components/features/skills/skill-card.d.ts +2 -1
  793. package/dist/components/features/skills/skill-detail-modal.d.ts +2 -1
  794. package/dist/components/features/skills/skill-facet-rail.d.ts +8 -0
  795. package/dist/components/features/skills/skill-facet-row.d.ts +13 -0
  796. package/dist/components/features/skills/skill-filter.d.ts +34 -0
  797. package/dist/components/features/skills/skill-filters-modal.d.ts +10 -0
  798. package/dist/components/features/skills/skill-icon-badge.d.ts +1 -1
  799. package/dist/components/features/skills/skill-type-badge.d.ts +1 -1
  800. package/dist/components/features/skills/skills-toolbar.d.ts +3 -4
  801. package/dist/components/features/suggestions/suggestion-item.d.ts +1 -1
  802. package/dist/components/features/suggestions/suggestions.d.ts +1 -1
  803. package/dist/components/features/terminal/empty-terminal-message.d.ts +1 -1
  804. package/dist/components/features/terminal/terminal.d.ts +1 -1
  805. package/dist/components/features/tips/random-tip.d.ts +2 -1
  806. package/dist/components/providers/agent-server-ui-providers.d.ts +1 -1
  807. package/dist/components/providers/agent-server-ui-root.d.ts +1 -1
  808. package/dist/components/providers/telemetry-provider.d.ts +1 -1
  809. package/dist/components/shared/action-tooltip.d.ts +1 -1
  810. package/dist/components/shared/agent-brand-icon.d.ts +1 -1
  811. package/dist/components/shared/badge.d.ts +1 -1
  812. package/dist/components/shared/buttons/back-nav-button-content.d.ts +1 -1
  813. package/dist/components/shared/buttons/circle-plus-check-toggle.d.ts +3 -2
  814. package/dist/components/shared/buttons/conversation-confirmation-buttons.d.ts +1 -1
  815. package/dist/components/shared/buttons/copy-to-clipboard-button.d.ts +1 -1
  816. package/dist/components/shared/buttons/copyable-content-wrapper.d.ts +1 -1
  817. package/dist/components/shared/buttons/modal-button.d.ts +1 -1
  818. package/dist/components/shared/buttons/openhands-logo-button.d.ts +1 -1
  819. package/dist/components/shared/buttons/remove-button.d.ts +1 -1
  820. package/dist/components/shared/buttons/scroll-to-bottom-button.d.ts +1 -1
  821. package/dist/components/shared/buttons/styled-tooltip.d.ts +1 -1
  822. package/dist/components/shared/filters/enum-filter-dropdown.cjs +1 -1
  823. package/dist/components/shared/filters/enum-filter-dropdown.cjs.map +1 -1
  824. package/dist/components/shared/filters/enum-filter-dropdown.d.ts +6 -2
  825. package/dist/components/shared/filters/enum-filter-dropdown.js +13 -13
  826. package/dist/components/shared/filters/enum-filter-dropdown.js.map +1 -1
  827. package/dist/components/shared/git-provider-icon.d.ts +1 -1
  828. package/dist/components/shared/hook-execution-event-message.d.ts +2 -1
  829. package/dist/components/shared/loading-spinner.d.ts +1 -1
  830. package/dist/components/shared/modals/confirmation-modal.d.ts +1 -1
  831. package/dist/components/shared/modals/confirmation-modals/base-modal.d.ts +3 -3
  832. package/dist/components/shared/modals/confirmation-modals/danger-modal.d.ts +1 -1
  833. package/dist/components/shared/modals/modal-body.d.ts +1 -1
  834. package/dist/components/shared/modals/modal-close-button.d.ts +1 -1
  835. package/dist/components/shared/modals/settings/model-selector.d.ts +2 -1
  836. package/dist/components/shared/modals/settings/settings-form.d.ts +2 -1
  837. package/dist/components/shared/modals/settings/settings-modal.d.ts +1 -1
  838. package/dist/components/shared/navigation-link.cjs +1 -1
  839. package/dist/components/shared/navigation-link.cjs.map +1 -1
  840. package/dist/components/shared/navigation-link.js +11 -7
  841. package/dist/components/shared/navigation-link.js.map +1 -1
  842. package/dist/components/shared/risk-alert.d.ts +1 -1
  843. package/dist/components/shared/text-shimmer.d.ts +1 -1
  844. package/dist/components/ui/resize-handle.d.ts +1 -1
  845. package/dist/config/defaults.cjs +1 -1
  846. package/dist/config/defaults.cjs.map +1 -1
  847. package/dist/config/defaults.js +3 -3
  848. package/dist/config/defaults.js.map +1 -1
  849. package/dist/context/navigation-context.d.ts +1 -1
  850. package/dist/context/scroll-context.d.ts +1 -1
  851. package/dist/contexts/active-backend-context.d.ts +1 -1
  852. package/dist/contexts/conversation-websocket-context.d.ts +1 -1
  853. package/dist/contexts/settings-section-header-context.d.ts +1 -1
  854. package/dist/contexts/websocket-provider-wrapper.d.ts +1 -1
  855. package/dist/fixtures/home-automations-demo.d.ts +19 -0
  856. package/dist/hooks/mutation/use-add-mcp-server.cjs +1 -1
  857. package/dist/hooks/mutation/use-add-mcp-server.cjs.map +1 -1
  858. package/dist/hooks/mutation/use-add-mcp-server.js +10 -14
  859. package/dist/hooks/mutation/use-add-mcp-server.js.map +1 -1
  860. package/dist/hooks/mutation/use-delete-mcp-server.cjs +1 -1
  861. package/dist/hooks/mutation/use-delete-mcp-server.cjs.map +1 -1
  862. package/dist/hooks/mutation/use-delete-mcp-server.d.ts +2 -7
  863. package/dist/hooks/mutation/use-delete-mcp-server.js +8 -34
  864. package/dist/hooks/mutation/use-delete-mcp-server.js.map +1 -1
  865. package/dist/hooks/mutation/use-save-settings.cjs +1 -1
  866. package/dist/hooks/mutation/use-save-settings.cjs.map +1 -1
  867. package/dist/hooks/mutation/use-save-settings.js +8 -4
  868. package/dist/hooks/mutation/use-save-settings.js.map +1 -1
  869. package/dist/hooks/mutation/use-update-mcp-server.cjs +1 -1
  870. package/dist/hooks/mutation/use-update-mcp-server.cjs.map +1 -1
  871. package/dist/hooks/mutation/use-update-mcp-server.d.ts +1 -1
  872. package/dist/hooks/mutation/use-update-mcp-server.js +31 -16
  873. package/dist/hooks/mutation/use-update-mcp-server.js.map +1 -1
  874. package/dist/hooks/query/query-keys.cjs.map +1 -1
  875. package/dist/hooks/query/query-keys.d.ts +4 -0
  876. package/dist/hooks/query/query-keys.js.map +1 -1
  877. package/dist/hooks/query/use-active-conversation.d.ts +1 -1
  878. package/dist/hooks/query/use-agent-profiles.d.ts +1 -1
  879. package/dist/hooks/query/use-app-installations.d.ts +1 -1
  880. package/dist/hooks/query/use-automation-detail.d.ts +2 -2
  881. package/dist/hooks/query/use-automation-health.d.ts +2 -0
  882. package/dist/hooks/query/use-automations.d.ts +5 -1
  883. package/dist/hooks/query/use-bash-command-logs.d.ts +1 -1
  884. package/dist/hooks/query/use-cloud-sandbox.d.ts +1 -1
  885. package/dist/hooks/query/use-commit-changes.d.ts +1 -1
  886. package/dist/hooks/query/use-config.d.ts +1 -1
  887. package/dist/hooks/query/use-conversation-history.d.ts +1 -1
  888. package/dist/hooks/query/use-conversation-hooks.d.ts +1 -1
  889. package/dist/hooks/query/use-conversation-skills.d.ts +1 -1
  890. package/dist/hooks/query/use-get-secrets.d.ts +1 -1
  891. package/dist/hooks/query/use-home-automations.d.ts +20 -0
  892. package/dist/hooks/query/use-latest-automation-runs.d.ts +19 -0
  893. package/dist/hooks/query/use-llm-profiles.d.ts +1 -1
  894. package/dist/hooks/query/use-llm-subscription-models.d.ts +1 -1
  895. package/dist/hooks/query/use-llm-subscription-status.d.ts +1 -1
  896. package/dist/hooks/query/use-local-git-info.d.ts +1 -1
  897. package/dist/hooks/query/use-local-workspaces.d.ts +1 -1
  898. package/dist/hooks/query/use-manifest-capabilities.d.ts +23 -0
  899. package/dist/hooks/query/use-manifest-prerequisites.d.ts +24 -0
  900. package/dist/hooks/query/use-plugin-file-content.d.ts +1 -1
  901. package/dist/hooks/query/use-plugins-marketplace.d.ts +1 -1
  902. package/dist/hooks/query/use-provider-models.d.ts +1 -1
  903. package/dist/hooks/query/use-search-branches.d.ts +1 -1
  904. package/dist/hooks/query/use-search-providers.d.ts +1 -1
  905. package/dist/hooks/query/use-search-repositories.d.ts +1 -1
  906. package/dist/hooks/query/use-search-subdirs.d.ts +2 -2
  907. package/dist/hooks/query/use-settings.d.ts +2 -2
  908. package/dist/hooks/query/use-skills.d.ts +1 -1
  909. package/dist/hooks/query/use-start-tasks.d.ts +1 -1
  910. package/dist/hooks/query/use-sub-conversation-task-polling.d.ts +1 -1
  911. package/dist/hooks/query/use-sub-conversations.d.ts +1 -1
  912. package/dist/hooks/query/use-suggested-tasks.d.ts +1 -1
  913. package/dist/hooks/query/use-task-polling.d.ts +2 -2
  914. package/dist/hooks/query/use-unified-get-git-changes.d.ts +1 -1
  915. package/dist/hooks/query/use-unified-git-diff.d.ts +1 -1
  916. package/dist/hooks/query/use-user-conversation.d.ts +1 -1
  917. package/dist/hooks/query/use-workspace-file-content.d.ts +1 -1
  918. package/dist/hooks/use-backend-scoped-path.cjs +2 -0
  919. package/dist/hooks/use-backend-scoped-path.cjs.map +1 -0
  920. package/dist/hooks/use-backend-scoped-path.d.ts +10 -0
  921. package/dist/hooks/use-backend-scoped-path.js +13 -0
  922. package/dist/hooks/use-backend-scoped-path.js.map +1 -0
  923. package/dist/hooks/use-home-automation-actions.d.ts +23 -0
  924. package/dist/hooks/use-home-pinned-automations.d.ts +26 -0
  925. package/dist/hooks/use-llm-configured.cjs +1 -1
  926. package/dist/hooks/use-llm-configured.cjs.map +1 -1
  927. package/dist/hooks/use-llm-configured.js +2 -1
  928. package/dist/hooks/use-llm-configured.js.map +1 -1
  929. package/dist/hooks/use-manifest-preflight.d.ts +18 -0
  930. package/dist/hooks/use-tracking.cjs +1 -1
  931. package/dist/hooks/use-tracking.cjs.map +1 -1
  932. package/dist/hooks/use-tracking.d.ts +18 -0
  933. package/dist/hooks/use-tracking.js +25 -1
  934. package/dist/hooks/use-tracking.js.map +1 -1
  935. package/dist/i18n/declaration.cjs +1 -1
  936. package/dist/i18n/declaration.cjs.map +1 -1
  937. package/dist/i18n/declaration.d.ts +103 -2
  938. package/dist/i18n/declaration.js +1 -1
  939. package/dist/i18n/declaration.js.map +1 -1
  940. package/dist/i18n/translation.cjs +2 -2
  941. package/dist/i18n/translation.cjs.map +1 -1
  942. package/dist/i18n/translation.js +1780 -63
  943. package/dist/i18n/translation.js.map +1 -1
  944. package/dist/icons/code-pill.d.ts +1 -1
  945. package/dist/icons/external-link.cjs +2 -0
  946. package/dist/icons/external-link.cjs.map +1 -0
  947. package/dist/icons/external-link.js +22 -0
  948. package/dist/icons/external-link.js.map +1 -0
  949. package/dist/icons/server.cjs +2 -0
  950. package/dist/icons/server.cjs.map +1 -0
  951. package/dist/icons/server.js +17 -0
  952. package/dist/icons/server.js.map +1 -0
  953. package/dist/locales/ar/openhands.json +106 -5
  954. package/dist/locales/ca/openhands.json +106 -5
  955. package/dist/locales/de/openhands.json +106 -5
  956. package/dist/locales/en/openhands.json +107 -6
  957. package/dist/locales/es/openhands.json +106 -5
  958. package/dist/locales/fr/openhands.json +106 -5
  959. package/dist/locales/it/openhands.json +106 -5
  960. package/dist/locales/ja/openhands.json +106 -5
  961. package/dist/locales/ko-KR/openhands.json +106 -5
  962. package/dist/locales/no/openhands.json +106 -5
  963. package/dist/locales/pt/openhands.json +106 -5
  964. package/dist/locales/tr/openhands.json +106 -5
  965. package/dist/locales/uk/openhands.json +106 -5
  966. package/dist/locales/zh-CN/openhands.json +106 -5
  967. package/dist/locales/zh-TW/openhands.json +106 -5
  968. package/dist/manifests/automation-insights.d.ts +64 -0
  969. package/dist/manifests/automation-interface.cjs +2 -0
  970. package/dist/manifests/automation-interface.cjs.map +1 -0
  971. package/dist/manifests/automation-interface.d.ts +76 -0
  972. package/dist/manifests/automation-interface.js +82 -0
  973. package/dist/manifests/automation-interface.js.map +1 -0
  974. package/dist/manifests/automation-setup.cjs +2 -0
  975. package/dist/manifests/automation-setup.cjs.map +1 -0
  976. package/dist/manifests/automation-setup.d.ts +52 -0
  977. package/dist/manifests/automation-setup.js +8 -0
  978. package/dist/manifests/automation-setup.js.map +1 -0
  979. package/dist/manifests/interface-validation.cjs +2 -0
  980. package/dist/manifests/interface-validation.cjs.map +1 -0
  981. package/dist/manifests/interface-validation.d.ts +27 -0
  982. package/dist/manifests/interface-validation.js +360 -0
  983. package/dist/manifests/interface-validation.js.map +1 -0
  984. package/dist/manifests/manifest-actions.d.ts +15 -0
  985. package/dist/manifests/manifest-capabilities.d.ts +25 -0
  986. package/dist/manifests/manifest-error-map.d.ts +40 -0
  987. package/dist/manifests/manifest-local-validation.d.ts +56 -0
  988. package/dist/manifests/manifest-registry.cjs +2 -0
  989. package/dist/manifests/manifest-registry.cjs.map +1 -0
  990. package/dist/manifests/manifest-registry.d.ts +15 -0
  991. package/dist/manifests/manifest-registry.js +26 -0
  992. package/dist/manifests/manifest-registry.js.map +1 -0
  993. package/dist/manifests/manifest-sources.cjs +2 -0
  994. package/dist/manifests/manifest-sources.cjs.map +1 -0
  995. package/dist/manifests/manifest-sources.d.ts +15 -0
  996. package/dist/manifests/manifest-sources.js +8 -0
  997. package/dist/manifests/manifest-sources.js.map +1 -0
  998. package/dist/manifests/manifest-template.d.ts +20 -0
  999. package/dist/manifests/manifest-validation.cjs +2 -0
  1000. package/dist/manifests/manifest-validation.cjs.map +1 -0
  1001. package/dist/manifests/manifest-validation.d.ts +30 -0
  1002. package/dist/manifests/manifest-validation.js +145 -0
  1003. package/dist/manifests/manifest-validation.js.map +1 -0
  1004. package/dist/manifests/types.cjs +2 -0
  1005. package/dist/manifests/types.cjs.map +1 -0
  1006. package/dist/manifests/types.d.ts +355 -0
  1007. package/dist/manifests/types.js +39 -0
  1008. package/dist/manifests/types.js.map +1 -0
  1009. package/dist/mockServiceWorker.js +21 -9
  1010. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs +9 -0
  1011. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs.map +1 -0
  1012. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js +75 -0
  1013. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js.map +1 -0
  1014. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs +9 -0
  1015. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs.map +1 -0
  1016. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js +78 -0
  1017. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js.map +1 -0
  1018. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.cjs +17 -0
  1019. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.cjs.map +1 -0
  1020. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.js +89 -0
  1021. package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.js.map +1 -0
  1022. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs +10 -0
  1023. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs.map +1 -0
  1024. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js +17 -0
  1025. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js.map +1 -0
  1026. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.cjs +9 -0
  1027. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.cjs.map +1 -0
  1028. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.js +15 -0
  1029. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.js.map +1 -0
  1030. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.cjs +9 -0
  1031. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.cjs.map +1 -0
  1032. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.js +18 -0
  1033. package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.js.map +1 -0
  1034. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.cjs +9 -0
  1035. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.cjs.map +1 -0
  1036. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.js +14 -0
  1037. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.js.map +1 -0
  1038. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.cjs +9 -0
  1039. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.cjs.map +1 -0
  1040. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.js +14 -0
  1041. package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.js.map +1 -0
  1042. package/dist/node_modules/@openhands/extensions/automations/catalog/upstream-fork-sync/manifest.cjs +9 -0
  1043. package/dist/node_modules/@openhands/extensions/automations/catalog/upstream-fork-sync/manifest.cjs.map +1 -0
  1044. package/dist/node_modules/@openhands/extensions/automations/catalog/upstream-fork-sync/manifest.js +74 -0
  1045. package/dist/node_modules/@openhands/extensions/automations/catalog/upstream-fork-sync/manifest.js.map +1 -0
  1046. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs +2 -0
  1047. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs.map +1 -0
  1048. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js +25 -0
  1049. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js.map +1 -0
  1050. package/dist/node_modules/@openhands/extensions/automations/index.cjs +2 -0
  1051. package/dist/node_modules/@openhands/extensions/automations/index.cjs.map +1 -0
  1052. package/dist/node_modules/@openhands/extensions/automations/index.js +18 -0
  1053. package/dist/node_modules/@openhands/extensions/automations/index.js.map +1 -0
  1054. package/dist/node_modules/@openhands/extensions/automations/interface.cjs +2 -0
  1055. package/dist/node_modules/@openhands/extensions/automations/interface.cjs.map +1 -0
  1056. package/dist/node_modules/@openhands/extensions/automations/interface.js +210 -0
  1057. package/dist/node_modules/@openhands/extensions/automations/interface.js.map +1 -0
  1058. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs +1 -1
  1059. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs.map +1 -1
  1060. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js +3 -3
  1061. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js.map +1 -1
  1062. package/dist/node_modules/@openhands/extensions/skills/index.cjs +174 -53
  1063. package/dist/node_modules/@openhands/extensions/skills/index.cjs.map +1 -1
  1064. package/dist/node_modules/@openhands/extensions/skills/index.js +115 -53
  1065. package/dist/node_modules/@openhands/extensions/skills/index.js.map +1 -1
  1066. package/dist/node_modules/@tanstack/query-core/build/modern/utils.cjs +1 -1
  1067. package/dist/node_modules/@tanstack/query-core/build/modern/utils.cjs.map +1 -1
  1068. package/dist/node_modules/@tanstack/query-core/build/modern/utils.js +12 -1
  1069. package/dist/node_modules/@tanstack/query-core/build/modern/utils.js.map +1 -1
  1070. package/dist/node_modules/@tanstack/react-query/build/modern/useBaseQuery.cjs +1 -1
  1071. package/dist/node_modules/@tanstack/react-query/build/modern/useBaseQuery.cjs.map +1 -1
  1072. package/dist/node_modules/@tanstack/react-query/build/modern/useBaseQuery.js +14 -12
  1073. package/dist/node_modules/@tanstack/react-query/build/modern/useBaseQuery.js.map +1 -1
  1074. package/dist/node_modules/html-parse-stringify/dist/esm/html-parse-stringify.cjs +2 -0
  1075. package/dist/node_modules/html-parse-stringify/dist/esm/html-parse-stringify.cjs.map +1 -0
  1076. package/dist/node_modules/html-parse-stringify/dist/esm/html-parse-stringify.js +177 -0
  1077. package/dist/node_modules/html-parse-stringify/dist/esm/html-parse-stringify.js.map +1 -0
  1078. package/dist/node_modules/i18next/dist/esm/i18next.cjs +1 -1
  1079. package/dist/node_modules/i18next/dist/esm/i18next.cjs.map +1 -1
  1080. package/dist/node_modules/i18next/dist/esm/i18next.js +31 -24
  1081. package/dist/node_modules/i18next/dist/esm/i18next.js.map +1 -1
  1082. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.cjs +2 -0
  1083. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.cjs.map +1 -0
  1084. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.js +29 -0
  1085. package/dist/node_modules/lucide-react/dist/esm/icons/monitor.js.map +1 -0
  1086. package/dist/node_modules/posthog-js/dist/module.cjs +2 -2
  1087. package/dist/node_modules/posthog-js/dist/module.cjs.map +1 -1
  1088. package/dist/node_modules/posthog-js/dist/module.js +2055 -1929
  1089. package/dist/node_modules/posthog-js/dist/module.js.map +1 -1
  1090. package/dist/node_modules/react-i18next/dist/es/TransWithoutContext.cjs +1 -1
  1091. package/dist/node_modules/react-i18next/dist/es/TransWithoutContext.cjs.map +1 -1
  1092. package/dist/node_modules/react-i18next/dist/es/TransWithoutContext.js +43 -62
  1093. package/dist/node_modules/react-i18next/dist/es/TransWithoutContext.js.map +1 -1
  1094. package/dist/node_modules/react-i18next/dist/es/useTranslation.cjs +1 -1
  1095. package/dist/node_modules/react-i18next/dist/es/useTranslation.cjs.map +1 -1
  1096. package/dist/node_modules/react-i18next/dist/es/useTranslation.js +12 -6
  1097. package/dist/node_modules/react-i18next/dist/es/useTranslation.js.map +1 -1
  1098. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.cjs +1 -1
  1099. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.cjs.map +1 -1
  1100. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +352 -310
  1101. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -1
  1102. package/dist/package.cjs +1 -1
  1103. package/dist/package.cjs.map +1 -1
  1104. package/dist/package.js +34 -33
  1105. package/dist/package.js.map +1 -1
  1106. package/dist/routes/agent-settings.d.ts +3 -2
  1107. package/dist/routes/app-settings.d.ts +2 -1
  1108. package/dist/routes/browser-tab.d.ts +1 -1
  1109. package/dist/routes/changes-tab.d.ts +2 -1
  1110. package/dist/routes/commits-tab.d.ts +1 -1
  1111. package/dist/routes/conversation.d.ts +2 -1
  1112. package/dist/routes/files-tab.d.ts +1 -1
  1113. package/dist/routes/llm-settings.d.ts +3 -2
  1114. package/dist/routes/mcp.cjs +1 -1
  1115. package/dist/routes/mcp.cjs.map +1 -1
  1116. package/dist/routes/mcp.d.ts +2 -1
  1117. package/dist/routes/mcp.js +1 -1
  1118. package/dist/routes/mcp.js.map +1 -1
  1119. package/dist/routes/planner-tab.d.ts +2 -1
  1120. package/dist/routes/secrets-settings.d.ts +2 -1
  1121. package/dist/routes/task-list-tab.d.ts +1 -1
  1122. package/dist/services/settings.cjs +1 -1
  1123. package/dist/services/settings.cjs.map +1 -1
  1124. package/dist/services/settings.js +3 -7
  1125. package/dist/services/settings.js.map +1 -1
  1126. package/dist/types/agent-server/core/events/conversation-state-event.d.ts +2 -19
  1127. package/dist/types/agent-server/core/events/observation-event.d.ts +2 -18
  1128. package/dist/types/automation.d.ts +23 -4
  1129. package/dist/types/mcp-auth.cjs.map +1 -1
  1130. package/dist/types/mcp-auth.d.ts +5 -41
  1131. package/dist/types/mcp-auth.js.map +1 -1
  1132. package/dist/types/mcp-server.d.ts +17 -32
  1133. package/dist/types/settings.d.ts +8 -28
  1134. package/dist/ui/card-title.d.ts +1 -1
  1135. package/dist/ui/card.d.ts +1 -1
  1136. package/dist/ui/combobox-caret.d.ts +3 -3
  1137. package/dist/ui/context-menu.cjs +1 -1
  1138. package/dist/ui/context-menu.cjs.map +1 -1
  1139. package/dist/ui/context-menu.d.ts +3 -2
  1140. package/dist/ui/context-menu.js +10 -9
  1141. package/dist/ui/context-menu.js.map +1 -1
  1142. package/dist/ui/divider.d.ts +1 -1
  1143. package/dist/ui/dropdown/clear-button.d.ts +1 -1
  1144. package/dist/ui/dropdown/dropdown-input.d.ts +1 -1
  1145. package/dist/ui/dropdown/dropdown-menu.d.ts +1 -1
  1146. package/dist/ui/dropdown/dropdown.d.ts +1 -1
  1147. package/dist/ui/dropdown/loading-spinner.d.ts +1 -1
  1148. package/dist/ui/dropdown/toggle-button.d.ts +1 -1
  1149. package/dist/ui/help-link.d.ts +1 -1
  1150. package/dist/ui/pre.d.ts +1 -1
  1151. package/dist/ui/toggle-switch.d.ts +2 -2
  1152. package/dist/ui/typography.d.ts +7 -7
  1153. package/dist/utils/api-error-message.d.ts +6 -2
  1154. package/dist/utils/automation-activity-log-export.d.ts +17 -0
  1155. package/dist/utils/automation-catalog.cjs +2 -0
  1156. package/dist/utils/automation-catalog.cjs.map +1 -0
  1157. package/dist/utils/automation-catalog.d.ts +28 -0
  1158. package/dist/utils/automation-catalog.js +5 -0
  1159. package/dist/utils/automation-catalog.js.map +1 -0
  1160. package/dist/utils/automation-timeout.d.ts +5 -6
  1161. package/dist/utils/custom-toast-handlers.d.ts +2 -2
  1162. package/dist/utils/format-relative-time.d.ts +3 -0
  1163. package/dist/utils/mcp-config.cjs +1 -1
  1164. package/dist/utils/mcp-config.cjs.map +1 -1
  1165. package/dist/utils/mcp-config.d.ts +12 -29
  1166. package/dist/utils/mcp-config.js +161 -143
  1167. package/dist/utils/mcp-config.js.map +1 -1
  1168. package/dist/utils/mcp-installed-servers.cjs +1 -1
  1169. package/dist/utils/mcp-installed-servers.cjs.map +1 -1
  1170. package/dist/utils/mcp-installed-servers.d.ts +2 -2
  1171. package/dist/utils/mcp-installed-servers.js +21 -32
  1172. package/dist/utils/mcp-installed-servers.js.map +1 -1
  1173. package/dist/utils/mcp-server-health-key.cjs.map +1 -1
  1174. package/dist/utils/mcp-server-health-key.d.ts +2 -4
  1175. package/dist/utils/mcp-server-health-key.js.map +1 -1
  1176. package/dist/utils/responder-deployment.d.ts +5 -1
  1177. package/dist/utils/settings-like-page-layout-classes.cjs +1 -1
  1178. package/dist/utils/settings-like-page-layout-classes.cjs.map +1 -1
  1179. package/dist/utils/settings-like-page-layout-classes.d.ts +6 -2
  1180. package/dist/utils/settings-like-page-layout-classes.js +1 -1
  1181. package/dist/utils/settings-like-page-layout-classes.js.map +1 -1
  1182. package/dist/utils/skill-category.d.ts +12 -0
  1183. package/dist/utils/transcript-export/index.cjs +5 -5
  1184. package/dist/utils/transcript-export/index.js +12 -12
  1185. package/package.json +36 -33
  1186. package/scripts/check-sdk-version-sync.mjs +6 -6
  1187. package/scripts/check-translation-completeness.cjs +1 -0
  1188. package/scripts/dev-safe.mjs +17 -12
  1189. package/scripts/dev-static.mjs +17 -0
  1190. package/scripts/dev-with-automation.mjs +15 -16
  1191. package/scripts/ingress.mjs +22 -0
  1192. package/scripts/proxy-utils.mjs +157 -2
  1193. package/scripts/runtime-services-info.mjs +6 -6
  1194. package/scripts/static-build.mjs +0 -7
  1195. package/scripts/static-server.mjs +10 -0
  1196. package/build/assets/Trans-B7lYw4uD.js +0 -1
  1197. package/build/assets/active-backend-context-mY7Gff5c.js +0 -2
  1198. package/build/assets/agent-context-settings-BTUmWEzL.js +0 -1
  1199. package/build/assets/agent-profiles-settings-Ilqid_R5.js +0 -1
  1200. package/build/assets/agent-server-conversation-service.api-C_7YnjzP.js +0 -41
  1201. package/build/assets/agent-settings-CxfT4ksO.js +0 -1
  1202. package/build/assets/alert-banner-eRyIwDyU.js +0 -1
  1203. package/build/assets/automation-BGP_I1RR.js +0 -1
  1204. package/build/assets/automation-detail-nEflClmc.js +0 -2
  1205. package/build/assets/automation-export-BO_kfqC8.js +0 -2
  1206. package/build/assets/automations-list-BYncC7gv.js +0 -1
  1207. package/build/assets/backend-form-modal-CKrBF80P.js +0 -1
  1208. package/build/assets/browser-3QjrEr1D.js +0 -6
  1209. package/build/assets/check-CrxQfJZ2.js +0 -1
  1210. package/build/assets/chevron-down-D_LsyTA7.js +0 -1
  1211. package/build/assets/circle-check-DZn9HkLE.js +0 -1
  1212. package/build/assets/cloud-funnel-analytics-NlmDoeo2.js +0 -1
  1213. package/build/assets/command-menu-CvLPs7dg.js +0 -1
  1214. package/build/assets/condenser-settings-C4Y9CzQV.js +0 -1
  1215. package/build/assets/context-menu-list-item-FGaafXGh.js +0 -1
  1216. package/build/assets/conversation-D_ORtpKC.js +0 -1
  1217. package/build/assets/conversation-Dpc5nmGi.js +0 -90
  1218. package/build/assets/conversation-panel-D_ORtpKC.js +0 -1
  1219. package/build/assets/conversation-state-store-CGRQemtx.js +0 -1
  1220. package/build/assets/entry.client-BO2KQj0y.js +0 -2
  1221. package/build/assets/enum-filter-dropdown-DSqPZnsD.js +0 -1
  1222. package/build/assets/files-tab-4c9HFSLo.js +0 -1
  1223. package/build/assets/format-time-delta-DICE64sz.js +0 -1
  1224. package/build/assets/git-provider-icon-0PqmIS_S.js +0 -1
  1225. package/build/assets/home-D9JsyEmE.js +0 -1
  1226. package/build/assets/home-TFhnmZLx.js +0 -1
  1227. package/build/assets/index-home-D9JsyEmE.js +0 -1
  1228. package/build/assets/install-server-modal-BgGRnqA0.js +0 -1
  1229. package/build/assets/llm-not-configured-banner-Y4W9-sar.js +0 -27
  1230. package/build/assets/llm-settings-nPwv7hKu.js +0 -1
  1231. package/build/assets/loader-circle-CGD6-Vak.js +0 -1
  1232. package/build/assets/manifest-1cf33a7b.js +0 -1
  1233. package/build/assets/markdown-renderer-U40HF0Ak.js +0 -8
  1234. package/build/assets/mcp-xDMaHzOw.js +0 -9
  1235. package/build/assets/messages-CdNfZPgd.js +0 -40
  1236. package/build/assets/navigation-link-Bxmn-pCs.js +0 -1
  1237. package/build/assets/onboarding-DWuFieEA.js +0 -1
  1238. package/build/assets/onboarding-modal-C8m72Dpb.js +0 -1
  1239. package/build/assets/plus-CTGLo3aa.js +0 -1
  1240. package/build/assets/recommended-automations-launcher-Dru1yN46.js +0 -58
  1241. package/build/assets/root-B5JXKp1P.css +0 -1
  1242. package/build/assets/root-DOLLQteU.js +0 -2
  1243. package/build/assets/root-layout-xmylWoew.js +0 -3
  1244. package/build/assets/search-BrpWXWUi.js +0 -1
  1245. package/build/assets/segmented-toggle-CZKOdIly.js +0 -1
  1246. package/build/assets/settings-Chfn5xTD.js +0 -1
  1247. package/build/assets/settings-input-BEaTCem1.js +0 -1
  1248. package/build/assets/settings-like-page-layout-classes-DyxyJ0k4.js +0 -1
  1249. package/build/assets/settings-service.api-CTJRrvMu.js +0 -1
  1250. package/build/assets/shared-conversation-BvWtTwES.js +0 -1
  1251. package/build/assets/sidebar-mobile-menu-toggle-xiKoUfGa.js +0 -1
  1252. package/build/assets/skills-settings-pUxMr6WZ.js +0 -2
  1253. package/build/assets/use-agent-profiles-DmT9zxAN.js +0 -1
  1254. package/build/assets/use-config-C959QcRC.js +0 -1
  1255. package/build/assets/use-is-authed-BsS4XwSL.js +0 -1
  1256. package/build/assets/use-llm-profiles-CdaxVpyY.js +0 -1
  1257. package/build/assets/use-save-agent-profile-DGJ3-u0M.js +0 -1
  1258. package/build/assets/use-settings-nav-items-DPK5sxvR.js +0 -16
  1259. package/build/assets/use-skills-D_mLhYNa.js +0 -1
  1260. package/build/assets/use-tracking-COqZLobY.js +0 -1
  1261. package/build/assets/useQuery-B38jBavx.js +0 -1
  1262. package/build/assets/utils-DsWhWn2F.js +0 -1
  1263. package/build/assets/v4-DDdyfk2q.js +0 -1
  1264. package/build/assets/vendor~browser-CIoZCqGs.js +0 -47
  1265. package/build/assets/vendor~entry.client-BfviqoVc.js +0 -1
  1266. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f1hl7voa-BrmgjeOw.js +0 -1
  1267. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f9xdmd0z-DLMP7bZx.js +0 -26
  1268. package/build/assets/vendor~module-BZXjBMvd.js +0 -2
  1269. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation-Acmf1sKj.js +0 -1
  1270. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-CmzCY1BT.js +0 -1
  1271. package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~onboarding-modal-C7Yh77RT.js +0 -1
  1272. package/build/assets/x-Dx_JbpHA.js +0 -1
  1273. package/dist/components/features/skills/skill-type-filter.d.ts +0 -3
  1274. package/dist/components/features/skills/skills-type-filter-dropdown.d.ts +0 -7
  1275. package/dist/node_modules/html-parse-stringify/dist/html-parse-stringify.module.cjs +0 -2
  1276. package/dist/node_modules/html-parse-stringify/dist/html-parse-stringify.module.cjs.map +0 -1
  1277. package/dist/node_modules/html-parse-stringify/dist/html-parse-stringify.module.js +0 -81
  1278. package/dist/node_modules/html-parse-stringify/dist/html-parse-stringify.module.js.map +0 -1
  1279. package/dist/node_modules/void-elements/index.cjs +0 -2
  1280. package/dist/node_modules/void-elements/index.cjs.map +0 -1
  1281. package/dist/node_modules/void-elements/index.js +0 -25
  1282. package/dist/node_modules/void-elements/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"chat-interface.js","names":[],"sources":["../../../../src/components/features/chat/chat-interface.tsx"],"sourcesContent":["import React from \"react\";\nimport { useNavigate } from \"react-router\";\nimport { useTracking } from \"#/hooks/use-tracking\";\nimport { useTranslation } from \"react-i18next\";\nimport { isAcpAuthErrorCode } from \"#/utils/acp-error-codes\";\nimport { convertImageToBase64 } from \"#/utils/convert-image-to-base-64\";\nimport { createChatMessage } from \"#/services/chat-service\";\nimport { BtwMessages } from \"./btw-messages\";\nimport { GoalStatusBanner } from \"./goal-status-banner\";\nimport { ModelMessages } from \"./model-messages\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { useGoalStore } from \"#/stores/goal-store\";\nimport { InteractiveChatBox } from \"./interactive-chat-box\";\nimport { AgentState } from \"#/types/agent-state\";\nimport { useFilteredEvents } from \"#/hooks/use-filtered-events\";\nimport { useScrollToBottom } from \"#/hooks/use-scroll-to-bottom\";\nimport { useLoadOlderEvents } from \"#/hooks/use-load-older-events\";\nimport { TypingIndicator } from \"./typing-indicator\";\nimport { ChatSuggestions } from \"./chat-suggestions\";\nimport { ScrollProvider } from \"#/context/scroll-context\";\nimport { useInitialQueryStore } from \"#/stores/initial-query-store\";\nimport { useSendMessage } from \"#/hooks/use-send-message\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\nimport { useIsArchivedConversation } from \"#/hooks/use-is-archived-conversation\";\nimport { useHandleBuildPlanClick } from \"#/hooks/use-handle-build-plan-click\";\n\nimport { ScrollToBottomButton } from \"#/components/shared/buttons/scroll-to-bottom-button\";\nimport { LoadingSpinner } from \"#/components/shared/loading-spinner\";\nimport { ChatMessagesSkeleton } from \"./chat-messages-skeleton\";\nimport { displayErrorToast } from \"#/utils/custom-toast-handlers\";\nimport { useErrorMessageStore } from \"#/stores/error-message-store\";\nimport { useOptimisticUserMessageStore } from \"#/stores/optimistic-user-message-store\";\nimport { SERVER_CONNECTION_ERROR_MESSAGE } from \"#/constants/server-connection-error\";\nimport { ErrorMessageBanner } from \"./error-message-banner\";\nimport { SkillInstallRestartBanner } from \"./skill-install-restart-banner\";\nimport { LlmNotConfiguredBanner } from \"#/components/features/home/llm-not-configured-banner\";\nimport { useLlmConfigured } from \"#/hooks/use-llm-configured\";\nimport { Messages } from \"#/components/conversation-events/chat/messages\";\nimport { PendingUserMessages } from \"./pending-user-messages\";\nimport { useUnifiedUploadFiles } from \"#/hooks/mutation/use-unified-upload-files\";\nimport { validateFiles } from \"#/utils/file-validation\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport ConfirmationModeEnabled from \"./confirmation-mode-enabled\";\nimport { useTaskPolling } from \"#/hooks/query/use-task-polling\";\nimport { matchesPendingConversationId } from \"#/utils/pending-task-message-link\";\nimport { useConversationWebSocket } from \"#/contexts/conversation-websocket-context\";\nimport ChatStatusIndicator from \"./chat-status-indicator\";\nimport { getStatusColor, getStatusText } from \"#/utils/utils\";\nimport { useNewConversationCommand } from \"#/hooks/mutation/use-new-conversation-command\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { hasConversationStarted } from \"./components/resolve-picker-kind\";\n\nfunction getEntryPoint(\n hasRepository: boolean | null,\n hasReplayJson: boolean | null,\n): string {\n if (hasRepository) return \"github\";\n if (hasReplayJson) return \"replay\";\n return \"direct\";\n}\n\nexport function ChatInterface() {\n const { trackInitialQuerySubmitted, trackUserMessageSent } = useTracking();\n const { setMessageToSend } = useConversationStore();\n const { errorMessage, errorCode, removeErrorMessage, setErrorMessage } =\n useErrorMessageStore();\n const navigate = useNavigate();\n const { isTask, taskStatus, taskDetail } = useTaskPolling();\n // Hide empty-state chrome for the entire `/conversations/task-{uuid}` route,\n // including the brief READY window before redirect completes.\n const isProvisioningTask = isTask;\n const conversationWebSocket = useConversationWebSocket();\n const { send } = useSendMessage();\n const {\n renderableEvents,\n allConversationEvents,\n totalEvents,\n hasSubstantiveAgentActions,\n userEventsExist,\n } = useFilteredEvents();\n const enqueuePendingMessage = useOptimisticUserMessageStore(\n (state) => state.enqueuePendingMessage,\n );\n const markPendingMessageError = useOptimisticUserMessageStore(\n (state) => state.markPendingMessageError,\n );\n const pendingMessages = useOptimisticUserMessageStore(\n (state) => state.pendingMessages,\n );\n const { t } = useTranslation(\"openhands\");\n const scrollRef = React.useRef<HTMLDivElement>(null);\n const {\n scrollDomToBottom,\n onChatBodyScroll,\n hitBottom,\n autoScroll,\n setAutoScroll,\n setHitBottom,\n } = useScrollToBottom(scrollRef);\n const {\n mutate: newConversationCommand,\n isPending: isNewConversationPending,\n } = useNewConversationCommand();\n\n const { curAgentState } = useAgentState();\n const { handleBuildPlanClick } = useHandleBuildPlanClick();\n\n // Cloud conversations whose sandbox is MISSING or ERROR are read-only:\n // the sandbox is gone and cannot be resumed, so we hide the chat input\n // and show an explanatory banner. For local backends sandbox_status is\n // always null, so this is effectively a no-op for non-cloud use.\n const { data: activeConversation } = useActiveConversation();\n const sandboxStatus = activeConversation?.sandbox_status ?? null;\n const isArchivedConversation = useIsArchivedConversation();\n\n // Block sending in a resumed conversation that has no usable LLM, and show\n // the same setup banner as the home screen so the dead end is explained.\n const { isConfigured: isLlmConfigured, isLoading: isLlmConfigLoading } =\n useLlmConfigured();\n const llmBlocked = !isLlmConfigLoading && !isLlmConfigured;\n\n // Disable Build button while agent is running (streaming)\n const isAgentRunning =\n curAgentState === AgentState.RUNNING ||\n curAgentState === AgentState.LOADING;\n\n // Global keyboard shortcut for Build button (Cmd+Enter / Ctrl+Enter)\n // This is placed here instead of PlanPreview to avoid duplicate listeners\n // when multiple PlanPreview components exist in the chat\n React.useEffect(() => {\n if (isAgentRunning) {\n return undefined;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n // Check for Cmd+Enter (Mac) or Ctrl+Enter (Windows/Linux)\n if ((event.metaKey || event.ctrlKey) && event.key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n handleBuildPlanClick(event);\n scrollDomToBottom();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [isAgentRunning, handleBuildPlanClick, scrollDomToBottom]);\n\n const { selectedRepository, replayJson } = useInitialQueryStore();\n const { conversationId } = useOptionalConversationId();\n\n // The live goal banner renders in the scroll stream but advances via store\n // updates (in-progress goal events are filtered out of `renderableEvents`),\n // so the bottom-following effect would not react to it. This key changes as\n // an active loop appears and advances each round; feeding it into that effect\n // keeps the banner in view when the user is pinned to the bottom.\n const activeGoalScrollKey = useGoalStore((s) => {\n const goal = conversationId\n ? s.statusByConversation[conversationId]\n : undefined;\n return goal?.active ? `${goal.iteration}:${goal.status}` : null;\n });\n const { mutateAsync: uploadFiles } = useUnifiedUploadFiles();\n\n // Lazy \"scroll up to load older events\" backfill. Initial REST fetch only\n // returns the most recent page; this hook paginates older events into the\n // store on demand so the chat doesn't load (potentially) thousands of\n // events on first render.\n const {\n isLoading: isLoadingOlderEvents,\n hasMore: hasMoreOlderEvents,\n loadOlder,\n } = useLoadOlderEvents(conversationId);\n\n // Trigger `loadOlder` and preserve the visual scroll position once the\n // older page is merged in (otherwise prepending events would jump the\n // chat far down). We fire from three places to cover the cases the\n // browser's scroll event misses:\n //\n // - `onScroll`: normal \"user scrolled near the top\" path.\n // - `onWheel`: user is already pinned at scrollTop=0 and tries to\n // wheel further up — no scroll event fires past 0.\n // - effect: content is shorter than the viewport (no scrollbar\n // at all), so the user has nothing to scroll. Re-runs\n // as more pages arrive until there's overflow or the\n // server runs out of older events.\n const SCROLL_TOP_THRESHOLD_PX = 80;\n const preserveScrollPosition = React.useRef<{\n scrollHeight: number;\n scrollTop: number;\n } | null>(null);\n const maybeLoadOlder = React.useCallback(\n (target: HTMLElement) => {\n if (isProvisioningTask || isLoadingOlderEvents || !hasMoreOlderEvents) {\n return;\n }\n\n const atTop = target.scrollTop <= SCROLL_TOP_THRESHOLD_PX;\n const noOverflow =\n target.scrollHeight <= target.clientHeight + SCROLL_TOP_THRESHOLD_PX;\n if (!atTop && !noOverflow) return;\n\n preserveScrollPosition.current = {\n scrollHeight: target.scrollHeight,\n scrollTop: target.scrollTop,\n };\n loadOlder().catch((error) => {\n preserveScrollPosition.current = null;\n const message =\n error instanceof Error && error.message\n ? error.message\n : t(I18nKey.ERROR$GENERIC);\n setErrorMessage(message);\n });\n },\n [\n hasMoreOlderEvents,\n isLoadingOlderEvents,\n isProvisioningTask,\n loadOlder,\n setErrorMessage,\n t,\n ],\n );\n\n const handleWheelForPagination = React.useCallback(\n (e: React.WheelEvent<HTMLDivElement>) => {\n // Browsers don't dispatch a scroll event when scrollTop is already\n // 0 and the user wheels upward, so onScroll alone misses this case.\n if (e.deltaY < 0 && e.currentTarget.scrollTop <= 0) {\n maybeLoadOlder(e.currentTarget);\n }\n },\n [maybeLoadOlder],\n );\n\n const hasPendingUserMessages = React.useMemo(\n () =>\n conversationId\n ? pendingMessages.some((message) =>\n matchesPendingConversationId(\n conversationId,\n message.conversationId,\n ),\n )\n : false,\n [pendingMessages, conversationId],\n );\n\n const hasModelEntries = useModelStore((s) =>\n conversationId\n ? (s.entriesByConversation[conversationId]?.length ?? 0) > 0\n : false,\n );\n const hasStartedConversation = hasConversationStarted({\n isLoadingHistory: conversationWebSocket?.isLoadingHistory === true,\n hasUserEvents: userEventsExist,\n hasPendingUserMessages,\n hasSubstantiveAgentActions,\n hasModelEntries,\n });\n\n // Show V1 messages immediately if events exist in store (e.g., remount),\n // if the user already has a locally-tracked pending bubble (home-page cloud\n // submit while history/WS catch up), or once loading completes. This\n // replaces the old transition-observation pattern (useState + useEffect\n // watching loading→loaded) which always showed skeleton on remount because\n // local state initialized to false.\n const showConversationMessages =\n allConversationEvents.length > 0 ||\n hasPendingUserMessages ||\n !conversationWebSocket?.isLoadingHistory;\n\n const isReturningToConversation = !!conversationId;\n // Only show loading skeleton when genuinely loading AND no events in store yet.\n // If events exist (e.g., remount after data was already fetched), skip skeleton.\n const isHistoryLoading = !showConversationMessages;\n const isChatLoading = isHistoryLoading && !isTask;\n\n const handleSendMessage = async (\n content: string,\n originalImages: File[],\n originalFiles: File[],\n ) => {\n // Handle /new command for V1 conversations\n if (content.trim() === \"/new\") {\n if (!conversationId) {\n displayErrorToast(t(I18nKey.CONVERSATION$CLEAR_NO_ID));\n return;\n }\n if (totalEvents === 0) {\n displayErrorToast(t(I18nKey.CONVERSATION$CLEAR_EMPTY));\n return;\n }\n if (isNewConversationPending) {\n return;\n }\n newConversationCommand();\n return;\n }\n\n // Create mutable copies of the arrays\n const images = [...originalImages];\n const files = [...originalFiles];\n if (totalEvents === 0) {\n trackInitialQuerySubmitted({\n entryPoint: getEntryPoint(\n selectedRepository !== null,\n replayJson !== null,\n ),\n queryCharacterLength: content.length,\n replayJsonSize: replayJson?.length,\n });\n } else {\n trackUserMessageSent({\n sessionMessageCount: totalEvents,\n currentMessageLength: content.length,\n });\n }\n\n // Validate file sizes before any processing\n const allFiles = [...images, ...files];\n const validation = validateFiles(allFiles);\n\n if (!validation.isValid) {\n displayErrorToast(`Error: ${validation.errorMessage}`);\n return; // Stop processing if validation fails\n }\n\n const promises = images.map((image) => convertImageToBase64(image));\n const imageUrls = await Promise.all(promises);\n\n const timestamp = new Date().toISOString();\n\n const { skipped_files: skippedFiles, uploaded_files: uploadedFiles } =\n files.length > 0\n ? await uploadFiles({ conversationId: conversationId!, files })\n : { skipped_files: [], uploaded_files: [] };\n\n skippedFiles.forEach((f) => displayErrorToast(f.reason));\n\n const filePrompt = `${t(I18nKey.CHAT_INTERFACE$AUGMENTED_PROMPT_FILES_TITLE)}: ${uploadedFiles.join(\"\\n\\n\")}`;\n const prompt =\n uploadedFiles.length > 0 ? `${content}\\n\\n${filePrompt}` : content;\n\n // Enqueue the message into the local pending queue with status \"sending\"\n // so the user immediately sees it in the chat with a faded treatment. The\n // entry is removed when the WebSocket echoes back the corresponding\n // `UserMessageEvent`. If the API call to send the message fails, the entry\n // is flipped to \"error\" with a retry link.\n const pendingId = enqueuePendingMessage({\n conversationId: conversationId!,\n // `text` is what the user sees in the bubble; `content` is what we\n // actually hand to the server (the prompt may include an appended\n // \"Files uploaded: …\" block) and is what the echo will be matched\n // against. They're different when there are file attachments.\n text: content,\n content: prompt,\n imageUrls,\n fileUrls: uploadedFiles,\n timestamp,\n });\n // Submitting a new prompt should always pull the chat back to the\n // latest message even if the user had scrolled up. This also re-arms\n // autoScroll so the streamed agent reply auto-follows.\n scrollDomToBottom();\n setMessageToSend(\"\");\n\n try {\n await send(\n createChatMessage(prompt, imageUrls, uploadedFiles, timestamp),\n );\n } catch (sendError) {\n const sendErrorMessage =\n sendError instanceof Error\n ? sendError.message\n : t(I18nKey.CHAT_INTERFACE$FAILED_TO_SEND_MESSAGE);\n markPendingMessageError(pendingId, sendErrorMessage);\n }\n };\n\n // Auto-scroll to bottom when new messages arrive — but only if the user is\n // already pinned to the bottom. Scrolling up to load older events also\n // grows `renderableEvents`, and we don't want to yank the user back to the\n // bottom in that case.\n React.useEffect(() => {\n // If a \"load older\" was just triggered, restore the scroll position so\n // the conversation appears to extend upward instead of jumping.\n if (preserveScrollPosition.current && scrollRef.current) {\n const { scrollHeight: prevHeight, scrollTop: prevTop } =\n preserveScrollPosition.current;\n const dom = scrollRef.current;\n const delta = dom.scrollHeight - prevHeight;\n if (delta > 0) {\n dom.scrollTop = prevTop + delta;\n }\n preserveScrollPosition.current = null;\n return;\n }\n\n if (autoScroll) {\n scrollDomToBottom();\n }\n // Note: We intentionally exclude autoScroll from deps because we only want\n // to scroll when message content changes, not when autoScroll state changes.\n }, [\n renderableEvents.length,\n hasPendingUserMessages,\n activeGoalScrollKey,\n scrollDomToBottom,\n ]);\n\n // Auto-load older events when the chat content doesn't overflow the\n // scroll area (no scrollbar to drag, no wheel events past 0). We\n // re-run only when the rendered list grows or `hasMore` flips, NOT\n // when `maybeLoadOlder` re-creates: the underlying hook's `loadOlder`\n // ref changes whenever its internal `isLoading` toggles, so depending\n // on `maybeLoadOlder` would re-fire the effect on every failed page\n // and tight-loop until the server recovered. Driving off\n // `renderableEvents.length` instead means a successful page (events\n // grow) chains the next request, while a failed page (events\n // unchanged) waits for the user to retry.\n const maybeLoadOlderRef = React.useRef(maybeLoadOlder);\n React.useEffect(() => {\n maybeLoadOlderRef.current = maybeLoadOlder;\n });\n React.useEffect(() => {\n const target = scrollRef.current;\n if (!target) return;\n maybeLoadOlderRef.current(target);\n }, [renderableEvents.length, hasMoreOlderEvents]);\n\n // Create a ScrollProvider with the scroll hook values\n const scrollProviderValue = {\n scrollRef,\n autoScroll,\n setAutoScroll,\n scrollDomToBottom,\n hitBottom,\n setHitBottom,\n onChatBodyScroll,\n };\n\n // Get server status indicator props\n const isStartingStatus =\n curAgentState === AgentState.LOADING || curAgentState === AgentState.INIT;\n const isStopStatus = curAgentState === AgentState.STOPPED;\n const isPausing = curAgentState === AgentState.PAUSED;\n const serverStatusColor = getStatusColor({\n isPausing,\n isTask,\n taskStatus,\n isStartingStatus,\n isStopStatus,\n curAgentState,\n });\n const serverStatusText = getStatusText({\n isPausing,\n isTask,\n taskStatus,\n taskDetail,\n isStartingStatus,\n isStopStatus,\n curAgentState,\n errorMessage,\n t,\n });\n\n return (\n <ScrollProvider value={scrollProviderValue}>\n <div\n className=\"relative flex h-full flex-col justify-between px-4\"\n data-testid=\"chat-interface\"\n >\n {!hasSubstantiveAgentActions &&\n !hasPendingUserMessages &&\n !userEventsExist &&\n !hasModelEntries &&\n !isChatLoading &&\n !isProvisioningTask &&\n totalEvents === 0 &&\n !isArchivedConversation &&\n // With no usable LLM the suggestions can't be acted on (the input is\n // disabled). They're also a `pointer-events-auto` overlay that would\n // sit over the LlmNotConfiguredBanner below and swallow clicks on its\n // setup button — so hide them and let the banner be the lone CTA.\n !llmBlocked && (\n <ChatSuggestions\n onSuggestionsClick={(message) => setMessageToSend(message)}\n />\n )}\n {/* Note: We only hide chat suggestions when there's a user message */}\n\n <div\n ref={scrollRef}\n data-testid=\"chat-scroll-container\"\n onScroll={(e) => {\n onChatBodyScroll(e.currentTarget);\n maybeLoadOlder(e.currentTarget);\n }}\n onWheel={handleWheelForPagination}\n 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\"\n >\n {isChatLoading && isReturningToConversation && (\n <ChatMessagesSkeleton />\n )}\n\n {isChatLoading && !isReturningToConversation && (\n <div className=\"flex justify-center\" data-testid=\"loading-spinner\">\n <LoadingSpinner size=\"small\" />\n </div>\n )}\n\n {isLoadingOlderEvents && (\n <div\n className=\"flex items-center justify-center gap-2 py-3 text-sm text-neutral-400\"\n data-testid=\"loading-older-events\"\n >\n <LoadingSpinner size=\"small\" />\n <span>{t(I18nKey.CHAT_INTERFACE$FETCHING_OLDER_MESSAGES)}</span>\n </div>\n )}\n\n {/*\n * Render whenever there's anything to display. Previously this\n * was gated on `conversationUserEventsExist`, but with the lazy\n * \"50 most recent\" REST fetch the initial window may not include\n * any `source: \"user\"` events (long agent runs between user\n * turns). That left the chat blank, leaving the user nothing to\n * scroll — which is why \"scroll up to load older\" appeared\n * broken. The empty-state ChatSuggestions block above still\n * keeps its own gate (`!userEventsExist && !hasSubstantiveAgentActions`)\n * so brand-new conversations show suggestions, not an empty chat.\n */}\n {/* /model entries created before any event is rendered are\n anchored to `null` and live above the message list. */}\n <ModelMessages conversationId={conversationId} anchorEventId={null} />\n\n {showConversationMessages && renderableEvents.length > 0 && (\n <Messages\n messages={renderableEvents}\n allEvents={allConversationEvents}\n />\n )}\n\n {/*\n Render the local pending-message queue independently so messages\n the user just submitted show up immediately (with a faded \"sending\"\n treatment) even before any real conversation event has come back\n from the server. Entries drain (FIFO) when the matching\n UserMessageEvent echoes back over the WebSocket, so this never\n double-renders alongside the real event list.\n */}\n <PendingUserMessages />\n\n {/* Goal-loop status sits at the end of the message flow — above the\n composer and its typing indicator — so progress stays in view. */}\n <GoalStatusBanner conversationId={conversationId} />\n </div>\n\n <div className=\"flex shrink-0 flex-col gap-[6px] pb-4\">\n <SkillInstallRestartBanner conversationId={conversationId} />\n <BtwMessages conversationId={conversationId} />\n {errorMessage && (\n <ErrorMessageBanner\n message={errorMessage}\n code={errorCode}\n onDismiss={removeErrorMessage}\n onRetry={\n errorMessage === SERVER_CONNECTION_ERROR_MESSAGE\n ? () => conversationWebSocket?.reconnect()\n : undefined\n }\n onReauth={\n isAcpAuthErrorCode(errorCode)\n ? () => navigate(\"/settings/agents\")\n : undefined\n }\n />\n )}\n\n {llmBlocked && !isArchivedConversation && <LlmNotConfiguredBanner />}\n\n {isArchivedConversation ? (\n // Archived / sandbox-error: show a read-only notice in place of\n // the chat input. The conversation history above is still visible.\n <div\n data-testid=\"archived-conversation-banner\"\n className=\"mx-1 px-4 py-3 rounded-lg bg-[var(--oh-surface)] border border-[var(--oh-border-subtle)]\"\n >\n <p className=\"text-xs font-semibold text-[var(--oh-foreground)]\">\n {sandboxStatus === \"ERROR\"\n ? t(I18nKey.CHAT_INTERFACE$ERROR_SANDBOX_TITLE)\n : t(I18nKey.CHAT_INTERFACE$ARCHIVED_SANDBOX_TITLE)}\n </p>\n <p className=\"text-xs text-[var(--oh-muted)] mt-0.5\">\n {sandboxStatus === \"ERROR\"\n ? t(I18nKey.CHAT_INTERFACE$ERROR_SANDBOX_DESCRIPTION)\n : t(I18nKey.CHAT_INTERFACE$ARCHIVED_SANDBOX_DESCRIPTION)}\n </p>\n </div>\n ) : (\n <div className=\"relative\">\n <div className=\"pointer-events-none absolute inset-x-0 bottom-full mb-1 z-20\">\n <div className=\"flex justify-between relative\">\n <div className=\"flex items-end gap-1 pointer-events-auto\">\n <ConfirmationModeEnabled />\n {isStartingStatus && (\n <ChatStatusIndicator\n statusColor={serverStatusColor}\n status={serverStatusText}\n />\n )}\n </div>\n\n {!hitBottom ? (\n <div className=\"absolute left-1/2 transform -translate-x-1/2 bottom-0 pointer-events-auto\">\n <ScrollToBottomButton onClick={scrollDomToBottom} />\n </div>\n ) : (\n curAgentState === AgentState.RUNNING && (\n <div className=\"absolute left-1/2 transform -translate-x-1/2 bottom-0 pointer-events-auto\">\n <TypingIndicator />\n </div>\n )\n )}\n </div>\n </div>\n\n <InteractiveChatBox\n onSubmit={handleSendMessage}\n disabled={isNewConversationPending || llmBlocked}\n hasStartedConversation={hasStartedConversation}\n />\n </div>\n )}\n </div>\n </div>\n </ScrollProvider>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"chat-interface.js","names":[],"sources":["../../../../src/components/features/chat/chat-interface.tsx"],"sourcesContent":["import React from \"react\";\nimport { useNavigate } from \"react-router\";\nimport { useTracking } from \"#/hooks/use-tracking\";\nimport { useTranslation } from \"react-i18next\";\nimport { isAcpAuthErrorCode } from \"#/utils/acp-error-codes\";\nimport { convertImageToBase64 } from \"#/utils/convert-image-to-base-64\";\nimport { createChatMessage } from \"#/services/chat-service\";\nimport { BtwMessages } from \"./btw-messages\";\nimport { GoalStatusBanner } from \"./goal-status-banner\";\nimport { ModelMessages } from \"./model-messages\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { useGoalStore } from \"#/stores/goal-store\";\nimport { InteractiveChatBox } from \"./interactive-chat-box\";\nimport { AgentState } from \"#/types/agent-state\";\nimport { useFilteredEvents } from \"#/hooks/use-filtered-events\";\nimport { useScrollToBottom } from \"#/hooks/use-scroll-to-bottom\";\nimport { useLoadOlderEvents } from \"#/hooks/use-load-older-events\";\nimport { TypingIndicator } from \"./typing-indicator\";\nimport { ChatSuggestions } from \"./chat-suggestions\";\nimport { ScrollProvider } from \"#/context/scroll-context\";\nimport { useInitialQueryStore } from \"#/stores/initial-query-store\";\nimport { useSendMessage } from \"#/hooks/use-send-message\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\nimport { useIsArchivedConversation } from \"#/hooks/use-is-archived-conversation\";\nimport { useHandleBuildPlanClick } from \"#/hooks/use-handle-build-plan-click\";\n\nimport { ScrollToBottomButton } from \"#/components/shared/buttons/scroll-to-bottom-button\";\nimport { LoadingSpinner } from \"#/components/shared/loading-spinner\";\nimport { ChatMessagesSkeleton } from \"./chat-messages-skeleton\";\nimport { displayErrorToast } from \"#/utils/custom-toast-handlers\";\nimport { useErrorMessageStore } from \"#/stores/error-message-store\";\nimport { useOptimisticUserMessageStore } from \"#/stores/optimistic-user-message-store\";\nimport { SERVER_CONNECTION_ERROR_MESSAGE } from \"#/constants/server-connection-error\";\nimport { ErrorMessageBanner } from \"./error-message-banner\";\nimport { SkillInstallRestartBanner } from \"./skill-install-restart-banner\";\nimport { LlmNotConfiguredBanner } from \"#/components/features/home/llm-not-configured-banner\";\nimport { useLlmConfigured } from \"#/hooks/use-llm-configured\";\nimport { Messages } from \"#/components/conversation-events/chat/messages\";\nimport { PendingUserMessages } from \"./pending-user-messages\";\nimport { useUnifiedUploadFiles } from \"#/hooks/mutation/use-unified-upload-files\";\nimport { validateFiles } from \"#/utils/file-validation\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport ConfirmationModeEnabled from \"./confirmation-mode-enabled\";\nimport { useTaskPolling } from \"#/hooks/query/use-task-polling\";\nimport { matchesPendingConversationId } from \"#/utils/pending-task-message-link\";\nimport { useConversationWebSocket } from \"#/contexts/conversation-websocket-context\";\nimport ChatStatusIndicator from \"./chat-status-indicator\";\nimport { getStatusColor, getStatusText } from \"#/utils/utils\";\nimport { useNewConversationCommand } from \"#/hooks/mutation/use-new-conversation-command\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { hasConversationStarted } from \"./components/resolve-picker-kind\";\n\nfunction getEntryPoint(\n hasRepository: boolean | null,\n hasReplayJson: boolean | null,\n): string {\n if (hasRepository) return \"github\";\n if (hasReplayJson) return \"replay\";\n return \"direct\";\n}\n\nexport function ChatInterface() {\n const { trackInitialQuerySubmitted, trackUserMessageSent } = useTracking();\n const { setMessageToSend } = useConversationStore();\n const { errorMessage, errorCode, removeErrorMessage, setErrorMessage } =\n useErrorMessageStore();\n const navigate = useNavigate();\n const { isTask, taskStatus, taskDetail } = useTaskPolling();\n // Hide empty-state chrome for the entire `/conversations/task-{uuid}` route,\n // including the brief READY window before redirect completes.\n const isProvisioningTask = isTask;\n const conversationWebSocket = useConversationWebSocket();\n const { send } = useSendMessage();\n const {\n renderableEvents,\n allConversationEvents,\n totalEvents,\n hasSubstantiveAgentActions,\n userEventsExist,\n } = useFilteredEvents();\n const enqueuePendingMessage = useOptimisticUserMessageStore(\n (state) => state.enqueuePendingMessage,\n );\n const markPendingMessageError = useOptimisticUserMessageStore(\n (state) => state.markPendingMessageError,\n );\n const pendingMessages = useOptimisticUserMessageStore(\n (state) => state.pendingMessages,\n );\n const { t } = useTranslation(\"openhands\");\n const scrollRef = React.useRef<HTMLDivElement>(null);\n const {\n scrollDomToBottom,\n onChatBodyScroll,\n hitBottom,\n autoScroll,\n setAutoScroll,\n setHitBottom,\n } = useScrollToBottom(scrollRef);\n const {\n mutate: newConversationCommand,\n isPending: isNewConversationPending,\n } = useNewConversationCommand();\n\n const { curAgentState } = useAgentState();\n const { handleBuildPlanClick } = useHandleBuildPlanClick();\n\n // Cloud conversations whose sandbox is MISSING or ERROR are read-only:\n // the sandbox is gone and cannot be resumed, so we hide the chat input\n // and show an explanatory banner. For local backends sandbox_status is\n // always null, so this is effectively a no-op for non-cloud use.\n const { data: activeConversation } = useActiveConversation();\n const sandboxStatus = activeConversation?.sandbox_status ?? null;\n const isArchivedConversation = useIsArchivedConversation();\n\n // Block sending in a resumed conversation that has no usable LLM, and show\n // the same setup banner as the home screen so the dead end is explained.\n const { isConfigured: isLlmConfigured, isLoading: isLlmConfigLoading } =\n useLlmConfigured();\n const llmBlocked = !isLlmConfigLoading && !isLlmConfigured;\n\n // Disable Build button while agent is running (streaming)\n const isAgentRunning =\n curAgentState === AgentState.RUNNING ||\n curAgentState === AgentState.LOADING;\n\n // Global keyboard shortcut for Build button (Cmd+Enter / Ctrl+Enter)\n // This is placed here instead of PlanPreview to avoid duplicate listeners\n // when multiple PlanPreview components exist in the chat\n React.useEffect(() => {\n if (isAgentRunning) {\n return undefined;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n // Check for Cmd+Enter (Mac) or Ctrl+Enter (Windows/Linux)\n if ((event.metaKey || event.ctrlKey) && event.key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n handleBuildPlanClick(event);\n scrollDomToBottom();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [isAgentRunning, handleBuildPlanClick, scrollDomToBottom]);\n\n const { selectedRepository, replayJson } = useInitialQueryStore();\n const { conversationId } = useOptionalConversationId();\n\n // The live goal banner renders in the scroll stream but advances via store\n // updates (in-progress goal events are filtered out of `renderableEvents`),\n // so the bottom-following effect would not react to it. This key changes as\n // an active loop appears and advances each round; feeding it into that effect\n // keeps the banner in view when the user is pinned to the bottom.\n const activeGoalScrollKey = useGoalStore((s) => {\n const goal = conversationId\n ? s.statusByConversation[conversationId]\n : undefined;\n return goal?.active ? `${goal.iteration}:${goal.status}` : null;\n });\n const { mutateAsync: uploadFiles } = useUnifiedUploadFiles();\n\n // Lazy \"scroll up to load older events\" backfill. Initial REST fetch only\n // returns the most recent page; this hook paginates older events into the\n // store on demand so the chat doesn't load (potentially) thousands of\n // events on first render.\n const {\n isLoading: isLoadingOlderEvents,\n hasMore: hasMoreOlderEvents,\n loadOlder,\n } = useLoadOlderEvents(conversationId);\n\n // Trigger `loadOlder` and preserve the visual scroll position once the\n // older page is merged in (otherwise prepending events would jump the\n // chat far down). We fire from three places to cover the cases the\n // browser's scroll event misses:\n //\n // - `onScroll`: normal \"user scrolled near the top\" path.\n // - `onWheel`: user is already pinned at scrollTop=0 and tries to\n // wheel further up — no scroll event fires past 0.\n // - effect: content is shorter than the viewport (no scrollbar\n // at all), so the user has nothing to scroll. Re-runs\n // as more pages arrive until there's overflow or the\n // server runs out of older events.\n const SCROLL_TOP_THRESHOLD_PX = 80;\n const preserveScrollPosition = React.useRef<{\n scrollHeight: number;\n scrollTop: number;\n } | null>(null);\n const maybeLoadOlder = React.useCallback(\n (target: HTMLElement) => {\n if (isProvisioningTask || isLoadingOlderEvents || !hasMoreOlderEvents) {\n return;\n }\n\n const atTop = target.scrollTop <= SCROLL_TOP_THRESHOLD_PX;\n const noOverflow =\n target.scrollHeight <= target.clientHeight + SCROLL_TOP_THRESHOLD_PX;\n if (!atTop && !noOverflow) return;\n\n preserveScrollPosition.current = {\n scrollHeight: target.scrollHeight,\n scrollTop: target.scrollTop,\n };\n loadOlder().catch((error) => {\n preserveScrollPosition.current = null;\n const message =\n error instanceof Error && error.message\n ? error.message\n : t(I18nKey.ERROR$GENERIC);\n setErrorMessage(message);\n });\n },\n [\n hasMoreOlderEvents,\n isLoadingOlderEvents,\n isProvisioningTask,\n loadOlder,\n setErrorMessage,\n t,\n ],\n );\n\n const handleWheelForPagination = React.useCallback(\n (e: React.WheelEvent<HTMLDivElement>) => {\n // Browsers don't dispatch a scroll event when scrollTop is already\n // 0 and the user wheels upward, so onScroll alone misses this case.\n if (e.deltaY < 0 && e.currentTarget.scrollTop <= 0) {\n maybeLoadOlder(e.currentTarget);\n }\n },\n [maybeLoadOlder],\n );\n\n const hasPendingUserMessages = React.useMemo(\n () =>\n conversationId\n ? pendingMessages.some((message) =>\n matchesPendingConversationId(\n conversationId,\n message.conversationId,\n ),\n )\n : false,\n [pendingMessages, conversationId],\n );\n\n const hasModelEntries = useModelStore((s) =>\n conversationId\n ? (s.entriesByConversation[conversationId]?.length ?? 0) > 0\n : false,\n );\n const hasStartedConversation = hasConversationStarted({\n isLoadingHistory: conversationWebSocket?.isLoadingHistory === true,\n hasUserEvents: userEventsExist,\n hasPendingUserMessages,\n hasSubstantiveAgentActions,\n hasModelEntries,\n });\n\n // Show V1 messages immediately if events exist in store (e.g., remount),\n // if the user already has a locally-tracked pending bubble (home-page cloud\n // submit while history/WS catch up), or once loading completes. This\n // replaces the old transition-observation pattern (useState + useEffect\n // watching loading→loaded) which always showed skeleton on remount because\n // local state initialized to false.\n const showConversationMessages =\n allConversationEvents.length > 0 ||\n hasPendingUserMessages ||\n !conversationWebSocket?.isLoadingHistory;\n\n const isReturningToConversation = !!conversationId;\n // Only show loading skeleton when genuinely loading AND no events in store yet.\n // If events exist (e.g., remount after data was already fetched), skip skeleton.\n const isHistoryLoading = !showConversationMessages;\n const isChatLoading = isHistoryLoading && !isTask;\n\n const handleSendMessage = async (\n content: string,\n originalImages: File[],\n originalFiles: File[],\n ) => {\n // Handle /new command for V1 conversations\n if (content.trim() === \"/new\") {\n if (!conversationId) {\n displayErrorToast(t(I18nKey.CONVERSATION$CLEAR_NO_ID));\n return;\n }\n if (totalEvents === 0) {\n displayErrorToast(t(I18nKey.CONVERSATION$CLEAR_EMPTY));\n return;\n }\n if (isNewConversationPending) {\n return;\n }\n newConversationCommand();\n return;\n }\n\n // Create mutable copies of the arrays\n const images = [...originalImages];\n const files = [...originalFiles];\n if (totalEvents === 0) {\n trackInitialQuerySubmitted({\n entryPoint: getEntryPoint(\n selectedRepository !== null,\n replayJson !== null,\n ),\n queryCharacterLength: content.length,\n replayJsonSize: replayJson?.length,\n });\n } else {\n trackUserMessageSent({\n sessionMessageCount: totalEvents,\n currentMessageLength: content.length,\n });\n }\n\n // Validate file sizes before any processing\n const allFiles = [...images, ...files];\n const validation = validateFiles(allFiles);\n\n if (!validation.isValid) {\n displayErrorToast(`Error: ${validation.errorMessage}`);\n return; // Stop processing if validation fails\n }\n\n const promises = images.map((image) => convertImageToBase64(image));\n const imageUrls = await Promise.all(promises);\n\n const timestamp = new Date().toISOString();\n\n const { skipped_files: skippedFiles, uploaded_files: uploadedFiles } =\n files.length > 0\n ? await uploadFiles({ conversationId: conversationId!, files })\n : { skipped_files: [], uploaded_files: [] };\n\n skippedFiles.forEach((f) => displayErrorToast(f.reason));\n\n const filePrompt = `${t(I18nKey.CHAT_INTERFACE$AUGMENTED_PROMPT_FILES_TITLE)}: ${uploadedFiles.join(\"\\n\\n\")}`;\n const prompt =\n uploadedFiles.length > 0 ? `${content}\\n\\n${filePrompt}` : content;\n\n // Enqueue the message into the local pending queue with status \"sending\"\n // so the user immediately sees it in the chat with a faded treatment. The\n // entry is removed when the WebSocket echoes back the corresponding\n // `UserMessageEvent`. If the API call to send the message fails, the entry\n // is flipped to \"error\" with a retry link.\n const pendingId = enqueuePendingMessage({\n conversationId: conversationId!,\n // `text` is what the user sees in the bubble; `content` is what we\n // actually hand to the server (the prompt may include an appended\n // \"Files uploaded: …\" block) and is what the echo will be matched\n // against. They're different when there are file attachments.\n text: content,\n content: prompt,\n imageUrls,\n fileUrls: uploadedFiles,\n timestamp,\n });\n // Submitting a new prompt should always pull the chat back to the\n // latest message even if the user had scrolled up. This also re-arms\n // autoScroll so the streamed agent reply auto-follows.\n scrollDomToBottom();\n setMessageToSend(\"\");\n\n try {\n await send(\n createChatMessage(prompt, imageUrls, uploadedFiles, timestamp),\n );\n } catch (sendError) {\n const sendErrorMessage =\n sendError instanceof Error\n ? sendError.message\n : t(I18nKey.CHAT_INTERFACE$FAILED_TO_SEND_MESSAGE);\n markPendingMessageError(pendingId, sendErrorMessage);\n }\n };\n\n // Auto-scroll to bottom when new messages arrive — but only if the user is\n // already pinned to the bottom. Scrolling up to load older events also\n // grows `renderableEvents`, and we don't want to yank the user back to the\n // bottom in that case.\n React.useEffect(() => {\n // If a \"load older\" was just triggered, restore the scroll position so\n // the conversation appears to extend upward instead of jumping.\n if (preserveScrollPosition.current && scrollRef.current) {\n const { scrollHeight: prevHeight, scrollTop: prevTop } =\n preserveScrollPosition.current;\n const dom = scrollRef.current;\n const delta = dom.scrollHeight - prevHeight;\n if (delta > 0) {\n dom.scrollTop = prevTop + delta;\n }\n preserveScrollPosition.current = null;\n return;\n }\n\n if (autoScroll) {\n scrollDomToBottom();\n }\n // Note: We intentionally exclude autoScroll from deps because we only want\n // to scroll when message content changes, not when autoScroll state changes.\n }, [\n renderableEvents.length,\n hasPendingUserMessages,\n activeGoalScrollKey,\n scrollDomToBottom,\n ]);\n\n // Auto-load older events when the chat content doesn't overflow the\n // scroll area (no scrollbar to drag, no wheel events past 0). We\n // re-run only when the rendered list grows or `hasMore` flips, NOT\n // when `maybeLoadOlder` re-creates: the underlying hook's `loadOlder`\n // ref changes whenever its internal `isLoading` toggles, so depending\n // on `maybeLoadOlder` would re-fire the effect on every failed page\n // and tight-loop until the server recovered. Driving off\n // `renderableEvents.length` instead means a successful page (events\n // grow) chains the next request, while a failed page (events\n // unchanged) waits for the user to retry.\n const maybeLoadOlderRef = React.useRef(maybeLoadOlder);\n React.useEffect(() => {\n maybeLoadOlderRef.current = maybeLoadOlder;\n });\n React.useEffect(() => {\n const target = scrollRef.current;\n if (!target) return;\n maybeLoadOlderRef.current(target);\n }, [renderableEvents.length, hasMoreOlderEvents]);\n\n // Create a ScrollProvider with the scroll hook values\n const scrollProviderValue = {\n scrollRef,\n autoScroll,\n setAutoScroll,\n scrollDomToBottom,\n hitBottom,\n setHitBottom,\n onChatBodyScroll,\n };\n\n // Get server status indicator props\n const isStartingStatus =\n curAgentState === AgentState.LOADING || curAgentState === AgentState.INIT;\n const isStopStatus = curAgentState === AgentState.STOPPED;\n const isPausing = curAgentState === AgentState.PAUSED;\n const serverStatusColor = getStatusColor({\n isPausing,\n isTask,\n taskStatus,\n isStartingStatus,\n isStopStatus,\n curAgentState,\n });\n const serverStatusText = getStatusText({\n isPausing,\n isTask,\n taskStatus,\n taskDetail,\n isStartingStatus,\n isStopStatus,\n curAgentState,\n errorMessage,\n t,\n });\n\n return (\n <ScrollProvider value={scrollProviderValue}>\n <div\n className=\"relative flex h-full flex-col justify-between px-4\"\n data-testid=\"chat-interface\"\n >\n {!hasSubstantiveAgentActions &&\n !hasPendingUserMessages &&\n !userEventsExist &&\n !hasModelEntries &&\n !isChatLoading &&\n !isProvisioningTask &&\n totalEvents === 0 &&\n !isArchivedConversation &&\n // With no usable LLM the suggestions can't be acted on (the input is\n // disabled). They're also a `pointer-events-auto` overlay that would\n // sit over the LlmNotConfiguredBanner below and swallow clicks on its\n // setup button — so hide them and let the banner be the lone CTA.\n !llmBlocked && (\n <ChatSuggestions\n onSuggestionsClick={(message) => setMessageToSend(message)}\n />\n )}\n {/* Note: We only hide chat suggestions when there's a user message */}\n\n <div\n ref={scrollRef}\n data-testid=\"chat-scroll-container\"\n onScroll={(e) => {\n onChatBodyScroll(e.currentTarget);\n maybeLoadOlder(e.currentTarget);\n }}\n onWheel={handleWheelForPagination}\n 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\"\n >\n {isChatLoading && isReturningToConversation && (\n <ChatMessagesSkeleton />\n )}\n\n {isChatLoading && !isReturningToConversation && (\n <div className=\"flex justify-center\" data-testid=\"loading-spinner\">\n <LoadingSpinner size=\"small\" />\n </div>\n )}\n\n {isLoadingOlderEvents && (\n <div\n className=\"flex items-center justify-center gap-2 py-3 text-sm text-neutral-400\"\n data-testid=\"loading-older-events\"\n >\n <LoadingSpinner size=\"small\" />\n <span>{t(I18nKey.CHAT_INTERFACE$FETCHING_OLDER_MESSAGES)}</span>\n </div>\n )}\n\n {/*\n * Render whenever there's anything to display. Previously this\n * was gated on `conversationUserEventsExist`, but with the lazy\n * \"50 most recent\" REST fetch the initial window may not include\n * any `source: \"user\"` events (long agent runs between user\n * turns). That left the chat blank, leaving the user nothing to\n * scroll — which is why \"scroll up to load older\" appeared\n * broken. The empty-state ChatSuggestions block above still\n * keeps its own gate (`!userEventsExist && !hasSubstantiveAgentActions`)\n * so brand-new conversations show suggestions, not an empty chat.\n */}\n {/* /model entries created before any event is rendered are\n anchored to `null` and live above the message list. */}\n <ModelMessages conversationId={conversationId} anchorEventId={null} />\n\n {showConversationMessages && renderableEvents.length > 0 && (\n <Messages\n messages={renderableEvents}\n allEvents={allConversationEvents}\n />\n )}\n\n {/*\n Render the local pending-message queue independently so messages\n the user just submitted show up immediately (with a faded \"sending\"\n treatment) even before any real conversation event has come back\n from the server. Entries drain (FIFO) when the matching\n UserMessageEvent echoes back over the WebSocket, so this never\n double-renders alongside the real event list.\n */}\n <PendingUserMessages />\n\n {/* Goal-loop status sits at the end of the message flow — above the\n composer and its typing indicator — so progress stays in view. */}\n <GoalStatusBanner conversationId={conversationId} />\n </div>\n\n <div className=\"flex shrink-0 flex-col gap-[6px] pb-4\">\n <SkillInstallRestartBanner conversationId={conversationId} />\n <BtwMessages conversationId={conversationId} />\n {errorMessage && (\n <ErrorMessageBanner\n message={errorMessage}\n code={errorCode}\n onDismiss={removeErrorMessage}\n onRetry={\n errorMessage === SERVER_CONNECTION_ERROR_MESSAGE\n ? () => conversationWebSocket?.reconnect()\n : undefined\n }\n onReauth={\n isAcpAuthErrorCode(errorCode)\n ? () => navigate(\"/settings/agents\")\n : undefined\n }\n />\n )}\n\n {llmBlocked && !isArchivedConversation && <LlmNotConfiguredBanner />}\n\n {isArchivedConversation ? (\n // Archived / sandbox-error: show a read-only notice in place of\n // the chat input. The conversation history above is still visible.\n <div\n data-testid=\"archived-conversation-banner\"\n className=\"mx-1 px-4 py-3 rounded-lg bg-[var(--oh-surface)] border border-[var(--oh-border-subtle)]\"\n >\n <p className=\"text-xs font-semibold text-[var(--oh-foreground)]\">\n {sandboxStatus === \"ERROR\"\n ? t(I18nKey.CHAT_INTERFACE$ERROR_SANDBOX_TITLE)\n : t(I18nKey.CHAT_INTERFACE$ARCHIVED_SANDBOX_TITLE)}\n </p>\n <p className=\"text-xs text-[var(--oh-muted)] mt-0.5\">\n {sandboxStatus === \"ERROR\"\n ? t(I18nKey.CHAT_INTERFACE$ERROR_SANDBOX_DESCRIPTION)\n : t(I18nKey.CHAT_INTERFACE$ARCHIVED_SANDBOX_DESCRIPTION)}\n </p>\n </div>\n ) : (\n <div className=\"relative\">\n <div className=\"pointer-events-none absolute inset-x-0 bottom-full mb-1 z-20\">\n <div className=\"flex justify-between relative\">\n <div className=\"flex items-end gap-1 pointer-events-auto\">\n <ConfirmationModeEnabled />\n {isStartingStatus && (\n <ChatStatusIndicator\n statusColor={serverStatusColor}\n status={serverStatusText}\n />\n )}\n </div>\n\n {!hitBottom ? (\n <div className=\"absolute left-1/2 transform -translate-x-1/2 bottom-0 pointer-events-auto\">\n <ScrollToBottomButton onClick={scrollDomToBottom} />\n </div>\n ) : (\n curAgentState === AgentState.RUNNING && (\n <div className=\"pointer-events-none absolute inset-x-9 bottom-0 flex justify-center\">\n <TypingIndicator events={allConversationEvents} />\n </div>\n )\n )}\n </div>\n </div>\n\n <InteractiveChatBox\n onSubmit={handleSendMessage}\n disabled={isNewConversationPending || llmBlocked}\n hasStartedConversation={hasStartedConversation}\n />\n </div>\n )}\n </div>\n </div>\n </ScrollProvider>\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("../../../utils/utils.cjs"),i=require("../../shared/buttons/copy-to-clipboard-button.cjs"),a=require("../markdown/markdown-renderer.cjs"),o=require("../../shared/buttons/styled-tooltip.cjs"),s=require("../../shared/text-shimmer.cjs"),c=require("./pending-stop-icon.cjs"),l=require("./user-message-body.cjs");let u=require("react");u=e.__toESM(u,1);let d=require("react/jsx-runtime");function f({type:e,message:f,children:p,actions:m,isFromPlanningAgent:h=!1,pendingStatus:g,onRetry:_,onStop:v}){let{t:y}=t.useTranslation(`openhands`),[b,x]=u.default.useState(!1),[S,C]=u.default.useState(!1),[w,T]=u.default.useState(!1),[E,D]=u.default.useState(!1),[O,k]=u.default.useState(!0),A=u.default.useRef(null);u.default.useEffect(()=>{T(!1)},[f]);let j=async()=>{await navigator.clipboard.writeText(f),C(!0)};u.default.useEffect(()=>{let e;return S&&(e=setTimeout(()=>{C(!1)},2e3)),()=>{clearTimeout(e)}},[S]);let M=e===`user`&&(g===`error`||g===`sending`),N=g===`sending`&&v!=null,P=N&&b,F=e===`user`&&g==null,I=F&&E&&!w,L=u.default.Children.count(p)>0;u.default.useLayoutEffect(()=>{if(!N||F)return;let e=A.current;if(!e)return;let t=()=>{let t=Number.parseFloat(getComputedStyle(e).lineHeight),n=Number.isFinite(t)&&t>0?t:24;k(e.scrollHeight<=n+1)};t();let n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[f,N,F]);let R=F?(0,d.jsx)(l.UserMessageBody,{message:f,isHovering:b,isExpanded:w,onTruncatableChange:D}):(0,d.jsx)(`div`,{ref:A,className:`min-w-0 text-sm leading-6 whitespace-normal [word-break:break-word]`,children:(0,d.jsx)(a.MarkdownRenderer,{includeStandard:!0,includeHeadings:!0,allowHtml:e!==`user`,components:l.chatBubbleMarkdownComponents,children:f})}),z=(0,d.jsxs)(`article`,{"data-testid":`${e}-message`,"data-pending-status":g,onMouseEnter:()=>x(!0),onMouseLeave:()=>x(!1),className:r.cn(`rounded-xl relative w-fit max-w-full flex flex-col`,L&&`gap-2`,e===`user`&&`mt-6 bg-tertiary self-end px-4 py-2.5`,e===`agent`&&`mt-6 w-full max-w-full bg-transparent`,h&&e===`agent`&&`border border-[#597ff4] bg-tertiary p-4 mt-2`,g===`error`&&`border border-[var(--oh-status-error)]/40`,!M&&`last:mb-4`),children:[(0,d.jsxs)(`div`,{className:r.cn(`absolute -top-2.5 -right-2.5 z-10`,!b||g===`sending`?`hidden`:`flex`,`items-center gap-1`),onClick:e=>e.stopPropagation(),children:[m?.map((e,t)=>e.tooltip?(0,d.jsx)(o.StyledTooltip,{content:e.tooltip,placement:`top`,children:(0,d.jsx)(`button`,{type:`button`,onClick:e.onClick,className:`button-base p-1 cursor-pointer`,"aria-label":e.tooltip,children:e.icon})},t):(0,d.jsx)(`button`,{type:`button`,onClick:e.onClick,className:`button-base p-1 cursor-pointer`,"aria-label":`Action ${t+1}`,children:e.icon},t)),(0,d.jsx)(i.CopyToClipboardButton,{isHidden:!b,isDisabled:S,onClick:j,mode:S?`copied`:`copy`})]}),R,N?(0,d.jsx)(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),v?.()},"data-testid":`chat-message-stop`,"aria-label":y(n.I18nKey.BUTTON$STOP),"aria-hidden":!P,tabIndex:P?0:-1,className:r.cn(`group absolute z-10 inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-[var(--oh-color-tertiary)] text-[var(--oh-foreground)] transition-opacity duration-150`,O?`right-3 top-1/2 -translate-y-1/2`:`right-3 bottom-2.5`,P?`opacity-100`:`pointer-events-none opacity-0`),children:(0,d.jsx)(c.PendingStopIcon,{className:`block h-7 w-7 max-w-none`})}):null,I?(0,d.jsx)(`button`,{type:`button`,"data-testid":`chat-message-expand`,"aria-expanded":!1,"aria-label":y(n.I18nKey.COMMON$VIEW_MORE),className:`absolute inset-0 z-[1] cursor-pointer rounded-xl border-0 bg-transparent p-0`,onClick:()=>T(!0)}):null,p]});return e===`user`&&g===`error`?(0,d.jsxs)(`div`,{className:`flex w-fit max-w-full flex-col items-end gap-1.5 self-end last:mb-4`,children:[z,(0,d.jsxs)(`div`,{role:`alert`,"data-testid":`chat-message-error`,className:`flex items-center gap-2 text-xs text-[var(--oh-status-error)]`,children:[(0,d.jsx)(`span`,{children:y(n.I18nKey.CHAT_INTERFACE$MESSAGE_SEND_FAILED)}),_?(0,d.jsx)(`button`,{type:`button`,onClick:_,className:`cursor-pointer rounded-md border border-[var(--oh-border)] px-2 py-1 text-xs font-normal text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]`,"data-testid":`chat-message-retry`,children:y(n.I18nKey.CHAT_INTERFACE$MESSAGE_RETRY)}):null]})]}):e===`user`&&g===`sending`?(0,d.jsxs)(`div`,{className:`flex w-full max-w-full flex-col last:mb-4`,children:[z,(0,d.jsx)(`div`,{className:`my-1 w-full py-1 text-sm`,children:(0,d.jsx)(s.TextShimmer,{as:`p`,role:`status`,"aria-live":`polite`,"data-testid":`chat-message-sending`,className:`block w-full text-sm font-normal`,duration:1,spread:2,children:y(n.I18nKey.CHAT_INTERFACE$MESSAGE_SENDING)})})]}):z}exports.ChatMessage=f;
1
+ const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../node_modules/react-i18next/dist/es/useTranslation.cjs"),n=require("../../../i18n/declaration.cjs"),r=require("../../../utils/utils.cjs"),i=require("../../shared/buttons/copy-to-clipboard-button.cjs"),a=require("../markdown/markdown-renderer.cjs"),o=require("../../shared/buttons/styled-tooltip.cjs"),s=require("../../shared/text-shimmer.cjs"),c=require("./pending-stop-icon.cjs"),l=require("./user-message-body.cjs");let u=require("react");u=e.__toESM(u,1);let d=require("react/jsx-runtime");function f({type:e,message:f,children:p,actions:m,isFromPlanningAgent:h=!1,pendingStatus:g,onRetry:_,onDismiss:v,onStop:y}){let{t:b}=t.useTranslation(`openhands`),[x,S]=u.default.useState(!1),[C,w]=u.default.useState(!1),[T,E]=u.default.useState(!1),[D,O]=u.default.useState(!1),[k,A]=u.default.useState(!0),j=u.default.useRef(null);u.default.useEffect(()=>{E(!1)},[f]);let M=async()=>{await navigator.clipboard.writeText(f),w(!0)};u.default.useEffect(()=>{let e;return C&&(e=setTimeout(()=>{w(!1)},2e3)),()=>{clearTimeout(e)}},[C]);let N=e===`user`&&(g===`error`||g===`sending`),P=g===`sending`&&y!=null,F=P&&x,I=e===`user`&&g==null,L=I&&D&&!T,R=u.default.Children.count(p)>0;u.default.useLayoutEffect(()=>{if(!P||I)return;let e=j.current;if(!e)return;let t=()=>{let t=Number.parseFloat(getComputedStyle(e).lineHeight),n=Number.isFinite(t)&&t>0?t:24;A(e.scrollHeight<=n+1)};t();let n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[f,P,I]);let z=I?(0,d.jsx)(l.UserMessageBody,{message:f,isHovering:x,isExpanded:T,onTruncatableChange:O}):(0,d.jsx)(`div`,{ref:j,className:`min-w-0 text-sm leading-6 whitespace-normal [word-break:break-word]`,children:(0,d.jsx)(a.MarkdownRenderer,{includeStandard:!0,includeHeadings:!0,allowHtml:e!==`user`,components:l.chatBubbleMarkdownComponents,children:f})}),B=(0,d.jsxs)(`article`,{"data-testid":`${e}-message`,"data-pending-status":g,onMouseEnter:()=>S(!0),onMouseLeave:()=>S(!1),className:r.cn(`rounded-xl relative w-fit max-w-full flex flex-col`,R&&`gap-2`,e===`user`&&`mt-6 bg-tertiary self-end px-4 py-2.5`,e===`agent`&&`mt-6 w-full max-w-full bg-transparent`,h&&e===`agent`&&`border border-[#597ff4] bg-tertiary p-4 mt-2`,g===`error`&&`border border-[var(--oh-status-error)]/40`,!N&&`last:mb-4`),children:[(0,d.jsxs)(`div`,{className:r.cn(`absolute -top-2.5 -right-2.5 z-10`,!x||g===`sending`?`hidden`:`flex`,`items-center gap-1`),onClick:e=>e.stopPropagation(),children:[m?.map((e,t)=>e.tooltip?(0,d.jsx)(o.StyledTooltip,{content:e.tooltip,placement:`top`,children:(0,d.jsx)(`button`,{type:`button`,onClick:e.onClick,className:`button-base p-1 cursor-pointer`,"aria-label":e.tooltip,children:e.icon})},t):(0,d.jsx)(`button`,{type:`button`,onClick:e.onClick,className:`button-base p-1 cursor-pointer`,"aria-label":`Action ${t+1}`,children:e.icon},t)),(0,d.jsx)(i.CopyToClipboardButton,{isHidden:!x,isDisabled:C,onClick:M,mode:C?`copied`:`copy`})]}),z,P?(0,d.jsx)(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),y?.()},"data-testid":`chat-message-stop`,"aria-label":b(n.I18nKey.BUTTON$STOP),"aria-hidden":!F,tabIndex:F?0:-1,className:r.cn(`group absolute z-10 inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-[var(--oh-color-tertiary)] text-[var(--oh-foreground)] transition-opacity duration-150`,k?`right-3 top-1/2 -translate-y-1/2`:`right-3 bottom-2.5`,F?`opacity-100`:`pointer-events-none opacity-0`),children:(0,d.jsx)(c.PendingStopIcon,{className:`block h-7 w-7 max-w-none`})}):null,L?(0,d.jsx)(`button`,{type:`button`,"data-testid":`chat-message-expand`,"aria-expanded":!1,"aria-label":b(n.I18nKey.COMMON$VIEW_MORE),className:`absolute inset-0 z-[1] cursor-pointer rounded-xl border-0 bg-transparent p-0`,onClick:()=>E(!0)}):null,p]});return e===`user`&&g===`error`?(0,d.jsxs)(`div`,{className:`flex w-fit max-w-full flex-col items-end gap-1.5 self-end last:mb-4`,children:[B,(0,d.jsxs)(`div`,{role:`alert`,"data-testid":`chat-message-error`,className:`flex items-center gap-2 text-xs text-[var(--oh-status-error)]`,children:[(0,d.jsx)(`span`,{children:b(n.I18nKey.CHAT_INTERFACE$MESSAGE_SEND_FAILED)}),_?(0,d.jsx)(`button`,{type:`button`,onClick:_,className:`cursor-pointer rounded-md border border-[var(--oh-border)] px-2 py-1 text-xs font-normal text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]`,"data-testid":`chat-message-retry`,children:b(n.I18nKey.CHAT_INTERFACE$MESSAGE_RETRY)}):null,v?(0,d.jsx)(`button`,{type:`button`,onClick:v,className:`cursor-pointer rounded-md border border-[var(--oh-border)] px-2 py-1 text-xs font-normal text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]`,"data-testid":`chat-message-dismiss`,children:b(n.I18nKey.CHAT_INTERFACE$MESSAGE_DISMISS)}):null]})]}):e===`user`&&g===`sending`?(0,d.jsxs)(`div`,{className:`flex w-full max-w-full flex-col last:mb-4`,children:[B,(0,d.jsx)(`div`,{className:`my-1 w-full py-1 text-sm`,children:(0,d.jsx)(s.TextShimmer,{as:`p`,role:`status`,"aria-live":`polite`,"data-testid":`chat-message-sending`,className:`block w-full text-sm font-normal`,duration:1,spread:2,children:b(n.I18nKey.CHAT_INTERFACE$MESSAGE_SENDING)})})]}):B}exports.ChatMessage=f;
2
2
  //# sourceMappingURL=chat-message.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message.cjs","names":[],"sources":["../../../../src/components/features/chat/chat-message.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { cn } from \"#/utils/utils\";\nimport { CopyToClipboardButton } from \"#/components/shared/buttons/copy-to-clipboard-button\";\nimport type { SourceType } from \"#/types/agent-server/core/base/common\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { TextShimmer } from \"#/components/shared/text-shimmer\";\nimport { MarkdownRenderer } from \"../markdown/markdown-renderer\";\nimport { PendingStopIcon } from \"./pending-stop-icon\";\nimport {\n UserMessageBody,\n chatBubbleMarkdownComponents,\n USER_MESSAGE_LINE_HEIGHT_PX,\n} from \"./user-message-body\";\n\nexport type ChatMessagePendingStatus = \"sending\" | \"error\";\n\ninterface ChatMessageProps {\n type: SourceType;\n message: string;\n actions?: Array<{\n icon: React.ReactNode;\n onClick: () => void;\n tooltip?: string;\n }>;\n isFromPlanningAgent?: boolean;\n pendingStatus?: ChatMessagePendingStatus;\n onRetry?: () => void;\n onStop?: () => void;\n}\n\nexport function ChatMessage({\n type,\n message,\n children,\n actions,\n isFromPlanningAgent = false,\n pendingStatus,\n onRetry,\n onStop,\n}: React.PropsWithChildren<ChatMessageProps>) {\n const { t } = useTranslation(\"openhands\");\n const [isHovering, setIsHovering] = React.useState(false);\n const [isCopy, setIsCopy] = React.useState(false);\n const [isExpanded, setIsExpanded] = React.useState(false);\n const [isTruncatable, setIsTruncatable] = React.useState(false);\n const [isSingleLinePendingMessage, setIsSingleLinePendingMessage] =\n React.useState(true);\n const pendingMessageContentRef = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n setIsExpanded(false);\n }, [message]);\n\n const handleCopyToClipboard = async () => {\n await navigator.clipboard.writeText(message);\n setIsCopy(true);\n };\n\n React.useEffect(() => {\n let timeout: NodeJS.Timeout;\n\n if (isCopy) {\n timeout = setTimeout(() => {\n setIsCopy(false);\n }, 2000);\n }\n\n return () => {\n clearTimeout(timeout);\n };\n }, [isCopy]);\n\n const isPendingUserMessage =\n type === \"user\" &&\n (pendingStatus === \"error\" || pendingStatus === \"sending\");\n const canStopPendingMessage = pendingStatus === \"sending\" && onStop != null;\n const showStopButton = canStopPendingMessage && isHovering;\n const useTruncatedUserBody = type === \"user\" && pendingStatus == null;\n const isCollapsed = useTruncatedUserBody && isTruncatable && !isExpanded;\n const hasBubbleChildren = React.Children.count(children) > 0;\n\n React.useLayoutEffect(() => {\n if (!canStopPendingMessage || useTruncatedUserBody) {\n return undefined;\n }\n\n const content = pendingMessageContentRef.current;\n if (!content) {\n return undefined;\n }\n\n const measure = () => {\n const lineHeight = Number.parseFloat(\n getComputedStyle(content).lineHeight,\n );\n const linePx =\n Number.isFinite(lineHeight) && lineHeight > 0\n ? lineHeight\n : USER_MESSAGE_LINE_HEIGHT_PX;\n\n setIsSingleLinePendingMessage(content.scrollHeight <= linePx + 1);\n };\n\n measure();\n\n const observer = new ResizeObserver(measure);\n observer.observe(content);\n\n return () => observer.disconnect();\n }, [message, canStopPendingMessage, useTruncatedUserBody]);\n\n const messageContent = useTruncatedUserBody ? (\n <UserMessageBody\n message={message}\n isHovering={isHovering}\n isExpanded={isExpanded}\n onTruncatableChange={setIsTruncatable}\n />\n ) : (\n <div\n ref={pendingMessageContentRef}\n className=\"min-w-0 text-sm leading-6 whitespace-normal [word-break:break-word]\"\n >\n <MarkdownRenderer\n includeStandard\n includeHeadings\n allowHtml={type !== \"user\"}\n components={chatBubbleMarkdownComponents}\n >\n {message}\n </MarkdownRenderer>\n </div>\n );\n\n const renderedMessageContent = messageContent;\n\n const messageBubble = (\n <article\n data-testid={`${type}-message`}\n data-pending-status={pendingStatus}\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n className={cn(\n \"rounded-xl relative w-fit max-w-full flex flex-col\",\n hasBubbleChildren && \"gap-2\",\n type === \"user\" && \"mt-6 bg-tertiary self-end px-4 py-2.5\",\n type === \"agent\" && \"mt-6 w-full max-w-full bg-transparent\",\n isFromPlanningAgent &&\n type === \"agent\" &&\n \"border border-[#597ff4] bg-tertiary p-4 mt-2\",\n pendingStatus === \"error\" &&\n \"border border-[var(--oh-status-error)]/40\",\n !isPendingUserMessage && \"last:mb-4\",\n )}\n >\n <div\n className={cn(\n \"absolute -top-2.5 -right-2.5 z-10\",\n !isHovering || pendingStatus === \"sending\" ? \"hidden\" : \"flex\",\n \"items-center gap-1\",\n )}\n onClick={(event) => event.stopPropagation()}\n >\n {actions?.map((action, index) =>\n action.tooltip ? (\n <StyledTooltip key={index} content={action.tooltip} placement=\"top\">\n <button\n type=\"button\"\n onClick={action.onClick}\n className=\"button-base p-1 cursor-pointer\"\n aria-label={action.tooltip}\n >\n {action.icon}\n </button>\n </StyledTooltip>\n ) : (\n <button\n key={index}\n type=\"button\"\n onClick={action.onClick}\n className=\"button-base p-1 cursor-pointer\"\n aria-label={`Action ${index + 1}`}\n >\n {action.icon}\n </button>\n ),\n )}\n\n <CopyToClipboardButton\n isHidden={!isHovering}\n isDisabled={isCopy}\n onClick={handleCopyToClipboard}\n mode={isCopy ? \"copied\" : \"copy\"}\n />\n </div>\n\n {renderedMessageContent}\n\n {canStopPendingMessage ? (\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onStop?.();\n }}\n data-testid=\"chat-message-stop\"\n aria-label={t(I18nKey.BUTTON$STOP)}\n aria-hidden={!showStopButton}\n tabIndex={showStopButton ? 0 : -1}\n className={cn(\n \"group absolute z-10 inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-[var(--oh-color-tertiary)] text-[var(--oh-foreground)] transition-opacity duration-150\",\n isSingleLinePendingMessage\n ? \"right-3 top-1/2 -translate-y-1/2\"\n : \"right-3 bottom-2.5\",\n showStopButton ? \"opacity-100\" : \"pointer-events-none opacity-0\",\n )}\n >\n <PendingStopIcon className=\"block h-7 w-7 max-w-none\" />\n </button>\n ) : null}\n\n {isCollapsed ? (\n <button\n type=\"button\"\n data-testid=\"chat-message-expand\"\n aria-expanded={false}\n aria-label={t(I18nKey.COMMON$VIEW_MORE)}\n className=\"absolute inset-0 z-[1] cursor-pointer rounded-xl border-0 bg-transparent p-0\"\n onClick={() => setIsExpanded(true)}\n />\n ) : null}\n\n {children}\n </article>\n );\n\n if (type === \"user\" && pendingStatus === \"error\") {\n return (\n <div className=\"flex w-fit max-w-full flex-col items-end gap-1.5 self-end last:mb-4\">\n {messageBubble}\n <div\n role=\"alert\"\n data-testid=\"chat-message-error\"\n className=\"flex items-center gap-2 text-xs text-[var(--oh-status-error)]\"\n >\n <span>{t(I18nKey.CHAT_INTERFACE$MESSAGE_SEND_FAILED)}</span>\n {onRetry ? (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"cursor-pointer rounded-md border border-[var(--oh-border)] px-2 py-1 text-xs font-normal text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]\"\n data-testid=\"chat-message-retry\"\n >\n {t(I18nKey.CHAT_INTERFACE$MESSAGE_RETRY)}\n </button>\n ) : null}\n </div>\n </div>\n );\n }\n\n if (type === \"user\" && pendingStatus === \"sending\") {\n return (\n <div className=\"flex w-full max-w-full flex-col last:mb-4\">\n {messageBubble}\n <div className=\"my-1 w-full py-1 text-sm\">\n <TextShimmer\n as=\"p\"\n role=\"status\"\n aria-live=\"polite\"\n data-testid=\"chat-message-sending\"\n className=\"block w-full text-sm font-normal\"\n duration={1}\n spread={2}\n >\n {t(I18nKey.CHAT_INTERFACE$MESSAGE_SENDING)}\n </TextShimmer>\n </div>\n </div>\n );\n }\n\n return messageBubble;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"chat-message.cjs","names":[],"sources":["../../../../src/components/features/chat/chat-message.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { cn } from \"#/utils/utils\";\nimport { CopyToClipboardButton } from \"#/components/shared/buttons/copy-to-clipboard-button\";\nimport type { SourceType } from \"#/types/agent-server/core/base/common\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { TextShimmer } from \"#/components/shared/text-shimmer\";\nimport { MarkdownRenderer } from \"../markdown/markdown-renderer\";\nimport { PendingStopIcon } from \"./pending-stop-icon\";\nimport {\n UserMessageBody,\n chatBubbleMarkdownComponents,\n USER_MESSAGE_LINE_HEIGHT_PX,\n} from \"./user-message-body\";\n\nexport type ChatMessagePendingStatus = \"sending\" | \"error\";\n\ninterface ChatMessageProps {\n type: SourceType;\n message: string;\n actions?: Array<{\n icon: React.ReactNode;\n onClick: () => void;\n tooltip?: string;\n }>;\n isFromPlanningAgent?: boolean;\n pendingStatus?: ChatMessagePendingStatus;\n onRetry?: () => void;\n onDismiss?: () => void;\n onStop?: () => void;\n}\n\nexport function ChatMessage({\n type,\n message,\n children,\n actions,\n isFromPlanningAgent = false,\n pendingStatus,\n onRetry,\n onDismiss,\n onStop,\n}: React.PropsWithChildren<ChatMessageProps>) {\n const { t } = useTranslation(\"openhands\");\n const [isHovering, setIsHovering] = React.useState(false);\n const [isCopy, setIsCopy] = React.useState(false);\n const [isExpanded, setIsExpanded] = React.useState(false);\n const [isTruncatable, setIsTruncatable] = React.useState(false);\n const [isSingleLinePendingMessage, setIsSingleLinePendingMessage] =\n React.useState(true);\n const pendingMessageContentRef = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n setIsExpanded(false);\n }, [message]);\n\n const handleCopyToClipboard = async () => {\n await navigator.clipboard.writeText(message);\n setIsCopy(true);\n };\n\n React.useEffect(() => {\n let timeout: NodeJS.Timeout;\n\n if (isCopy) {\n timeout = setTimeout(() => {\n setIsCopy(false);\n }, 2000);\n }\n\n return () => {\n clearTimeout(timeout);\n };\n }, [isCopy]);\n\n const isPendingUserMessage =\n type === \"user\" &&\n (pendingStatus === \"error\" || pendingStatus === \"sending\");\n const canStopPendingMessage = pendingStatus === \"sending\" && onStop != null;\n const showStopButton = canStopPendingMessage && isHovering;\n const useTruncatedUserBody = type === \"user\" && pendingStatus == null;\n const isCollapsed = useTruncatedUserBody && isTruncatable && !isExpanded;\n const hasBubbleChildren = React.Children.count(children) > 0;\n\n React.useLayoutEffect(() => {\n if (!canStopPendingMessage || useTruncatedUserBody) {\n return undefined;\n }\n\n const content = pendingMessageContentRef.current;\n if (!content) {\n return undefined;\n }\n\n const measure = () => {\n const lineHeight = Number.parseFloat(\n getComputedStyle(content).lineHeight,\n );\n const linePx =\n Number.isFinite(lineHeight) && lineHeight > 0\n ? lineHeight\n : USER_MESSAGE_LINE_HEIGHT_PX;\n\n setIsSingleLinePendingMessage(content.scrollHeight <= linePx + 1);\n };\n\n measure();\n\n const observer = new ResizeObserver(measure);\n observer.observe(content);\n\n return () => observer.disconnect();\n }, [message, canStopPendingMessage, useTruncatedUserBody]);\n\n const messageContent = useTruncatedUserBody ? (\n <UserMessageBody\n message={message}\n isHovering={isHovering}\n isExpanded={isExpanded}\n onTruncatableChange={setIsTruncatable}\n />\n ) : (\n <div\n ref={pendingMessageContentRef}\n className=\"min-w-0 text-sm leading-6 whitespace-normal [word-break:break-word]\"\n >\n <MarkdownRenderer\n includeStandard\n includeHeadings\n allowHtml={type !== \"user\"}\n components={chatBubbleMarkdownComponents}\n >\n {message}\n </MarkdownRenderer>\n </div>\n );\n\n const renderedMessageContent = messageContent;\n\n const messageBubble = (\n <article\n data-testid={`${type}-message`}\n data-pending-status={pendingStatus}\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n className={cn(\n \"rounded-xl relative w-fit max-w-full flex flex-col\",\n hasBubbleChildren && \"gap-2\",\n type === \"user\" && \"mt-6 bg-tertiary self-end px-4 py-2.5\",\n type === \"agent\" && \"mt-6 w-full max-w-full bg-transparent\",\n isFromPlanningAgent &&\n type === \"agent\" &&\n \"border border-[#597ff4] bg-tertiary p-4 mt-2\",\n pendingStatus === \"error\" &&\n \"border border-[var(--oh-status-error)]/40\",\n !isPendingUserMessage && \"last:mb-4\",\n )}\n >\n <div\n className={cn(\n \"absolute -top-2.5 -right-2.5 z-10\",\n !isHovering || pendingStatus === \"sending\" ? \"hidden\" : \"flex\",\n \"items-center gap-1\",\n )}\n onClick={(event) => event.stopPropagation()}\n >\n {actions?.map((action, index) =>\n action.tooltip ? (\n <StyledTooltip key={index} content={action.tooltip} placement=\"top\">\n <button\n type=\"button\"\n onClick={action.onClick}\n className=\"button-base p-1 cursor-pointer\"\n aria-label={action.tooltip}\n >\n {action.icon}\n </button>\n </StyledTooltip>\n ) : (\n <button\n key={index}\n type=\"button\"\n onClick={action.onClick}\n className=\"button-base p-1 cursor-pointer\"\n aria-label={`Action ${index + 1}`}\n >\n {action.icon}\n </button>\n ),\n )}\n\n <CopyToClipboardButton\n isHidden={!isHovering}\n isDisabled={isCopy}\n onClick={handleCopyToClipboard}\n mode={isCopy ? \"copied\" : \"copy\"}\n />\n </div>\n\n {renderedMessageContent}\n\n {canStopPendingMessage ? (\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onStop?.();\n }}\n data-testid=\"chat-message-stop\"\n aria-label={t(I18nKey.BUTTON$STOP)}\n aria-hidden={!showStopButton}\n tabIndex={showStopButton ? 0 : -1}\n className={cn(\n \"group absolute z-10 inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-[var(--oh-color-tertiary)] text-[var(--oh-foreground)] transition-opacity duration-150\",\n isSingleLinePendingMessage\n ? \"right-3 top-1/2 -translate-y-1/2\"\n : \"right-3 bottom-2.5\",\n showStopButton ? \"opacity-100\" : \"pointer-events-none opacity-0\",\n )}\n >\n <PendingStopIcon className=\"block h-7 w-7 max-w-none\" />\n </button>\n ) : null}\n\n {isCollapsed ? (\n <button\n type=\"button\"\n data-testid=\"chat-message-expand\"\n aria-expanded={false}\n aria-label={t(I18nKey.COMMON$VIEW_MORE)}\n className=\"absolute inset-0 z-[1] cursor-pointer rounded-xl border-0 bg-transparent p-0\"\n onClick={() => setIsExpanded(true)}\n />\n ) : null}\n\n {children}\n </article>\n );\n\n if (type === \"user\" && pendingStatus === \"error\") {\n return (\n <div className=\"flex w-fit max-w-full flex-col items-end gap-1.5 self-end last:mb-4\">\n {messageBubble}\n <div\n role=\"alert\"\n data-testid=\"chat-message-error\"\n className=\"flex items-center gap-2 text-xs text-[var(--oh-status-error)]\"\n >\n <span>{t(I18nKey.CHAT_INTERFACE$MESSAGE_SEND_FAILED)}</span>\n {onRetry ? (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"cursor-pointer rounded-md border border-[var(--oh-border)] px-2 py-1 text-xs font-normal text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]\"\n data-testid=\"chat-message-retry\"\n >\n {t(I18nKey.CHAT_INTERFACE$MESSAGE_RETRY)}\n </button>\n ) : null}\n {onDismiss ? (\n <button\n type=\"button\"\n onClick={onDismiss}\n className=\"cursor-pointer rounded-md border border-[var(--oh-border)] px-2 py-1 text-xs font-normal text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]\"\n data-testid=\"chat-message-dismiss\"\n >\n {t(I18nKey.CHAT_INTERFACE$MESSAGE_DISMISS)}\n </button>\n ) : null}\n </div>\n </div>\n );\n }\n\n if (type === \"user\" && pendingStatus === \"sending\") {\n return (\n <div className=\"flex w-full max-w-full flex-col last:mb-4\">\n {messageBubble}\n <div className=\"my-1 w-full py-1 text-sm\">\n <TextShimmer\n as=\"p\"\n role=\"status\"\n aria-live=\"polite\"\n data-testid=\"chat-message-sending\"\n className=\"block w-full text-sm font-normal\"\n duration={1}\n spread={2}\n >\n {t(I18nKey.CHAT_INTERFACE$MESSAGE_SENDING)}\n </TextShimmer>\n </div>\n </div>\n );\n }\n\n return messageBubble;\n}\n"],"mappings":"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"}
@@ -12,7 +12,8 @@ interface ChatMessageProps {
12
12
  isFromPlanningAgent?: boolean;
13
13
  pendingStatus?: ChatMessagePendingStatus;
14
14
  onRetry?: () => void;
15
+ onDismiss?: () => void;
15
16
  onStop?: () => void;
16
17
  }
17
- export declare function ChatMessage({ type, message, children, actions, isFromPlanningAgent, pendingStatus, onRetry, onStop, }: React.PropsWithChildren<ChatMessageProps>): import("react/jsx-runtime").JSX.Element;
18
+ export declare function ChatMessage({ type, message, children, actions, isFromPlanningAgent, pendingStatus, onRetry, onDismiss, onStop, }: React.PropsWithChildren<ChatMessageProps>): React.JSX.Element;
18
19
  export {};
@@ -10,46 +10,46 @@ import { UserMessageBody as c, chatBubbleMarkdownComponents as l } from "./user-
10
10
  import u from "react";
11
11
  import { jsx as d, jsxs as f } from "react/jsx-runtime";
12
12
  //#region src/components/features/chat/chat-message.tsx
13
- function p({ type: p, message: m, children: h, actions: g, isFromPlanningAgent: _ = !1, pendingStatus: v, onRetry: y, onStop: b }) {
14
- let { t: x } = e("openhands"), [S, C] = u.useState(!1), [w, T] = u.useState(!1), [E, D] = u.useState(!1), [O, k] = u.useState(!1), [A, j] = u.useState(!0), M = u.useRef(null);
13
+ function p({ type: p, message: m, children: h, actions: g, isFromPlanningAgent: _ = !1, pendingStatus: v, onRetry: y, onDismiss: b, onStop: x }) {
14
+ let { t: S } = e("openhands"), [C, w] = u.useState(!1), [T, E] = u.useState(!1), [D, O] = u.useState(!1), [k, A] = u.useState(!1), [j, M] = u.useState(!0), N = u.useRef(null);
15
15
  u.useEffect(() => {
16
- D(!1);
16
+ O(!1);
17
17
  }, [m]);
18
- let N = async () => {
19
- await navigator.clipboard.writeText(m), T(!0);
18
+ let P = async () => {
19
+ await navigator.clipboard.writeText(m), E(!0);
20
20
  };
21
21
  u.useEffect(() => {
22
22
  let e;
23
- return w && (e = setTimeout(() => {
24
- T(!1);
23
+ return T && (e = setTimeout(() => {
24
+ E(!1);
25
25
  }, 2e3)), () => {
26
26
  clearTimeout(e);
27
27
  };
28
- }, [w]);
29
- let P = p === "user" && (v === "error" || v === "sending"), F = v === "sending" && b != null, I = F && S, L = p === "user" && v == null, R = L && O && !E, z = u.Children.count(h) > 0;
28
+ }, [T]);
29
+ let F = p === "user" && (v === "error" || v === "sending"), I = v === "sending" && x != null, L = I && C, R = p === "user" && v == null, z = R && k && !D, B = u.Children.count(h) > 0;
30
30
  u.useLayoutEffect(() => {
31
- if (!F || L) return;
32
- let e = M.current;
31
+ if (!I || R) return;
32
+ let e = N.current;
33
33
  if (!e) return;
34
34
  let t = () => {
35
35
  let t = Number.parseFloat(getComputedStyle(e).lineHeight), n = Number.isFinite(t) && t > 0 ? t : 24;
36
- j(e.scrollHeight <= n + 1);
36
+ M(e.scrollHeight <= n + 1);
37
37
  };
38
38
  t();
39
39
  let n = new ResizeObserver(t);
40
40
  return n.observe(e), () => n.disconnect();
41
41
  }, [
42
42
  m,
43
- F,
44
- L
43
+ I,
44
+ R
45
45
  ]);
46
- let B = L ? /* @__PURE__ */ d(c, {
46
+ let V = R ? /* @__PURE__ */ d(c, {
47
47
  message: m,
48
- isHovering: S,
49
- isExpanded: E,
50
- onTruncatableChange: k
48
+ isHovering: C,
49
+ isExpanded: D,
50
+ onTruncatableChange: A
51
51
  }) : /* @__PURE__ */ d("div", {
52
- ref: M,
52
+ ref: N,
53
53
  className: "min-w-0 text-sm leading-6 whitespace-normal [word-break:break-word]",
54
54
  children: /* @__PURE__ */ d(i, {
55
55
  includeStandard: !0,
@@ -58,15 +58,15 @@ function p({ type: p, message: m, children: h, actions: g, isFromPlanningAgent:
58
58
  components: l,
59
59
  children: m
60
60
  })
61
- }), V = /* @__PURE__ */ f("article", {
61
+ }), H = /* @__PURE__ */ f("article", {
62
62
  "data-testid": `${p}-message`,
63
63
  "data-pending-status": v,
64
- onMouseEnter: () => C(!0),
65
- onMouseLeave: () => C(!1),
66
- className: n("rounded-xl relative w-fit max-w-full flex flex-col", z && "gap-2", p === "user" && "mt-6 bg-tertiary self-end px-4 py-2.5", p === "agent" && "mt-6 w-full max-w-full bg-transparent", _ && p === "agent" && "border border-[#597ff4] bg-tertiary p-4 mt-2", v === "error" && "border border-[var(--oh-status-error)]/40", !P && "last:mb-4"),
64
+ onMouseEnter: () => w(!0),
65
+ onMouseLeave: () => w(!1),
66
+ className: n("rounded-xl relative w-fit max-w-full flex flex-col", B && "gap-2", p === "user" && "mt-6 bg-tertiary self-end px-4 py-2.5", p === "agent" && "mt-6 w-full max-w-full bg-transparent", _ && p === "agent" && "border border-[#597ff4] bg-tertiary p-4 mt-2", v === "error" && "border border-[var(--oh-status-error)]/40", !F && "last:mb-4"),
67
67
  children: [
68
68
  /* @__PURE__ */ f("div", {
69
- className: n("absolute -top-2.5 -right-2.5 z-10", !S || v === "sending" ? "hidden" : "flex", "items-center gap-1"),
69
+ className: n("absolute -top-2.5 -right-2.5 z-10", !C || v === "sending" ? "hidden" : "flex", "items-center gap-1"),
70
70
  onClick: (e) => e.stopPropagation(),
71
71
  children: [g?.map((e, t) => e.tooltip ? /* @__PURE__ */ d(a, {
72
72
  content: e.tooltip,
@@ -85,53 +85,63 @@ function p({ type: p, message: m, children: h, actions: g, isFromPlanningAgent:
85
85
  "aria-label": `Action ${t + 1}`,
86
86
  children: e.icon
87
87
  }, t)), /* @__PURE__ */ d(r, {
88
- isHidden: !S,
89
- isDisabled: w,
90
- onClick: N,
91
- mode: w ? "copied" : "copy"
88
+ isHidden: !C,
89
+ isDisabled: T,
90
+ onClick: P,
91
+ mode: T ? "copied" : "copy"
92
92
  })]
93
93
  }),
94
- B,
95
- F ? /* @__PURE__ */ d("button", {
94
+ V,
95
+ I ? /* @__PURE__ */ d("button", {
96
96
  type: "button",
97
97
  onClick: (e) => {
98
- e.stopPropagation(), b?.();
98
+ e.stopPropagation(), x?.();
99
99
  },
100
100
  "data-testid": "chat-message-stop",
101
- "aria-label": x(t.BUTTON$STOP),
102
- "aria-hidden": !I,
103
- tabIndex: I ? 0 : -1,
104
- className: n("group absolute z-10 inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-[var(--oh-color-tertiary)] text-[var(--oh-foreground)] transition-opacity duration-150", A ? "right-3 top-1/2 -translate-y-1/2" : "right-3 bottom-2.5", I ? "opacity-100" : "pointer-events-none opacity-0"),
101
+ "aria-label": S(t.BUTTON$STOP),
102
+ "aria-hidden": !L,
103
+ tabIndex: L ? 0 : -1,
104
+ className: n("group absolute z-10 inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-[var(--oh-color-tertiary)] text-[var(--oh-foreground)] transition-opacity duration-150", j ? "right-3 top-1/2 -translate-y-1/2" : "right-3 bottom-2.5", L ? "opacity-100" : "pointer-events-none opacity-0"),
105
105
  children: /* @__PURE__ */ d(s, { className: "block h-7 w-7 max-w-none" })
106
106
  }) : null,
107
- R ? /* @__PURE__ */ d("button", {
107
+ z ? /* @__PURE__ */ d("button", {
108
108
  type: "button",
109
109
  "data-testid": "chat-message-expand",
110
110
  "aria-expanded": !1,
111
- "aria-label": x(t.COMMON$VIEW_MORE),
111
+ "aria-label": S(t.COMMON$VIEW_MORE),
112
112
  className: "absolute inset-0 z-[1] cursor-pointer rounded-xl border-0 bg-transparent p-0",
113
- onClick: () => D(!0)
113
+ onClick: () => O(!0)
114
114
  }) : null,
115
115
  h
116
116
  ]
117
117
  });
118
118
  return p === "user" && v === "error" ? /* @__PURE__ */ f("div", {
119
119
  className: "flex w-fit max-w-full flex-col items-end gap-1.5 self-end last:mb-4",
120
- children: [V, /* @__PURE__ */ f("div", {
120
+ children: [H, /* @__PURE__ */ f("div", {
121
121
  role: "alert",
122
122
  "data-testid": "chat-message-error",
123
123
  className: "flex items-center gap-2 text-xs text-[var(--oh-status-error)]",
124
- children: [/* @__PURE__ */ d("span", { children: x(t.CHAT_INTERFACE$MESSAGE_SEND_FAILED) }), y ? /* @__PURE__ */ d("button", {
125
- type: "button",
126
- onClick: y,
127
- className: "cursor-pointer rounded-md border border-[var(--oh-border)] px-2 py-1 text-xs font-normal text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]",
128
- "data-testid": "chat-message-retry",
129
- children: x(t.CHAT_INTERFACE$MESSAGE_RETRY)
130
- }) : null]
124
+ children: [
125
+ /* @__PURE__ */ d("span", { children: S(t.CHAT_INTERFACE$MESSAGE_SEND_FAILED) }),
126
+ y ? /* @__PURE__ */ d("button", {
127
+ type: "button",
128
+ onClick: y,
129
+ className: "cursor-pointer rounded-md border border-[var(--oh-border)] px-2 py-1 text-xs font-normal text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]",
130
+ "data-testid": "chat-message-retry",
131
+ children: S(t.CHAT_INTERFACE$MESSAGE_RETRY)
132
+ }) : null,
133
+ b ? /* @__PURE__ */ d("button", {
134
+ type: "button",
135
+ onClick: b,
136
+ className: "cursor-pointer rounded-md border border-[var(--oh-border)] px-2 py-1 text-xs font-normal text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]",
137
+ "data-testid": "chat-message-dismiss",
138
+ children: S(t.CHAT_INTERFACE$MESSAGE_DISMISS)
139
+ }) : null
140
+ ]
131
141
  })]
132
142
  }) : p === "user" && v === "sending" ? /* @__PURE__ */ f("div", {
133
143
  className: "flex w-full max-w-full flex-col last:mb-4",
134
- children: [V, /* @__PURE__ */ d("div", {
144
+ children: [H, /* @__PURE__ */ d("div", {
135
145
  className: "my-1 w-full py-1 text-sm",
136
146
  children: /* @__PURE__ */ d(o, {
137
147
  as: "p",
@@ -141,10 +151,10 @@ function p({ type: p, message: m, children: h, actions: g, isFromPlanningAgent:
141
151
  className: "block w-full text-sm font-normal",
142
152
  duration: 1,
143
153
  spread: 2,
144
- children: x(t.CHAT_INTERFACE$MESSAGE_SENDING)
154
+ children: S(t.CHAT_INTERFACE$MESSAGE_SENDING)
145
155
  })
146
156
  })]
147
- }) : V;
157
+ }) : H;
148
158
  }
149
159
  //#endregion
150
160
  export { p as ChatMessage };
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message.js","names":[],"sources":["../../../../src/components/features/chat/chat-message.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { cn } from \"#/utils/utils\";\nimport { CopyToClipboardButton } from \"#/components/shared/buttons/copy-to-clipboard-button\";\nimport type { SourceType } from \"#/types/agent-server/core/base/common\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { TextShimmer } from \"#/components/shared/text-shimmer\";\nimport { MarkdownRenderer } from \"../markdown/markdown-renderer\";\nimport { PendingStopIcon } from \"./pending-stop-icon\";\nimport {\n UserMessageBody,\n chatBubbleMarkdownComponents,\n USER_MESSAGE_LINE_HEIGHT_PX,\n} from \"./user-message-body\";\n\nexport type ChatMessagePendingStatus = \"sending\" | \"error\";\n\ninterface ChatMessageProps {\n type: SourceType;\n message: string;\n actions?: Array<{\n icon: React.ReactNode;\n onClick: () => void;\n tooltip?: string;\n }>;\n isFromPlanningAgent?: boolean;\n pendingStatus?: ChatMessagePendingStatus;\n onRetry?: () => void;\n onStop?: () => void;\n}\n\nexport function ChatMessage({\n type,\n message,\n children,\n actions,\n isFromPlanningAgent = false,\n pendingStatus,\n onRetry,\n onStop,\n}: React.PropsWithChildren<ChatMessageProps>) {\n const { t } = useTranslation(\"openhands\");\n const [isHovering, setIsHovering] = React.useState(false);\n const [isCopy, setIsCopy] = React.useState(false);\n const [isExpanded, setIsExpanded] = React.useState(false);\n const [isTruncatable, setIsTruncatable] = React.useState(false);\n const [isSingleLinePendingMessage, setIsSingleLinePendingMessage] =\n React.useState(true);\n const pendingMessageContentRef = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n setIsExpanded(false);\n }, [message]);\n\n const handleCopyToClipboard = async () => {\n await navigator.clipboard.writeText(message);\n setIsCopy(true);\n };\n\n React.useEffect(() => {\n let timeout: NodeJS.Timeout;\n\n if (isCopy) {\n timeout = setTimeout(() => {\n setIsCopy(false);\n }, 2000);\n }\n\n return () => {\n clearTimeout(timeout);\n };\n }, [isCopy]);\n\n const isPendingUserMessage =\n type === \"user\" &&\n (pendingStatus === \"error\" || pendingStatus === \"sending\");\n const canStopPendingMessage = pendingStatus === \"sending\" && onStop != null;\n const showStopButton = canStopPendingMessage && isHovering;\n const useTruncatedUserBody = type === \"user\" && pendingStatus == null;\n const isCollapsed = useTruncatedUserBody && isTruncatable && !isExpanded;\n const hasBubbleChildren = React.Children.count(children) > 0;\n\n React.useLayoutEffect(() => {\n if (!canStopPendingMessage || useTruncatedUserBody) {\n return undefined;\n }\n\n const content = pendingMessageContentRef.current;\n if (!content) {\n return undefined;\n }\n\n const measure = () => {\n const lineHeight = Number.parseFloat(\n getComputedStyle(content).lineHeight,\n );\n const linePx =\n Number.isFinite(lineHeight) && lineHeight > 0\n ? lineHeight\n : USER_MESSAGE_LINE_HEIGHT_PX;\n\n setIsSingleLinePendingMessage(content.scrollHeight <= linePx + 1);\n };\n\n measure();\n\n const observer = new ResizeObserver(measure);\n observer.observe(content);\n\n return () => observer.disconnect();\n }, [message, canStopPendingMessage, useTruncatedUserBody]);\n\n const messageContent = useTruncatedUserBody ? (\n <UserMessageBody\n message={message}\n isHovering={isHovering}\n isExpanded={isExpanded}\n onTruncatableChange={setIsTruncatable}\n />\n ) : (\n <div\n ref={pendingMessageContentRef}\n className=\"min-w-0 text-sm leading-6 whitespace-normal [word-break:break-word]\"\n >\n <MarkdownRenderer\n includeStandard\n includeHeadings\n allowHtml={type !== \"user\"}\n components={chatBubbleMarkdownComponents}\n >\n {message}\n </MarkdownRenderer>\n </div>\n );\n\n const renderedMessageContent = messageContent;\n\n const messageBubble = (\n <article\n data-testid={`${type}-message`}\n data-pending-status={pendingStatus}\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n className={cn(\n \"rounded-xl relative w-fit max-w-full flex flex-col\",\n hasBubbleChildren && \"gap-2\",\n type === \"user\" && \"mt-6 bg-tertiary self-end px-4 py-2.5\",\n type === \"agent\" && \"mt-6 w-full max-w-full bg-transparent\",\n isFromPlanningAgent &&\n type === \"agent\" &&\n \"border border-[#597ff4] bg-tertiary p-4 mt-2\",\n pendingStatus === \"error\" &&\n \"border border-[var(--oh-status-error)]/40\",\n !isPendingUserMessage && \"last:mb-4\",\n )}\n >\n <div\n className={cn(\n \"absolute -top-2.5 -right-2.5 z-10\",\n !isHovering || pendingStatus === \"sending\" ? \"hidden\" : \"flex\",\n \"items-center gap-1\",\n )}\n onClick={(event) => event.stopPropagation()}\n >\n {actions?.map((action, index) =>\n action.tooltip ? (\n <StyledTooltip key={index} content={action.tooltip} placement=\"top\">\n <button\n type=\"button\"\n onClick={action.onClick}\n className=\"button-base p-1 cursor-pointer\"\n aria-label={action.tooltip}\n >\n {action.icon}\n </button>\n </StyledTooltip>\n ) : (\n <button\n key={index}\n type=\"button\"\n onClick={action.onClick}\n className=\"button-base p-1 cursor-pointer\"\n aria-label={`Action ${index + 1}`}\n >\n {action.icon}\n </button>\n ),\n )}\n\n <CopyToClipboardButton\n isHidden={!isHovering}\n isDisabled={isCopy}\n onClick={handleCopyToClipboard}\n mode={isCopy ? \"copied\" : \"copy\"}\n />\n </div>\n\n {renderedMessageContent}\n\n {canStopPendingMessage ? (\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onStop?.();\n }}\n data-testid=\"chat-message-stop\"\n aria-label={t(I18nKey.BUTTON$STOP)}\n aria-hidden={!showStopButton}\n tabIndex={showStopButton ? 0 : -1}\n className={cn(\n \"group absolute z-10 inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-[var(--oh-color-tertiary)] text-[var(--oh-foreground)] transition-opacity duration-150\",\n isSingleLinePendingMessage\n ? \"right-3 top-1/2 -translate-y-1/2\"\n : \"right-3 bottom-2.5\",\n showStopButton ? \"opacity-100\" : \"pointer-events-none opacity-0\",\n )}\n >\n <PendingStopIcon className=\"block h-7 w-7 max-w-none\" />\n </button>\n ) : null}\n\n {isCollapsed ? (\n <button\n type=\"button\"\n data-testid=\"chat-message-expand\"\n aria-expanded={false}\n aria-label={t(I18nKey.COMMON$VIEW_MORE)}\n className=\"absolute inset-0 z-[1] cursor-pointer rounded-xl border-0 bg-transparent p-0\"\n onClick={() => setIsExpanded(true)}\n />\n ) : null}\n\n {children}\n </article>\n );\n\n if (type === \"user\" && pendingStatus === \"error\") {\n return (\n <div className=\"flex w-fit max-w-full flex-col items-end gap-1.5 self-end last:mb-4\">\n {messageBubble}\n <div\n role=\"alert\"\n data-testid=\"chat-message-error\"\n className=\"flex items-center gap-2 text-xs text-[var(--oh-status-error)]\"\n >\n <span>{t(I18nKey.CHAT_INTERFACE$MESSAGE_SEND_FAILED)}</span>\n {onRetry ? (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"cursor-pointer rounded-md border border-[var(--oh-border)] px-2 py-1 text-xs font-normal text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]\"\n data-testid=\"chat-message-retry\"\n >\n {t(I18nKey.CHAT_INTERFACE$MESSAGE_RETRY)}\n </button>\n ) : null}\n </div>\n </div>\n );\n }\n\n if (type === \"user\" && pendingStatus === \"sending\") {\n return (\n <div className=\"flex w-full max-w-full flex-col last:mb-4\">\n {messageBubble}\n <div className=\"my-1 w-full py-1 text-sm\">\n <TextShimmer\n as=\"p\"\n role=\"status\"\n aria-live=\"polite\"\n data-testid=\"chat-message-sending\"\n className=\"block w-full text-sm font-normal\"\n duration={1}\n spread={2}\n >\n {t(I18nKey.CHAT_INTERFACE$MESSAGE_SENDING)}\n </TextShimmer>\n </div>\n </div>\n );\n }\n\n return messageBubble;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"chat-message.js","names":[],"sources":["../../../../src/components/features/chat/chat-message.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { cn } from \"#/utils/utils\";\nimport { CopyToClipboardButton } from \"#/components/shared/buttons/copy-to-clipboard-button\";\nimport type { SourceType } from \"#/types/agent-server/core/base/common\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { TextShimmer } from \"#/components/shared/text-shimmer\";\nimport { MarkdownRenderer } from \"../markdown/markdown-renderer\";\nimport { PendingStopIcon } from \"./pending-stop-icon\";\nimport {\n UserMessageBody,\n chatBubbleMarkdownComponents,\n USER_MESSAGE_LINE_HEIGHT_PX,\n} from \"./user-message-body\";\n\nexport type ChatMessagePendingStatus = \"sending\" | \"error\";\n\ninterface ChatMessageProps {\n type: SourceType;\n message: string;\n actions?: Array<{\n icon: React.ReactNode;\n onClick: () => void;\n tooltip?: string;\n }>;\n isFromPlanningAgent?: boolean;\n pendingStatus?: ChatMessagePendingStatus;\n onRetry?: () => void;\n onDismiss?: () => void;\n onStop?: () => void;\n}\n\nexport function ChatMessage({\n type,\n message,\n children,\n actions,\n isFromPlanningAgent = false,\n pendingStatus,\n onRetry,\n onDismiss,\n onStop,\n}: React.PropsWithChildren<ChatMessageProps>) {\n const { t } = useTranslation(\"openhands\");\n const [isHovering, setIsHovering] = React.useState(false);\n const [isCopy, setIsCopy] = React.useState(false);\n const [isExpanded, setIsExpanded] = React.useState(false);\n const [isTruncatable, setIsTruncatable] = React.useState(false);\n const [isSingleLinePendingMessage, setIsSingleLinePendingMessage] =\n React.useState(true);\n const pendingMessageContentRef = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n setIsExpanded(false);\n }, [message]);\n\n const handleCopyToClipboard = async () => {\n await navigator.clipboard.writeText(message);\n setIsCopy(true);\n };\n\n React.useEffect(() => {\n let timeout: NodeJS.Timeout;\n\n if (isCopy) {\n timeout = setTimeout(() => {\n setIsCopy(false);\n }, 2000);\n }\n\n return () => {\n clearTimeout(timeout);\n };\n }, [isCopy]);\n\n const isPendingUserMessage =\n type === \"user\" &&\n (pendingStatus === \"error\" || pendingStatus === \"sending\");\n const canStopPendingMessage = pendingStatus === \"sending\" && onStop != null;\n const showStopButton = canStopPendingMessage && isHovering;\n const useTruncatedUserBody = type === \"user\" && pendingStatus == null;\n const isCollapsed = useTruncatedUserBody && isTruncatable && !isExpanded;\n const hasBubbleChildren = React.Children.count(children) > 0;\n\n React.useLayoutEffect(() => {\n if (!canStopPendingMessage || useTruncatedUserBody) {\n return undefined;\n }\n\n const content = pendingMessageContentRef.current;\n if (!content) {\n return undefined;\n }\n\n const measure = () => {\n const lineHeight = Number.parseFloat(\n getComputedStyle(content).lineHeight,\n );\n const linePx =\n Number.isFinite(lineHeight) && lineHeight > 0\n ? lineHeight\n : USER_MESSAGE_LINE_HEIGHT_PX;\n\n setIsSingleLinePendingMessage(content.scrollHeight <= linePx + 1);\n };\n\n measure();\n\n const observer = new ResizeObserver(measure);\n observer.observe(content);\n\n return () => observer.disconnect();\n }, [message, canStopPendingMessage, useTruncatedUserBody]);\n\n const messageContent = useTruncatedUserBody ? (\n <UserMessageBody\n message={message}\n isHovering={isHovering}\n isExpanded={isExpanded}\n onTruncatableChange={setIsTruncatable}\n />\n ) : (\n <div\n ref={pendingMessageContentRef}\n className=\"min-w-0 text-sm leading-6 whitespace-normal [word-break:break-word]\"\n >\n <MarkdownRenderer\n includeStandard\n includeHeadings\n allowHtml={type !== \"user\"}\n components={chatBubbleMarkdownComponents}\n >\n {message}\n </MarkdownRenderer>\n </div>\n );\n\n const renderedMessageContent = messageContent;\n\n const messageBubble = (\n <article\n data-testid={`${type}-message`}\n data-pending-status={pendingStatus}\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n className={cn(\n \"rounded-xl relative w-fit max-w-full flex flex-col\",\n hasBubbleChildren && \"gap-2\",\n type === \"user\" && \"mt-6 bg-tertiary self-end px-4 py-2.5\",\n type === \"agent\" && \"mt-6 w-full max-w-full bg-transparent\",\n isFromPlanningAgent &&\n type === \"agent\" &&\n \"border border-[#597ff4] bg-tertiary p-4 mt-2\",\n pendingStatus === \"error\" &&\n \"border border-[var(--oh-status-error)]/40\",\n !isPendingUserMessage && \"last:mb-4\",\n )}\n >\n <div\n className={cn(\n \"absolute -top-2.5 -right-2.5 z-10\",\n !isHovering || pendingStatus === \"sending\" ? \"hidden\" : \"flex\",\n \"items-center gap-1\",\n )}\n onClick={(event) => event.stopPropagation()}\n >\n {actions?.map((action, index) =>\n action.tooltip ? (\n <StyledTooltip key={index} content={action.tooltip} placement=\"top\">\n <button\n type=\"button\"\n onClick={action.onClick}\n className=\"button-base p-1 cursor-pointer\"\n aria-label={action.tooltip}\n >\n {action.icon}\n </button>\n </StyledTooltip>\n ) : (\n <button\n key={index}\n type=\"button\"\n onClick={action.onClick}\n className=\"button-base p-1 cursor-pointer\"\n aria-label={`Action ${index + 1}`}\n >\n {action.icon}\n </button>\n ),\n )}\n\n <CopyToClipboardButton\n isHidden={!isHovering}\n isDisabled={isCopy}\n onClick={handleCopyToClipboard}\n mode={isCopy ? \"copied\" : \"copy\"}\n />\n </div>\n\n {renderedMessageContent}\n\n {canStopPendingMessage ? (\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onStop?.();\n }}\n data-testid=\"chat-message-stop\"\n aria-label={t(I18nKey.BUTTON$STOP)}\n aria-hidden={!showStopButton}\n tabIndex={showStopButton ? 0 : -1}\n className={cn(\n \"group absolute z-10 inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-[var(--oh-color-tertiary)] text-[var(--oh-foreground)] transition-opacity duration-150\",\n isSingleLinePendingMessage\n ? \"right-3 top-1/2 -translate-y-1/2\"\n : \"right-3 bottom-2.5\",\n showStopButton ? \"opacity-100\" : \"pointer-events-none opacity-0\",\n )}\n >\n <PendingStopIcon className=\"block h-7 w-7 max-w-none\" />\n </button>\n ) : null}\n\n {isCollapsed ? (\n <button\n type=\"button\"\n data-testid=\"chat-message-expand\"\n aria-expanded={false}\n aria-label={t(I18nKey.COMMON$VIEW_MORE)}\n className=\"absolute inset-0 z-[1] cursor-pointer rounded-xl border-0 bg-transparent p-0\"\n onClick={() => setIsExpanded(true)}\n />\n ) : null}\n\n {children}\n </article>\n );\n\n if (type === \"user\" && pendingStatus === \"error\") {\n return (\n <div className=\"flex w-fit max-w-full flex-col items-end gap-1.5 self-end last:mb-4\">\n {messageBubble}\n <div\n role=\"alert\"\n data-testid=\"chat-message-error\"\n className=\"flex items-center gap-2 text-xs text-[var(--oh-status-error)]\"\n >\n <span>{t(I18nKey.CHAT_INTERFACE$MESSAGE_SEND_FAILED)}</span>\n {onRetry ? (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"cursor-pointer rounded-md border border-[var(--oh-border)] px-2 py-1 text-xs font-normal text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]\"\n data-testid=\"chat-message-retry\"\n >\n {t(I18nKey.CHAT_INTERFACE$MESSAGE_RETRY)}\n </button>\n ) : null}\n {onDismiss ? (\n <button\n type=\"button\"\n onClick={onDismiss}\n className=\"cursor-pointer rounded-md border border-[var(--oh-border)] px-2 py-1 text-xs font-normal text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]\"\n data-testid=\"chat-message-dismiss\"\n >\n {t(I18nKey.CHAT_INTERFACE$MESSAGE_DISMISS)}\n </button>\n ) : null}\n </div>\n </div>\n );\n }\n\n if (type === \"user\" && pendingStatus === \"sending\") {\n return (\n <div className=\"flex w-full max-w-full flex-col last:mb-4\">\n {messageBubble}\n <div className=\"my-1 w-full py-1 text-sm\">\n <TextShimmer\n as=\"p\"\n role=\"status\"\n aria-live=\"polite\"\n data-testid=\"chat-message-sending\"\n className=\"block w-full text-sm font-normal\"\n duration={1}\n spread={2}\n >\n {t(I18nKey.CHAT_INTERFACE$MESSAGE_SENDING)}\n </TextShimmer>\n </div>\n </div>\n );\n }\n\n return messageBubble;\n}\n"],"mappings":"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"}
@@ -1 +1,2 @@
1
- export declare function ChatMessagesSkeleton(): import("react/jsx-runtime").JSX.Element;
1
+ import React from "react";
2
+ export declare function ChatMessagesSkeleton(): React.JSX.Element;
@@ -2,4 +2,4 @@ export interface ChatResumeAgentButtonProps {
2
2
  onAgentResumed: () => void;
3
3
  disabled?: boolean;
4
4
  }
5
- export declare function ChatResumeAgentButton({ onAgentResumed, disabled, }: ChatResumeAgentButtonProps): import("react/jsx-runtime").JSX.Element;
5
+ export declare function ChatResumeAgentButton({ onAgentResumed, disabled, }: ChatResumeAgentButtonProps): import("react").JSX.Element;
@@ -3,4 +3,4 @@ export interface ChatSendButtonProps {
3
3
  handleSubmit: () => void;
4
4
  disabled: boolean;
5
5
  }
6
- export declare function ChatSendButton({ buttonClassName, handleSubmit, disabled, }: ChatSendButtonProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function ChatSendButton({ buttonClassName, handleSubmit, disabled, }: ChatSendButtonProps): import("react").JSX.Element;
@@ -2,5 +2,5 @@ interface ChatStatusIndicatorProps {
2
2
  status: string;
3
3
  statusColor: string;
4
4
  }
5
- declare function ChatStatusIndicator({ status, statusColor, }: ChatStatusIndicatorProps): import("react/jsx-runtime").JSX.Element;
5
+ declare function ChatStatusIndicator({ status, statusColor, }: ChatStatusIndicatorProps): import("react").JSX.Element;
6
6
  export default ChatStatusIndicator;
@@ -1,4 +1,4 @@
1
1
  export interface ChatStopButtonProps {
2
2
  handleStop: () => void;
3
3
  }
4
- export declare function ChatStopButton({ handleStop }: ChatStopButtonProps): import("react/jsx-runtime").JSX.Element;
4
+ export declare function ChatStopButton({ handleStop }: ChatStopButtonProps): import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  interface ChatSuggestionsProps {
2
2
  onSuggestionsClick: (value: string) => void;
3
3
  }
4
- export declare function ChatSuggestions({ onSuggestionsClick }: ChatSuggestionsProps): import("react/jsx-runtime").JSX.Element;
4
+ export declare function ChatSuggestions({ onSuggestionsClick }: ChatSuggestionsProps): import("react").JSX.Element;
5
5
  export {};
@@ -1,3 +1,4 @@
1
+ import React from "react";
1
2
  interface ChatInputActionsProps {
2
3
  disabled: boolean;
3
4
  canSubmit?: boolean;
@@ -7,5 +8,5 @@ interface ChatInputActionsProps {
7
8
  buttonClassName?: string;
8
9
  handleSubmit?: () => void;
9
10
  }
10
- export declare function ChatInputActions({ disabled, canSubmit, hasStartedConversation, onAddFileClick, showButton, buttonClassName, handleSubmit, }: ChatInputActionsProps): import("react/jsx-runtime").JSX.Element;
11
+ export declare function ChatInputActions({ disabled, canSubmit, hasStartedConversation, onAddFileClick, showButton, buttonClassName, handleSubmit, }: ChatInputActionsProps): React.JSX.Element;
11
12
  export {};
@@ -25,5 +25,5 @@ interface ChatInputContainerProps {
25
25
  slashSelectedIndex?: number;
26
26
  onSlashSelect?: (item: SlashCommandItem) => void;
27
27
  }
28
- export declare function ChatInputContainer({ chatContainerRef, isDragOver, disabled, canSubmit, hasStartedConversation, isNewConversationPending, showButton, buttonClassName, chatInputRef, handleFileIconClick, handleSubmit, onDragOver, onDragLeave, onDrop, onInput, onPaste, onKeyDown, onFocus, onBlur, isSlashMenuOpen, slashItems, slashSelectedIndex, onSlashSelect, }: ChatInputContainerProps): import("react/jsx-runtime").JSX.Element;
28
+ export declare function ChatInputContainer({ chatContainerRef, isDragOver, disabled, canSubmit, hasStartedConversation, isNewConversationPending, showButton, buttonClassName, chatInputRef, handleFileIconClick, handleSubmit, onDragOver, onDragLeave, onDrop, onInput, onPaste, onKeyDown, onFocus, onBlur, isSlashMenuOpen, slashItems, slashSelectedIndex, onSlashSelect, }: ChatInputContainerProps): React.JSX.Element;
29
29
  export {};