@openhands/agent-canvas 1.4.0 → 1.5.1

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 (710) hide show
  1. package/README.md +11 -12
  2. package/README.windows.md +4 -2
  3. package/build/assets/{Trans-Ch-OVWEA.js → Trans-DqF_OEZB.js} +1 -1
  4. package/build/assets/{acp-providers-Sy2LKyMa.js → acp-providers-DerAmTyY.js} +1 -1
  5. package/build/assets/active-backend-context-B8rMv0X9.js +1 -0
  6. package/build/assets/{add-backend-modal-Bgy8anoR.js → add-backend-modal-CxC7BNEc.js} +1 -1
  7. package/build/assets/{agent-profiles-settings-3mmXljZX.js → agent-profiles-settings-BJb8YXR1.js} +1 -1
  8. package/build/assets/agent-server-compatibility-BWN-EIQn.js +1 -0
  9. package/build/assets/agent-server-conversation-service.api-DSPIkMwJ.js +41 -0
  10. package/build/assets/{agent-settings-B-W10B4E.js → agent-settings-CgCnqaAA.js} +2 -2
  11. package/build/assets/agent-settings-DDkSavD7.js +1 -0
  12. package/build/assets/{alert-banner-Bpf2NQJq.js → alert-banner-Dh51WURQ.js} +1 -1
  13. package/build/assets/api-key-entry-screen-iZc7n8AI.js +1 -0
  14. package/build/assets/app-settings-B5zyipxJ.js +1 -0
  15. package/build/assets/automation-detail-CZsu2CoM.js +2 -0
  16. package/build/assets/automation-export-BwRX6H32.js +2 -0
  17. package/build/assets/automations-list-lHAVzMoA.js +1 -0
  18. package/build/assets/{back-nav-button-CUS2mi-U.js → back-nav-button-DVknCcSP.js} +1 -1
  19. package/build/assets/backend-form-modal-RGcu909r.js +1 -0
  20. package/build/assets/{backend-synced-settings-badge-D9hZx05w.js → backend-synced-settings-badge-BSfN0AZA.js} +1 -1
  21. package/build/assets/{base-modal-BuF2f0YL.js → base-modal-CIF_785P.js} +1 -1
  22. package/build/assets/{bot-D7eUAuSB.js → bot-C-EA6685.js} +1 -1
  23. package/build/assets/{brand-button-vMVuyDXu.js → brand-button-B1izLAdR.js} +1 -1
  24. package/build/assets/{browser-BifzWIBd.js → browser-DKaeq_sT.js} +3 -3
  25. package/build/assets/{browser-tab-CkkqJnqw.js → browser-tab-qb_ftCxW.js} +1 -1
  26. package/build/assets/canvas-ui-COgjltGz.js +1 -0
  27. package/build/assets/{chat-send-button-B_jc5z5C.js → chat-send-button-BZHG2hAW.js} +1 -1
  28. package/build/assets/check-TbOEtHKj.js +1 -0
  29. package/build/assets/{chevron-down-CI8A6tet.js → chevron-down-D7IvFMBM.js} +1 -1
  30. package/build/assets/{circle-plus-check-toggle-C5YxjxvI.js → circle-plus-check-toggle-DoFIjVE0.js} +1 -1
  31. package/build/assets/client-source-BZK8vRs2.js +1 -0
  32. package/build/assets/cloud-funnel-analytics-Zcv57hfT.js +1 -0
  33. package/build/assets/{color-themes-DPBzNtVg.js → color-themes-CHizm1xF.js} +1 -1
  34. package/build/assets/{combobox-caret-DoObzqf4.js → combobox-caret-CxZpqoSR.js} +1 -1
  35. package/build/assets/{command-menu-D-JV3Wqm.js → command-menu-oTvKDU3Y.js} +1 -1
  36. package/build/assets/condenser-settings-BGlWn93P.js +1 -0
  37. package/build/assets/{confirmation-modal-BGLu6XJN.js → confirmation-modal-DGBWM2Ls.js} +1 -1
  38. package/build/assets/{context-menu-list-item-BD5_EaKN.js → context-menu-list-item-6psNyl7X.js} +1 -1
  39. package/build/assets/conversation-BoCYx8n2.js +89 -0
  40. package/build/assets/conversation-DgHqMjnY.js +1 -0
  41. package/build/assets/conversation-panel-78Rxh_-I.js +1 -0
  42. package/build/assets/conversation-service.api-_f9GlIEi.js +1 -0
  43. package/build/assets/{conversation-tab-empty-state-B2dDYEwf.js → conversation-tab-empty-state-CNUmIms2.js} +1 -1
  44. package/build/assets/{copy-3JCw_XFB.js → copy-D1YGjP-C.js} +1 -1
  45. package/build/assets/{copy-to-clipboard-button-CaR52OnA.js → copy-to-clipboard-button-CFzH_NOX.js} +1 -1
  46. package/build/assets/declaration-BGsHjPEW.js +1 -0
  47. package/build/assets/{device-verify-Dj6I4Iqe.js → device-verify-WBSjJBLH.js} +1 -1
  48. package/build/assets/{dropdown-classes-DJSXeLqc.js → dropdown-classes-D3wMJlXT.js} +1 -1
  49. package/build/assets/{ellipsis-button-C5Z-tPFp.js → ellipsis-button-CbNnHlIq.js} +1 -1
  50. package/build/assets/{entry.client-2_3ePAm0.js → entry.client-DNlPGxsu.js} +2 -2
  51. package/build/assets/{enum-filter-dropdown-DXbVwiNZ.js → enum-filter-dropdown-JLYv1t8L.js} +1 -1
  52. package/build/assets/{environment-switch-overlay-DZQfRGTx.js → environment-switch-overlay-B1PFO8P8.js} +1 -1
  53. package/build/assets/{extensions-hub-CLjmOGqS.js → extensions-hub-CCbLA7IM.js} +1 -1
  54. package/build/assets/{extensions-navigation-B5MeUiMq.js → extensions-navigation-CPNjMNvR.js} +1 -1
  55. package/build/assets/{external-link-D2zJjE9G.js → external-link-lhdITPqq.js} +1 -1
  56. package/build/assets/files-tab-y4K7EXBO.js +1 -0
  57. package/build/assets/{form-control-classes-ChpNBe9n.js → form-control-classes-CbdN5aO3.js} +1 -1
  58. package/build/assets/format-time-delta-DhDbkD7V.js +1 -0
  59. package/build/assets/git-provider-icon-ITvsH4Ko.js +1 -0
  60. package/build/assets/home-BwbeOWwU.js +1 -0
  61. package/build/assets/home-DKPGQ5P3.js +1 -0
  62. package/build/assets/index-home-Bko2Itv5.js +1 -0
  63. package/build/assets/install-server-modal-Qk1gwyI8.js +1 -0
  64. package/build/assets/{launch-V_3Rp7WS.js → launch-CAGavYl-.js} +1 -1
  65. package/build/assets/lesson-plan-DMCPdtrf.js +4 -0
  66. package/build/assets/{list-todo-BfH6yYUK.js → list-todo-CAtvkzcy.js} +1 -1
  67. package/build/assets/llm-not-configured-banner-C1ktyb3C.js +27 -0
  68. package/build/assets/llm-settings-BBsZFi9l.js +1 -0
  69. package/build/assets/llm-settings-DFkJQr_w.js +1 -0
  70. package/build/assets/llm-subscription-service-Casyzgn1.js +1 -0
  71. package/build/assets/loader-circle-CsAsfLIs.js +1 -0
  72. package/build/assets/{loading-spinner-BLdswi6q.js → loading-spinner-BcdnT0mN.js} +1 -1
  73. package/build/assets/manage-backends-modal-CKQ46rvw.js +1 -0
  74. package/build/assets/manifest-03478bbf.js +1 -0
  75. package/build/assets/{map-provider-BM2SJarp.js → map-provider-BbIb12oh.js} +1 -1
  76. package/build/assets/{markdown-renderer-DMT7Zkpd.js → markdown-renderer-B4V2OMFP.js} +1 -1
  77. package/build/assets/{mcp-BQufNPZ6.js → mcp-BapoJsDc.js} +2 -2
  78. package/build/assets/{messages-BnJCqnFf.js → messages-CUBFMY5o.js} +26 -26
  79. package/build/assets/{modal-body-DouOE5KH.js → modal-body-Cc2zp0xb.js} +1 -1
  80. package/build/assets/{modal-classes-Cf-4tbHz.js → modal-classes-3qT9Ap7Q.js} +1 -1
  81. package/build/assets/{modal-close-button-B6CfxxJj.js → modal-close-button-BcIBUdSq.js} +1 -1
  82. package/build/assets/model-selector-DJrMrFAr.js +1 -0
  83. package/build/assets/onboarding-6NMkdNxV.js +1 -0
  84. package/build/assets/onboarding-modal-Q4AnpIdg.js +1 -0
  85. package/build/assets/organization-service.api-vrRNwOma.js +1 -0
  86. package/build/assets/path-utils-PNfCKQDV.js +1 -0
  87. package/build/assets/{pencil-Dj2XjKmI.js → pencil-CWhApFIT.js} +1 -1
  88. package/build/assets/{plan-components-CcCBmCzW.js → plan-components-BdZXPyZU.js} +1 -1
  89. package/build/assets/{planner-tab-Dhyqcqmb.js → planner-tab-ByOw1he8.js} +1 -1
  90. package/build/assets/plugins-management-service-B75jyC56.js +1 -0
  91. package/build/assets/profiles-service.api-BQTklD5D.js +1 -0
  92. package/build/assets/providers-DfTB2gPd.js +1 -0
  93. package/build/assets/proxy-B3tCGf0X.js +1 -0
  94. package/build/assets/{recommended-automations-launcher-CTcGTl4d.js → recommended-automations-launcher-Bj7PuHY1.js} +1 -1
  95. package/build/assets/{refresh-cw-DM82EIyx.js → refresh-cw-B9B7-vsy.js} +1 -1
  96. package/build/assets/root-CDnuTToz.js +2 -0
  97. package/build/assets/root-CYWeTrWE.css +1 -0
  98. package/build/assets/root-layout-DfYVlcRG.js +2 -0
  99. package/build/assets/{runtime-waiting-state-BsXLElvN.js → runtime-waiting-state-CnyVhX4T.js} +1 -1
  100. package/build/assets/schema-field-CUwk4wrQ.js +1 -0
  101. package/build/assets/sdk-section-page-DLLNrYjI.js +1 -0
  102. package/build/assets/{sdk-settings-schema-Cv7M9eSe.js → sdk-settings-schema-CLR01YIK.js} +1 -1
  103. package/build/assets/search-dIQ09UY2.js +1 -0
  104. package/build/assets/secrets-service-CvyPWJhg.js +1 -0
  105. package/build/assets/{secrets-settings-Cx6yJlyb.js → secrets-settings-CHy72A5C.js} +1 -1
  106. package/build/assets/{segmented-toggle-DyQqPhoD.js → segmented-toggle-kzwZkLaj.js} +1 -1
  107. package/build/assets/settings-B9S8UVQr.js +1 -0
  108. package/build/assets/{settings-dropdown-input-BjunGXJb.js → settings-dropdown-input-Dhx9ErGd.js} +1 -1
  109. package/build/assets/{settings-index-D6sxWSRk.js → settings-index-BKDl2CQ-.js} +1 -1
  110. package/build/assets/{settings-input-bD6npsDm.js → settings-input-BsgQWS5R.js} +1 -1
  111. package/build/assets/{settings-list-classes-Dp_OgzN0.js → settings-list-classes-DSJJX99U.js} +1 -1
  112. package/build/assets/settings-modal-DeK11CyT.js +1 -0
  113. package/build/assets/settings-service.api-DXk5TdeJ.js +1 -0
  114. package/build/assets/{settings-switch-5cuxl8Dc.js → settings-switch-Bes8dIlV.js} +1 -1
  115. package/build/assets/{settings-utils-BMdG65By.js → settings-utils-DzCVfiR3.js} +1 -1
  116. package/build/assets/shared-conversation-9atDzTR4.js +1 -0
  117. package/build/assets/{sidebar-layout-DuzJMMw-.js → sidebar-layout-Bm7pa3Vk.js} +1 -1
  118. package/build/assets/{sidebar-mobile-menu-toggle-VvvX32iF.js → sidebar-mobile-menu-toggle-giMMZctn.js} +1 -1
  119. package/build/assets/{sidebar-nav-link-5AlTT5-j.js → sidebar-nav-link-CHqyFXwV.js} +1 -1
  120. package/build/assets/{sidebar-store-CZuE8AH5.js → sidebar-store-uiUXBU1N.js} +1 -1
  121. package/build/assets/{skill-card-pill-row-eTIkE4nz.js → skill-card-pill-row-BPYKQ3IN.js} +1 -1
  122. package/build/assets/skills-plugins-Tropusio.js +1 -0
  123. package/build/assets/{skills-settings-BUv04tSc.js → skills-settings-BvzBBCWk.js} +2 -2
  124. package/build/assets/{square-chevron-right-Czw3FFWc.js → square-chevron-right-DE-JN-2Z.js} +1 -1
  125. package/build/assets/{styled-tooltip-CgX2oRaK.js → styled-tooltip-B14i_Uac.js} +1 -1
  126. package/build/assets/{suspense-BO1Tl_Vf.js → suspense-DmZ3MSSh.js} +1 -1
  127. package/build/assets/{task-list-tab-0k9PhuqO.js → task-list-tab-DyfgG4MC.js} +1 -1
  128. package/build/assets/telemetry-C5JMEfqB.js +2 -0
  129. package/build/assets/{terminal-B61WrJdS.js → terminal-DRXt2Lr4.js} +1 -1
  130. package/build/assets/{toggle-switch-2j5wwR85.js → toggle-switch-DX_k418f.js} +1 -1
  131. package/build/assets/{trash-2-Be_7y3Mn.js → trash-2-BU6BlW4i.js} +1 -1
  132. package/build/assets/{typography-D8mHDeNG.js → typography-CzfoD9DY.js} +1 -1
  133. package/build/assets/use-acp-credential-form-Bm8qXdlc.js +1 -0
  134. package/build/assets/{use-activate-agent-profile-20v1xU0H.js → use-activate-agent-profile-DlykqEfN.js} +1 -1
  135. package/build/assets/{use-active-agent-profile-BkJN7Xsy.js → use-active-agent-profile-hI-x-UBa.js} +1 -1
  136. package/build/assets/{use-active-conversation-DOZVSVtU.js → use-active-conversation-2qeez40F.js} +1 -1
  137. package/build/assets/use-agent-profiles-0pr5bLS7.js +1 -0
  138. package/build/assets/{use-agent-state-DHZO1obC.js → use-agent-state-C6peDXUm.js} +1 -1
  139. package/build/assets/use-backends-health-CLHPitJM.js +1 -0
  140. package/build/assets/{use-can-manage-org-profiles-C-OhWVBS.js → use-can-manage-org-profiles-Ck_bsNbH.js} +1 -1
  141. package/build/assets/use-cloud-current-user-id-DUCSxNjY.js +1 -0
  142. package/build/assets/use-config-B5r8erYt.js +1 -0
  143. package/build/assets/use-create-conversation-r1JHfKO5.js +1 -0
  144. package/build/assets/{use-create-secret-D0HCOZFu.js → use-create-secret-Cf2N11d2.js} +1 -1
  145. package/build/assets/{use-event-store-DjgU4wfO.js → use-event-store-Bbaz51GR.js} +1 -1
  146. package/build/assets/{use-handle-plan-click-DyRASKMC.js → use-handle-plan-click-CsAW3FlH.js} +1 -1
  147. package/build/assets/use-is-authed-BezEyfeh.js +1 -0
  148. package/build/assets/use-llm-profiles-Dr5__SlZ.js +1 -0
  149. package/build/assets/use-plugins-marketplace-BplU65ae.js +1 -0
  150. package/build/assets/use-runtime-is-ready-vCFOcLFa.js +1 -0
  151. package/build/assets/use-save-agent-profile-RqUGqTv6.js +1 -0
  152. package/build/assets/use-save-settings-Chvzeu2s.js +1 -0
  153. package/build/assets/use-settings-CyxSlyTQ.js +1 -0
  154. package/build/assets/use-settings-nav-items-zEkSO_Bf.js +16 -0
  155. package/build/assets/use-skills-xrVoKYrF.js +1 -0
  156. package/build/assets/{use-task-list-AVBLbbcR.js → use-task-list-CfisapBW.js} +1 -1
  157. package/build/assets/use-tracking-D2Qg5Lpd.js +1 -0
  158. package/build/assets/{use-user-conversation-zpx7I18x.js → use-user-conversation-CnE4zhOA.js} +1 -1
  159. package/build/assets/{useMutation-DrCAVg5w.js → useMutation-u8UgRgDK.js} +1 -1
  160. package/build/assets/{useMutationState-D8QN0ZCy.js → useMutationState-OnAsCLA_.js} +1 -1
  161. package/build/assets/{useQueries-DClgUTc7.js → useQueries-BpIlT8Mt.js} +1 -1
  162. package/build/assets/{useQuery-CRBP8vIS.js → useQuery-D5pEZbY0.js} +1 -1
  163. package/build/assets/{useTranslation-CDRCKC9-.js → useTranslation-Cbf5AGg_.js} +1 -1
  164. package/build/assets/{utils-D3U3rlqr.js → utils-DB9LsAzA.js} +1 -1
  165. package/build/assets/{vendor~browser-tab-Di0kh5Zw.js → vendor~browser-tab-CsMb-pta.js} +1 -1
  166. package/build/assets/{vendor~browser-Cvg7jXCP.js → vendor~browser-wXQ-WZEC.js} +1 -1
  167. package/build/assets/{vendor~entry.client-9tWQ_Ugw.js → vendor~entry.client-DDuH4--y.js} +1 -1
  168. package/build/assets/{vendor~entry.client-D6BtSOtn.js → vendor~entry.client-DQGrNspu.js} +1 -1
  169. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~dhilvkxv-eGLBu60s.js +2 -0
  170. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~iztiaf2o-rqo6vRFz.js +185 -0
  171. package/build/assets/{vendor~files-tab-B02k3xvx.js → vendor~files-tab-B-5fBohe.js} +1 -1
  172. package/build/assets/{vendor~home~conversation-panel~conversation-CYMF9JYB.js → vendor~index-home~home~conversation-panel~conversation-ChmYLVgz.js} +1 -1
  173. package/build/assets/vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BD7v71DM.js +2 -0
  174. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BD0GaRGa.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BT05Osu4.js} +1 -1
  175. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-D7EUmQ8Y.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DgzWSMRc.js} +1 -1
  176. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-d8aETPbZ.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DqZatR3B.js} +1 -1
  177. package/build/assets/{vendor~launch-CHXA9cJu.js → vendor~launch-_Km3J77E.js} +1 -1
  178. package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~ivvrgjsa-BlIZPCXX.js → vendor~module-D5a_AClf.js} +1 -1
  179. package/build/assets/{vendor~root-layout~conversation-panel~conversation-CpiTHpHl.js → vendor~root-layout~conversation-panel~conversation-8tIsyrPj.js} +1 -1
  180. package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-_TdZcNMD.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-BrguKXCn.js} +1 -1
  181. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation-Cn2jwSga.js → vendor~root-layout~index-home~home~conversation-panel~conversation-BTvhGHHG.js} +1 -1
  182. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-CZM4hwUT.js → vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation~aler~gfu7qdtz-BOKQkbc6.js} +1 -1
  183. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~settings~settings-index~agen~enjl5xdm-B0EIDu4M.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~ftka0fnu-cFNmfAE6.js} +2 -2
  184. package/build/assets/{verification-settings-D576N2xa.js → verification-settings-CfkrXoSa.js} +1 -1
  185. package/build/assets/x-ZE4iplpF.js +1 -0
  186. package/build/index.html +4 -4
  187. package/build/locales/ar/openhands.json +9 -0
  188. package/build/locales/ca/openhands.json +9 -0
  189. package/build/locales/de/openhands.json +9 -0
  190. package/build/locales/en/openhands.json +9 -0
  191. package/build/locales/es/openhands.json +9 -0
  192. package/build/locales/fr/openhands.json +9 -0
  193. package/build/locales/it/openhands.json +9 -0
  194. package/build/locales/ja/openhands.json +9 -0
  195. package/build/locales/ko-KR/openhands.json +9 -0
  196. package/build/locales/no/openhands.json +9 -0
  197. package/build/locales/pt/openhands.json +9 -0
  198. package/build/locales/tr/openhands.json +9 -0
  199. package/build/locales/uk/openhands.json +9 -0
  200. package/build/locales/zh-CN/openhands.json +9 -0
  201. package/build/locales/zh-TW/openhands.json +9 -0
  202. package/config/defaults.json +5 -4
  203. package/dist/api/agent-server-adapter.cjs +3 -3
  204. package/dist/api/agent-server-adapter.cjs.map +1 -1
  205. package/dist/api/agent-server-adapter.d.ts +9 -1
  206. package/dist/api/agent-server-adapter.js +105 -102
  207. package/dist/api/agent-server-adapter.js.map +1 -1
  208. package/dist/api/agent-server-config.cjs +1 -1
  209. package/dist/api/agent-server-config.cjs.map +1 -1
  210. package/dist/api/agent-server-config.d.ts +3 -0
  211. package/dist/api/agent-server-config.js +45 -23
  212. package/dist/api/agent-server-config.js.map +1 -1
  213. package/dist/api/backend-registry/auth.cjs +1 -1
  214. package/dist/api/backend-registry/auth.cjs.map +1 -1
  215. package/dist/api/backend-registry/auth.js +1 -1
  216. package/dist/api/backend-registry/auth.js.map +1 -1
  217. package/dist/api/backend-registry/default-backend.cjs +1 -1
  218. package/dist/api/backend-registry/default-backend.cjs.map +1 -1
  219. package/dist/api/backend-registry/default-backend.d.ts +3 -0
  220. package/dist/api/backend-registry/default-backend.js +22 -10
  221. package/dist/api/backend-registry/default-backend.js.map +1 -1
  222. package/dist/api/backend-registry/storage.cjs +1 -1
  223. package/dist/api/backend-registry/storage.cjs.map +1 -1
  224. package/dist/api/backend-registry/storage.js +38 -33
  225. package/dist/api/backend-registry/storage.js.map +1 -1
  226. package/dist/api/backend-registry/types.d.ts +2 -0
  227. package/dist/api/canvas-ui-client-tool.cjs +38 -0
  228. package/dist/api/canvas-ui-client-tool.cjs.map +1 -0
  229. package/dist/api/canvas-ui-client-tool.d.ts +14 -0
  230. package/dist/api/canvas-ui-client-tool.js +47 -0
  231. package/dist/api/canvas-ui-client-tool.js.map +1 -0
  232. package/dist/api/client-source.cjs +2 -0
  233. package/dist/api/client-source.cjs.map +1 -0
  234. package/dist/api/client-source.d.ts +9 -0
  235. package/dist/api/client-source.js +10 -0
  236. package/dist/api/client-source.js.map +1 -0
  237. package/dist/api/cloud/client.cjs +2 -0
  238. package/dist/api/cloud/client.cjs.map +1 -0
  239. package/dist/api/cloud/client.d.ts +4 -0
  240. package/dist/api/cloud/client.js +38 -0
  241. package/dist/api/cloud/client.js.map +1 -0
  242. package/dist/api/cloud/conversation-service.api.cjs +1 -1
  243. package/dist/api/cloud/conversation-service.api.cjs.map +1 -1
  244. package/dist/api/cloud/conversation-service.api.js +35 -33
  245. package/dist/api/cloud/conversation-service.api.js.map +1 -1
  246. package/dist/api/cloud/organization-service.api.cjs +1 -1
  247. package/dist/api/cloud/organization-service.api.cjs.map +1 -1
  248. package/dist/api/cloud/organization-service.api.js +11 -10
  249. package/dist/api/cloud/organization-service.api.js.map +1 -1
  250. package/dist/api/cloud/proxy.cjs +1 -1
  251. package/dist/api/cloud/proxy.cjs.map +1 -1
  252. package/dist/api/cloud/proxy.d.ts +2 -40
  253. package/dist/api/cloud/proxy.js +14 -39
  254. package/dist/api/cloud/proxy.js.map +1 -1
  255. package/dist/api/conversation-metadata-store.cjs +1 -1
  256. package/dist/api/conversation-metadata-store.cjs.map +1 -1
  257. package/dist/api/conversation-metadata-store.d.ts +2 -9
  258. package/dist/api/conversation-metadata-store.js +13 -9
  259. package/dist/api/conversation-metadata-store.js.map +1 -1
  260. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
  261. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
  262. package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +2 -1
  263. package/dist/api/conversation-service/agent-server-conversation-service.api.js +98 -88
  264. package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
  265. package/dist/api/conversation-service/agent-server-conversation-service.types.d.ts +5 -0
  266. package/dist/api/device-flow-client.cjs +1 -1
  267. package/dist/api/device-flow-client.cjs.map +1 -1
  268. package/dist/api/device-flow-client.d.ts +4 -58
  269. package/dist/api/device-flow-client.js +8 -98
  270. package/dist/api/device-flow-client.js.map +1 -1
  271. package/dist/api/git-service/agent-server-git-service.api.cjs +1 -1
  272. package/dist/api/git-service/agent-server-git-service.api.cjs.map +1 -1
  273. package/dist/api/git-service/agent-server-git-service.api.d.ts +10 -2
  274. package/dist/api/git-service/agent-server-git-service.api.js +107 -40
  275. package/dist/api/git-service/agent-server-git-service.api.js.map +1 -1
  276. package/dist/api/open-hands.types.d.ts +11 -0
  277. package/dist/api/option-service/option-service.api.cjs +1 -1
  278. package/dist/api/option-service/option-service.api.cjs.map +1 -1
  279. package/dist/api/option-service/option-service.api.js +0 -1
  280. package/dist/api/option-service/option-service.api.js.map +1 -1
  281. package/dist/api/option-service/option.types.d.ts +0 -1
  282. package/dist/api/secrets-service.cjs +1 -1
  283. package/dist/api/secrets-service.cjs.map +1 -1
  284. package/dist/api/secrets-service.js +15 -14
  285. package/dist/api/secrets-service.js.map +1 -1
  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 +73 -64
  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-content-helpers/get-observation-content.cjs +2 -2
  291. package/dist/components/conversation-events/chat/event-content-helpers/get-observation-content.cjs.map +1 -1
  292. package/dist/components/conversation-events/chat/event-content-helpers/get-observation-content.js +2 -0
  293. package/dist/components/conversation-events/chat/event-content-helpers/get-observation-content.js.map +1 -1
  294. package/dist/components/features/backends/backend-form-modal.cjs +1 -1
  295. package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
  296. package/dist/components/features/backends/backend-form-modal.d.ts +4 -2
  297. package/dist/components/features/backends/backend-form-modal.js +108 -101
  298. package/dist/components/features/backends/backend-form-modal.js.map +1 -1
  299. package/dist/components/features/backends/backend-row.cjs +1 -1
  300. package/dist/components/features/backends/backend-row.cjs.map +1 -1
  301. package/dist/components/features/backends/backend-row.js +2 -1
  302. package/dist/components/features/backends/backend-row.js.map +1 -1
  303. package/dist/components/features/backends/backend-selector.cjs +1 -1
  304. package/dist/components/features/backends/backend-selector.cjs.map +1 -1
  305. package/dist/components/features/backends/backend-selector.js +51 -51
  306. package/dist/components/features/backends/backend-selector.js.map +1 -1
  307. package/dist/components/features/backends/device-flow-auth.cjs +1 -1
  308. package/dist/components/features/backends/device-flow-auth.cjs.map +1 -1
  309. package/dist/components/features/backends/device-flow-auth.d.ts +4 -1
  310. package/dist/components/features/backends/device-flow-auth.js +38 -38
  311. package/dist/components/features/backends/device-flow-auth.js.map +1 -1
  312. package/dist/components/features/chat/chat-interface.cjs +2 -2
  313. package/dist/components/features/chat/chat-interface.cjs.map +1 -1
  314. package/dist/components/features/chat/chat-interface.js +173 -165
  315. package/dist/components/features/chat/chat-interface.js.map +1 -1
  316. package/dist/components/features/chat/components/chat-input-actions.cjs +1 -1
  317. package/dist/components/features/chat/components/chat-input-actions.cjs.map +1 -1
  318. package/dist/components/features/chat/components/chat-input-actions.d.ts +2 -1
  319. package/dist/components/features/chat/components/chat-input-actions.js +44 -43
  320. package/dist/components/features/chat/components/chat-input-actions.js.map +1 -1
  321. package/dist/components/features/chat/components/chat-input-container.cjs +1 -1
  322. package/dist/components/features/chat/components/chat-input-container.cjs.map +1 -1
  323. package/dist/components/features/chat/components/chat-input-container.d.ts +2 -1
  324. package/dist/components/features/chat/components/chat-input-container.js +20 -19
  325. package/dist/components/features/chat/components/chat-input-container.js.map +1 -1
  326. package/dist/components/features/chat/components/chat-input-profile-picker.cjs +1 -1
  327. package/dist/components/features/chat/components/chat-input-profile-picker.cjs.map +1 -1
  328. package/dist/components/features/chat/components/chat-input-profile-picker.js +44 -32
  329. package/dist/components/features/chat/components/chat-input-profile-picker.js.map +1 -1
  330. package/dist/components/features/chat/components/resolve-picker-kind.cjs +1 -1
  331. package/dist/components/features/chat/components/resolve-picker-kind.cjs.map +1 -1
  332. package/dist/components/features/chat/components/resolve-picker-kind.d.ts +10 -22
  333. package/dist/components/features/chat/components/resolve-picker-kind.js +6 -3
  334. package/dist/components/features/chat/components/resolve-picker-kind.js.map +1 -1
  335. package/dist/components/features/chat/custom-chat-input.cjs +1 -1
  336. package/dist/components/features/chat/custom-chat-input.cjs.map +1 -1
  337. package/dist/components/features/chat/custom-chat-input.d.ts +2 -1
  338. package/dist/components/features/chat/custom-chat-input.js +52 -51
  339. package/dist/components/features/chat/custom-chat-input.js.map +1 -1
  340. package/dist/components/features/chat/interactive-chat-box.cjs +1 -1
  341. package/dist/components/features/chat/interactive-chat-box.cjs.map +1 -1
  342. package/dist/components/features/chat/interactive-chat-box.d.ts +2 -1
  343. package/dist/components/features/chat/interactive-chat-box.js +9 -8
  344. package/dist/components/features/chat/interactive-chat-box.js.map +1 -1
  345. package/dist/components/features/diff-viewer/commit-list.cjs +2 -0
  346. package/dist/components/features/diff-viewer/commit-list.cjs.map +1 -0
  347. package/dist/components/features/diff-viewer/commit-list.d.ts +13 -0
  348. package/dist/components/features/diff-viewer/commit-list.js +27 -0
  349. package/dist/components/features/diff-viewer/commit-list.js.map +1 -0
  350. package/dist/components/features/diff-viewer/commit-row.cjs +2 -0
  351. package/dist/components/features/diff-viewer/commit-row.cjs.map +1 -0
  352. package/dist/components/features/diff-viewer/commit-row.d.ts +14 -0
  353. package/dist/components/features/diff-viewer/commit-row.js +59 -0
  354. package/dist/components/features/diff-viewer/commit-row.js.map +1 -0
  355. package/dist/components/features/diff-viewer/file-diff-viewer.cjs +1 -1
  356. package/dist/components/features/diff-viewer/file-diff-viewer.cjs.map +1 -1
  357. package/dist/components/features/diff-viewer/file-diff-viewer.d.ts +7 -1
  358. package/dist/components/features/diff-viewer/file-diff-viewer.js +40 -39
  359. package/dist/components/features/diff-viewer/file-diff-viewer.js.map +1 -1
  360. package/dist/components/features/plugins/plugin-detail-modal.d.ts +2 -1
  361. package/dist/components/providers/agent-server-ui-providers.cjs +1 -1
  362. package/dist/components/providers/agent-server-ui-providers.cjs.map +1 -1
  363. package/dist/components/providers/agent-server-ui-providers.d.ts +4 -2
  364. package/dist/components/providers/agent-server-ui-providers.js +9 -2
  365. package/dist/components/providers/agent-server-ui-providers.js.map +1 -1
  366. package/dist/components/providers/index.cjs +1 -1
  367. package/dist/components/providers/index.d.ts +1 -2
  368. package/dist/components/providers/index.js +0 -1
  369. package/dist/components/providers/telemetry-provider.cjs +2 -0
  370. package/dist/components/providers/telemetry-provider.cjs.map +1 -0
  371. package/dist/components/providers/telemetry-provider.d.ts +6 -0
  372. package/dist/components/providers/telemetry-provider.js +64 -0
  373. package/dist/components/providers/telemetry-provider.js.map +1 -0
  374. package/dist/components/shared/modals/settings/settings-modal.cjs +1 -1
  375. package/dist/components/shared/modals/settings/settings-modal.cjs.map +1 -1
  376. package/dist/components/shared/modals/settings/settings-modal.js +23 -22
  377. package/dist/components/shared/modals/settings/settings-modal.js.map +1 -1
  378. package/dist/config/defaults.cjs +1 -1
  379. package/dist/config/defaults.cjs.map +1 -1
  380. package/dist/config/defaults.js +5 -4
  381. package/dist/config/defaults.js.map +1 -1
  382. package/dist/constants/acp-providers.cjs.map +1 -1
  383. package/dist/constants/acp-providers.d.ts +1 -1
  384. package/dist/constants/acp-providers.js.map +1 -1
  385. package/dist/constants/canvas-ui.cjs +2 -0
  386. package/dist/constants/canvas-ui.cjs.map +1 -0
  387. package/dist/constants/canvas-ui.d.ts +8 -0
  388. package/dist/constants/canvas-ui.js +6 -0
  389. package/dist/constants/canvas-ui.js.map +1 -0
  390. package/dist/contexts/conversation-websocket-context.cjs +3 -3
  391. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  392. package/dist/contexts/conversation-websocket-context.js +197 -204
  393. package/dist/contexts/conversation-websocket-context.js.map +1 -1
  394. package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
  395. package/dist/hooks/mutation/use-create-conversation.cjs.map +1 -1
  396. package/dist/hooks/mutation/use-create-conversation.d.ts +2 -1
  397. package/dist/hooks/mutation/use-create-conversation.js +52 -52
  398. package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
  399. package/dist/hooks/mutation/use-save-settings.cjs +1 -1
  400. package/dist/hooks/mutation/use-save-settings.cjs.map +1 -1
  401. package/dist/hooks/mutation/use-save-settings.d.ts +3 -1
  402. package/dist/hooks/mutation/use-save-settings.js +6 -5
  403. package/dist/hooks/mutation/use-save-settings.js.map +1 -1
  404. package/dist/hooks/query/query-keys.cjs +1 -1
  405. package/dist/hooks/query/query-keys.cjs.map +1 -1
  406. package/dist/hooks/query/query-keys.d.ts +2 -0
  407. package/dist/hooks/query/query-keys.js +4 -1
  408. package/dist/hooks/query/query-keys.js.map +1 -1
  409. package/dist/hooks/query/use-backends-health.cjs +1 -1
  410. package/dist/hooks/query/use-backends-health.cjs.map +1 -1
  411. package/dist/hooks/query/use-backends-health.js +50 -48
  412. package/dist/hooks/query/use-backends-health.js.map +1 -1
  413. package/dist/hooks/query/use-cloud-organizations.cjs +1 -1
  414. package/dist/hooks/query/use-cloud-organizations.cjs.map +1 -1
  415. package/dist/hooks/query/use-cloud-organizations.d.ts +1 -0
  416. package/dist/hooks/query/use-cloud-organizations.js +5 -2
  417. package/dist/hooks/query/use-cloud-organizations.js.map +1 -1
  418. package/dist/hooks/query/use-commit-changes.cjs +2 -0
  419. package/dist/hooks/query/use-commit-changes.cjs.map +1 -0
  420. package/dist/hooks/query/use-commit-changes.d.ts +5 -0
  421. package/dist/hooks/query/use-commit-changes.js +34 -0
  422. package/dist/hooks/query/use-commit-changes.js.map +1 -0
  423. package/dist/hooks/query/use-task-polling.cjs +1 -1
  424. package/dist/hooks/query/use-task-polling.cjs.map +1 -1
  425. package/dist/hooks/query/use-task-polling.d.ts +3 -2
  426. package/dist/hooks/query/use-task-polling.js +53 -40
  427. package/dist/hooks/query/use-task-polling.js.map +1 -1
  428. package/dist/hooks/query/use-unified-git-commits.cjs +2 -0
  429. package/dist/hooks/query/use-unified-git-commits.cjs.map +1 -0
  430. package/dist/hooks/query/use-unified-git-commits.d.ts +10 -0
  431. package/dist/hooks/query/use-unified-git-commits.js +41 -0
  432. package/dist/hooks/query/use-unified-git-commits.js.map +1 -0
  433. package/dist/hooks/query/use-unified-git-diff.cjs +1 -1
  434. package/dist/hooks/query/use-unified-git-diff.cjs.map +1 -1
  435. package/dist/hooks/query/use-unified-git-diff.d.ts +5 -0
  436. package/dist/hooks/query/use-unified-git-diff.js +11 -4
  437. package/dist/hooks/query/use-unified-git-diff.js.map +1 -1
  438. package/dist/hooks/use-acp-model-context.cjs +1 -1
  439. package/dist/hooks/use-acp-model-context.cjs.map +1 -1
  440. package/dist/hooks/use-acp-model-context.d.ts +4 -1
  441. package/dist/hooks/use-acp-model-context.js +9 -8
  442. package/dist/hooks/use-acp-model-context.js.map +1 -1
  443. package/dist/hooks/use-auto-refresh-files-on-edit.cjs +1 -1
  444. package/dist/hooks/use-auto-refresh-files-on-edit.cjs.map +1 -1
  445. package/dist/hooks/use-auto-refresh-files-on-edit.js +1 -1
  446. package/dist/hooks/use-auto-refresh-files-on-edit.js.map +1 -1
  447. package/dist/hooks/use-chat-input-model-state.cjs.map +1 -1
  448. package/dist/hooks/use-chat-input-model-state.d.ts +2 -1
  449. package/dist/hooks/use-chat-input-model-state.js.map +1 -1
  450. package/dist/hooks/use-chat-input-profile-state.cjs +1 -1
  451. package/dist/hooks/use-chat-input-profile-state.cjs.map +1 -1
  452. package/dist/hooks/use-chat-input-profile-state.d.ts +1 -10
  453. package/dist/hooks/use-chat-input-profile-state.js +42 -15
  454. package/dist/hooks/use-chat-input-profile-state.js.map +1 -1
  455. package/dist/hooks/use-device-flow.cjs +1 -1
  456. package/dist/hooks/use-device-flow.cjs.map +1 -1
  457. package/dist/hooks/use-device-flow.d.ts +4 -1
  458. package/dist/hooks/use-device-flow.js +42 -40
  459. package/dist/hooks/use-device-flow.js.map +1 -1
  460. package/dist/hooks/use-telemetry.cjs +1 -1
  461. package/dist/hooks/use-telemetry.cjs.map +1 -1
  462. package/dist/hooks/use-telemetry.d.ts +3 -3
  463. package/dist/hooks/use-telemetry.js +16 -22
  464. package/dist/hooks/use-telemetry.js.map +1 -1
  465. package/dist/hooks/use-tracking.cjs +1 -1
  466. package/dist/hooks/use-tracking.cjs.map +1 -1
  467. package/dist/hooks/use-tracking.d.ts +5 -5
  468. package/dist/hooks/use-tracking.js +37 -37
  469. package/dist/hooks/use-tracking.js.map +1 -1
  470. package/dist/i18n/declaration.cjs +1 -1
  471. package/dist/i18n/declaration.cjs.map +1 -1
  472. package/dist/i18n/declaration.d.ts +9 -0
  473. package/dist/i18n/declaration.js +1 -1
  474. package/dist/i18n/declaration.js.map +1 -1
  475. package/dist/i18n/index.cjs +1 -1
  476. package/dist/i18n/index.cjs.map +1 -1
  477. package/dist/i18n/index.js +19 -18
  478. package/dist/i18n/index.js.map +1 -1
  479. package/dist/i18n/translation.cjs +2 -2
  480. package/dist/i18n/translation.cjs.map +1 -1
  481. package/dist/i18n/translation.js +153 -0
  482. package/dist/i18n/translation.js.map +1 -1
  483. package/dist/index.cjs +1 -1
  484. package/dist/index.js +32 -32
  485. package/dist/lib/index.cjs +1 -1
  486. package/dist/lib/index.d.ts +2 -2
  487. package/dist/lib/index.js +1 -1
  488. package/dist/locales/ar/openhands.json +9 -0
  489. package/dist/locales/ca/openhands.json +9 -0
  490. package/dist/locales/de/openhands.json +9 -0
  491. package/dist/locales/en/openhands.json +9 -0
  492. package/dist/locales/es/openhands.json +9 -0
  493. package/dist/locales/fr/openhands.json +9 -0
  494. package/dist/locales/it/openhands.json +9 -0
  495. package/dist/locales/ja/openhands.json +9 -0
  496. package/dist/locales/ko-KR/openhands.json +9 -0
  497. package/dist/locales/no/openhands.json +9 -0
  498. package/dist/locales/pt/openhands.json +9 -0
  499. package/dist/locales/tr/openhands.json +9 -0
  500. package/dist/locales/uk/openhands.json +9 -0
  501. package/dist/locales/zh-CN/openhands.json +9 -0
  502. package/dist/locales/zh-TW/openhands.json +9 -0
  503. package/dist/node_modules/@openhands/typescript-client/dist/client/cloud-client.cjs +2 -0
  504. package/dist/node_modules/@openhands/typescript-client/dist/client/cloud-client.cjs.map +1 -0
  505. package/dist/node_modules/@openhands/typescript-client/dist/client/cloud-client.js +351 -0
  506. package/dist/node_modules/@openhands/typescript-client/dist/client/cloud-client.js.map +1 -0
  507. package/dist/node_modules/@openhands/typescript-client/dist/client/device-flow-client.cjs +2 -0
  508. package/dist/node_modules/@openhands/typescript-client/dist/client/device-flow-client.cjs.map +1 -0
  509. package/dist/node_modules/@openhands/typescript-client/dist/client/device-flow-client.js +106 -0
  510. package/dist/node_modules/@openhands/typescript-client/dist/client/device-flow-client.js.map +1 -0
  511. package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.cjs +2 -0
  512. package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.cjs.map +1 -0
  513. package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.js +69 -0
  514. package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.js.map +1 -0
  515. package/dist/node_modules/@openhands/typescript-client/dist/clients.cjs +1 -1
  516. package/dist/node_modules/@openhands/typescript-client/dist/clients.js +3 -0
  517. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs +1 -1
  518. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs.map +1 -1
  519. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js +18 -2
  520. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js.map +1 -1
  521. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.cjs.map +1 -1
  522. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.js.map +1 -1
  523. package/dist/node_modules/axios/index.cjs +1 -1
  524. package/dist/node_modules/axios/index.js +1 -1
  525. package/dist/package.cjs +1 -1
  526. package/dist/package.cjs.map +1 -1
  527. package/dist/package.js +3 -3
  528. package/dist/package.js.map +1 -1
  529. package/dist/routes/app-settings.cjs +1 -1
  530. package/dist/routes/app-settings.cjs.map +1 -1
  531. package/dist/routes/app-settings.js +59 -60
  532. package/dist/routes/app-settings.js.map +1 -1
  533. package/dist/routes/commits-tab.cjs +2 -0
  534. package/dist/routes/commits-tab.cjs.map +1 -0
  535. package/dist/routes/commits-tab.d.ts +8 -0
  536. package/dist/routes/commits-tab.js +45 -0
  537. package/dist/routes/commits-tab.js.map +1 -0
  538. package/dist/routes/files-tab.cjs +1 -1
  539. package/dist/routes/files-tab.cjs.map +1 -1
  540. package/dist/routes/files-tab.js +148 -127
  541. package/dist/routes/files-tab.js.map +1 -1
  542. package/dist/routes/llm-settings.cjs +1 -1
  543. package/dist/routes/llm-settings.cjs.map +1 -1
  544. package/dist/routes/llm-settings.js +4 -1
  545. package/dist/routes/llm-settings.js.map +1 -1
  546. package/dist/services/cloud-funnel-analytics.cjs +2 -0
  547. package/dist/services/cloud-funnel-analytics.cjs.map +1 -0
  548. package/dist/services/cloud-funnel-analytics.d.ts +4 -0
  549. package/dist/services/cloud-funnel-analytics.js +39 -0
  550. package/dist/services/cloud-funnel-analytics.js.map +1 -0
  551. package/dist/services/telemetry.cjs +1 -1
  552. package/dist/services/telemetry.cjs.map +1 -1
  553. package/dist/services/telemetry.d.ts +46 -9
  554. package/dist/services/telemetry.js +182 -71
  555. package/dist/services/telemetry.js.map +1 -1
  556. package/dist/themes/color-themes.cjs.map +1 -1
  557. package/dist/themes/color-themes.d.ts +3 -6
  558. package/dist/themes/color-themes.js.map +1 -1
  559. package/dist/types/agent-server/core/base/action.d.ts +5 -4
  560. package/dist/types/agent-server/core/base/base.d.ts +3 -2
  561. package/dist/types/agent-server/core/base/observation.d.ts +1 -1
  562. package/dist/types/agent-server/type-guards.cjs +1 -1
  563. package/dist/types/agent-server/type-guards.cjs.map +1 -1
  564. package/dist/types/agent-server/type-guards.d.ts +3 -5
  565. package/dist/types/agent-server/type-guards.js +2 -1
  566. package/dist/types/agent-server/type-guards.js.map +1 -1
  567. package/dist/types/automation.d.ts +5 -0
  568. package/dist/utils/api-error-message.d.ts +11 -0
  569. package/dist/utils/automation-timeout.d.ts +19 -0
  570. package/dist/utils/base-path.cjs +2 -0
  571. package/dist/utils/base-path.cjs.map +1 -0
  572. package/dist/utils/base-path.d.ts +2 -0
  573. package/dist/utils/base-path.js +23 -0
  574. package/dist/utils/base-path.js.map +1 -0
  575. package/dist/utils/error-handler.cjs +1 -1
  576. package/dist/utils/error-handler.cjs.map +1 -1
  577. package/dist/utils/error-handler.d.ts +1 -4
  578. package/dist/utils/error-handler.js +6 -7
  579. package/dist/utils/error-handler.js.map +1 -1
  580. package/dist/utils/map-provider.cjs +1 -1
  581. package/dist/utils/map-provider.cjs.map +1 -1
  582. package/dist/utils/map-provider.d.ts +1 -0
  583. package/dist/utils/map-provider.js +2 -1
  584. package/dist/utils/map-provider.js.map +1 -1
  585. package/package.json +3 -3
  586. package/scripts/check-sdk-version-sync.mjs +6 -6
  587. package/scripts/dev-safe.mjs +7 -8
  588. package/scripts/dev-static.mjs +3 -0
  589. package/scripts/dev-with-automation.mjs +3 -0
  590. package/scripts/docker-build.mjs +4 -0
  591. package/scripts/static-server.mjs +93 -7
  592. package/tools/canvas_ui_tool.py +14 -8
  593. package/build/assets/active-backend-context-hxq31W25.js +0 -1
  594. package/build/assets/agent-server-client-options-DVLRd9sw.js +0 -1
  595. package/build/assets/agent-server-conversation-service.api-CuSdr4Qb.js +0 -5
  596. package/build/assets/agent-settings-D_yOy8XB.js +0 -1
  597. package/build/assets/api-key-entry-screen-Dl0qVYi4.js +0 -1
  598. package/build/assets/app-settings-yVizGXox.js +0 -1
  599. package/build/assets/automation-detail-dvJfLs5u.js +0 -2
  600. package/build/assets/automation-export-BPcgLqPD.js +0 -2
  601. package/build/assets/automations-list-CUXogTe0.js +0 -1
  602. package/build/assets/backend-form-modal-CQJGmItq.js +0 -1
  603. package/build/assets/check-Bvi71siz.js +0 -1
  604. package/build/assets/condenser-settings-Ca8fYZ_Z.js +0 -1
  605. package/build/assets/conversation-9NBSRoR9.js +0 -1
  606. package/build/assets/conversation-BXg6Oti2.js +0 -89
  607. package/build/assets/conversation-panel-CZri9Rup.js +0 -1
  608. package/build/assets/conversation-service.api-DPBQvTKD.js +0 -1
  609. package/build/assets/declaration-gq8V5eTU.js +0 -1
  610. package/build/assets/files-tab-UVoray88.js +0 -1
  611. package/build/assets/git-provider-icon-o6hdnJUB.js +0 -1
  612. package/build/assets/handle-capture-consent-CPMXU29K.js +0 -1
  613. package/build/assets/home-D1IHvGTN.js +0 -1
  614. package/build/assets/index-redirect-CUUJiNki.js +0 -1
  615. package/build/assets/install-server-modal-BbuQaA2w.js +0 -1
  616. package/build/assets/lesson-plan-jC0HBoe6.js +0 -4
  617. package/build/assets/llm-not-configured-banner-DoARbcdL.js +0 -27
  618. package/build/assets/llm-settings-4JMLV8mq.js +0 -1
  619. package/build/assets/llm-settings-D91gMw3U.js +0 -1
  620. package/build/assets/llm-subscription-service-CKyaV24y.js +0 -1
  621. package/build/assets/loader-circle-BEykUKYG.js +0 -1
  622. package/build/assets/manage-backends-modal-DkWAMSle.js +0 -1
  623. package/build/assets/manifest-aa5c29f6.js +0 -1
  624. package/build/assets/model-selector-BfqpMkSJ.js +0 -1
  625. package/build/assets/mouse-pointer-click-PdEQPL6v.js +0 -1
  626. package/build/assets/onboarding-Bu-HN1ze.js +0 -1
  627. package/build/assets/onboarding-modal-CZgjs5Bx.js +0 -1
  628. package/build/assets/option-service.api-BrZ5q87N.js +0 -1
  629. package/build/assets/organization-service.api-Bk4pCGU1.js +0 -1
  630. package/build/assets/path-utils-CSmuZoix.js +0 -1
  631. package/build/assets/plugins-management-service-BRBLxvUl.js +0 -1
  632. package/build/assets/profiles-service.api-BMXQ9pZC.js +0 -1
  633. package/build/assets/providers-BpO967xS.js +0 -1
  634. package/build/assets/proxy-BgJLtxu7.js +0 -1
  635. package/build/assets/root-BM5WgQ4_.js +0 -2
  636. package/build/assets/root-V8fkplMy.css +0 -1
  637. package/build/assets/root-layout-BdoyoobY.js +0 -2
  638. package/build/assets/schema-field-BSHrUMme.js +0 -1
  639. package/build/assets/sdk-section-page-t82gsOqa.js +0 -1
  640. package/build/assets/search-4DHskuhE.js +0 -1
  641. package/build/assets/secrets-service-B2GqPV0N.js +0 -1
  642. package/build/assets/settings-DmPLkgq0.js +0 -1
  643. package/build/assets/settings-modal-CwrZKrTq.js +0 -1
  644. package/build/assets/settings-service.api-Ce-ub11I.js +0 -1
  645. package/build/assets/shared-conversation-BDREQPnE.js +0 -1
  646. package/build/assets/skills-plugins-2Y44YHbO.js +0 -1
  647. package/build/assets/use-acp-credential-form-MzZM6D7D.js +0 -1
  648. package/build/assets/use-agent-profiles-DwZxnwO5.js +0 -1
  649. package/build/assets/use-backends-health-CRHzuvxO.js +0 -1
  650. package/build/assets/use-cloud-current-user-id-utFreJ0i.js +0 -1
  651. package/build/assets/use-config-mJrtZHP1.js +0 -1
  652. package/build/assets/use-create-conversation-DdqsP78F.js +0 -1
  653. package/build/assets/use-is-authed-B6M0mcGL.js +0 -1
  654. package/build/assets/use-llm-profiles-RC-PkpBl.js +0 -1
  655. package/build/assets/use-plugins-marketplace-FHlbeQ4c.js +0 -1
  656. package/build/assets/use-runtime-is-ready-RKj2WmEh.js +0 -1
  657. package/build/assets/use-save-agent-profile-tvDP15mh.js +0 -1
  658. package/build/assets/use-save-settings-BGlSfuYn.js +0 -1
  659. package/build/assets/use-settings-CH5LzXD8.js +0 -1
  660. package/build/assets/use-settings-nav-items-Dwktv8wo.js +0 -16
  661. package/build/assets/use-skills-CSzSL6HG.js +0 -1
  662. package/build/assets/use-tracking-BIXzagSI.js +0 -1
  663. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~lf310vj7-CSVPGId3.js +0 -10
  664. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~nfpll1wp-BCpa95De.js +0 -177
  665. package/build/assets/vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~jewnulst-C57fm7C-.js +0 -1
  666. package/build/assets/vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CqXiHwjU.js +0 -2
  667. package/build/assets/x-Cb0WAtak.js +0 -1
  668. package/dist/components/providers/posthog-wrapper.cjs +0 -2
  669. package/dist/components/providers/posthog-wrapper.cjs.map +0 -1
  670. package/dist/components/providers/posthog-wrapper.d.ts +0 -4
  671. package/dist/components/providers/posthog-wrapper.js +0 -49
  672. package/dist/components/providers/posthog-wrapper.js.map +0 -1
  673. package/dist/node_modules/posthog-js/react/dist/esm/index.cjs +0 -2
  674. package/dist/node_modules/posthog-js/react/dist/esm/index.cjs.map +0 -1
  675. package/dist/node_modules/posthog-js/react/dist/esm/index.js +0 -113
  676. package/dist/node_modules/posthog-js/react/dist/esm/index.js.map +0 -1
  677. package/dist/utils/handle-capture-consent.cjs +0 -2
  678. package/dist/utils/handle-capture-consent.cjs.map +0 -1
  679. package/dist/utils/handle-capture-consent.d.ts +0 -7
  680. package/dist/utils/handle-capture-consent.js +0 -8
  681. package/dist/utils/handle-capture-consent.js.map +0 -1
  682. /package/build/assets/{__vite-browser-external-4xJsU2-u.js → __vite-browser-external-BQUj0sYu.js} +0 -0
  683. /package/build/assets/{agent-server-ui-style-scope-COnDHTm5.js → agent-server-ui-style-scope-qhnhZHBV.js} +0 -0
  684. /package/build/assets/{automation-BU8zu-FP.js → automation-LZB0MjdV.js} +0 -0
  685. /package/build/assets/{close-p3Op5lxI.js → close-DLFb5kfv.js} +0 -0
  686. /package/build/assets/{common-Dh7OqABE.js → common-CxbUL3nR.js} +0 -0
  687. /package/build/assets/{createLucideIcon-CVAsW2Yo.js → createLucideIcon-D4Tak8A1.js} +0 -0
  688. /package/build/assets/{folder-mMWFvaw0.js → folder-Bk311brm.js} +0 -0
  689. /package/build/assets/{get-language-from-path-CPNnuVhI.js → get-language-from-path-DBqBsCWH.js} +0 -0
  690. /package/build/assets/{git-status-mapper-BI8FyUVp.js → git-status-mapper-DnL9OC8_.js} +0 -0
  691. /package/build/assets/{iconBase-DaTRRUjy.js → iconBase-Dz51Zn5x.js} +0 -0
  692. /package/build/assets/{link-external-DfKQroKX.js → link-external-CaBmUEs_.js} +0 -0
  693. /package/build/assets/{search-BsjCEFNf.js → search-BgOCR7_c.js} +0 -0
  694. /package/build/assets/{settings-like-page-layout-classes-DENKlZpD.js → settings-like-page-layout-classes-Cdl6jOe5.js} +0 -0
  695. /package/build/assets/{skills-9cDZONKh.js → skills-EqzxYBvT.js} +0 -0
  696. /package/build/assets/{terminal-BuLtIrb9.js → terminal-Cgf___rK.js} +0 -0
  697. /package/build/assets/{u-check-circle-half-LiwZkuFe.js → u-check-circle-half-MsShT8Ec.js} +0 -0
  698. /package/build/assets/{u-edit-DJ90xc8Z.js → u-edit-DL5LgKon.js} +0 -0
  699. /package/build/assets/{use-breakpoint-B-O0lQ84.js → use-breakpoint-BP3lqLMx.js} +0 -0
  700. /package/build/assets/{use-click-outside-element-Bf4Omzot.js → use-click-outside-element-D9BYdANT.js} +0 -0
  701. /package/build/assets/{use-launch-skill-in-chat-BnoDgvAy.js → use-launch-skill-in-chat-DJWEfVc5.js} +0 -0
  702. /package/build/assets/{vendor~browser-Dqd33JyP.js → vendor~browser-By2MVv_N.js} +0 -0
  703. /package/build/assets/{vendor~conversation-panel~conversation~alert-banner-DHDkknt5.js → vendor~conversation-panel~conversation~alert-banner-CxfzCmkN.js} +0 -0
  704. /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~epa72zsm-B4rXs7Zd.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~e0djk9ee-Cw6LUe8p.js} +0 -0
  705. /package/build/assets/{vendor~entry.client~root~root-layout~index-redirect~home~conversation-panel~conversation~la~byh8a1g4-XNPdpuO8.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~jkpzbynd-CkpBIhVe.js} +0 -0
  706. /package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-9UMeuPV6.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-COhHANvV.js} +0 -0
  707. /package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DTzw2x50.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-FghQ3Z1a.js} +0 -0
  708. /package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~skills-settings~automations-~ki5qnp0d-rV6d1Iv_.js → vendor~root-layout~index-home~home~conversation-panel~conversation~launch~skills-settings~a~j2jlu22h-mC0v44WR.js} +0 -0
  709. /package/build/assets/{vendor~root-layout~home~mcp~automations-list~onboarding-modal-CXyYYvYh.js → vendor~root-layout~index-home~home~mcp~automations-list~onboarding-modal-C4-GDgiF.js} +0 -0
  710. /package/build/assets/{vendor~terminal-aeP3PnKf.js → vendor~terminal-CnKZILnC.js} +0 -0
@@ -5,6 +5,7 @@ interface ChatInputContainerProps {
5
5
  isDragOver: boolean;
6
6
  disabled: boolean;
7
7
  canSubmit: boolean;
8
+ hasStartedConversation?: boolean;
8
9
  isNewConversationPending?: boolean;
9
10
  showButton: boolean;
10
11
  buttonClassName: string;
@@ -24,5 +25,5 @@ interface ChatInputContainerProps {
24
25
  slashSelectedIndex?: number;
25
26
  onSlashSelect?: (item: SlashCommandItem) => void;
26
27
  }
27
- export declare function ChatInputContainer({ chatContainerRef, isDragOver, disabled, canSubmit, 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): import("react/jsx-runtime").JSX.Element;
28
29
  export {};
@@ -8,39 +8,40 @@ import { SlashCommandMenu as o } from "./slash-command-menu.js";
8
8
  import "react";
9
9
  import { jsx as s, jsxs as c } from "react/jsx-runtime";
10
10
  //#region src/components/features/chat/components/chat-input-container.tsx
11
- function l({ chatContainerRef: l, isDragOver: u, disabled: d, canSubmit: f, isNewConversationPending: p = !1, showButton: m, buttonClassName: h, chatInputRef: g, handleFileIconClick: _, handleSubmit: v, onDragOver: y, onDragLeave: b, onDrop: x, onInput: S, onPaste: C, onKeyDown: w, onFocus: T, onBlur: E, isSlashMenuOpen: D = !1, slashItems: O = [], slashSelectedIndex: k = 0, onSlashSelect: A }) {
11
+ function l({ chatContainerRef: l, isDragOver: u, disabled: d, canSubmit: f, hasStartedConversation: p, isNewConversationPending: m = !1, showButton: h, buttonClassName: g, chatInputRef: _, handleFileIconClick: v, handleSubmit: y, onDragOver: b, onDragLeave: x, onDrop: S, onInput: C, onPaste: w, onKeyDown: T, onFocus: E, onBlur: D, isSlashMenuOpen: O = !1, slashItems: k = [], slashSelectedIndex: A = 0, onSlashSelect: j }) {
12
12
  return /* @__PURE__ */ c("div", {
13
13
  ref: l,
14
14
  className: e("bg-[var(--oh-surface)] box-border content-stretch flex flex-col items-start justify-center p-4 relative rounded-[15px] w-full", t((e) => e.conversationMode) === "plan" && "border border-[#597FF4]"),
15
- onDragOver: (e) => y(e, d),
16
- onDragLeave: (e) => b(e, d),
17
- onDrop: (e) => x(e, d),
15
+ onDragOver: (e) => b(e, d),
16
+ onDragLeave: (e) => x(e, d),
17
+ onDrop: (e) => S(e, d),
18
18
  children: [
19
19
  u && /* @__PURE__ */ s(n, {}),
20
20
  /* @__PURE__ */ s(r, {}),
21
21
  /* @__PURE__ */ c("div", {
22
22
  className: "relative w-full",
23
- children: [D && A && /* @__PURE__ */ s(o, {
24
- items: O,
25
- selectedIndex: k,
26
- onSelect: A
23
+ children: [O && j && /* @__PURE__ */ s(o, {
24
+ items: k,
25
+ selectedIndex: A,
26
+ onSelect: j
27
27
  }), /* @__PURE__ */ s(i, {
28
- chatInputRef: g,
29
- isNewConversationPending: p,
30
- onInput: S,
31
- onPaste: C,
32
- onKeyDown: w,
33
- onFocus: T,
34
- onBlur: E
28
+ chatInputRef: _,
29
+ isNewConversationPending: m,
30
+ onInput: C,
31
+ onPaste: w,
32
+ onKeyDown: T,
33
+ onFocus: E,
34
+ onBlur: D
35
35
  })]
36
36
  }),
37
37
  /* @__PURE__ */ s(a, {
38
38
  disabled: d,
39
39
  canSubmit: f,
40
- onAddFileClick: () => _(d),
41
- showButton: m,
42
- buttonClassName: h,
43
- handleSubmit: v
40
+ hasStartedConversation: p,
41
+ onAddFileClick: () => v(d),
42
+ showButton: h,
43
+ buttonClassName: g,
44
+ handleSubmit: y
44
45
  })
45
46
  ]
46
47
  });
@@ -1 +1 @@
1
- {"version":3,"file":"chat-input-container.js","names":[],"sources":["../../../../../src/components/features/chat/components/chat-input-container.tsx"],"sourcesContent":["import React from \"react\";\nimport { DragOver } from \"../drag-over\";\nimport { UploadedFiles } from \"../uploaded-files\";\nimport { ChatInputRow } from \"./chat-input-row\";\nimport { ChatInputActions } from \"./chat-input-actions\";\nimport { SlashCommandMenu } from \"./slash-command-menu\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { cn } from \"#/utils/utils\";\nimport { SlashCommandItem } from \"#/hooks/chat/use-slash-command\";\n\ninterface ChatInputContainerProps {\n chatContainerRef: React.RefObject<HTMLDivElement | null>;\n isDragOver: boolean;\n disabled: boolean;\n canSubmit: boolean;\n isNewConversationPending?: boolean;\n showButton: boolean;\n buttonClassName: string;\n chatInputRef: React.RefObject<HTMLDivElement | null>;\n handleFileIconClick: (isDisabled: boolean) => void;\n handleSubmit: () => void;\n onDragOver: (e: React.DragEvent, isDisabled: boolean) => void;\n onDragLeave: (e: React.DragEvent, isDisabled: boolean) => void;\n onDrop: (e: React.DragEvent, isDisabled: boolean) => void;\n onInput: () => void;\n onPaste: (e: React.ClipboardEvent) => void;\n onKeyDown: (e: React.KeyboardEvent) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n isSlashMenuOpen?: boolean;\n slashItems?: SlashCommandItem[];\n slashSelectedIndex?: number;\n onSlashSelect?: (item: SlashCommandItem) => void;\n}\n\nexport function ChatInputContainer({\n chatContainerRef,\n isDragOver,\n disabled,\n canSubmit,\n isNewConversationPending = false,\n showButton,\n buttonClassName,\n chatInputRef,\n handleFileIconClick,\n handleSubmit,\n onDragOver,\n onDragLeave,\n onDrop,\n onInput,\n onPaste,\n onKeyDown,\n onFocus,\n onBlur,\n isSlashMenuOpen = false,\n slashItems = [],\n slashSelectedIndex = 0,\n onSlashSelect,\n}: ChatInputContainerProps) {\n const conversationMode = useConversationStore(\n (state) => state.conversationMode,\n );\n\n return (\n <div\n ref={chatContainerRef}\n className={cn(\n \"bg-[var(--oh-surface)] box-border content-stretch flex flex-col items-start justify-center p-4 relative rounded-[15px] w-full\",\n conversationMode === \"plan\" && \"border border-[#597FF4]\",\n )}\n onDragOver={(e) => onDragOver(e, disabled)}\n onDragLeave={(e) => onDragLeave(e, disabled)}\n onDrop={(e) => onDrop(e, disabled)}\n >\n {/* Drag Over UI */}\n {isDragOver && <DragOver />}\n\n <UploadedFiles />\n\n {/* Wrapper so the slash menu anchors just above the input row,\n not above the entire (possibly resized) container */}\n <div className=\"relative w-full\">\n {isSlashMenuOpen && onSlashSelect && (\n <SlashCommandMenu\n items={slashItems}\n selectedIndex={slashSelectedIndex}\n onSelect={onSlashSelect}\n />\n )}\n\n <ChatInputRow\n chatInputRef={chatInputRef}\n isNewConversationPending={isNewConversationPending}\n onInput={onInput}\n onPaste={onPaste}\n onKeyDown={onKeyDown}\n onFocus={onFocus}\n onBlur={onBlur}\n />\n </div>\n\n <ChatInputActions\n disabled={disabled}\n canSubmit={canSubmit}\n onAddFileClick={() => handleFileIconClick(disabled)}\n showButton={showButton}\n buttonClassName={buttonClassName}\n handleSubmit={handleSubmit}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAmCA,SAAgB,EAAmB,EACjC,qBACA,eACA,aACA,cACA,8BAA2B,IAC3B,eACA,oBACA,iBACA,wBACA,iBACA,eACA,gBACA,WACA,YACA,YACA,cACA,YACA,WACA,qBAAkB,IAClB,gBAAa,EAAE,EACf,wBAAqB,GACrB,oBAC0B;AAK1B,QACE,kBAAC,OAAD;EACE,KAAK;EACL,WAAW,EACT,iIARmB,GACtB,MAAU,EAAM,iBAQb,KAAqB,UAAU,0BAChC;EACD,aAAa,MAAM,EAAW,GAAG,EAAS;EAC1C,cAAc,MAAM,EAAY,GAAG,EAAS;EAC5C,SAAS,MAAM,EAAO,GAAG,EAAS;YARpC;GAWG,KAAc,kBAAC,GAAD,EAAY,CAAA;GAE3B,kBAAC,GAAD,EAAiB,CAAA;GAIjB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACG,KAAmB,KAClB,kBAAC,GAAD;KACE,OAAO;KACP,eAAe;KACf,UAAU;KACV,CAAA,EAGJ,kBAAC,GAAD;KACgB;KACY;KACjB;KACA;KACE;KACF;KACD;KACR,CAAA,CACE;;GAEN,kBAAC,GAAD;IACY;IACC;IACX,sBAAsB,EAAoB,EAAS;IACvC;IACK;IACH;IACd,CAAA;GACE"}
1
+ {"version":3,"file":"chat-input-container.js","names":[],"sources":["../../../../../src/components/features/chat/components/chat-input-container.tsx"],"sourcesContent":["import React from \"react\";\nimport { DragOver } from \"../drag-over\";\nimport { UploadedFiles } from \"../uploaded-files\";\nimport { ChatInputRow } from \"./chat-input-row\";\nimport { ChatInputActions } from \"./chat-input-actions\";\nimport { SlashCommandMenu } from \"./slash-command-menu\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { cn } from \"#/utils/utils\";\nimport { SlashCommandItem } from \"#/hooks/chat/use-slash-command\";\n\ninterface ChatInputContainerProps {\n chatContainerRef: React.RefObject<HTMLDivElement | null>;\n isDragOver: boolean;\n disabled: boolean;\n canSubmit: boolean;\n hasStartedConversation?: boolean;\n isNewConversationPending?: boolean;\n showButton: boolean;\n buttonClassName: string;\n chatInputRef: React.RefObject<HTMLDivElement | null>;\n handleFileIconClick: (isDisabled: boolean) => void;\n handleSubmit: () => void;\n onDragOver: (e: React.DragEvent, isDisabled: boolean) => void;\n onDragLeave: (e: React.DragEvent, isDisabled: boolean) => void;\n onDrop: (e: React.DragEvent, isDisabled: boolean) => void;\n onInput: () => void;\n onPaste: (e: React.ClipboardEvent) => void;\n onKeyDown: (e: React.KeyboardEvent) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n isSlashMenuOpen?: boolean;\n slashItems?: SlashCommandItem[];\n slashSelectedIndex?: number;\n onSlashSelect?: (item: SlashCommandItem) => void;\n}\n\nexport function ChatInputContainer({\n chatContainerRef,\n isDragOver,\n disabled,\n canSubmit,\n hasStartedConversation,\n isNewConversationPending = false,\n showButton,\n buttonClassName,\n chatInputRef,\n handleFileIconClick,\n handleSubmit,\n onDragOver,\n onDragLeave,\n onDrop,\n onInput,\n onPaste,\n onKeyDown,\n onFocus,\n onBlur,\n isSlashMenuOpen = false,\n slashItems = [],\n slashSelectedIndex = 0,\n onSlashSelect,\n}: ChatInputContainerProps) {\n const conversationMode = useConversationStore(\n (state) => state.conversationMode,\n );\n\n return (\n <div\n ref={chatContainerRef}\n className={cn(\n \"bg-[var(--oh-surface)] box-border content-stretch flex flex-col items-start justify-center p-4 relative rounded-[15px] w-full\",\n conversationMode === \"plan\" && \"border border-[#597FF4]\",\n )}\n onDragOver={(e) => onDragOver(e, disabled)}\n onDragLeave={(e) => onDragLeave(e, disabled)}\n onDrop={(e) => onDrop(e, disabled)}\n >\n {/* Drag Over UI */}\n {isDragOver && <DragOver />}\n\n <UploadedFiles />\n\n {/* Wrapper so the slash menu anchors just above the input row,\n not above the entire (possibly resized) container */}\n <div className=\"relative w-full\">\n {isSlashMenuOpen && onSlashSelect && (\n <SlashCommandMenu\n items={slashItems}\n selectedIndex={slashSelectedIndex}\n onSelect={onSlashSelect}\n />\n )}\n\n <ChatInputRow\n chatInputRef={chatInputRef}\n isNewConversationPending={isNewConversationPending}\n onInput={onInput}\n onPaste={onPaste}\n onKeyDown={onKeyDown}\n onFocus={onFocus}\n onBlur={onBlur}\n />\n </div>\n\n <ChatInputActions\n disabled={disabled}\n canSubmit={canSubmit}\n hasStartedConversation={hasStartedConversation}\n onAddFileClick={() => handleFileIconClick(disabled)}\n showButton={showButton}\n buttonClassName={buttonClassName}\n handleSubmit={handleSubmit}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAoCA,SAAgB,EAAmB,EACjC,qBACA,eACA,aACA,cACA,2BACA,8BAA2B,IAC3B,eACA,oBACA,iBACA,wBACA,iBACA,eACA,gBACA,WACA,YACA,YACA,cACA,YACA,WACA,qBAAkB,IAClB,gBAAa,EAAE,EACf,wBAAqB,GACrB,oBAC0B;AAK1B,QACE,kBAAC,OAAD;EACE,KAAK;EACL,WAAW,EACT,iIARmB,GACtB,MAAU,EAAM,iBAQb,KAAqB,UAAU,0BAChC;EACD,aAAa,MAAM,EAAW,GAAG,EAAS;EAC1C,cAAc,MAAM,EAAY,GAAG,EAAS;EAC5C,SAAS,MAAM,EAAO,GAAG,EAAS;YARpC;GAWG,KAAc,kBAAC,GAAD,EAAY,CAAA;GAE3B,kBAAC,GAAD,EAAiB,CAAA;GAIjB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACG,KAAmB,KAClB,kBAAC,GAAD;KACE,OAAO;KACP,eAAe;KACf,UAAU;KACV,CAAA,EAGJ,kBAAC,GAAD;KACgB;KACY;KACjB;KACA;KACE;KACF;KACD;KACR,CAAA,CACE;;GAEN,kBAAC,GAAD;IACY;IACC;IACa;IACxB,sBAAsB,EAAoB,EAAS;IACvC;IACK;IACH;IACd,CAAA;GACE"}
@@ -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(`../../../../icons/checkmark.cjs`),a=require(`../../../../utils/form-control-classes.cjs`),o=require(`../../../../ui/typography.cjs`),s=require(`../../../../ui/combobox-caret.cjs`),c=require(`../../../../ui/context-menu.cjs`),l=require(`../../context-menu/context-menu-list-item.cjs`),u=require(`../../../../hooks/use-click-outside-element.cjs`),d=require(`../../../../icons/settings-gear.cjs`),f=require(`../../../shared/navigation-link.cjs`),p=require(`../../../../ui/divider.cjs`),m=require(`../../../../hooks/use-chat-input-profile-state.cjs`);let h=require(`react`);h=e.__toESM(h,1);let g=require(`react/jsx-runtime`);var _=18;function v(e){return e.length<=_?e:`${e.slice(0,_)}…`}function y({onClose:e,dividerInset:a,settingsLinkClassName:s,settingsIconClassName:c}){let{t:u}=t.useTranslation(`openhands`),{profiles:h,currentProfileId:_,selectProfile:v}=m.useChatInputProfileState(),y=t=>{v(t),e()};return(0,g.jsxs)(g.Fragment,{children:[h.length>0&&(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`li`,{role:`presentation`,className:`px-2 pt-1 pb-0.5`,children:(0,g.jsx)(o.Typography.Text,{className:`text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4`,children:u(n.I18nKey.SETTINGS$AVAILABLE_PROFILES)})}),h.map(t=>{let n=t.id!=null&&t.id===_;return(0,g.jsxs)(l.ContextMenuListItem,{testId:`chat-input-agent-profile-option-${t.name}`,onClick:r=>{if(r.preventDefault(),r.stopPropagation(),n){e();return}y(t)},className:r.cn(`flex items-center gap-2`,n&&`bg-[var(--oh-interactive-hover)]`),children:[(0,g.jsx)(`span`,{className:`flex-1 truncate text-sm leading-5`,title:t.name,children:t.name}),n&&(0,g.jsx)(i.default,{width:14,height:14,className:`shrink-0`,"aria-hidden":!0})]},t.id??t.name)})]}),h.length>0&&(0,g.jsx)(p.Divider,{inset:a}),(0,g.jsx)(`li`,{className:`text-sm`,children:(0,g.jsxs)(f.NavigationLink,{to:`/settings/agents`,onClick:e,className:r.cn(`flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)] transition-colors`,s),children:[(0,g.jsx)(d.default,{width:16,height:16,className:r.cn(`shrink-0`,c),"aria-hidden":!0}),(0,g.jsx)(`span`,{children:u(n.I18nKey.CHAT$MANAGE_AGENT_PROFILES)})]})})]})}function b(){let{t:e}=t.useTranslation(`openhands`),{profiles:i,currentProfileName:o,isLoading:l,isSwitching:d}=m.useChatInputProfileState(),[f,p]=h.default.useState(!1),_=h.default.useRef(null),b=u.useClickOutsideElement(()=>p(!1),_);if(l||i.length===0)return null;let x=o??e(n.I18nKey.CHAT$AGENT_PROFILE_PLACEHOLDER);return(0,g.jsxs)(`div`,{className:`relative min-w-0`,children:[(0,g.jsxs)(`button`,{ref:_,type:`button`,className:r.cn(a.chatInputPillButtonClassName,`max-w-[200px]`),title:o??void 0,"data-testid":`chat-input-agent-profile`,"aria-expanded":f,"aria-haspopup":`dialog`,disabled:d,"aria-busy":d,onClick:e=>{e.preventDefault(),e.stopPropagation(),p(e=>!e)},children:[(0,g.jsx)(`span`,{className:`truncate`,children:v(x)}),(0,g.jsx)(s.ComboboxCaretInline,{isOpen:f})]}),f&&(0,g.jsx)(c.ContextMenu,{ref:b,testId:`chat-input-agent-profile-popover`,position:`top`,alignment:`left`,spacing:`none`,className:`z-[60] mb-2 min-w-[200px] max-w-[320px] max-h-[60vh] overflow-y-auto`,children:(0,g.jsx)(y,{onClose:()=>p(!1)})})]})}exports.ChatInputProfileMenuContent=y,exports.ChatInputProfilePicker=b;
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(`../../../../icons/checkmark.cjs`),a=require(`../../../../utils/form-control-classes.cjs`),o=require(`../../../../ui/typography.cjs`),s=require(`../../../../ui/combobox-caret.cjs`),c=require(`../../../../ui/context-menu.cjs`),l=require(`../../context-menu/context-menu-list-item.cjs`),u=require(`../../../../hooks/use-click-outside-element.cjs`),d=require(`../../../../icons/settings-gear.cjs`),f=require(`../../../shared/navigation-link.cjs`),p=require(`../../../../ui/divider.cjs`),m=require(`../../../../hooks/use-chat-input-profile-state.cjs`);let h=require(`react`);h=e.__toESM(h,1);let g=require(`react/jsx-runtime`);var _=18;function v(e){return e.length<=_?e:`${e.slice(0,_)}…`}function y({onClose:e,dividerInset:a,settingsLinkClassName:s,settingsIconClassName:c}){let{t:u}=t.useTranslation(`openhands`),{profiles:h,currentProfileId:_,isInConversation:v,isSwitching:y,selectProfile:b}=m.useChatInputProfileState(),x=t=>{b(t),e()};return(0,g.jsxs)(g.Fragment,{children:[h.length>0&&(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`li`,{role:`presentation`,className:`px-2 pt-1 pb-0.5`,children:(0,g.jsx)(o.Typography.Text,{className:`text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4`,children:u(n.I18nKey.SETTINGS$AVAILABLE_PROFILES)})}),h.map(t=>{let n=t.id!=null&&t.id===_;return(0,g.jsxs)(l.ContextMenuListItem,{testId:`chat-input-agent-profile-option-${t.name}`,isDisabled:y,onClick:r=>{if(r.preventDefault(),r.stopPropagation(),n){e();return}x(t)},className:r.cn(`flex items-center gap-2`,n&&`bg-[var(--oh-interactive-hover)]`),children:[(0,g.jsx)(`span`,{className:`flex-1 truncate text-sm leading-5`,title:t.name,children:t.name}),n&&(0,g.jsx)(i.default,{width:14,height:14,className:`shrink-0`,"aria-hidden":!0})]},t.id??t.name)}),v&&(0,g.jsx)(`li`,{role:`presentation`,className:`px-2 pt-0.5 pb-1`,children:(0,g.jsx)(o.Typography.Text,{className:`text-[11px] text-[var(--oh-text-dim)] leading-4`,children:u(n.I18nKey.CHAT$START_NEW_WITH_PROFILE_HINT)})})]}),h.length>0&&(0,g.jsx)(p.Divider,{inset:a}),(0,g.jsx)(`li`,{className:`text-sm`,children:(0,g.jsxs)(f.NavigationLink,{to:`/settings/agents`,onClick:e,className:r.cn(`flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)] transition-colors`,s),children:[(0,g.jsx)(d.default,{width:16,height:16,className:r.cn(`shrink-0`,c),"aria-hidden":!0}),(0,g.jsx)(`span`,{children:u(n.I18nKey.CHAT$MANAGE_AGENT_PROFILES)})]})})]})}function b(){let{t:e}=t.useTranslation(`openhands`),{profiles:i,currentProfileName:o,isLoading:l,isSwitching:d}=m.useChatInputProfileState(),[f,p]=h.default.useState(!1),_=h.default.useRef(null),b=u.useClickOutsideElement(()=>p(!1),_);if(l||i.length===0)return null;let x=o??e(n.I18nKey.CHAT$AGENT_PROFILE_PLACEHOLDER);return(0,g.jsxs)(`div`,{className:`relative min-w-0`,children:[(0,g.jsxs)(`button`,{ref:_,type:`button`,className:r.cn(a.chatInputPillButtonClassName,`max-w-[200px]`),title:o??void 0,"data-testid":`chat-input-agent-profile`,"aria-expanded":f,"aria-haspopup":`dialog`,disabled:d,"aria-busy":d,onClick:e=>{e.preventDefault(),e.stopPropagation(),p(e=>!e)},children:[(0,g.jsx)(`span`,{className:`truncate`,children:v(x)}),(0,g.jsx)(s.ComboboxCaretInline,{isOpen:f})]}),f&&(0,g.jsx)(c.ContextMenu,{ref:b,testId:`chat-input-agent-profile-popover`,position:`top`,alignment:`left`,spacing:`none`,className:`z-[60] mb-2 min-w-[200px] max-w-[320px] max-h-[60vh] overflow-y-auto`,children:(0,g.jsx)(y,{onClose:()=>p(!1)})})]})}exports.ChatInputProfileMenuContent=y,exports.ChatInputProfilePicker=b;
2
2
  //# sourceMappingURL=chat-input-profile-picker.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-input-profile-picker.cjs","names":[],"sources":["../../../../../src/components/features/chat/components/chat-input-profile-picker.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useChatInputProfileState } from \"#/hooks/use-chat-input-profile-state\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport SettingsGearIcon from \"#/icons/settings-gear.svg?react\";\nimport CheckIcon from \"#/icons/checkmark.svg?react\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { ContextMenu } from \"#/ui/context-menu\";\nimport { ContextMenuListItem } from \"#/components/features/context-menu/context-menu-list-item\";\nimport { Divider } from \"#/ui/divider\";\nimport { Typography } from \"#/ui/typography\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\n\nconst PROFILE_LABEL_MAX_CHARS = 18;\n\nfunction truncateLabel(label: string): string {\n return label.length <= PROFILE_LABEL_MAX_CHARS\n ? label\n : `${label.slice(0, PROFILE_LABEL_MAX_CHARS)}…`;\n}\n\ninterface ChatInputProfileMenuContentProps {\n onClose: () => void;\n dividerInset?: \"menu\";\n settingsLinkClassName?: string;\n settingsIconClassName?: string;\n}\n\nexport function ChatInputProfileMenuContent({\n onClose,\n dividerInset,\n settingsLinkClassName,\n settingsIconClassName,\n}: ChatInputProfileMenuContentProps) {\n const { t } = useTranslation(\"openhands\");\n const { profiles, currentProfileId, selectProfile } =\n useChatInputProfileState();\n\n const handleSelect = (profile: (typeof profiles)[number]) => {\n selectProfile(profile);\n onClose();\n };\n\n return (\n <>\n {profiles.length > 0 && (\n <>\n {/* role=\"presentation\" keeps this a valid <li> child of the\n ContextMenu <ul> without exposing the label as a menu item. */}\n <li role=\"presentation\" className=\"px-2 pt-1 pb-0.5\">\n <Typography.Text className=\"text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4\">\n {t(I18nKey.SETTINGS$AVAILABLE_PROFILES)}\n </Typography.Text>\n </li>\n {profiles.map((profile) => {\n const isCurrent =\n profile.id != null && profile.id === currentProfileId;\n return (\n <ContextMenuListItem\n key={profile.id ?? profile.name}\n testId={`chat-input-agent-profile-option-${profile.name}`}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (isCurrent) {\n onClose();\n return;\n }\n handleSelect(profile);\n }}\n className={cn(\n \"flex items-center gap-2\",\n isCurrent && \"bg-[var(--oh-interactive-hover)]\",\n )}\n >\n <span\n className=\"flex-1 truncate text-sm leading-5\"\n title={profile.name}\n >\n {profile.name}\n </span>\n {isCurrent && (\n <CheckIcon\n width={14}\n height={14}\n className=\"shrink-0\"\n aria-hidden\n />\n )}\n </ContextMenuListItem>\n );\n })}\n </>\n )}\n {profiles.length > 0 && <Divider inset={dividerInset} />}\n <li className=\"text-sm\">\n <NavigationLink\n to=\"/settings/agents\"\n onClick={onClose}\n className={cn(\n \"flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)] transition-colors\",\n settingsLinkClassName,\n )}\n >\n <SettingsGearIcon\n width={16}\n height={16}\n className={cn(\"shrink-0\", settingsIconClassName)}\n aria-hidden\n />\n <span>{t(I18nKey.CHAT$MANAGE_AGENT_PROFILES)}</span>\n </NavigationLink>\n </li>\n </>\n );\n}\n\nexport function ChatInputProfilePicker() {\n const { t } = useTranslation(\"openhands\");\n const { profiles, currentProfileName, isLoading, isSwitching } =\n useChatInputProfileState();\n const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const popoverRef = useClickOutsideElement<HTMLUListElement>(\n () => setIsPopoverOpen(false),\n triggerRef,\n );\n\n // Nothing to launch from yet (empty store before the backend seeds, or an\n // agent-server without the /api/agent-profiles surface): stay out of the way.\n if (isLoading || profiles.length === 0) {\n return null;\n }\n\n const label = currentProfileName ?? t(I18nKey.CHAT$AGENT_PROFILE_PLACEHOLDER);\n\n return (\n <div className=\"relative min-w-0\">\n <button\n ref={triggerRef}\n type=\"button\"\n className={cn(chatInputPillButtonClassName, \"max-w-[200px]\")}\n title={currentProfileName ?? undefined}\n data-testid=\"chat-input-agent-profile\"\n aria-expanded={isPopoverOpen}\n aria-haspopup=\"dialog\"\n // Disabled while a profile switch (new-conversation create / activate) is\n // in flight, so re-opening the menu can't fire a second create. The menu\n // closes on select, so this is the only double-submit path.\n disabled={isSwitching}\n aria-busy={isSwitching}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setIsPopoverOpen((open) => !open);\n }}\n >\n <span className=\"truncate\">{truncateLabel(label)}</span>\n <ComboboxCaretInline isOpen={isPopoverOpen} />\n </button>\n\n {isPopoverOpen && (\n <ContextMenu\n ref={popoverRef}\n testId=\"chat-input-agent-profile-popover\"\n position=\"top\"\n alignment=\"left\"\n spacing=\"none\"\n className=\"z-[60] mb-2 min-w-[200px] max-w-[320px] max-h-[60vh] overflow-y-auto\"\n >\n <ChatInputProfileMenuContent\n onClose={() => setIsPopoverOpen(false)}\n />\n </ContextMenu>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"chat-input-profile-picker.cjs","names":[],"sources":["../../../../../src/components/features/chat/components/chat-input-profile-picker.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useChatInputProfileState } from \"#/hooks/use-chat-input-profile-state\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport SettingsGearIcon from \"#/icons/settings-gear.svg?react\";\nimport CheckIcon from \"#/icons/checkmark.svg?react\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { ContextMenu } from \"#/ui/context-menu\";\nimport { ContextMenuListItem } from \"#/components/features/context-menu/context-menu-list-item\";\nimport { Divider } from \"#/ui/divider\";\nimport { Typography } from \"#/ui/typography\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\n\nconst PROFILE_LABEL_MAX_CHARS = 18;\n\nfunction truncateLabel(label: string): string {\n return label.length <= PROFILE_LABEL_MAX_CHARS\n ? label\n : `${label.slice(0, PROFILE_LABEL_MAX_CHARS)}…`;\n}\n\ninterface ChatInputProfileMenuContentProps {\n onClose: () => void;\n dividerInset?: \"menu\";\n settingsLinkClassName?: string;\n settingsIconClassName?: string;\n}\n\nexport function ChatInputProfileMenuContent({\n onClose,\n dividerInset,\n settingsLinkClassName,\n settingsIconClassName,\n}: ChatInputProfileMenuContentProps) {\n const { t } = useTranslation(\"openhands\");\n const {\n profiles,\n currentProfileId,\n isInConversation,\n isSwitching,\n selectProfile,\n } = useChatInputProfileState();\n\n const handleSelect = (profile: (typeof profiles)[number]) => {\n selectProfile(profile);\n onClose();\n };\n\n return (\n <>\n {profiles.length > 0 && (\n <>\n {/* role=\"presentation\" keeps this a valid <li> child of the\n ContextMenu <ul> without exposing the label as a menu item. */}\n <li role=\"presentation\" className=\"px-2 pt-1 pb-0.5\">\n <Typography.Text className=\"text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4\">\n {t(I18nKey.SETTINGS$AVAILABLE_PROFILES)}\n </Typography.Text>\n </li>\n {profiles.map((profile) => {\n const isCurrent =\n profile.id != null && profile.id === currentProfileId;\n return (\n <ContextMenuListItem\n key={profile.id ?? profile.name}\n testId={`chat-input-agent-profile-option-${profile.name}`}\n isDisabled={isSwitching}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (isCurrent) {\n onClose();\n return;\n }\n handleSelect(profile);\n }}\n className={cn(\n \"flex items-center gap-2\",\n isCurrent && \"bg-[var(--oh-interactive-hover)]\",\n )}\n >\n <span\n className=\"flex-1 truncate text-sm leading-5\"\n title={profile.name}\n >\n {profile.name}\n </span>\n {isCurrent && (\n <CheckIcon\n width={14}\n height={14}\n className=\"shrink-0\"\n aria-hidden\n />\n )}\n </ContextMenuListItem>\n );\n })}\n {isInConversation && (\n <li role=\"presentation\" className=\"px-2 pt-0.5 pb-1\">\n <Typography.Text className=\"text-[11px] text-[var(--oh-text-dim)] leading-4\">\n {t(I18nKey.CHAT$START_NEW_WITH_PROFILE_HINT)}\n </Typography.Text>\n </li>\n )}\n </>\n )}\n {profiles.length > 0 && <Divider inset={dividerInset} />}\n <li className=\"text-sm\">\n <NavigationLink\n to=\"/settings/agents\"\n onClick={onClose}\n className={cn(\n \"flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)] transition-colors\",\n settingsLinkClassName,\n )}\n >\n <SettingsGearIcon\n width={16}\n height={16}\n className={cn(\"shrink-0\", settingsIconClassName)}\n aria-hidden\n />\n <span>{t(I18nKey.CHAT$MANAGE_AGENT_PROFILES)}</span>\n </NavigationLink>\n </li>\n </>\n );\n}\n\nexport function ChatInputProfilePicker() {\n const { t } = useTranslation(\"openhands\");\n const { profiles, currentProfileName, isLoading, isSwitching } =\n useChatInputProfileState();\n const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const popoverRef = useClickOutsideElement<HTMLUListElement>(\n () => setIsPopoverOpen(false),\n triggerRef,\n );\n\n // Nothing to launch from yet (empty store before the backend seeds, or an\n // agent-server without the /api/agent-profiles surface): stay out of the way.\n if (isLoading || profiles.length === 0) {\n return null;\n }\n\n const label = currentProfileName ?? t(I18nKey.CHAT$AGENT_PROFILE_PLACEHOLDER);\n\n return (\n <div className=\"relative min-w-0\">\n <button\n ref={triggerRef}\n type=\"button\"\n className={cn(chatInputPillButtonClassName, \"max-w-[200px]\")}\n title={currentProfileName ?? undefined}\n data-testid=\"chat-input-agent-profile\"\n aria-expanded={isPopoverOpen}\n aria-haspopup=\"dialog\"\n // Disabled while a profile switch (new-conversation create / activate) is\n // in flight, so re-opening the menu can't fire a second create. The menu\n // closes on select, so this is the only double-submit path.\n disabled={isSwitching}\n aria-busy={isSwitching}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setIsPopoverOpen((open) => !open);\n }}\n >\n <span className=\"truncate\">{truncateLabel(label)}</span>\n <ComboboxCaretInline isOpen={isPopoverOpen} />\n </button>\n\n {isPopoverOpen && (\n <ContextMenu\n ref={popoverRef}\n testId=\"chat-input-agent-profile-popover\"\n position=\"top\"\n alignment=\"left\"\n spacing=\"none\"\n className=\"z-[60] mb-2 min-w-[200px] max-w-[320px] max-h-[60vh] overflow-y-auto\"\n >\n <ChatInputProfileMenuContent\n onClose={() => setIsPopoverOpen(false)}\n />\n </ContextMenu>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -20,41 +20,53 @@ function y(e) {
20
20
  return e.length <= v ? e : `${e.slice(0, v)}…`;
21
21
  }
22
22
  function b({ onClose: i, dividerInset: o, settingsLinkClassName: s, settingsIconClassName: l }) {
23
- let { t: m } = e("openhands"), { profiles: v, currentProfileId: y, selectProfile: b } = p(), x = (e) => {
24
- b(e), i();
23
+ let { t: m } = e("openhands"), { profiles: v, currentProfileId: y, isInConversation: b, isSwitching: x, selectProfile: S } = p(), C = (e) => {
24
+ S(e), i();
25
25
  };
26
26
  return /* @__PURE__ */ _(h, { children: [
27
- v.length > 0 && /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g("li", {
28
- role: "presentation",
29
- className: "px-2 pt-1 pb-0.5",
30
- children: /* @__PURE__ */ g(a.Text, {
31
- className: "text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4",
32
- children: m(t.SETTINGS$AVAILABLE_PROFILES)
27
+ v.length > 0 && /* @__PURE__ */ _(h, { children: [
28
+ /* @__PURE__ */ g("li", {
29
+ role: "presentation",
30
+ className: "px-2 pt-1 pb-0.5",
31
+ children: /* @__PURE__ */ g(a.Text, {
32
+ className: "text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4",
33
+ children: m(t.SETTINGS$AVAILABLE_PROFILES)
34
+ })
35
+ }),
36
+ v.map((e) => {
37
+ let t = e.id != null && e.id === y;
38
+ return /* @__PURE__ */ _(c, {
39
+ testId: `chat-input-agent-profile-option-${e.name}`,
40
+ isDisabled: x,
41
+ onClick: (n) => {
42
+ if (n.preventDefault(), n.stopPropagation(), t) {
43
+ i();
44
+ return;
45
+ }
46
+ C(e);
47
+ },
48
+ className: n("flex items-center gap-2", t && "bg-[var(--oh-interactive-hover)]"),
49
+ children: [/* @__PURE__ */ g("span", {
50
+ className: "flex-1 truncate text-sm leading-5",
51
+ title: e.name,
52
+ children: e.name
53
+ }), t && /* @__PURE__ */ g(r, {
54
+ width: 14,
55
+ height: 14,
56
+ className: "shrink-0",
57
+ "aria-hidden": !0
58
+ })]
59
+ }, e.id ?? e.name);
60
+ }),
61
+ b && /* @__PURE__ */ g("li", {
62
+ role: "presentation",
63
+ className: "px-2 pt-0.5 pb-1",
64
+ children: /* @__PURE__ */ g(a.Text, {
65
+ className: "text-[11px] text-[var(--oh-text-dim)] leading-4",
66
+ children: m(t.CHAT$START_NEW_WITH_PROFILE_HINT)
67
+ })
33
68
  })
34
- }), v.map((e) => {
35
- let t = e.id != null && e.id === y;
36
- return /* @__PURE__ */ _(c, {
37
- testId: `chat-input-agent-profile-option-${e.name}`,
38
- onClick: (n) => {
39
- if (n.preventDefault(), n.stopPropagation(), t) {
40
- i();
41
- return;
42
- }
43
- x(e);
44
- },
45
- className: n("flex items-center gap-2", t && "bg-[var(--oh-interactive-hover)]"),
46
- children: [/* @__PURE__ */ g("span", {
47
- className: "flex-1 truncate text-sm leading-5",
48
- title: e.name,
49
- children: e.name
50
- }), t && /* @__PURE__ */ g(r, {
51
- width: 14,
52
- height: 14,
53
- className: "shrink-0",
54
- "aria-hidden": !0
55
- })]
56
- }, e.id ?? e.name);
57
- })] }),
69
+ ] }),
58
70
  v.length > 0 && /* @__PURE__ */ g(f, { inset: o }),
59
71
  /* @__PURE__ */ g("li", {
60
72
  className: "text-sm",
@@ -1 +1 @@
1
- {"version":3,"file":"chat-input-profile-picker.js","names":[],"sources":["../../../../../src/components/features/chat/components/chat-input-profile-picker.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useChatInputProfileState } from \"#/hooks/use-chat-input-profile-state\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport SettingsGearIcon from \"#/icons/settings-gear.svg?react\";\nimport CheckIcon from \"#/icons/checkmark.svg?react\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { ContextMenu } from \"#/ui/context-menu\";\nimport { ContextMenuListItem } from \"#/components/features/context-menu/context-menu-list-item\";\nimport { Divider } from \"#/ui/divider\";\nimport { Typography } from \"#/ui/typography\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\n\nconst PROFILE_LABEL_MAX_CHARS = 18;\n\nfunction truncateLabel(label: string): string {\n return label.length <= PROFILE_LABEL_MAX_CHARS\n ? label\n : `${label.slice(0, PROFILE_LABEL_MAX_CHARS)}…`;\n}\n\ninterface ChatInputProfileMenuContentProps {\n onClose: () => void;\n dividerInset?: \"menu\";\n settingsLinkClassName?: string;\n settingsIconClassName?: string;\n}\n\nexport function ChatInputProfileMenuContent({\n onClose,\n dividerInset,\n settingsLinkClassName,\n settingsIconClassName,\n}: ChatInputProfileMenuContentProps) {\n const { t } = useTranslation(\"openhands\");\n const { profiles, currentProfileId, selectProfile } =\n useChatInputProfileState();\n\n const handleSelect = (profile: (typeof profiles)[number]) => {\n selectProfile(profile);\n onClose();\n };\n\n return (\n <>\n {profiles.length > 0 && (\n <>\n {/* role=\"presentation\" keeps this a valid <li> child of the\n ContextMenu <ul> without exposing the label as a menu item. */}\n <li role=\"presentation\" className=\"px-2 pt-1 pb-0.5\">\n <Typography.Text className=\"text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4\">\n {t(I18nKey.SETTINGS$AVAILABLE_PROFILES)}\n </Typography.Text>\n </li>\n {profiles.map((profile) => {\n const isCurrent =\n profile.id != null && profile.id === currentProfileId;\n return (\n <ContextMenuListItem\n key={profile.id ?? profile.name}\n testId={`chat-input-agent-profile-option-${profile.name}`}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (isCurrent) {\n onClose();\n return;\n }\n handleSelect(profile);\n }}\n className={cn(\n \"flex items-center gap-2\",\n isCurrent && \"bg-[var(--oh-interactive-hover)]\",\n )}\n >\n <span\n className=\"flex-1 truncate text-sm leading-5\"\n title={profile.name}\n >\n {profile.name}\n </span>\n {isCurrent && (\n <CheckIcon\n width={14}\n height={14}\n className=\"shrink-0\"\n aria-hidden\n />\n )}\n </ContextMenuListItem>\n );\n })}\n </>\n )}\n {profiles.length > 0 && <Divider inset={dividerInset} />}\n <li className=\"text-sm\">\n <NavigationLink\n to=\"/settings/agents\"\n onClick={onClose}\n className={cn(\n \"flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)] transition-colors\",\n settingsLinkClassName,\n )}\n >\n <SettingsGearIcon\n width={16}\n height={16}\n className={cn(\"shrink-0\", settingsIconClassName)}\n aria-hidden\n />\n <span>{t(I18nKey.CHAT$MANAGE_AGENT_PROFILES)}</span>\n </NavigationLink>\n </li>\n </>\n );\n}\n\nexport function ChatInputProfilePicker() {\n const { t } = useTranslation(\"openhands\");\n const { profiles, currentProfileName, isLoading, isSwitching } =\n useChatInputProfileState();\n const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const popoverRef = useClickOutsideElement<HTMLUListElement>(\n () => setIsPopoverOpen(false),\n triggerRef,\n );\n\n // Nothing to launch from yet (empty store before the backend seeds, or an\n // agent-server without the /api/agent-profiles surface): stay out of the way.\n if (isLoading || profiles.length === 0) {\n return null;\n }\n\n const label = currentProfileName ?? t(I18nKey.CHAT$AGENT_PROFILE_PLACEHOLDER);\n\n return (\n <div className=\"relative min-w-0\">\n <button\n ref={triggerRef}\n type=\"button\"\n className={cn(chatInputPillButtonClassName, \"max-w-[200px]\")}\n title={currentProfileName ?? undefined}\n data-testid=\"chat-input-agent-profile\"\n aria-expanded={isPopoverOpen}\n aria-haspopup=\"dialog\"\n // Disabled while a profile switch (new-conversation create / activate) is\n // in flight, so re-opening the menu can't fire a second create. The menu\n // closes on select, so this is the only double-submit path.\n disabled={isSwitching}\n aria-busy={isSwitching}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setIsPopoverOpen((open) => !open);\n }}\n >\n <span className=\"truncate\">{truncateLabel(label)}</span>\n <ComboboxCaretInline isOpen={isPopoverOpen} />\n </button>\n\n {isPopoverOpen && (\n <ContextMenu\n ref={popoverRef}\n testId=\"chat-input-agent-profile-popover\"\n position=\"top\"\n alignment=\"left\"\n spacing=\"none\"\n className=\"z-[60] mb-2 min-w-[200px] max-w-[320px] max-h-[60vh] overflow-y-auto\"\n >\n <ChatInputProfileMenuContent\n onClose={() => setIsPopoverOpen(false)}\n />\n </ContextMenu>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,IAAM,IAA0B;AAEhC,SAAS,EAAc,GAAuB;AAC5C,QAAO,EAAM,UAAU,IACnB,IACA,GAAG,EAAM,MAAM,GAAG,EAAwB,CAAC;;AAUjD,SAAgB,EAA4B,EAC1C,YACA,iBACA,0BACA,4BACmC;CACnC,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,EAAE,aAAU,qBAAkB,qBAClC,GAA0B,EAEtB,KAAgB,MAAuC;AAE3D,EADA,EAAc,EAAQ,EACtB,GAAS;;AAGX,QACE,kBAAA,GAAA,EAAA,UAAA;EACG,EAAS,SAAS,KACjB,kBAAA,GAAA,EAAA,UAAA,CAGE,kBAAC,MAAD;GAAI,MAAK;GAAe,WAAU;aAChC,kBAAC,EAAW,MAAZ;IAAiB,WAAU;cACxB,EAAE,EAAQ,4BAA4B;IACvB,CAAA;GACf,CAAA,EACJ,EAAS,KAAK,MAAY;GACzB,IAAM,IACJ,EAAQ,MAAM,QAAQ,EAAQ,OAAO;AACvC,UACE,kBAAC,GAAD;IAEE,QAAQ,mCAAmC,EAAQ;IACnD,UAAU,MAAU;AAGlB,SAFA,EAAM,gBAAgB,EACtB,EAAM,iBAAiB,EACnB,GAAW;AACb,SAAS;AACT;;AAEF,OAAa,EAAQ;;IAEvB,WAAW,EACT,2BACA,KAAa,mCACd;cAfH,CAiBE,kBAAC,QAAD;KACE,WAAU;KACV,OAAO,EAAQ;eAEd,EAAQ;KACJ,CAAA,EACN,KACC,kBAAC,GAAD;KACE,OAAO;KACP,QAAQ;KACR,WAAU;KACV,eAAA;KACA,CAAA,CAEgB;MA9Bf,EAAQ,MAAM,EAAQ,KA8BP;IAExB,CACD,EAAA,CAAA;EAEJ,EAAS,SAAS,KAAK,kBAAC,GAAD,EAAS,OAAO,GAAgB,CAAA;EACxD,kBAAC,MAAD;GAAI,WAAU;aACZ,kBAAC,GAAD;IACE,IAAG;IACH,SAAS;IACT,WAAW,EACT,+IACA,EACD;cANH,CAQE,kBAAC,GAAD;KACE,OAAO;KACP,QAAQ;KACR,WAAW,EAAG,YAAY,EAAsB;KAChD,eAAA;KACA,CAAA,EACF,kBAAC,QAAD,EAAA,UAAO,EAAE,EAAQ,2BAA2B,EAAQ,CAAA,CACrC;;GACd,CAAA;EACJ,EAAA,CAAA;;AAIP,SAAgB,IAAyB;CACvC,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,EAAE,aAAU,uBAAoB,cAAW,mBAC/C,GAA0B,EACtB,CAAC,GAAe,KAAoB,EAAM,SAAS,GAAM,EACzD,IAAa,EAAM,OAA0B,KAAK,EAClD,IAAa,QACX,EAAiB,GAAM,EAC7B,EACD;AAID,KAAI,KAAa,EAAS,WAAW,EACnC,QAAO;CAGT,IAAM,IAAQ,KAAsB,EAAE,EAAQ,+BAA+B;AAE7E,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,UAAD;GACE,KAAK;GACL,MAAK;GACL,WAAW,EAAG,GAA8B,gBAAgB;GAC5D,OAAO,KAAsB,KAAA;GAC7B,eAAY;GACZ,iBAAe;GACf,iBAAc;GAId,UAAU;GACV,aAAW;GACX,UAAU,MAAU;AAGlB,IAFA,EAAM,gBAAgB,EACtB,EAAM,iBAAiB,EACvB,GAAkB,MAAS,CAAC,EAAK;;aAhBrC,CAmBE,kBAAC,QAAD;IAAM,WAAU;cAAY,EAAc,EAAM;IAAQ,CAAA,EACxD,kBAAC,GAAD,EAAqB,QAAQ,GAAiB,CAAA,CACvC;MAER,KACC,kBAAC,GAAD;GACE,KAAK;GACL,QAAO;GACP,UAAS;GACT,WAAU;GACV,SAAQ;GACR,WAAU;aAEV,kBAAC,GAAD,EACE,eAAe,EAAiB,GAAM,EACtC,CAAA;GACU,CAAA,CAEZ"}
1
+ {"version":3,"file":"chat-input-profile-picker.js","names":[],"sources":["../../../../../src/components/features/chat/components/chat-input-profile-picker.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useChatInputProfileState } from \"#/hooks/use-chat-input-profile-state\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport SettingsGearIcon from \"#/icons/settings-gear.svg?react\";\nimport CheckIcon from \"#/icons/checkmark.svg?react\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { ContextMenu } from \"#/ui/context-menu\";\nimport { ContextMenuListItem } from \"#/components/features/context-menu/context-menu-list-item\";\nimport { Divider } from \"#/ui/divider\";\nimport { Typography } from \"#/ui/typography\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\n\nconst PROFILE_LABEL_MAX_CHARS = 18;\n\nfunction truncateLabel(label: string): string {\n return label.length <= PROFILE_LABEL_MAX_CHARS\n ? label\n : `${label.slice(0, PROFILE_LABEL_MAX_CHARS)}…`;\n}\n\ninterface ChatInputProfileMenuContentProps {\n onClose: () => void;\n dividerInset?: \"menu\";\n settingsLinkClassName?: string;\n settingsIconClassName?: string;\n}\n\nexport function ChatInputProfileMenuContent({\n onClose,\n dividerInset,\n settingsLinkClassName,\n settingsIconClassName,\n}: ChatInputProfileMenuContentProps) {\n const { t } = useTranslation(\"openhands\");\n const {\n profiles,\n currentProfileId,\n isInConversation,\n isSwitching,\n selectProfile,\n } = useChatInputProfileState();\n\n const handleSelect = (profile: (typeof profiles)[number]) => {\n selectProfile(profile);\n onClose();\n };\n\n return (\n <>\n {profiles.length > 0 && (\n <>\n {/* role=\"presentation\" keeps this a valid <li> child of the\n ContextMenu <ul> without exposing the label as a menu item. */}\n <li role=\"presentation\" className=\"px-2 pt-1 pb-0.5\">\n <Typography.Text className=\"text-[11px] font-medium text-[var(--oh-text-dim)] uppercase tracking-wide leading-4\">\n {t(I18nKey.SETTINGS$AVAILABLE_PROFILES)}\n </Typography.Text>\n </li>\n {profiles.map((profile) => {\n const isCurrent =\n profile.id != null && profile.id === currentProfileId;\n return (\n <ContextMenuListItem\n key={profile.id ?? profile.name}\n testId={`chat-input-agent-profile-option-${profile.name}`}\n isDisabled={isSwitching}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (isCurrent) {\n onClose();\n return;\n }\n handleSelect(profile);\n }}\n className={cn(\n \"flex items-center gap-2\",\n isCurrent && \"bg-[var(--oh-interactive-hover)]\",\n )}\n >\n <span\n className=\"flex-1 truncate text-sm leading-5\"\n title={profile.name}\n >\n {profile.name}\n </span>\n {isCurrent && (\n <CheckIcon\n width={14}\n height={14}\n className=\"shrink-0\"\n aria-hidden\n />\n )}\n </ContextMenuListItem>\n );\n })}\n {isInConversation && (\n <li role=\"presentation\" className=\"px-2 pt-0.5 pb-1\">\n <Typography.Text className=\"text-[11px] text-[var(--oh-text-dim)] leading-4\">\n {t(I18nKey.CHAT$START_NEW_WITH_PROFILE_HINT)}\n </Typography.Text>\n </li>\n )}\n </>\n )}\n {profiles.length > 0 && <Divider inset={dividerInset} />}\n <li className=\"text-sm\">\n <NavigationLink\n to=\"/settings/agents\"\n onClick={onClose}\n className={cn(\n \"flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)] transition-colors\",\n settingsLinkClassName,\n )}\n >\n <SettingsGearIcon\n width={16}\n height={16}\n className={cn(\"shrink-0\", settingsIconClassName)}\n aria-hidden\n />\n <span>{t(I18nKey.CHAT$MANAGE_AGENT_PROFILES)}</span>\n </NavigationLink>\n </li>\n </>\n );\n}\n\nexport function ChatInputProfilePicker() {\n const { t } = useTranslation(\"openhands\");\n const { profiles, currentProfileName, isLoading, isSwitching } =\n useChatInputProfileState();\n const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const popoverRef = useClickOutsideElement<HTMLUListElement>(\n () => setIsPopoverOpen(false),\n triggerRef,\n );\n\n // Nothing to launch from yet (empty store before the backend seeds, or an\n // agent-server without the /api/agent-profiles surface): stay out of the way.\n if (isLoading || profiles.length === 0) {\n return null;\n }\n\n const label = currentProfileName ?? t(I18nKey.CHAT$AGENT_PROFILE_PLACEHOLDER);\n\n return (\n <div className=\"relative min-w-0\">\n <button\n ref={triggerRef}\n type=\"button\"\n className={cn(chatInputPillButtonClassName, \"max-w-[200px]\")}\n title={currentProfileName ?? undefined}\n data-testid=\"chat-input-agent-profile\"\n aria-expanded={isPopoverOpen}\n aria-haspopup=\"dialog\"\n // Disabled while a profile switch (new-conversation create / activate) is\n // in flight, so re-opening the menu can't fire a second create. The menu\n // closes on select, so this is the only double-submit path.\n disabled={isSwitching}\n aria-busy={isSwitching}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setIsPopoverOpen((open) => !open);\n }}\n >\n <span className=\"truncate\">{truncateLabel(label)}</span>\n <ComboboxCaretInline isOpen={isPopoverOpen} />\n </button>\n\n {isPopoverOpen && (\n <ContextMenu\n ref={popoverRef}\n testId=\"chat-input-agent-profile-popover\"\n position=\"top\"\n alignment=\"left\"\n spacing=\"none\"\n className=\"z-[60] mb-2 min-w-[200px] max-w-[320px] max-h-[60vh] overflow-y-auto\"\n >\n <ChatInputProfileMenuContent\n onClose={() => setIsPopoverOpen(false)}\n />\n </ContextMenu>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- require(`../../../../_virtual/_rolldown/runtime.cjs`);function e({hasConversation:e,isCloud:t,isAcp:n,profilesAvailable:r}){return e?n?`model`:`llm-profile`:r?`agent-profile`:t?`model`:`llm-profile`}exports.resolvePickerKind=e;
1
+ require(`../../../../_virtual/_rolldown/runtime.cjs`);function e({isLoadingHistory:e,hasUserEvents:t,hasPendingUserMessages:n,hasSubstantiveAgentActions:r,hasModelEntries:i}){return e||t||n||r||i}function t({hasConversation:e,hasStartedConversation:t=e,isCloud:n,isAcp:r,profilesAvailable:i}){return!e||!t?i?`agent-profile`:n?`model`:`llm-profile`:r?`model`:`llm-profile`}exports.hasConversationStarted=e,exports.resolvePickerKind=t;
2
2
  //# sourceMappingURL=resolve-picker-kind.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-picker-kind.cjs","names":[],"sources":["../../../../../src/components/features/chat/components/resolve-picker-kind.ts"],"sourcesContent":["export type PickerKind = \"model\" | \"agent-profile\" | \"llm-profile\";\n\nexport interface ResolvePickerKindInput {\n /** A conversation is active (i.e. we're inside a conversation, not on home). */\n hasConversation: boolean;\n /** The active backend is cloud (vs. a local agent-server). */\n isCloud: boolean;\n /** The current context runs an ACP agent (active conv or home ACP settings). */\n isAcp: boolean;\n /** At least one AgentProfile exists to launch the next conversation from. */\n profilesAvailable: boolean;\n}\n\n/**\n * Decide which chat-input model/profile picker to show. Pure so the matrix is\n * unit-tested directly (see `resolve-picker-kind.test.ts`).\n *\n * - Home (local or cloud): the AgentProfile picker, which starts a new\n * conversation / activates the default (#3727, cloud via #15060). When no\n * profiles exist yet, fall back — cloud → model, local → LLM-profile (cloud\n * has no home LLM-profile activate path).\n * - In an ACP conversation (local or cloud): the model picker — ACP owns its\n * LLM via the subprocess/session, so the picker just live-switches the\n * session model (set_session_model / cloud's switch_acp_model proxy).\n * - In an OpenHands conversation (local or cloud): the LLM-profile picker,\n * which live-switches the running conversation's LLM profile via\n * /switch_profile — a real endpoint on both backends (cloud proxies\n * POST /api/v1/app-conversations/{id}/switch_profile, unchanged since\n * OpenHands#14288). There is no cloud-specific restriction here.\n */\nexport function resolvePickerKind({\n hasConversation,\n isCloud,\n isAcp,\n profilesAvailable,\n}: ResolvePickerKindInput): PickerKind {\n if (!hasConversation) {\n if (profilesAvailable) return \"agent-profile\";\n return isCloud ? \"model\" : \"llm-profile\";\n }\n return isAcp ? \"model\" : \"llm-profile\";\n}\n"],"mappings":"sDA8BA,SAAgB,EAAkB,CAChC,kBACA,UACA,QACA,qBACqC,CAKrC,OAJK,EAIE,EAAQ,QAAU,cAHnB,EAA0B,gBACvB,EAAU,QAAU"}
1
+ {"version":3,"file":"resolve-picker-kind.cjs","names":[],"sources":["../../../../../src/components/features/chat/components/resolve-picker-kind.ts"],"sourcesContent":["export type PickerKind = \"model\" | \"agent-profile\" | \"llm-profile\";\n\nexport interface ConversationStartState {\n isLoadingHistory: boolean;\n hasUserEvents: boolean;\n hasPendingUserMessages: boolean;\n hasSubstantiveAgentActions: boolean;\n hasModelEntries: boolean;\n}\n\nexport function hasConversationStarted({\n isLoadingHistory,\n hasUserEvents,\n hasPendingUserMessages,\n hasSubstantiveAgentActions,\n hasModelEntries,\n}: ConversationStartState) {\n return (\n isLoadingHistory ||\n hasUserEvents ||\n hasPendingUserMessages ||\n hasSubstantiveAgentActions ||\n hasModelEntries\n );\n}\n\nexport interface ResolvePickerKindInput {\n hasConversation: boolean;\n hasStartedConversation?: boolean;\n isCloud: boolean;\n isAcp: boolean;\n profilesAvailable: boolean;\n}\nexport function resolvePickerKind({\n hasConversation,\n hasStartedConversation = hasConversation,\n isCloud,\n isAcp,\n profilesAvailable,\n}: ResolvePickerKindInput): PickerKind {\n if (!hasConversation || !hasStartedConversation) {\n if (profilesAvailable) return \"agent-profile\";\n return isCloud ? \"model\" : \"llm-profile\";\n }\n return isAcp ? \"model\" : \"llm-profile\";\n}\n"],"mappings":"sDAUA,SAAgB,EAAuB,CACrC,mBACA,gBACA,yBACA,6BACA,mBACyB,CACzB,OACE,GACA,GACA,GACA,GACA,EAWJ,SAAgB,EAAkB,CAChC,kBACA,yBAAyB,EACzB,UACA,QACA,qBACqC,CAKrC,MAJI,CAAC,GAAmB,CAAC,EACnB,EAA0B,gBACvB,EAAU,QAAU,cAEtB,EAAQ,QAAU"}
@@ -1,29 +1,17 @@
1
1
  export type PickerKind = "model" | "agent-profile" | "llm-profile";
2
+ export interface ConversationStartState {
3
+ isLoadingHistory: boolean;
4
+ hasUserEvents: boolean;
5
+ hasPendingUserMessages: boolean;
6
+ hasSubstantiveAgentActions: boolean;
7
+ hasModelEntries: boolean;
8
+ }
9
+ export declare function hasConversationStarted({ isLoadingHistory, hasUserEvents, hasPendingUserMessages, hasSubstantiveAgentActions, hasModelEntries, }: ConversationStartState): boolean;
2
10
  export interface ResolvePickerKindInput {
3
- /** A conversation is active (i.e. we're inside a conversation, not on home). */
4
11
  hasConversation: boolean;
5
- /** The active backend is cloud (vs. a local agent-server). */
12
+ hasStartedConversation?: boolean;
6
13
  isCloud: boolean;
7
- /** The current context runs an ACP agent (active conv or home ACP settings). */
8
14
  isAcp: boolean;
9
- /** At least one AgentProfile exists to launch the next conversation from. */
10
15
  profilesAvailable: boolean;
11
16
  }
12
- /**
13
- * Decide which chat-input model/profile picker to show. Pure so the matrix is
14
- * unit-tested directly (see `resolve-picker-kind.test.ts`).
15
- *
16
- * - Home (local or cloud): the AgentProfile picker, which starts a new
17
- * conversation / activates the default (#3727, cloud via #15060). When no
18
- * profiles exist yet, fall back — cloud → model, local → LLM-profile (cloud
19
- * has no home LLM-profile activate path).
20
- * - In an ACP conversation (local or cloud): the model picker — ACP owns its
21
- * LLM via the subprocess/session, so the picker just live-switches the
22
- * session model (set_session_model / cloud's switch_acp_model proxy).
23
- * - In an OpenHands conversation (local or cloud): the LLM-profile picker,
24
- * which live-switches the running conversation's LLM profile via
25
- * /switch_profile — a real endpoint on both backends (cloud proxies
26
- * POST /api/v1/app-conversations/{id}/switch_profile, unchanged since
27
- * OpenHands#14288). There is no cloud-specific restriction here.
28
- */
29
- export declare function resolvePickerKind({ hasConversation, isCloud, isAcp, profilesAvailable, }: ResolvePickerKindInput): PickerKind;
17
+ export declare function resolvePickerKind({ hasConversation, hasStartedConversation, isCloud, isAcp, profilesAvailable, }: ResolvePickerKindInput): PickerKind;
@@ -1,8 +1,11 @@
1
1
  //#region src/components/features/chat/components/resolve-picker-kind.ts
2
- function e({ hasConversation: e, isCloud: t, isAcp: n, profilesAvailable: r }) {
3
- return e ? n ? "model" : "llm-profile" : r ? "agent-profile" : t ? "model" : "llm-profile";
2
+ function e({ isLoadingHistory: e, hasUserEvents: t, hasPendingUserMessages: n, hasSubstantiveAgentActions: r, hasModelEntries: i }) {
3
+ return e || t || n || r || i;
4
+ }
5
+ function t({ hasConversation: e, hasStartedConversation: t = e, isCloud: n, isAcp: r, profilesAvailable: i }) {
6
+ return !e || !t ? i ? "agent-profile" : n ? "model" : "llm-profile" : r ? "model" : "llm-profile";
4
7
  }
5
8
  //#endregion
6
- export { e as resolvePickerKind };
9
+ export { e as hasConversationStarted, t as resolvePickerKind };
7
10
 
8
11
  //# sourceMappingURL=resolve-picker-kind.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-picker-kind.js","names":[],"sources":["../../../../../src/components/features/chat/components/resolve-picker-kind.ts"],"sourcesContent":["export type PickerKind = \"model\" | \"agent-profile\" | \"llm-profile\";\n\nexport interface ResolvePickerKindInput {\n /** A conversation is active (i.e. we're inside a conversation, not on home). */\n hasConversation: boolean;\n /** The active backend is cloud (vs. a local agent-server). */\n isCloud: boolean;\n /** The current context runs an ACP agent (active conv or home ACP settings). */\n isAcp: boolean;\n /** At least one AgentProfile exists to launch the next conversation from. */\n profilesAvailable: boolean;\n}\n\n/**\n * Decide which chat-input model/profile picker to show. Pure so the matrix is\n * unit-tested directly (see `resolve-picker-kind.test.ts`).\n *\n * - Home (local or cloud): the AgentProfile picker, which starts a new\n * conversation / activates the default (#3727, cloud via #15060). When no\n * profiles exist yet, fall back — cloud → model, local → LLM-profile (cloud\n * has no home LLM-profile activate path).\n * - In an ACP conversation (local or cloud): the model picker — ACP owns its\n * LLM via the subprocess/session, so the picker just live-switches the\n * session model (set_session_model / cloud's switch_acp_model proxy).\n * - In an OpenHands conversation (local or cloud): the LLM-profile picker,\n * which live-switches the running conversation's LLM profile via\n * /switch_profile — a real endpoint on both backends (cloud proxies\n * POST /api/v1/app-conversations/{id}/switch_profile, unchanged since\n * OpenHands#14288). There is no cloud-specific restriction here.\n */\nexport function resolvePickerKind({\n hasConversation,\n isCloud,\n isAcp,\n profilesAvailable,\n}: ResolvePickerKindInput): PickerKind {\n if (!hasConversation) {\n if (profilesAvailable) return \"agent-profile\";\n return isCloud ? \"model\" : \"llm-profile\";\n }\n return isAcp ? \"model\" : \"llm-profile\";\n}\n"],"mappings":";AA8BA,SAAgB,EAAkB,EAChC,oBACA,YACA,UACA,wBACqC;AAKrC,QAJK,IAIE,IAAQ,UAAU,gBAHnB,IAA0B,kBACvB,IAAU,UAAU"}
1
+ {"version":3,"file":"resolve-picker-kind.js","names":[],"sources":["../../../../../src/components/features/chat/components/resolve-picker-kind.ts"],"sourcesContent":["export type PickerKind = \"model\" | \"agent-profile\" | \"llm-profile\";\n\nexport interface ConversationStartState {\n isLoadingHistory: boolean;\n hasUserEvents: boolean;\n hasPendingUserMessages: boolean;\n hasSubstantiveAgentActions: boolean;\n hasModelEntries: boolean;\n}\n\nexport function hasConversationStarted({\n isLoadingHistory,\n hasUserEvents,\n hasPendingUserMessages,\n hasSubstantiveAgentActions,\n hasModelEntries,\n}: ConversationStartState) {\n return (\n isLoadingHistory ||\n hasUserEvents ||\n hasPendingUserMessages ||\n hasSubstantiveAgentActions ||\n hasModelEntries\n );\n}\n\nexport interface ResolvePickerKindInput {\n hasConversation: boolean;\n hasStartedConversation?: boolean;\n isCloud: boolean;\n isAcp: boolean;\n profilesAvailable: boolean;\n}\nexport function resolvePickerKind({\n hasConversation,\n hasStartedConversation = hasConversation,\n isCloud,\n isAcp,\n profilesAvailable,\n}: ResolvePickerKindInput): PickerKind {\n if (!hasConversation || !hasStartedConversation) {\n if (profilesAvailable) return \"agent-profile\";\n return isCloud ? \"model\" : \"llm-profile\";\n }\n return isAcp ? \"model\" : \"llm-profile\";\n}\n"],"mappings":";AAUA,SAAgB,EAAuB,EACrC,qBACA,kBACA,2BACA,+BACA,sBACyB;AACzB,QACE,KACA,KACA,KACA,KACA;;AAWJ,SAAgB,EAAkB,EAChC,oBACA,4BAAyB,GACzB,YACA,UACA,wBACqC;AAKrC,QAJI,CAAC,KAAmB,CAAC,IACnB,IAA0B,kBACvB,IAAU,UAAU,gBAEtB,IAAQ,UAAU"}
@@ -1,2 +1,2 @@
1
- const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../utils/utils.cjs`),n=require(`../../../stores/conversation-store.cjs`),r=require(`../../../hooks/chat/use-chat-input-logic.cjs`),i=require(`../../../hooks/chat/use-file-handling.cjs`),a=require(`../../../hooks/chat/use-grip-resize.cjs`),o=require(`../../../hooks/chat/use-chat-input-events.cjs`),s=require(`../../../hooks/chat/use-chat-submission.cjs`),c=require(`../../../hooks/chat/use-slash-command.cjs`),l=require(`./components/chat-input-grip.cjs`),u=require(`./components/chat-input-container.cjs`),d=require(`./components/hidden-file-input.cjs`);let f=require(`react`);f=e.__toESM(f,1);let p=require(`react/jsx-runtime`);function m({disabled:e=!1,isNewConversationPending:m=!1,showButton:h=!0,onSubmit:g,onFocus:_,onBlur:v,onFilesPaste:ee,className:te=``,buttonClassName:y=``}){let[b,x]=f.default.useState(!1),{submittedMessage:S,clearAllFiles:C,setShouldHideSuggestions:w,setSubmittedMessage:T,images:E,files:D}=n.useConversationStore(),O=e,k=(0,f.useRef)(g);(0,f.useEffect)(()=>{k.current=g},[g]),(0,f.useEffect)(()=>{!S||e||(k.current(S),T(null))},[S,e,T]);let{chatInputRef:A,messageToSend:j,checkIsContentEmpty:M,clearEmptyContentHandler:N,saveDraft:P}=r.useChatInputLogic(),F=f.default.useCallback(()=>{let e=A.current?.innerText??``,t=E.length>0||D.length>0;x(e.trim().length>0||t)},[A,E,D]),{fileInputRef:I,chatContainerRef:L,isDragOver:R,handleFileIconClick:z,handleFileInputChange:B,handleDragOver:V,handleDragLeave:H,handleDrop:ne}=i.useFileHandling(ee),{gripRef:U,isGripVisible:W,isGripDragging:G,handleTopEdgeClick:K,smartResize:q,handleGripMouseDown:J,handleGripTouchStart:Y,increaseHeightForEmptyContent:X,resetManualResize:Z}=a.useGripResize(A,j),{handleSubmit:Q}=s.useChatSubmission(A,I,q,g,Z),$=f.default.useCallback(()=>{Q(),F()},[Q,F]),{handleInput:re,handlePaste:ie,handleKeyDown:ae,handleBlur:oe,handleFocus:se}=o.useChatInputEvents(A,q,X,M,N,_,v),{isMenuOpen:ce,filteredItems:le,selectedIndex:ue,updateSlashMenu:de,selectItem:fe,handleSlashKeyDown:pe,closeMenu:me}=c.useSlashCommand(A);return(0,f.useEffect)(()=>()=>{w(!1),C()},[w,C]),(0,f.useEffect)(()=>{F()},[F,E.length,D.length]),(0,p.jsxs)(`div`,{className:t.cn(`w-full`,te),children:[(0,p.jsx)(d.HiddenFileInput,{fileInputRef:I,onChange:B}),(0,p.jsxs)(`div`,{className:`relative w-full`,children:[(0,p.jsx)(l.ChatInputGrip,{gripRef:U,isGripVisible:W,isGripDragging:G,handleTopEdgeClick:K,handleGripMouseDown:J,handleGripTouchStart:Y}),(0,p.jsx)(u.ChatInputContainer,{chatContainerRef:L,isDragOver:R,disabled:O,canSubmit:b,isNewConversationPending:m,showButton:h,buttonClassName:y,chatInputRef:A,handleFileIconClick:z,handleSubmit:$,onDragOver:V,onDragLeave:H,onDrop:ne,onInput:()=>{re(),de(),P(),F()},onPaste:ie,onKeyDown:e=>{pe(e)||ae(e,O,$)},onFocus:se,onBlur:()=>{oe(),me(),F()},isSlashMenuOpen:ce,slashItems:le,slashSelectedIndex:ue,onSlashSelect:fe})]})]})}exports.CustomChatInput=m;
1
+ const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../utils/utils.cjs`),n=require(`../../../stores/conversation-store.cjs`),r=require(`../../../hooks/chat/use-chat-input-logic.cjs`),i=require(`../../../hooks/chat/use-file-handling.cjs`),a=require(`../../../hooks/chat/use-grip-resize.cjs`),o=require(`../../../hooks/chat/use-chat-input-events.cjs`),s=require(`../../../hooks/chat/use-chat-submission.cjs`),c=require(`../../../hooks/chat/use-slash-command.cjs`),l=require(`./components/chat-input-grip.cjs`),u=require(`./components/chat-input-container.cjs`),d=require(`./components/hidden-file-input.cjs`);let f=require(`react`);f=e.__toESM(f,1);let p=require(`react/jsx-runtime`);function m({disabled:e=!1,isNewConversationPending:m=!1,hasStartedConversation:h,showButton:g=!0,onSubmit:_,onFocus:ee,onBlur:te,onFilesPaste:ne,className:v=``,buttonClassName:y=``}){let[b,x]=f.default.useState(!1),{submittedMessage:S,clearAllFiles:C,setShouldHideSuggestions:w,setSubmittedMessage:T,images:E,files:D}=n.useConversationStore(),O=e,k=(0,f.useRef)(_);(0,f.useEffect)(()=>{k.current=_},[_]),(0,f.useEffect)(()=>{!S||e||(k.current(S),T(null))},[S,e,T]);let{chatInputRef:A,messageToSend:j,checkIsContentEmpty:M,clearEmptyContentHandler:N,saveDraft:P}=r.useChatInputLogic(),F=f.default.useCallback(()=>{let e=A.current?.innerText??``,t=E.length>0||D.length>0;x(e.trim().length>0||t)},[A,E,D]),{fileInputRef:I,chatContainerRef:L,isDragOver:R,handleFileIconClick:z,handleFileInputChange:B,handleDragOver:V,handleDragLeave:re,handleDrop:H}=i.useFileHandling(ne),{gripRef:U,isGripVisible:W,isGripDragging:G,handleTopEdgeClick:K,smartResize:q,handleGripMouseDown:J,handleGripTouchStart:Y,increaseHeightForEmptyContent:X,resetManualResize:ie}=a.useGripResize(A,j),{handleSubmit:Z}=s.useChatSubmission(A,I,q,_,ie),Q=f.default.useCallback(()=>{Z(),F()},[Z,F]),{handleInput:ae,handlePaste:oe,handleKeyDown:se,handleBlur:ce,handleFocus:le}=o.useChatInputEvents(A,q,X,M,N,ee,te),{isMenuOpen:$,filteredItems:ue,selectedIndex:de,updateSlashMenu:fe,selectItem:pe,handleSlashKeyDown:me,closeMenu:he}=c.useSlashCommand(A);return(0,f.useEffect)(()=>()=>{w(!1),C()},[w,C]),(0,f.useEffect)(()=>{F()},[F,E.length,D.length]),(0,p.jsxs)(`div`,{className:t.cn(`w-full`,v),children:[(0,p.jsx)(d.HiddenFileInput,{fileInputRef:I,onChange:B}),(0,p.jsxs)(`div`,{className:`relative w-full`,children:[(0,p.jsx)(l.ChatInputGrip,{gripRef:U,isGripVisible:W,isGripDragging:G,handleTopEdgeClick:K,handleGripMouseDown:J,handleGripTouchStart:Y}),(0,p.jsx)(u.ChatInputContainer,{chatContainerRef:L,isDragOver:R,disabled:O,canSubmit:b,hasStartedConversation:h,isNewConversationPending:m,showButton:g,buttonClassName:y,chatInputRef:A,handleFileIconClick:z,handleSubmit:Q,onDragOver:V,onDragLeave:re,onDrop:H,onInput:()=>{ae(),fe(),P(),F()},onPaste:oe,onKeyDown:e=>{me(e)||se(e,O,Q)},onFocus:le,onBlur:()=>{ce(),he(),F()},isSlashMenuOpen:$,slashItems:ue,slashSelectedIndex:de,onSlashSelect:pe})]})]})}exports.CustomChatInput=m;
2
2
  //# sourceMappingURL=custom-chat-input.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"custom-chat-input.cjs","names":[],"sources":["../../../../src/components/features/chat/custom-chat-input.tsx"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport { useChatInputLogic } from \"#/hooks/chat/use-chat-input-logic\";\nimport { useFileHandling } from \"#/hooks/chat/use-file-handling\";\nimport { useGripResize } from \"#/hooks/chat/use-grip-resize\";\nimport { useChatInputEvents } from \"#/hooks/chat/use-chat-input-events\";\nimport { useChatSubmission } from \"#/hooks/chat/use-chat-submission\";\nimport { useSlashCommand } from \"#/hooks/chat/use-slash-command\";\nimport { ChatInputGrip } from \"./components/chat-input-grip\";\nimport { ChatInputContainer } from \"./components/chat-input-container\";\nimport { HiddenFileInput } from \"./components/hidden-file-input\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { cn } from \"#/utils/utils\";\n\nexport interface CustomChatInputProps {\n disabled?: boolean;\n isNewConversationPending?: boolean;\n showButton?: boolean;\n onSubmit: (message: string) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n onFilesPaste?: (\n files: File[],\n options?: import(\"#/hooks/chat/use-chat-attachment-upload\").ChatAttachmentUploadOptions,\n ) => void;\n className?: React.HTMLAttributes<HTMLDivElement>[\"className\"];\n buttonClassName?: React.HTMLAttributes<HTMLButtonElement>[\"className\"];\n}\n\nexport function CustomChatInput({\n disabled = false,\n isNewConversationPending = false,\n showButton = true,\n onSubmit,\n onFocus,\n onBlur,\n onFilesPaste,\n className = \"\",\n buttonClassName = \"\",\n}: CustomChatInputProps) {\n const [canSubmit, setCanSubmit] = React.useState(false);\n const {\n submittedMessage,\n clearAllFiles,\n setShouldHideSuggestions,\n setSubmittedMessage,\n images,\n files,\n } = useConversationStore();\n\n // Note: we intentionally do NOT disable the input when the conversation is\n // in an ERROR/STUCK execution state. Users should be able to send a follow-up\n // message to recover the conversation; the message will be delivered\n // immediately via the WebSocket if connected, or queued via REST otherwise.\n const isDisabled = disabled;\n\n // Always call the latest `onSubmit` without making the effect re-run when\n // its identity changes. `onSubmit` (typically `handleSendMessage`) is a\n // fresh function on every parent render, and the parent re-renders\n // whenever the pending-message queue updates synchronously inside\n // `onSubmit` itself. Listing it in the dep array caused the effect to\n // fire twice — once for the original submit and again from the\n // mid-submit re-render, before `setSubmittedMessage(null)` was applied —\n // producing a duplicate \"Sending…\" bubble.\n const onSubmitRef = useRef(onSubmit);\n useEffect(() => {\n onSubmitRef.current = onSubmit;\n }, [onSubmit]);\n\n // Listen to submittedMessage state changes\n useEffect(() => {\n if (!submittedMessage || disabled) {\n return;\n }\n onSubmitRef.current(submittedMessage);\n setSubmittedMessage(null);\n }, [submittedMessage, disabled, setSubmittedMessage]);\n\n // Custom hooks\n const {\n chatInputRef,\n messageToSend,\n checkIsContentEmpty,\n clearEmptyContentHandler,\n saveDraft,\n } = useChatInputLogic();\n\n const syncCanSubmit = React.useCallback(() => {\n const text = chatInputRef.current?.innerText ?? \"\";\n const hasAttachments = images.length > 0 || files.length > 0;\n setCanSubmit(text.trim().length > 0 || hasAttachments);\n }, [chatInputRef, images, files]);\n\n const {\n fileInputRef,\n chatContainerRef,\n isDragOver,\n handleFileIconClick,\n handleFileInputChange,\n handleDragOver,\n handleDragLeave,\n handleDrop,\n } = useFileHandling(onFilesPaste);\n\n const {\n gripRef,\n isGripVisible,\n isGripDragging,\n handleTopEdgeClick,\n smartResize,\n handleGripMouseDown,\n handleGripTouchStart,\n increaseHeightForEmptyContent,\n resetManualResize,\n } = useGripResize(\n chatInputRef as React.RefObject<HTMLDivElement | null>,\n messageToSend,\n );\n\n const { handleSubmit } = useChatSubmission(\n chatInputRef as React.RefObject<HTMLDivElement | null>,\n fileInputRef as React.RefObject<HTMLInputElement | null>,\n smartResize,\n onSubmit,\n resetManualResize,\n );\n const handleSubmitAndSync = React.useCallback(() => {\n handleSubmit();\n syncCanSubmit();\n }, [handleSubmit, syncCanSubmit]);\n\n const { handleInput, handlePaste, handleKeyDown, handleBlur, handleFocus } =\n useChatInputEvents(\n chatInputRef as React.RefObject<HTMLDivElement | null>,\n smartResize,\n increaseHeightForEmptyContent,\n checkIsContentEmpty,\n clearEmptyContentHandler,\n onFocus,\n onBlur,\n );\n\n const {\n isMenuOpen: isSlashMenuOpen,\n filteredItems: slashItems,\n selectedIndex: slashSelectedIndex,\n updateSlashMenu,\n selectItem: selectSlashItem,\n handleSlashKeyDown,\n closeMenu: closeSlashMenu,\n } = useSlashCommand(chatInputRef as React.RefObject<HTMLDivElement | null>);\n\n // Cleanup: reset suggestions visibility when component unmounts\n useEffect(\n () => () => {\n setShouldHideSuggestions(false);\n clearAllFiles();\n },\n [setShouldHideSuggestions, clearAllFiles],\n );\n useEffect(() => {\n syncCanSubmit();\n }, [syncCanSubmit, images.length, files.length]);\n return (\n <div className={cn(\"w-full\", className)}>\n {/* Hidden file input */}\n <HiddenFileInput\n fileInputRef={fileInputRef}\n onChange={handleFileInputChange}\n />\n\n {/* Container with grip */}\n <div className=\"relative w-full\">\n <ChatInputGrip\n gripRef={gripRef}\n isGripVisible={isGripVisible}\n isGripDragging={isGripDragging}\n handleTopEdgeClick={handleTopEdgeClick}\n handleGripMouseDown={handleGripMouseDown}\n handleGripTouchStart={handleGripTouchStart}\n />\n\n <ChatInputContainer\n chatContainerRef={chatContainerRef}\n isDragOver={isDragOver}\n disabled={isDisabled}\n canSubmit={canSubmit}\n isNewConversationPending={isNewConversationPending}\n showButton={showButton}\n buttonClassName={buttonClassName}\n chatInputRef={chatInputRef}\n handleFileIconClick={handleFileIconClick}\n handleSubmit={handleSubmitAndSync}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onInput={() => {\n handleInput();\n updateSlashMenu();\n saveDraft();\n syncCanSubmit();\n }}\n onPaste={handlePaste}\n onKeyDown={(e) => {\n if (handleSlashKeyDown(e)) return;\n handleKeyDown(e, isDisabled, handleSubmitAndSync);\n }}\n onFocus={handleFocus}\n onBlur={() => {\n handleBlur();\n closeSlashMenu();\n syncCanSubmit();\n }}\n isSlashMenuOpen={isSlashMenuOpen}\n slashItems={slashItems}\n slashSelectedIndex={slashSelectedIndex}\n onSlashSelect={selectSlashItem}\n />\n </div>\n </div>\n );\n}\n"],"mappings":"ksBA4BA,SAAgB,EAAgB,CAC9B,WAAW,GACX,2BAA2B,GAC3B,aAAa,GACb,WACA,UACA,SACA,gBACA,aAAY,GACZ,kBAAkB,IACK,CACvB,GAAM,CAAC,EAAW,GAAgB,EAAA,QAAM,SAAS,GAAM,CACjD,CACJ,mBACA,gBACA,2BACA,sBACA,SACA,SACE,EAAA,sBAAsB,CAMpB,EAAa,EAUb,GAAA,EAAA,EAAA,QAAqB,EAAS,EACpC,EAAA,EAAA,eAAgB,CACd,EAAY,QAAU,GACrB,CAAC,EAAS,CAAC,EAGd,EAAA,EAAA,eAAgB,CACV,CAAC,GAAoB,IAGzB,EAAY,QAAQ,EAAiB,CACrC,EAAoB,KAAK,GACxB,CAAC,EAAkB,EAAU,EAAoB,CAAC,CAGrD,GAAM,CACJ,eACA,gBACA,sBACA,2BACA,aACE,EAAA,mBAAmB,CAEjB,EAAgB,EAAA,QAAM,gBAAkB,CAC5C,IAAM,EAAO,EAAa,SAAS,WAAa,GAC1C,EAAiB,EAAO,OAAS,GAAK,EAAM,OAAS,EAC3D,EAAa,EAAK,MAAM,CAAC,OAAS,GAAK,EAAe,EACrD,CAAC,EAAc,EAAQ,EAAM,CAAC,CAE3B,CACJ,eACA,mBACA,aACA,sBACA,wBACA,iBACA,kBACA,eACE,EAAA,gBAAgB,GAAa,CAE3B,CACJ,UACA,gBACA,iBACA,qBACA,cACA,sBACA,uBACA,gCACA,qBACE,EAAA,cACF,EACA,EACD,CAEK,CAAE,gBAAiB,EAAA,kBACvB,EACA,EACA,EACA,EACA,EACD,CACK,EAAsB,EAAA,QAAM,gBAAkB,CAClD,GAAc,CACd,GAAe,EACd,CAAC,EAAc,EAAc,CAAC,CAE3B,CAAE,eAAa,eAAa,iBAAe,cAAY,gBAC3D,EAAA,mBACE,EACA,EACA,EACA,EACA,EACA,EACA,EACD,CAEG,CACJ,WAAY,GACZ,cAAe,GACf,cAAe,GACf,mBACA,WAAY,GACZ,sBACA,UAAW,IACT,EAAA,gBAAgB,EAAuD,CAa3E,OAVA,EAAA,EAAA,mBACc,CACV,EAAyB,GAAM,CAC/B,GAAe,EAEjB,CAAC,EAA0B,EAAc,CAC1C,EACD,EAAA,EAAA,eAAgB,CACd,GAAe,EACd,CAAC,EAAe,EAAO,OAAQ,EAAM,OAAO,CAAC,EAE9C,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAA,GAAG,SAAU,GAAU,UAAvC,EAEE,EAAA,EAAA,KAAC,EAAA,gBAAD,CACgB,eACd,SAAU,EACV,CAAA,EAGF,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,2BAAf,EACE,EAAA,EAAA,KAAC,EAAA,cAAD,CACW,UACM,gBACC,iBACI,qBACC,sBACC,uBACtB,CAAA,EAEF,EAAA,EAAA,KAAC,EAAA,mBAAD,CACoB,mBACN,aACZ,SAAU,EACC,YACe,2BACd,aACK,kBACH,eACO,sBACrB,aAAc,EACd,WAAY,EACZ,YAAa,EACb,OAAQ,GACR,YAAe,CACb,IAAa,CACb,IAAiB,CACjB,GAAW,CACX,GAAe,EAEjB,QAAS,GACT,UAAY,GAAM,CACZ,GAAmB,EAAE,EACzB,GAAc,EAAG,EAAY,EAAoB,EAEnD,QAAS,GACT,WAAc,CACZ,IAAY,CACZ,IAAgB,CAChB,GAAe,EAEA,mBACL,cACQ,sBACpB,cAAe,GACf,CAAA,CACE,GACF"}
1
+ {"version":3,"file":"custom-chat-input.cjs","names":[],"sources":["../../../../src/components/features/chat/custom-chat-input.tsx"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport { useChatInputLogic } from \"#/hooks/chat/use-chat-input-logic\";\nimport { useFileHandling } from \"#/hooks/chat/use-file-handling\";\nimport { useGripResize } from \"#/hooks/chat/use-grip-resize\";\nimport { useChatInputEvents } from \"#/hooks/chat/use-chat-input-events\";\nimport { useChatSubmission } from \"#/hooks/chat/use-chat-submission\";\nimport { useSlashCommand } from \"#/hooks/chat/use-slash-command\";\nimport { ChatInputGrip } from \"./components/chat-input-grip\";\nimport { ChatInputContainer } from \"./components/chat-input-container\";\nimport { HiddenFileInput } from \"./components/hidden-file-input\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { cn } from \"#/utils/utils\";\n\nexport interface CustomChatInputProps {\n disabled?: boolean;\n isNewConversationPending?: boolean;\n hasStartedConversation?: boolean;\n showButton?: boolean;\n onSubmit: (message: string) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n onFilesPaste?: (\n files: File[],\n options?: import(\"#/hooks/chat/use-chat-attachment-upload\").ChatAttachmentUploadOptions,\n ) => void;\n className?: React.HTMLAttributes<HTMLDivElement>[\"className\"];\n buttonClassName?: React.HTMLAttributes<HTMLButtonElement>[\"className\"];\n}\n\nexport function CustomChatInput({\n disabled = false,\n isNewConversationPending = false,\n hasStartedConversation,\n showButton = true,\n onSubmit,\n onFocus,\n onBlur,\n onFilesPaste,\n className = \"\",\n buttonClassName = \"\",\n}: CustomChatInputProps) {\n const [canSubmit, setCanSubmit] = React.useState(false);\n const {\n submittedMessage,\n clearAllFiles,\n setShouldHideSuggestions,\n setSubmittedMessage,\n images,\n files,\n } = useConversationStore();\n\n // Note: we intentionally do NOT disable the input when the conversation is\n // in an ERROR/STUCK execution state. Users should be able to send a follow-up\n // message to recover the conversation; the message will be delivered\n // immediately via the WebSocket if connected, or queued via REST otherwise.\n const isDisabled = disabled;\n\n // Always call the latest `onSubmit` without making the effect re-run when\n // its identity changes. `onSubmit` (typically `handleSendMessage`) is a\n // fresh function on every parent render, and the parent re-renders\n // whenever the pending-message queue updates synchronously inside\n // `onSubmit` itself. Listing it in the dep array caused the effect to\n // fire twice — once for the original submit and again from the\n // mid-submit re-render, before `setSubmittedMessage(null)` was applied —\n // producing a duplicate \"Sending…\" bubble.\n const onSubmitRef = useRef(onSubmit);\n useEffect(() => {\n onSubmitRef.current = onSubmit;\n }, [onSubmit]);\n\n // Listen to submittedMessage state changes\n useEffect(() => {\n if (!submittedMessage || disabled) {\n return;\n }\n onSubmitRef.current(submittedMessage);\n setSubmittedMessage(null);\n }, [submittedMessage, disabled, setSubmittedMessage]);\n\n // Custom hooks\n const {\n chatInputRef,\n messageToSend,\n checkIsContentEmpty,\n clearEmptyContentHandler,\n saveDraft,\n } = useChatInputLogic();\n\n const syncCanSubmit = React.useCallback(() => {\n const text = chatInputRef.current?.innerText ?? \"\";\n const hasAttachments = images.length > 0 || files.length > 0;\n setCanSubmit(text.trim().length > 0 || hasAttachments);\n }, [chatInputRef, images, files]);\n\n const {\n fileInputRef,\n chatContainerRef,\n isDragOver,\n handleFileIconClick,\n handleFileInputChange,\n handleDragOver,\n handleDragLeave,\n handleDrop,\n } = useFileHandling(onFilesPaste);\n\n const {\n gripRef,\n isGripVisible,\n isGripDragging,\n handleTopEdgeClick,\n smartResize,\n handleGripMouseDown,\n handleGripTouchStart,\n increaseHeightForEmptyContent,\n resetManualResize,\n } = useGripResize(\n chatInputRef as React.RefObject<HTMLDivElement | null>,\n messageToSend,\n );\n\n const { handleSubmit } = useChatSubmission(\n chatInputRef as React.RefObject<HTMLDivElement | null>,\n fileInputRef as React.RefObject<HTMLInputElement | null>,\n smartResize,\n onSubmit,\n resetManualResize,\n );\n const handleSubmitAndSync = React.useCallback(() => {\n handleSubmit();\n syncCanSubmit();\n }, [handleSubmit, syncCanSubmit]);\n\n const { handleInput, handlePaste, handleKeyDown, handleBlur, handleFocus } =\n useChatInputEvents(\n chatInputRef as React.RefObject<HTMLDivElement | null>,\n smartResize,\n increaseHeightForEmptyContent,\n checkIsContentEmpty,\n clearEmptyContentHandler,\n onFocus,\n onBlur,\n );\n\n const {\n isMenuOpen: isSlashMenuOpen,\n filteredItems: slashItems,\n selectedIndex: slashSelectedIndex,\n updateSlashMenu,\n selectItem: selectSlashItem,\n handleSlashKeyDown,\n closeMenu: closeSlashMenu,\n } = useSlashCommand(chatInputRef as React.RefObject<HTMLDivElement | null>);\n\n // Cleanup: reset suggestions visibility when component unmounts\n useEffect(\n () => () => {\n setShouldHideSuggestions(false);\n clearAllFiles();\n },\n [setShouldHideSuggestions, clearAllFiles],\n );\n useEffect(() => {\n syncCanSubmit();\n }, [syncCanSubmit, images.length, files.length]);\n return (\n <div className={cn(\"w-full\", className)}>\n {/* Hidden file input */}\n <HiddenFileInput\n fileInputRef={fileInputRef}\n onChange={handleFileInputChange}\n />\n\n {/* Container with grip */}\n <div className=\"relative w-full\">\n <ChatInputGrip\n gripRef={gripRef}\n isGripVisible={isGripVisible}\n isGripDragging={isGripDragging}\n handleTopEdgeClick={handleTopEdgeClick}\n handleGripMouseDown={handleGripMouseDown}\n handleGripTouchStart={handleGripTouchStart}\n />\n\n <ChatInputContainer\n chatContainerRef={chatContainerRef}\n isDragOver={isDragOver}\n disabled={isDisabled}\n canSubmit={canSubmit}\n hasStartedConversation={hasStartedConversation}\n isNewConversationPending={isNewConversationPending}\n showButton={showButton}\n buttonClassName={buttonClassName}\n chatInputRef={chatInputRef}\n handleFileIconClick={handleFileIconClick}\n handleSubmit={handleSubmitAndSync}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onInput={() => {\n handleInput();\n updateSlashMenu();\n saveDraft();\n syncCanSubmit();\n }}\n onPaste={handlePaste}\n onKeyDown={(e) => {\n if (handleSlashKeyDown(e)) return;\n handleKeyDown(e, isDisabled, handleSubmitAndSync);\n }}\n onFocus={handleFocus}\n onBlur={() => {\n handleBlur();\n closeSlashMenu();\n syncCanSubmit();\n }}\n isSlashMenuOpen={isSlashMenuOpen}\n slashItems={slashItems}\n slashSelectedIndex={slashSelectedIndex}\n onSlashSelect={selectSlashItem}\n />\n </div>\n </div>\n );\n}\n"],"mappings":"ksBA6BA,SAAgB,EAAgB,CAC9B,WAAW,GACX,2BAA2B,GAC3B,yBACA,aAAa,GACb,WACA,WACA,UACA,gBACA,YAAY,GACZ,kBAAkB,IACK,CACvB,GAAM,CAAC,EAAW,GAAgB,EAAA,QAAM,SAAS,GAAM,CACjD,CACJ,mBACA,gBACA,2BACA,sBACA,SACA,SACE,EAAA,sBAAsB,CAMpB,EAAa,EAUb,GAAA,EAAA,EAAA,QAAqB,EAAS,EACpC,EAAA,EAAA,eAAgB,CACd,EAAY,QAAU,GACrB,CAAC,EAAS,CAAC,EAGd,EAAA,EAAA,eAAgB,CACV,CAAC,GAAoB,IAGzB,EAAY,QAAQ,EAAiB,CACrC,EAAoB,KAAK,GACxB,CAAC,EAAkB,EAAU,EAAoB,CAAC,CAGrD,GAAM,CACJ,eACA,gBACA,sBACA,2BACA,aACE,EAAA,mBAAmB,CAEjB,EAAgB,EAAA,QAAM,gBAAkB,CAC5C,IAAM,EAAO,EAAa,SAAS,WAAa,GAC1C,EAAiB,EAAO,OAAS,GAAK,EAAM,OAAS,EAC3D,EAAa,EAAK,MAAM,CAAC,OAAS,GAAK,EAAe,EACrD,CAAC,EAAc,EAAQ,EAAM,CAAC,CAE3B,CACJ,eACA,mBACA,aACA,sBACA,wBACA,iBACA,mBACA,cACE,EAAA,gBAAgB,GAAa,CAE3B,CACJ,UACA,gBACA,iBACA,qBACA,cACA,sBACA,uBACA,gCACA,sBACE,EAAA,cACF,EACA,EACD,CAEK,CAAE,gBAAiB,EAAA,kBACvB,EACA,EACA,EACA,EACA,GACD,CACK,EAAsB,EAAA,QAAM,gBAAkB,CAClD,GAAc,CACd,GAAe,EACd,CAAC,EAAc,EAAc,CAAC,CAE3B,CAAE,eAAa,eAAa,iBAAe,cAAY,gBAC3D,EAAA,mBACE,EACA,EACA,EACA,EACA,EACA,GACA,GACD,CAEG,CACJ,WAAY,EACZ,cAAe,GACf,cAAe,GACf,mBACA,WAAY,GACZ,sBACA,UAAW,IACT,EAAA,gBAAgB,EAAuD,CAa3E,OAVA,EAAA,EAAA,mBACc,CACV,EAAyB,GAAM,CAC/B,GAAe,EAEjB,CAAC,EAA0B,EAAc,CAC1C,EACD,EAAA,EAAA,eAAgB,CACd,GAAe,EACd,CAAC,EAAe,EAAO,OAAQ,EAAM,OAAO,CAAC,EAE9C,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAA,GAAG,SAAU,EAAU,UAAvC,EAEE,EAAA,EAAA,KAAC,EAAA,gBAAD,CACgB,eACd,SAAU,EACV,CAAA,EAGF,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,2BAAf,EACE,EAAA,EAAA,KAAC,EAAA,cAAD,CACW,UACM,gBACC,iBACI,qBACC,sBACC,uBACtB,CAAA,EAEF,EAAA,EAAA,KAAC,EAAA,mBAAD,CACoB,mBACN,aACZ,SAAU,EACC,YACa,yBACE,2BACd,aACK,kBACH,eACO,sBACrB,aAAc,EACd,WAAY,EACZ,YAAa,GACb,OAAQ,EACR,YAAe,CACb,IAAa,CACb,IAAiB,CACjB,GAAW,CACX,GAAe,EAEjB,QAAS,GACT,UAAY,GAAM,CACZ,GAAmB,EAAE,EACzB,GAAc,EAAG,EAAY,EAAoB,EAEnD,QAAS,GACT,WAAc,CACZ,IAAY,CACZ,IAAgB,CAChB,GAAe,EAEA,kBACL,cACQ,sBACpB,cAAe,GACf,CAAA,CACE,GACF"}
@@ -2,6 +2,7 @@ import React from "react";
2
2
  export interface CustomChatInputProps {
3
3
  disabled?: boolean;
4
4
  isNewConversationPending?: boolean;
5
+ hasStartedConversation?: boolean;
5
6
  showButton?: boolean;
6
7
  onSubmit: (message: string) => void;
7
8
  onFocus?: () => void;
@@ -10,4 +11,4 @@ export interface CustomChatInputProps {
10
11
  className?: React.HTMLAttributes<HTMLDivElement>["className"];
11
12
  buttonClassName?: React.HTMLAttributes<HTMLButtonElement>["className"];
12
13
  }
13
- export declare function CustomChatInput({ disabled, isNewConversationPending, showButton, onSubmit, onFocus, onBlur, onFilesPaste, className, buttonClassName, }: CustomChatInputProps): import("react/jsx-runtime").JSX.Element;
14
+ export declare function CustomChatInput({ disabled, isNewConversationPending, hasStartedConversation, showButton, onSubmit, onFocus, onBlur, onFilesPaste, className, buttonClassName, }: CustomChatInputProps): import("react/jsx-runtime").JSX.Element;