@openhands/agent-canvas 1.11.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (766) hide show
  1. package/README.md +1 -1
  2. package/README.windows.md +2 -2
  3. package/build/assets/{acp-providers-BkL3HWa3.js → acp-providers-D1PORKc0.js} +1 -1
  4. package/build/assets/active-backend-context-IqOjobNK.js +2 -0
  5. package/build/assets/{agent-context-settings-Bno1nwPL.js → agent-context-settings-DMrObcIS.js} +1 -1
  6. package/build/assets/agent-profiles-settings-DororXN5.js +1 -0
  7. package/build/assets/agent-server-conversation-service.api-DWBe0rbX.js +86 -0
  8. package/build/assets/{agent-settings-h8hQz-IU.js → agent-settings-BJVk92PU.js} +1 -1
  9. package/build/assets/agent-settings-COfJsQ1d.js +1 -0
  10. package/build/assets/{alert-banner-lrK-2_0Y.js → alert-banner-CzZsm7ms.js} +1 -1
  11. package/build/assets/{api-key-entry-screen-Qsb83VX1.js → api-key-entry-screen-D8Fade_-.js} +1 -1
  12. package/build/assets/app-settings-CpyGB3AT.js +1 -0
  13. package/build/assets/{automation-detail-7LkL91j9.js → automation-detail-B-jQ39Mm.js} +1 -1
  14. package/build/assets/{automation-export-U2QNyNy6.js → automation-export-B1dywoqk.js} +1 -1
  15. package/build/assets/{automation-setup-route-Bel9_Lue.js → automation-setup-route-C-bWUZBi.js} +1 -1
  16. package/build/assets/{automation-templates-CRLDssaI.js → automation-templates-DgpCGOJV.js} +1 -1
  17. package/build/assets/{automations-list-B2iV3ZKW.js → automations-list-DnMxlxsL.js} +1 -1
  18. package/build/assets/{back-nav-button-B3pYwmUJ.js → back-nav-button-HHEneWMw.js} +1 -1
  19. package/build/assets/backend-form-modal-DiVrD4Cm.js +1 -0
  20. package/build/assets/{backend-synced-settings-badge-DB4717Iu.js → backend-synced-settings-badge-7MIjpr8M.js} +1 -1
  21. package/build/assets/{badge-yR53enbU.js → badge-CpYmcVZV.js} +1 -1
  22. package/build/assets/{base-modal-3NmIOKDm.js → base-modal-Fnh6Uln9.js} +1 -1
  23. package/build/assets/bot-BQZx8e2i.js +1 -0
  24. package/build/assets/{brand-button-CJcwjnfb.js → brand-button-swT1RyO0.js} +1 -1
  25. package/build/assets/browser-B9AbV6kG.js +7 -0
  26. package/build/assets/{browser-tab-A94o33Vn.js → browser-tab-zAY12m_i.js} +1 -1
  27. package/build/assets/{chat-send-button-B8n6-DQA.js → chat-send-button-DsJtivmL.js} +1 -1
  28. package/build/assets/check-WAFXrrs_.js +1 -0
  29. package/build/assets/chevron-down-CifNWzme.js +1 -0
  30. package/build/assets/circle-check-CtnimJa8.js +1 -0
  31. package/build/assets/{circle-plus-check-toggle-BVzv5EkZ.js → circle-plus-check-toggle-Cuzx55bo.js} +1 -1
  32. package/build/assets/{cloud-funnel-analytics-CBQdPZl_.js → cloud-funnel-analytics-86CwNdSh.js} +1 -1
  33. package/build/assets/{combobox-caret-BlmRwiM8.js → combobox-caret-D0fRotFi.js} +1 -1
  34. package/build/assets/{command-menu-PsRXVBz2.js → command-menu-BXy03FBl.js} +1 -1
  35. package/build/assets/{condenser-settings-w7L3EFvm.js → condenser-settings-BmZa0ui_.js} +1 -1
  36. package/build/assets/{confirmation-modal-DAH0XtOp.js → confirmation-modal-BgoN6lbN.js} +1 -1
  37. package/build/assets/{context-menu-list-item-BQhmFVEK.js → context-menu-list-item-Bq02tc-P.js} +1 -1
  38. package/build/assets/conversation-BPo8SvLN.js +1 -0
  39. package/build/assets/conversation-CPCVsCUY.js +90 -0
  40. package/build/assets/conversation-panel-BPo8SvLN.js +1 -0
  41. package/build/assets/{conversation-state-store-Bs8gA263.js → conversation-state-store-C5YpjMNy.js} +1 -1
  42. package/build/assets/conversation-store-Blc5xysY.js +6 -0
  43. package/build/assets/{conversation-tab-empty-state-C9sfDOlt.js → conversation-tab-empty-state-CMqo_0Bd.js} +1 -1
  44. package/build/assets/{copy-to-clipboard-button-DatoElj8.js → copy-to-clipboard-button-Cg1pF0xn.js} +1 -1
  45. package/build/assets/{device-verify-BIjXeW9N.js → device-verify-BfQLgNyq.js} +1 -1
  46. package/build/assets/{dropdown-classes-zFW7qPSK.js → dropdown-classes-BIqQr5mx.js} +1 -1
  47. package/build/assets/{entry.client-DzbDyLkV.js → entry.client-CxFjRYqH.js} +2 -2
  48. package/build/assets/{enum-filter-dropdown-CctILg5t.js → enum-filter-dropdown-C_yV4_bo.js} +1 -1
  49. package/build/assets/{environment-switch-overlay-Cvmo6clk.js → environment-switch-overlay-Bi4qbh2g.js} +1 -1
  50. package/build/assets/{extensions-hub-DOmHPGTA.js → extensions-hub-BqUINAhp.js} +1 -1
  51. package/build/assets/{extensions-navigation-6zU5M1pa.js → extensions-navigation-lraj88Wk.js} +1 -1
  52. package/build/assets/external-link-CgtpA_a1.js +1 -0
  53. package/build/assets/{file-text-RecuaId_.js → file-text-DEK4LSVw.js} +1 -1
  54. package/build/assets/files-tab-DV0L-lFE.js +1 -0
  55. package/build/assets/{form-control-classes-DLN3Qgub.js → form-control-classes-7yFSQJq_.js} +1 -1
  56. package/build/assets/format-model-name-BN_rx1Y3.js +1 -0
  57. package/build/assets/{format-relative-time-DGPQlPx0.js → format-relative-time-DSErAuVr.js} +1 -1
  58. package/build/assets/git-provider-icon-BvlLAche.js +1 -0
  59. package/build/assets/{git-repo-dropdown-B7RvO70z.js → git-repo-dropdown-ByMzpNko.js} +1 -1
  60. package/build/assets/git-repo-dropdown-C6R7hgM8.js +1 -0
  61. package/build/assets/{highlighted-source-view-CgJfD5VT.js → highlighted-source-view-C_sfncLZ.js} +1 -1
  62. package/build/assets/{home-DEZaZqYv.js → home-BOrlwLqG.js} +1 -1
  63. package/build/assets/home-BvMNC6E-.js +1 -0
  64. package/build/assets/{home-store-D7CjMN_-.js → home-store-CxqsY9Fi.js} +1 -1
  65. package/build/assets/index-home-BvMNC6E-.js +1 -0
  66. package/build/assets/info-BRVcJAUg.js +1 -0
  67. package/build/assets/{install-server-modal-BTwK5lbi.js → install-server-modal-Bl4G1zF4.js} +1 -1
  68. package/build/assets/{kebab-menu-item-content-C4CkeiJO.js → kebab-menu-item-content-BGoGFEAg.js} +1 -1
  69. package/build/assets/{launch-DVlx4v9o.js → launch-CkqiSCqi.js} +1 -1
  70. package/build/assets/{list-todo-CheUtB7F.js → list-todo-DNWlzfaM.js} +1 -1
  71. package/build/assets/llm-not-configured-banner-DLw_tu-G.js +27 -0
  72. package/build/assets/llm-settings-B-pkVCrt.js +1 -0
  73. package/build/assets/llm-settings-DSC0-IQ7.js +1 -0
  74. package/build/assets/llm-subscription-service-BAdOl5Xx.js +1 -0
  75. package/build/assets/loader-circle-B47W9XqT.js +1 -0
  76. package/build/assets/{loading-spinner-CN3riY7k.js → loading-spinner-xhnrGP4Y.js} +1 -1
  77. package/build/assets/{manage-backends-modal-HNWKLYhq.js → manage-backends-modal-DhGk5mJt.js} +1 -1
  78. package/build/assets/manifest-653b89aa.js +1 -0
  79. package/build/assets/{manifest-subpage-layout-D-m-h8_t.js → manifest-subpage-layout-CKWvL2ig.js} +1 -1
  80. package/build/assets/{map-provider-7Bp2aih5.js → map-provider-Mx8mZuE-.js} +1 -1
  81. package/build/assets/markdown-renderer-DUmk7pFc.js +8 -0
  82. package/build/assets/{mcp-gLgPP7AS.js → mcp-DCkvl6K0.js} +2 -2
  83. package/build/assets/mcp-marketplace-utils-DEbMXlQr.js +1 -0
  84. package/build/assets/messages-DSXvyc21.js +40 -0
  85. package/build/assets/{modal-body-duRaxj_K.js → modal-body-gIe21fDv.js} +1 -1
  86. package/build/assets/{modal-classes-CLEXO6dj.js → modal-classes-D66dlgZ7.js} +1 -1
  87. package/build/assets/{modal-close-button-D0aT02hs.js → modal-close-button-B6iOGYpI.js} +1 -1
  88. package/build/assets/{mouse-pointer-click-Px-dXWcS.js → mouse-pointer-click-BYX1Pw5W.js} +1 -1
  89. package/build/assets/{npm-DRzJF5Zn.js → npm-DLckoeJc.js} +1 -1
  90. package/build/assets/{onboarding-DSr8hOpk.js → onboarding-D7WDG66N.js} +1 -1
  91. package/build/assets/{onboarding-modal-C6Euf7N4.js → onboarding-modal-C_xVrFNv.js} +1 -1
  92. package/build/assets/{organization-service.api-C4GYWwj9.js → organization-service.api-D-s9z18a.js} +1 -1
  93. package/build/assets/pencil-BGOCPRyu.js +1 -0
  94. package/build/assets/{planner-tab-CZcguxTK.js → planner-tab-AKaXIIfg.js} +1 -1
  95. package/build/assets/{plugins-management-service-BmDzOQsd.js → plugins-management-service-wtmY4QQw.js} +1 -1
  96. package/build/assets/plus-zNEL8rcX.js +1 -0
  97. package/build/assets/{profiles-service.api-CoLTwjc1.js → profiles-service.api-DCMYxHMi.js} +1 -1
  98. package/build/assets/{providers-tBzTpz1w.js → providers-BjrtjX4L.js} +1 -1
  99. package/build/assets/{proxy-DCI9S-LA.js → proxy-9Z_WZggZ.js} +1 -1
  100. package/build/assets/{puzzle-B3v361yY.js → puzzle-BWLmN8z4.js} +1 -1
  101. package/build/assets/recommended-automations-launcher-CFlzhu1o.js +1 -0
  102. package/build/assets/refresh-cw-CXtFWpwv.js +1 -0
  103. package/build/assets/root-CanxKlNV.css +1 -0
  104. package/build/assets/root-DkfG_UWR.js +2 -0
  105. package/build/assets/root-layout-D75LHYhh.js +2 -0
  106. package/build/assets/{schema-field-zhsVDllR.js → schema-field-OnM5Uob_.js} +1 -1
  107. package/build/assets/{sdk-section-page-CS4GWn0y.js → sdk-section-page-m5WQm2sy.js} +1 -1
  108. package/build/assets/search-CycosyjN.js +1 -0
  109. package/build/assets/{secrets-service-DjgGduXk.js → secrets-service-B26R61C1.js} +1 -1
  110. package/build/assets/{secrets-settings-f-qahfbi.js → secrets-settings-CbLYCKOX.js} +1 -1
  111. package/build/assets/{segmented-toggle-SmvsR3jW.js → segmented-toggle-DCspm2U5.js} +1 -1
  112. package/build/assets/{settings-DQd0xLEw.js → settings-BJQI_iBM.js} +1 -1
  113. package/build/assets/{settings-dropdown-input-TWIeiG02.js → settings-dropdown-input-BI8V_Nov.js} +1 -1
  114. package/build/assets/{settings-index-BVwy9JEp.js → settings-index-BiTqJoH7.js} +1 -1
  115. package/build/assets/{settings-input-D61Vzp9e.js → settings-input-Cz62hWVW.js} +1 -1
  116. package/build/assets/{settings-list-classes-sE0ASr1s.js → settings-list-classes-z_3FW5H3.js} +1 -1
  117. package/build/assets/{settings-modal-D6D5ngET.js → settings-modal-BIrIVn97.js} +1 -1
  118. package/build/assets/{settings-service.api-DZp7E7A9.js → settings-service.api--rJmnuLa.js} +1 -1
  119. package/build/assets/{settings-switch-Drt-rF5s.js → settings-switch-BRsSI8Vs.js} +1 -1
  120. package/build/assets/{settings-utils-gw2ppAvw.js → settings-utils-Ba7vel6T.js} +1 -1
  121. package/build/assets/shared-conversation-CQK_PqHx.js +1 -0
  122. package/build/assets/shield-check-T3JsDJiM.js +1 -0
  123. package/build/assets/{sidebar-layout-Dxg6zc2K.js → sidebar-layout-Bhi3hVcu.js} +1 -1
  124. package/build/assets/{sidebar-mobile-menu-toggle-OoZBHxaT.js → sidebar-mobile-menu-toggle-YWJNRN4p.js} +1 -1
  125. package/build/assets/{sidebar-nav-link-CxLoG-dG.js → sidebar-nav-link-BSUlY5Ml.js} +1 -1
  126. package/build/assets/{sidebar-store-BJeYY-E9.js → sidebar-store-Cl1cUv_F.js} +1 -1
  127. package/build/assets/{skill-card-pill-row-B_BYBONu.js → skill-card-pill-row-BXz8L8Rn.js} +1 -1
  128. package/build/assets/{skill-icon-badge-CN41Hy9l.js → skill-icon-badge-QgfKv31M.js} +1 -1
  129. package/build/assets/{skill-scope-B1Per5XI.js → skill-scope-Dc3JPW-8.js} +1 -1
  130. package/build/assets/{skills-plugins-B3AO6sMz.js → skills-plugins-CpTV27n3.js} +1 -1
  131. package/build/assets/{skills-settings-DmmgJ6CT.js → skills-settings-CSW__IW4.js} +1 -1
  132. package/build/assets/{sparkles-g7y3r-Ut.js → sparkles-TJ0mdECe.js} +1 -1
  133. package/build/assets/{styled-tooltip-C5C07RQC.js → styled-tooltip-BUMSbgrF.js} +1 -1
  134. package/build/assets/{task-list-tab-C19Q_JNf.js → task-list-tab-mAHMOkUz.js} +1 -1
  135. package/build/assets/{terminal-CbuMRYal.js → terminal-BzxBaHx2.js} +1 -1
  136. package/build/assets/{toggle-switch-CIioisto.js → toggle-switch-O5v1FgxW.js} +1 -1
  137. package/build/assets/trash-2-C0xNVp9c.js +1 -0
  138. package/build/assets/{typography-D9tiHct7.js → typography-NOKSk9_R.js} +1 -1
  139. package/build/assets/usage-tab-tEmVN0KD.js +1 -0
  140. package/build/assets/{use-acp-credential-form-DJmmJKMo.js → use-acp-credential-form-BPNi0Zbm.js} +1 -1
  141. package/build/assets/{use-activate-agent-profile-CeFfYwu_.js → use-activate-agent-profile-D9YRQPTF.js} +1 -1
  142. package/build/assets/{use-agent-profiles-BHLkLbRR.js → use-agent-profiles-Cb2zUW3l.js} +1 -1
  143. package/build/assets/{use-can-manage-org-profiles-Bu4y8gSx.js → use-can-manage-org-profiles-Dxzq2AEd.js} +1 -1
  144. package/build/assets/{use-cloud-current-user-id-QD9x3ySO.js → use-cloud-current-user-id-Co2eJk2A.js} +1 -1
  145. package/build/assets/{use-config-CPwqciXN.js → use-config-DKAMiI5R.js} +1 -1
  146. package/build/assets/use-create-conversation-CoHTiCbI.js +1 -0
  147. package/build/assets/{use-create-secret-BsOfOLvg.js → use-create-secret-2zBlCDsF.js} +1 -1
  148. package/build/assets/use-is-authed-C52-ivnB.js +1 -0
  149. package/build/assets/{use-is-creating-conversation-CVefC9Ns.js → use-is-creating-conversation-DdaAE6jV.js} +1 -1
  150. package/build/assets/{use-launch-skill-in-chat-BcKNjxxd.js → use-launch-skill-in-chat-COnDpxCQ.js} +1 -1
  151. package/build/assets/use-llm-profiles-C_BHue65.js +1 -0
  152. package/build/assets/{use-manifest-capabilities-DBYPjyV6.js → use-manifest-capabilities-DPrQsaPP.js} +1 -1
  153. package/build/assets/{use-onboarding-completion-CtNJxkXG.js → use-onboarding-completion-CCE8OQgV.js} +1 -1
  154. package/build/assets/{use-plugins-marketplace-ZEA-gyM9.js → use-plugins-marketplace-CEiak69h.js} +1 -1
  155. package/build/assets/use-save-agent-profile-DK9idD6a.js +1 -0
  156. package/build/assets/{use-save-settings-pSjRhD_m.js → use-save-settings-DNmnbG6f.js} +1 -1
  157. package/build/assets/{use-settings-nav-items-CQgkxUbV.js → use-settings-nav-items-BlFL7YhM.js} +1 -1
  158. package/build/assets/{use-settings-BHWsOcIG.js → use-settings-wCwPaSIv.js} +1 -1
  159. package/build/assets/{use-tracking-CGCsBWhg.js → use-tracking-CVwPmhlX.js} +1 -1
  160. package/build/assets/{use-user-conversation-DRfEU8x0.js → use-user-conversation-DVtfg0B_.js} +1 -1
  161. package/build/assets/{useInfiniteQuery-DbCv0Jzd.js → useInfiniteQuery-p1xq35r2.js} +1 -1
  162. package/build/assets/{useMutation-ChpkYxI5.js → useMutation-BFDQmgk9.js} +1 -1
  163. package/build/assets/{useQueries-Cjv3E8_1.js → useQueries-DF1NAAeC.js} +1 -1
  164. package/build/assets/{useQuery-BCnzy4LX.js → useQuery-DRv--6bK.js} +1 -1
  165. package/build/assets/utils-zxEjKE70.js +1 -0
  166. package/build/assets/{vendor~browser-DJ1pl_wn.js → vendor~browser-B-fae1JU.js} +14 -14
  167. package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~kv3pap4j-oGvLV0dO.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~kv3pap4j-B8i84bh4.js} +3 -3
  168. package/build/assets/{vendor~files-tab-C87pjSpi.js → vendor~files-tab-D9wR9yM2.js} +1 -1
  169. package/build/assets/vendor~index-home~home~conversation-panel~conversation-Ipoe6hvY.js +13 -0
  170. package/build/assets/vendor~root-layout-C-IgVx6e.js +1 -0
  171. package/build/assets/{vendor~root-layout~conversation-panel~conversation-DEzjR4K7.js → vendor~root-layout~conversation-panel~conversation-Dhd_I4H4.js} +1 -1
  172. package/build/assets/{vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-U-xdsAEx.js → vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-Cc0f9kPP.js} +1 -1
  173. package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-CQR5Sa0H.js → vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-d7svw-BB.js} +1 -1
  174. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gxu4j2ea-Cwhh3zLe.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gxu4j2ea-D5DWZVc7.js} +1 -1
  175. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hjcjabwg-CuQhkiS7.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hjcjabwg-4WsUP-tz.js} +2 -2
  176. package/build/assets/{verification-settings-BItwt998.js → verification-settings-B8UMQ7MG.js} +1 -1
  177. package/build/assets/{wrench-B1_H-tL1.js → wrench-DIka3hCq.js} +1 -1
  178. package/build/assets/x-BWKA2Ver.js +1 -0
  179. package/build/assets/zap-DHddTPc0.js +1 -0
  180. package/build/index.html +4 -4
  181. package/build/locales/ar/openhands.json +28 -1
  182. package/build/locales/ca/openhands.json +28 -1
  183. package/build/locales/de/openhands.json +28 -1
  184. package/build/locales/en/openhands.json +28 -1
  185. package/build/locales/es/openhands.json +28 -1
  186. package/build/locales/fr/openhands.json +28 -1
  187. package/build/locales/it/openhands.json +28 -1
  188. package/build/locales/ja/openhands.json +28 -1
  189. package/build/locales/ko-KR/openhands.json +28 -1
  190. package/build/locales/no/openhands.json +28 -1
  191. package/build/locales/pt/openhands.json +28 -1
  192. package/build/locales/tr/openhands.json +28 -1
  193. package/build/locales/uk/openhands.json +28 -1
  194. package/build/locales/zh-CN/openhands.json +28 -1
  195. package/build/locales/zh-TW/openhands.json +28 -1
  196. package/config/defaults.json +3 -3
  197. package/dist/api/agent-server-compatibility.cjs +1 -1
  198. package/dist/api/agent-server-compatibility.cjs.map +1 -1
  199. package/dist/api/agent-server-compatibility.js +1 -1
  200. package/dist/api/agent-server-compatibility.js.map +1 -1
  201. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
  202. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
  203. package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +24 -1
  204. package/dist/api/conversation-service/agent-server-conversation-service.api.js +116 -97
  205. package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
  206. package/dist/api/llm-balance-service.cjs +2 -0
  207. package/dist/api/llm-balance-service.cjs.map +1 -0
  208. package/dist/api/llm-balance-service.d.ts +33 -0
  209. package/dist/api/llm-balance-service.js +53 -0
  210. package/dist/api/llm-balance-service.js.map +1 -0
  211. package/dist/api/llm-subscription-service.cjs +1 -1
  212. package/dist/api/llm-subscription-service.cjs.map +1 -1
  213. package/dist/api/llm-subscription-service.js +42 -34
  214. package/dist/api/llm-subscription-service.js.map +1 -1
  215. package/dist/components/conversation/index.cjs +1 -1
  216. package/dist/components/conversation/index.d.ts +0 -1
  217. package/dist/components/conversation/index.js +0 -1
  218. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
  219. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
  220. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +1 -1
  221. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
  222. package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.cjs +1 -1
  223. package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.cjs.map +1 -1
  224. package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.js +24 -23
  225. package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.js.map +1 -1
  226. package/dist/components/conversation-events/chat/group-events.cjs +1 -1
  227. package/dist/components/conversation-events/chat/group-events.cjs.map +1 -1
  228. package/dist/components/conversation-events/chat/group-events.d.ts +3 -3
  229. package/dist/components/conversation-events/chat/group-events.js +27 -26
  230. package/dist/components/conversation-events/chat/group-events.js.map +1 -1
  231. package/dist/components/features/automations/recommended-automations-section.d.ts +7 -0
  232. package/dist/components/features/chat/components/chat-input-actions.cjs +1 -1
  233. package/dist/components/features/chat/components/chat-input-actions.cjs.map +1 -1
  234. package/dist/components/features/chat/components/chat-input-actions.js +123 -118
  235. package/dist/components/features/chat/components/chat-input-actions.js.map +1 -1
  236. package/dist/components/features/chat/components/chat-input-grip.cjs +1 -1
  237. package/dist/components/features/chat/components/chat-input-grip.cjs.map +1 -1
  238. package/dist/components/features/chat/components/chat-input-grip.d.ts +2 -1
  239. package/dist/components/features/chat/components/chat-input-grip.js +7 -7
  240. package/dist/components/features/chat/components/chat-input-grip.js.map +1 -1
  241. package/dist/components/features/chat/components/chat-input-llm-profile-picker.cjs +1 -1
  242. package/dist/components/features/chat/components/chat-input-llm-profile-picker.cjs.map +1 -1
  243. package/dist/components/features/chat/components/chat-input-llm-profile-picker.js +61 -60
  244. package/dist/components/features/chat/components/chat-input-llm-profile-picker.js.map +1 -1
  245. package/dist/components/features/chat/components/context-window-meter.cjs +2 -0
  246. package/dist/components/features/chat/components/context-window-meter.cjs.map +1 -0
  247. package/dist/components/features/chat/components/context-window-meter.d.ts +2 -0
  248. package/dist/components/features/chat/components/context-window-meter.js +131 -0
  249. package/dist/components/features/chat/components/context-window-meter.js.map +1 -0
  250. package/dist/components/features/chat/components/context-window-ring.cjs +2 -0
  251. package/dist/components/features/chat/components/context-window-ring.cjs.map +1 -0
  252. package/dist/components/features/chat/components/context-window-ring.d.ts +26 -0
  253. package/dist/components/features/chat/components/context-window-ring.js +45 -0
  254. package/dist/components/features/chat/components/context-window-ring.js.map +1 -0
  255. package/dist/components/features/chat/custom-chat-input.cjs +1 -1
  256. package/dist/components/features/chat/custom-chat-input.cjs.map +1 -1
  257. package/dist/components/features/chat/custom-chat-input.js +68 -67
  258. package/dist/components/features/chat/custom-chat-input.js.map +1 -1
  259. package/dist/components/features/chat/model-messages.cjs +1 -1
  260. package/dist/components/features/chat/model-messages.cjs.map +1 -1
  261. package/dist/components/features/chat/model-messages.js +26 -25
  262. package/dist/components/features/chat/model-messages.js.map +1 -1
  263. package/dist/components/features/chat/path-component.cjs +1 -1
  264. package/dist/components/features/chat/path-component.cjs.map +1 -1
  265. package/dist/components/features/chat/path-component.js +9 -6
  266. package/dist/components/features/chat/path-component.js.map +1 -1
  267. package/dist/components/features/chat/plan-preview.cjs +1 -1
  268. package/dist/components/features/chat/plan-preview.js +4 -4
  269. package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.cjs +1 -1
  270. package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.cjs.map +1 -1
  271. package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.d.ts +0 -8
  272. package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.js +92 -50
  273. package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.js.map +1 -1
  274. package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.cjs +1 -1
  275. package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.cjs.map +1 -1
  276. package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.d.ts +7 -2
  277. package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.js +15 -9
  278. package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.js.map +1 -1
  279. package/dist/components/features/chat/tool-visualizers/primitives/markdown-file-preview.cjs +2 -0
  280. package/dist/components/features/chat/tool-visualizers/primitives/markdown-file-preview.cjs.map +1 -0
  281. package/dist/components/features/chat/tool-visualizers/primitives/markdown-file-preview.d.ts +20 -0
  282. package/dist/components/features/chat/tool-visualizers/primitives/markdown-file-preview.js +76 -0
  283. package/dist/components/features/chat/tool-visualizers/primitives/markdown-file-preview.js.map +1 -0
  284. package/dist/components/features/controls/server-status-context-menu.cjs +1 -1
  285. package/dist/components/features/controls/server-status-context-menu.cjs.map +1 -1
  286. package/dist/components/features/controls/server-status-context-menu.d.ts +5 -3
  287. package/dist/components/features/controls/server-status-context-menu.js +8 -8
  288. package/dist/components/features/controls/server-status-context-menu.js.map +1 -1
  289. package/dist/components/features/conversation/conversation-name-context-menu.cjs +1 -1
  290. package/dist/components/features/conversation/conversation-name-context-menu.cjs.map +1 -1
  291. package/dist/components/features/conversation/conversation-name-context-menu.js +58 -61
  292. package/dist/components/features/conversation/conversation-name-context-menu.js.map +1 -1
  293. package/dist/components/features/conversation/conversation-name-with-status.cjs +1 -1
  294. package/dist/components/features/conversation/conversation-name-with-status.cjs.map +1 -1
  295. package/dist/components/features/conversation/conversation-name-with-status.js +74 -46
  296. package/dist/components/features/conversation/conversation-name-with-status.js.map +1 -1
  297. package/dist/components/features/conversation/conversation-name.cjs +1 -1
  298. package/dist/components/features/conversation/conversation-name.cjs.map +1 -1
  299. package/dist/components/features/conversation/conversation-name.js +69 -71
  300. package/dist/components/features/conversation/conversation-name.js.map +1 -1
  301. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.cjs +1 -1
  302. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.cjs.map +1 -1
  303. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.js +7 -6
  304. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.js.map +1 -1
  305. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs +1 -1
  306. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs.map +1 -1
  307. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js +92 -86
  308. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js.map +1 -1
  309. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs +1 -1
  310. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs.map +1 -1
  311. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js +81 -71
  312. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js.map +1 -1
  313. package/dist/components/features/conversation/metrics-modal/cost-section.cjs +1 -1
  314. package/dist/components/features/conversation/metrics-modal/cost-section.cjs.map +1 -1
  315. package/dist/components/features/conversation/metrics-modal/cost-section.js +6 -6
  316. package/dist/components/features/conversation/metrics-modal/cost-section.js.map +1 -1
  317. package/dist/components/features/conversation/metrics-modal/metric-row.cjs +1 -1
  318. package/dist/components/features/conversation/metrics-modal/metric-row.cjs.map +1 -1
  319. package/dist/components/features/conversation/metrics-modal/metric-row.d.ts +2 -1
  320. package/dist/components/features/conversation/metrics-modal/metric-row.js +10 -9
  321. package/dist/components/features/conversation/metrics-modal/metric-row.js.map +1 -1
  322. package/dist/components/features/conversation/metrics-modal/usage-section.cjs +1 -1
  323. package/dist/components/features/conversation/metrics-modal/usage-section.cjs.map +1 -1
  324. package/dist/components/features/conversation/metrics-modal/usage-section.js +2 -1
  325. package/dist/components/features/conversation/metrics-modal/usage-section.js.map +1 -1
  326. package/dist/components/features/conversation/usage-panel/compact-context-button.cjs +2 -0
  327. package/dist/components/features/conversation/usage-panel/compact-context-button.cjs.map +1 -0
  328. package/dist/components/features/conversation/usage-panel/compact-context-button.d.ts +16 -0
  329. package/dist/components/features/conversation/usage-panel/compact-context-button.js +59 -0
  330. package/dist/components/features/conversation/usage-panel/compact-context-button.js.map +1 -0
  331. package/dist/components/features/conversation/usage-panel/context-meter.cjs +2 -0
  332. package/dist/components/features/conversation/usage-panel/context-meter.cjs.map +1 -0
  333. package/dist/components/features/conversation/usage-panel/context-meter.d.ts +19 -0
  334. package/dist/components/features/conversation/usage-panel/context-meter.js +46 -0
  335. package/dist/components/features/conversation/usage-panel/context-meter.js.map +1 -0
  336. package/dist/components/features/conversation/usage-panel/provider-balance-card.cjs +2 -0
  337. package/dist/components/features/conversation/usage-panel/provider-balance-card.cjs.map +1 -0
  338. package/dist/components/features/conversation/usage-panel/provider-balance-card.d.ts +7 -0
  339. package/dist/components/features/conversation/usage-panel/provider-balance-card.js +57 -0
  340. package/dist/components/features/conversation/usage-panel/provider-balance-card.js.map +1 -0
  341. package/dist/components/features/conversation/usage-panel/usage-panel.cjs +2 -0
  342. package/dist/components/features/conversation/usage-panel/usage-panel.cjs.map +1 -0
  343. package/dist/components/features/conversation/usage-panel/usage-panel.d.ts +9 -0
  344. package/dist/components/features/conversation/usage-panel/usage-panel.js +68 -0
  345. package/dist/components/features/conversation/usage-panel/usage-panel.js.map +1 -0
  346. package/dist/components/features/conversation-panel/budget-display.cjs +1 -1
  347. package/dist/components/features/conversation-panel/budget-display.cjs.map +1 -1
  348. package/dist/components/features/conversation-panel/budget-display.js +10 -13
  349. package/dist/components/features/conversation-panel/budget-display.js.map +1 -1
  350. package/dist/components/features/conversation-panel/budget-progress-bar.cjs +1 -1
  351. package/dist/components/features/conversation-panel/budget-progress-bar.cjs.map +1 -1
  352. package/dist/components/features/conversation-panel/budget-progress-bar.js +2 -2
  353. package/dist/components/features/conversation-panel/budget-progress-bar.js.map +1 -1
  354. package/dist/components/features/conversation-panel/confirm-archive-modal.cjs +2 -0
  355. package/dist/components/features/conversation-panel/confirm-archive-modal.cjs.map +1 -0
  356. package/dist/components/features/conversation-panel/confirm-archive-modal.d.ts +8 -0
  357. package/dist/components/features/conversation-panel/confirm-archive-modal.js +48 -0
  358. package/dist/components/features/conversation-panel/confirm-archive-modal.js.map +1 -0
  359. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.cjs +1 -1
  360. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.cjs.map +1 -1
  361. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.d.ts +3 -1
  362. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.js +39 -34
  363. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.js.map +1 -1
  364. package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.cjs +1 -1
  365. package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.cjs.map +1 -1
  366. package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.d.ts +3 -1
  367. package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.js +104 -80
  368. package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.js.map +1 -1
  369. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs +1 -1
  370. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs.map +1 -1
  371. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.d.ts +7 -1
  372. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js +28 -20
  373. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js.map +1 -1
  374. package/dist/components/features/conversation-panel/conversation-card/conversation-card.cjs +1 -1
  375. package/dist/components/features/conversation-panel/conversation-card/conversation-card.cjs.map +1 -1
  376. package/dist/components/features/conversation-panel/conversation-card/conversation-card.d.ts +9 -1
  377. package/dist/components/features/conversation-panel/conversation-card/conversation-card.js +94 -84
  378. package/dist/components/features/conversation-panel/conversation-card/conversation-card.js.map +1 -1
  379. package/dist/components/features/conversation-panel/conversation-group-folder-list.cjs +1 -1
  380. package/dist/components/features/conversation-panel/conversation-group-folder-list.cjs.map +1 -1
  381. package/dist/components/features/conversation-panel/conversation-group-folder-list.d.ts +2 -1
  382. package/dist/components/features/conversation-panel/conversation-group-folder-list.js +32 -31
  383. package/dist/components/features/conversation-panel/conversation-group-folder-list.js.map +1 -1
  384. package/dist/components/features/conversation-panel/conversation-group-folder-row.cjs +1 -1
  385. package/dist/components/features/conversation-panel/conversation-group-folder-row.cjs.map +1 -1
  386. package/dist/components/features/conversation-panel/conversation-group-folder-row.d.ts +2 -1
  387. package/dist/components/features/conversation-panel/conversation-group-folder-row.js +27 -26
  388. package/dist/components/features/conversation-panel/conversation-group-folder-row.js.map +1 -1
  389. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs +1 -1
  390. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs.map +1 -1
  391. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.d.ts +3 -1
  392. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js +116 -106
  393. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js.map +1 -1
  394. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs +1 -1
  395. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs.map +1 -1
  396. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.d.ts +27 -0
  397. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js +69 -46
  398. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js.map +1 -1
  399. package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
  400. package/dist/components/features/conversation-panel/conversation-panel.cjs.map +1 -1
  401. package/dist/components/features/conversation-panel/conversation-panel.js +230 -165
  402. package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
  403. package/dist/components/features/files-tab/file-content-viewer.cjs +1 -1
  404. package/dist/components/features/files-tab/file-content-viewer.cjs.map +1 -1
  405. package/dist/components/features/files-tab/file-content-viewer.js +22 -25
  406. package/dist/components/features/files-tab/file-content-viewer.js.map +1 -1
  407. package/dist/components/features/markdown/markdown-table-scroll.cjs +1 -1
  408. package/dist/components/features/markdown/markdown-table-scroll.cjs.map +1 -1
  409. package/dist/components/features/markdown/markdown-table-scroll.js +2 -2
  410. package/dist/components/features/markdown/markdown-table-scroll.js.map +1 -1
  411. package/dist/components/features/settings/llm-profiles/profile-row.cjs +1 -1
  412. package/dist/components/features/settings/llm-profiles/profile-row.js +1 -0
  413. package/dist/components/shared/buttons/conversation-confirmation-buttons.cjs +1 -1
  414. package/dist/components/shared/buttons/conversation-confirmation-buttons.cjs.map +1 -1
  415. package/dist/components/shared/buttons/conversation-confirmation-buttons.js +2 -2
  416. package/dist/components/shared/buttons/conversation-confirmation-buttons.js.map +1 -1
  417. package/dist/components/shared/modals/confirmation-modals/base-modal.cjs +1 -1
  418. package/dist/components/shared/modals/confirmation-modals/base-modal.cjs.map +1 -1
  419. package/dist/components/shared/modals/confirmation-modals/base-modal.js +1 -1
  420. package/dist/components/shared/modals/confirmation-modals/base-modal.js.map +1 -1
  421. package/dist/components/shared/modals/settings/model-selector.cjs +1 -1
  422. package/dist/components/shared/modals/settings/model-selector.cjs.map +1 -1
  423. package/dist/components/shared/modals/settings/model-selector.js +154 -98
  424. package/dist/components/shared/modals/settings/model-selector.js.map +1 -1
  425. package/dist/config/defaults.cjs +1 -1
  426. package/dist/config/defaults.cjs.map +1 -1
  427. package/dist/config/defaults.js +3 -3
  428. package/dist/config/defaults.js.map +1 -1
  429. package/dist/constants/llm-balance.cjs +2 -0
  430. package/dist/constants/llm-balance.cjs.map +1 -0
  431. package/dist/constants/llm-balance.d.ts +13 -0
  432. package/dist/constants/llm-balance.js +6 -0
  433. package/dist/constants/llm-balance.js.map +1 -0
  434. package/dist/contexts/conversation-websocket-context.cjs +2 -2
  435. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  436. package/dist/contexts/conversation-websocket-context.js +217 -209
  437. package/dist/contexts/conversation-websocket-context.js.map +1 -1
  438. package/dist/hooks/chat/use-grip-resize.cjs +1 -1
  439. package/dist/hooks/chat/use-grip-resize.cjs.map +1 -1
  440. package/dist/hooks/chat/use-grip-resize.d.ts +1 -0
  441. package/dist/hooks/chat/use-grip-resize.js +39 -30
  442. package/dist/hooks/chat/use-grip-resize.js.map +1 -1
  443. package/dist/hooks/chat/use-slash-command.cjs +1 -1
  444. package/dist/hooks/chat/use-slash-command.cjs.map +1 -1
  445. package/dist/hooks/chat/use-slash-command.js +61 -60
  446. package/dist/hooks/chat/use-slash-command.js.map +1 -1
  447. package/dist/hooks/mutation/use-condense-conversation.cjs +2 -0
  448. package/dist/hooks/mutation/use-condense-conversation.cjs.map +1 -0
  449. package/dist/hooks/mutation/use-condense-conversation.d.ts +12 -0
  450. package/dist/hooks/mutation/use-condense-conversation.js +17 -0
  451. package/dist/hooks/mutation/use-condense-conversation.js.map +1 -0
  452. package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
  453. package/dist/hooks/mutation/use-create-conversation.cjs.map +1 -1
  454. package/dist/hooks/mutation/use-create-conversation.js +30 -21
  455. package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
  456. package/dist/hooks/mutation/use-new-conversation-command.cjs +1 -1
  457. package/dist/hooks/mutation/use-new-conversation-command.cjs.map +1 -1
  458. package/dist/hooks/mutation/use-new-conversation-command.js +1 -1
  459. package/dist/hooks/mutation/use-new-conversation-command.js.map +1 -1
  460. package/dist/hooks/query/use-conversation-metrics.cjs +1 -1
  461. package/dist/hooks/query/use-conversation-metrics.cjs.map +1 -1
  462. package/dist/hooks/query/use-conversation-metrics.js +1 -1
  463. package/dist/hooks/query/use-conversation-metrics.js.map +1 -1
  464. package/dist/hooks/query/use-llm-balance.cjs +2 -0
  465. package/dist/hooks/query/use-llm-balance.cjs.map +1 -0
  466. package/dist/hooks/query/use-llm-balance.d.ts +10 -0
  467. package/dist/hooks/query/use-llm-balance.js +24 -0
  468. package/dist/hooks/query/use-llm-balance.js.map +1 -0
  469. package/dist/hooks/query/use-search-providers.cjs +1 -1
  470. package/dist/hooks/query/use-search-providers.cjs.map +1 -1
  471. package/dist/hooks/query/use-search-providers.js +1 -1
  472. package/dist/hooks/query/use-search-providers.js.map +1 -1
  473. package/dist/hooks/use-await-context-compaction.cjs +2 -0
  474. package/dist/hooks/use-await-context-compaction.cjs.map +1 -0
  475. package/dist/hooks/use-await-context-compaction.d.ts +38 -0
  476. package/dist/hooks/use-await-context-compaction.js +61 -0
  477. package/dist/hooks/use-await-context-compaction.js.map +1 -0
  478. package/dist/hooks/use-compact-context-action.cjs +2 -0
  479. package/dist/hooks/use-compact-context-action.cjs.map +1 -0
  480. package/dist/hooks/use-compact-context-action.d.ts +10 -0
  481. package/dist/hooks/use-compact-context-action.js +61 -0
  482. package/dist/hooks/use-compact-context-action.js.map +1 -0
  483. package/dist/hooks/use-context-window-usage.cjs +2 -0
  484. package/dist/hooks/use-context-window-usage.cjs.map +1 -0
  485. package/dist/hooks/use-context-window-usage.d.ts +5 -0
  486. package/dist/hooks/use-context-window-usage.js +20 -0
  487. package/dist/hooks/use-context-window-usage.js.map +1 -0
  488. package/dist/hooks/use-conversation-name-context-menu.cjs +1 -1
  489. package/dist/hooks/use-conversation-name-context-menu.cjs.map +1 -1
  490. package/dist/hooks/use-conversation-name-context-menu.d.ts +0 -3
  491. package/dist/hooks/use-conversation-name-context-menu.js +54 -57
  492. package/dist/hooks/use-conversation-name-context-menu.js.map +1 -1
  493. package/dist/hooks/use-drag-resize.cjs +1 -1
  494. package/dist/hooks/use-drag-resize.cjs.map +1 -1
  495. package/dist/hooks/use-drag-resize.d.ts +8 -0
  496. package/dist/hooks/use-drag-resize.js +21 -18
  497. package/dist/hooks/use-drag-resize.js.map +1 -1
  498. package/dist/hooks/use-live-conversation-metrics.cjs +2 -0
  499. package/dist/hooks/use-live-conversation-metrics.cjs.map +1 -0
  500. package/dist/hooks/use-live-conversation-metrics.d.ts +18 -0
  501. package/dist/hooks/use-live-conversation-metrics.js +37 -0
  502. package/dist/hooks/use-live-conversation-metrics.js.map +1 -0
  503. package/dist/hooks/use-select-conversation-tab.cjs +1 -1
  504. package/dist/hooks/use-select-conversation-tab.cjs.map +1 -1
  505. package/dist/hooks/use-select-conversation-tab.js +2 -2
  506. package/dist/hooks/use-select-conversation-tab.js.map +1 -1
  507. package/dist/i18n/declaration.cjs +1 -1
  508. package/dist/i18n/declaration.cjs.map +1 -1
  509. package/dist/i18n/declaration.d.ts +27 -0
  510. package/dist/i18n/declaration.js +1 -1
  511. package/dist/i18n/declaration.js.map +1 -1
  512. package/dist/i18n/translation.cjs +2 -2
  513. package/dist/i18n/translation.cjs.map +1 -1
  514. package/dist/i18n/translation.js +474 -15
  515. package/dist/i18n/translation.js.map +1 -1
  516. package/dist/index.cjs +1 -1
  517. package/dist/index.js +28 -29
  518. package/dist/lib/index.cjs +1 -1
  519. package/dist/lib/index.js +0 -1
  520. package/dist/locales/ar/openhands.json +28 -1
  521. package/dist/locales/ca/openhands.json +28 -1
  522. package/dist/locales/de/openhands.json +28 -1
  523. package/dist/locales/en/openhands.json +28 -1
  524. package/dist/locales/es/openhands.json +28 -1
  525. package/dist/locales/fr/openhands.json +28 -1
  526. package/dist/locales/it/openhands.json +28 -1
  527. package/dist/locales/ja/openhands.json +28 -1
  528. package/dist/locales/ko-KR/openhands.json +28 -1
  529. package/dist/locales/no/openhands.json +28 -1
  530. package/dist/locales/pt/openhands.json +28 -1
  531. package/dist/locales/tr/openhands.json +28 -1
  532. package/dist/locales/uk/openhands.json +28 -1
  533. package/dist/locales/zh-CN/openhands.json +28 -1
  534. package/dist/locales/zh-TW/openhands.json +28 -1
  535. package/dist/node_modules/@microlink/react-json-view/dist/main.cjs +5 -5
  536. package/dist/node_modules/@microlink/react-json-view/dist/main.cjs.map +1 -1
  537. package/dist/node_modules/@microlink/react-json-view/dist/main.js +5194 -5187
  538. package/dist/node_modules/@microlink/react-json-view/dist/main.js.map +1 -1
  539. package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.cjs +2 -1
  540. package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.cjs.map +1 -0
  541. package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.js +21 -1
  542. package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.js.map +1 -0
  543. package/dist/node_modules/@openhands/typescript-client/dist/client/hooks-client.cjs +2 -1
  544. package/dist/node_modules/@openhands/typescript-client/dist/client/hooks-client.cjs.map +1 -0
  545. package/dist/node_modules/@openhands/typescript-client/dist/client/hooks-client.js +22 -1
  546. package/dist/node_modules/@openhands/typescript-client/dist/client/hooks-client.js.map +1 -0
  547. package/dist/node_modules/@openhands/typescript-client/dist/client/meta-profiles-client.cjs +2 -1
  548. package/dist/node_modules/@openhands/typescript-client/dist/client/meta-profiles-client.cjs.map +1 -0
  549. package/dist/node_modules/@openhands/typescript-client/dist/client/meta-profiles-client.js +33 -1
  550. package/dist/node_modules/@openhands/typescript-client/dist/client/meta-profiles-client.js.map +1 -0
  551. package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.cjs +1 -1
  552. package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.cjs.map +1 -1
  553. package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.js +56 -22
  554. package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.js.map +1 -1
  555. package/dist/node_modules/@openhands/typescript-client/dist/client/profiles-client.cjs +1 -1
  556. package/dist/node_modules/@openhands/typescript-client/dist/client/profiles-client.cjs.map +1 -1
  557. package/dist/node_modules/@openhands/typescript-client/dist/client/profiles-client.js +3 -0
  558. package/dist/node_modules/@openhands/typescript-client/dist/client/profiles-client.js.map +1 -1
  559. package/dist/node_modules/@openhands/typescript-client/dist/client/shared-client.cjs +2 -1
  560. package/dist/node_modules/@openhands/typescript-client/dist/client/shared-client.cjs.map +1 -0
  561. package/dist/node_modules/@openhands/typescript-client/dist/client/shared-client.js +31 -1
  562. package/dist/node_modules/@openhands/typescript-client/dist/client/shared-client.js.map +1 -0
  563. package/dist/node_modules/@openhands/typescript-client/dist/client/sub-agents-client.cjs +2 -1
  564. package/dist/node_modules/@openhands/typescript-client/dist/client/sub-agents-client.cjs.map +1 -0
  565. package/dist/node_modules/@openhands/typescript-client/dist/client/sub-agents-client.js +21 -1
  566. package/dist/node_modules/@openhands/typescript-client/dist/client/sub-agents-client.js.map +1 -0
  567. package/dist/node_modules/@openhands/typescript-client/dist/client/tool-client.cjs +2 -1
  568. package/dist/node_modules/@openhands/typescript-client/dist/client/tool-client.cjs.map +1 -0
  569. package/dist/node_modules/@openhands/typescript-client/dist/client/tool-client.js +21 -1
  570. package/dist/node_modules/@openhands/typescript-client/dist/client/tool-client.js.map +1 -0
  571. package/dist/node_modules/@openhands/typescript-client/dist/conversation/local-conversation.cjs.map +1 -1
  572. package/dist/node_modules/@openhands/typescript-client/dist/conversation/local-conversation.js.map +1 -1
  573. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs +1 -1
  574. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs.map +1 -1
  575. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js +9 -5
  576. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js.map +1 -1
  577. package/dist/node_modules/i18next-http-backend/esm/index.cjs +1 -1
  578. package/dist/node_modules/i18next-http-backend/esm/index.cjs.map +1 -1
  579. package/dist/node_modules/i18next-http-backend/esm/index.js +2 -2
  580. package/dist/node_modules/i18next-http-backend/esm/index.js.map +1 -1
  581. package/dist/node_modules/lucide-react/dist/esm/icons/archive-restore.cjs +2 -0
  582. package/dist/node_modules/lucide-react/dist/esm/icons/archive-restore.cjs.map +1 -0
  583. package/dist/node_modules/lucide-react/dist/esm/icons/archive-restore.js +31 -0
  584. package/dist/node_modules/lucide-react/dist/esm/icons/archive-restore.js.map +1 -0
  585. package/dist/node_modules/lucide-react/dist/esm/icons/archive.cjs +2 -0
  586. package/dist/node_modules/lucide-react/dist/esm/icons/archive.cjs.map +1 -0
  587. package/dist/node_modules/lucide-react/dist/esm/icons/archive.js +23 -0
  588. package/dist/node_modules/lucide-react/dist/esm/icons/archive.js.map +1 -0
  589. package/dist/node_modules/lucide-react/dist/esm/icons/gauge.cjs +2 -0
  590. package/dist/node_modules/lucide-react/dist/esm/icons/gauge.cjs.map +1 -0
  591. package/dist/node_modules/lucide-react/dist/esm/icons/gauge.js +12 -0
  592. package/dist/node_modules/lucide-react/dist/esm/icons/gauge.js.map +1 -0
  593. package/dist/node_modules/lucide-react/dist/esm/icons/minimize.cjs +2 -0
  594. package/dist/node_modules/lucide-react/dist/esm/icons/minimize.cjs.map +1 -0
  595. package/dist/node_modules/lucide-react/dist/esm/icons/minimize.js +23 -0
  596. package/dist/node_modules/lucide-react/dist/esm/icons/minimize.js.map +1 -0
  597. package/dist/node_modules/zustand/esm/middleware.cjs +3 -3
  598. package/dist/node_modules/zustand/esm/middleware.cjs.map +1 -1
  599. package/dist/node_modules/zustand/esm/middleware.js +33 -31
  600. package/dist/node_modules/zustand/esm/middleware.js.map +1 -1
  601. package/dist/package.cjs +1 -1
  602. package/dist/package.cjs.map +1 -1
  603. package/dist/package.js +17 -16
  604. package/dist/package.js.map +1 -1
  605. package/dist/routes/app-settings.cjs +1 -1
  606. package/dist/routes/app-settings.cjs.map +1 -1
  607. package/dist/routes/app-settings.js +94 -93
  608. package/dist/routes/app-settings.js.map +1 -1
  609. package/dist/routes/llm-settings.cjs +1 -1
  610. package/dist/routes/llm-settings.cjs.map +1 -1
  611. package/dist/routes/llm-settings.js +131 -119
  612. package/dist/routes/llm-settings.js.map +1 -1
  613. package/dist/routes/usage-tab.cjs +2 -0
  614. package/dist/routes/usage-tab.cjs.map +1 -0
  615. package/dist/routes/usage-tab.d.ts +2 -0
  616. package/dist/routes/usage-tab.js +10 -0
  617. package/dist/routes/usage-tab.js.map +1 -0
  618. package/dist/services/child-conversation-launch.cjs +1 -1
  619. package/dist/services/child-conversation-launch.cjs.map +1 -1
  620. package/dist/services/child-conversation-launch.js +11 -5
  621. package/dist/services/child-conversation-launch.js.map +1 -1
  622. package/dist/stores/archived-conversations-store.cjs +2 -0
  623. package/dist/stores/archived-conversations-store.cjs.map +1 -0
  624. package/dist/stores/archived-conversations-store.d.ts +24 -0
  625. package/dist/stores/archived-conversations-store.js +33 -0
  626. package/dist/stores/archived-conversations-store.js.map +1 -0
  627. package/dist/stores/conversation-panel-preferences-store.cjs +1 -1
  628. package/dist/stores/conversation-panel-preferences-store.cjs.map +1 -1
  629. package/dist/stores/conversation-panel-preferences-store.d.ts +3 -0
  630. package/dist/stores/conversation-panel-preferences-store.js +4 -0
  631. package/dist/stores/conversation-panel-preferences-store.js.map +1 -1
  632. package/dist/stores/conversation-store.cjs.map +1 -1
  633. package/dist/stores/conversation-store.d.ts +1 -1
  634. package/dist/stores/conversation-store.js.map +1 -1
  635. package/dist/stores/metrics-store.cjs +1 -1
  636. package/dist/stores/metrics-store.cjs.map +1 -1
  637. package/dist/stores/metrics-store.d.ts +1 -0
  638. package/dist/stores/metrics-store.js +7 -4
  639. package/dist/stores/metrics-store.js.map +1 -1
  640. package/dist/types/agent-server/core/events/condensation-event.d.ts +3 -0
  641. package/dist/types/agent-server/core/events/conversation-state-event.d.ts +4 -6
  642. package/dist/types/agent-server/type-guards.cjs +1 -1
  643. package/dist/types/agent-server/type-guards.cjs.map +1 -1
  644. package/dist/types/agent-server/type-guards.d.ts +5 -0
  645. package/dist/types/agent-server/type-guards.js +3 -3
  646. package/dist/types/agent-server/type-guards.js.map +1 -1
  647. package/dist/utils/conversation-local-storage.cjs +1 -1
  648. package/dist/utils/conversation-local-storage.cjs.map +1 -1
  649. package/dist/utils/conversation-local-storage.js +2 -1
  650. package/dist/utils/conversation-local-storage.js.map +1 -1
  651. package/dist/utils/format-model-name.cjs +1 -1
  652. package/dist/utils/format-model-name.cjs.map +1 -1
  653. package/dist/utils/format-model-name.d.ts +11 -0
  654. package/dist/utils/format-model-name.js +11 -3
  655. package/dist/utils/format-model-name.js.map +1 -1
  656. package/dist/utils/format-token-count.cjs +2 -0
  657. package/dist/utils/format-token-count.cjs.map +1 -0
  658. package/dist/utils/format-token-count.d.ts +3 -0
  659. package/dist/utils/format-token-count.js +19 -0
  660. package/dist/utils/format-token-count.js.map +1 -0
  661. package/dist/utils/hover-reveal-classes.cjs +2 -0
  662. package/dist/utils/hover-reveal-classes.cjs.map +1 -0
  663. package/dist/utils/hover-reveal-classes.d.ts +34 -0
  664. package/dist/utils/hover-reveal-classes.js +41 -0
  665. package/dist/utils/hover-reveal-classes.js.map +1 -0
  666. package/dist/utils/is-markdown-file-path.cjs +2 -0
  667. package/dist/utils/is-markdown-file-path.cjs.map +1 -0
  668. package/dist/utils/is-markdown-file-path.d.ts +4 -0
  669. package/dist/utils/is-markdown-file-path.js +14 -0
  670. package/dist/utils/is-markdown-file-path.js.map +1 -0
  671. package/dist/utils/mcp-marketplace-utils.cjs +1 -1
  672. package/dist/utils/mcp-marketplace-utils.cjs.map +1 -1
  673. package/dist/utils/mcp-marketplace-utils.d.ts +7 -0
  674. package/dist/utils/mcp-marketplace-utils.js +19 -16
  675. package/dist/utils/mcp-marketplace-utils.js.map +1 -1
  676. package/dist/utils/transcript-export/index.cjs +3 -3
  677. package/dist/utils/transcript-export/index.cjs.map +1 -1
  678. package/dist/utils/transcript-export/index.js +12 -12
  679. package/dist/utils/transcript-export/index.js.map +1 -1
  680. package/dist/utils/transcript-export/load-complete-events.cjs +1 -1
  681. package/dist/utils/transcript-export/load-complete-events.cjs.map +1 -1
  682. package/dist/utils/transcript-export/load-complete-events.js +4 -4
  683. package/dist/utils/transcript-export/load-complete-events.js.map +1 -1
  684. package/dist/utils/workspace-relative-path.cjs +2 -0
  685. package/dist/utils/workspace-relative-path.cjs.map +1 -0
  686. package/dist/utils/workspace-relative-path.d.ts +10 -0
  687. package/dist/utils/workspace-relative-path.js +22 -0
  688. package/dist/utils/workspace-relative-path.js.map +1 -0
  689. package/package.json +17 -16
  690. package/scripts/check-sdk-version-sync.mjs +6 -6
  691. package/scripts/dev-process-utils.mjs +6 -1
  692. package/scripts/dev-safe.mjs +57 -2
  693. package/build/assets/active-backend-context-BBvP-bI2.js +0 -2
  694. package/build/assets/agent-profiles-settings-DqoS7RL3.js +0 -1
  695. package/build/assets/agent-server-conversation-service.api-0RztSdJJ.js +0 -86
  696. package/build/assets/agent-settings-BJHryp65.js +0 -1
  697. package/build/assets/app-settings-r1RUbgGi.js +0 -1
  698. package/build/assets/backend-form-modal-OroTqnAv.js +0 -1
  699. package/build/assets/bot-DuN83i3p.js +0 -1
  700. package/build/assets/browser--eoQOo4M.js +0 -6
  701. package/build/assets/check-DLOKoFU9.js +0 -1
  702. package/build/assets/chevron-down-CnIbtM6i.js +0 -1
  703. package/build/assets/circle-check-CxCYJrpZ.js +0 -1
  704. package/build/assets/conversation-BUzBZAc-.js +0 -90
  705. package/build/assets/conversation-panel-pzAKsSDb.js +0 -1
  706. package/build/assets/conversation-pzAKsSDb.js +0 -1
  707. package/build/assets/conversation-store-B8Eahyeg.js +0 -6
  708. package/build/assets/external-link-zWbg5KXS.js +0 -1
  709. package/build/assets/files-tab-BzofBmF4.js +0 -1
  710. package/build/assets/git-provider-icon-BLMlwy02.js +0 -1
  711. package/build/assets/git-repo-dropdown-B_PTq4ol.js +0 -1
  712. package/build/assets/home-r89Vj2td.js +0 -1
  713. package/build/assets/index-home-r89Vj2td.js +0 -1
  714. package/build/assets/llm-not-configured-banner-CwKu8C6g.js +0 -27
  715. package/build/assets/llm-settings-BJotLQND.js +0 -1
  716. package/build/assets/llm-settings-CDM-5H2A.js +0 -1
  717. package/build/assets/llm-subscription-service-7eVfDIE1.js +0 -1
  718. package/build/assets/loader-circle-C5AnEN8r.js +0 -1
  719. package/build/assets/manifest-2a36a8f8.js +0 -1
  720. package/build/assets/markdown-renderer-BiiiIznl.js +0 -8
  721. package/build/assets/mcp-marketplace-utils-Dr_HG_ol.js +0 -1
  722. package/build/assets/messages-D1cbVhRK.js +0 -40
  723. package/build/assets/pencil-Bl3GWhgq.js +0 -1
  724. package/build/assets/plus-CtzlyAoF.js +0 -1
  725. package/build/assets/recommended-automations-launcher-BbJAJVED.js +0 -1
  726. package/build/assets/refresh-cw-B9GhC3QC.js +0 -1
  727. package/build/assets/root-BfM_kC_d.css +0 -1
  728. package/build/assets/root-gstBEjty.js +0 -2
  729. package/build/assets/root-layout-BIAFLP9p.js +0 -2
  730. package/build/assets/search-CYaiKHRp.js +0 -1
  731. package/build/assets/shared-conversation-DIxZjElr.js +0 -1
  732. package/build/assets/shield-check-D2cpEpv3.js +0 -1
  733. package/build/assets/trash-2-CzDVN-Iw.js +0 -1
  734. package/build/assets/use-create-conversation-DWaSVUOB.js +0 -1
  735. package/build/assets/use-is-authed-Bka89Xmm.js +0 -1
  736. package/build/assets/use-llm-profiles-CU8ah1pz.js +0 -1
  737. package/build/assets/use-save-agent-profile-DgI_Uz9a.js +0 -1
  738. package/build/assets/utils-DPQfkd-7.js +0 -1
  739. package/build/assets/vendor~index-home~home~conversation-panel~conversation-DiXf0dkj.js +0 -13
  740. package/build/assets/x-RYDBg-e2.js +0 -1
  741. package/build/assets/zap-tbKDzCe3.js +0 -1
  742. package/dist/components/features/conversation/metrics-modal/context-window-section.cjs +0 -2
  743. package/dist/components/features/conversation/metrics-modal/context-window-section.cjs.map +0 -1
  744. package/dist/components/features/conversation/metrics-modal/context-window-section.d.ts +0 -6
  745. package/dist/components/features/conversation/metrics-modal/context-window-section.js +0 -46
  746. package/dist/components/features/conversation/metrics-modal/context-window-section.js.map +0 -1
  747. package/dist/components/features/conversation/metrics-modal/empty-state.cjs +0 -2
  748. package/dist/components/features/conversation/metrics-modal/empty-state.cjs.map +0 -1
  749. package/dist/components/features/conversation/metrics-modal/empty-state.d.ts +0 -1
  750. package/dist/components/features/conversation/metrics-modal/empty-state.js +0 -18
  751. package/dist/components/features/conversation/metrics-modal/empty-state.js.map +0 -1
  752. package/dist/components/features/conversation/metrics-modal/metrics-modal-header.cjs +0 -2
  753. package/dist/components/features/conversation/metrics-modal/metrics-modal-header.cjs.map +0 -1
  754. package/dist/components/features/conversation/metrics-modal/metrics-modal-header.d.ts +0 -5
  755. package/dist/components/features/conversation/metrics-modal/metrics-modal-header.js +0 -20
  756. package/dist/components/features/conversation/metrics-modal/metrics-modal-header.js.map +0 -1
  757. package/dist/components/features/conversation/metrics-modal/metrics-modal.cjs +0 -2
  758. package/dist/components/features/conversation/metrics-modal/metrics-modal.cjs.map +0 -1
  759. package/dist/components/features/conversation/metrics-modal/metrics-modal.d.ts +0 -6
  760. package/dist/components/features/conversation/metrics-modal/metrics-modal.js +0 -57
  761. package/dist/components/features/conversation/metrics-modal/metrics-modal.js.map +0 -1
  762. package/dist/icons/u-credit-card.cjs +0 -2
  763. package/dist/icons/u-credit-card.cjs.map +0 -1
  764. package/dist/icons/u-credit-card.js +0 -21
  765. package/dist/icons/u-credit-card.js.map +0 -1
  766. /package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~cy4jtuc2-rfV8mQ9m.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~dh9v73sa-rfV8mQ9m.js} +0 -0
@@ -1,19 +1,20 @@
1
1
  import { BUILT_IN_COMMANDS as e, MODEL_COMMAND as t } from "../../utils/constants.js";
2
2
  import { useActiveBackend as n } from "../../contexts/active-backend-context.js";
3
- import { useConversationSkills as r } from "../query/use-conversation-skills.js";
4
- import { useLlmProfiles as i } from "../query/use-llm-profiles.js";
5
- import { useCallback as a, useEffect as o, useMemo as s, useRef as c, useState as l } from "react";
3
+ import { formatModelNameForDisplay as r } from "../../utils/format-model-name.js";
4
+ import { useConversationSkills as i } from "../query/use-conversation-skills.js";
5
+ import { useLlmProfiles as a } from "../query/use-llm-profiles.js";
6
+ import { useCallback as o, useEffect as s, useMemo as c, useRef as l, useState as u } from "react";
6
7
  //#region src/hooks/chat/use-slash-command.ts
7
- function u(e) {
8
+ function d(e) {
8
9
  let t = window.getSelection();
9
10
  if (!t || t.rangeCount === 0) return -1;
10
11
  let n = t.getRangeAt(0), r = n.cloneRange();
11
12
  return r.selectNodeContents(e), r.setEnd(n.startContainer, n.startOffset), r.toString().length;
12
13
  }
13
- var d = (d) => {
14
- let { data: f, isLoading: p } = r(), m = n().backend.kind === "cloud", { data: h, isLoading: g } = i(), [_, v] = l(!1), [y, b] = l(""), [x, S] = l("command"), [C, w] = l(0), T = s(() => {
15
- let t = e.filter((e) => e.command === "/new" ? m : !0);
16
- return p || !f || f.forEach((e) => {
14
+ var f = (f) => {
15
+ let { data: p, isLoading: m } = i(), h = n().backend.kind === "cloud", { data: g, isLoading: _ } = a(), [v, y] = u(!1), [b, x] = u(""), [S, C] = u("command"), [w, T] = u(0), E = c(() => {
16
+ let t = e.filter((e) => e.command === "/new" ? h : !0);
17
+ return m || !p || p.forEach((e) => {
17
18
  let n = (e.triggers || []).filter((e) => e.startsWith("/"));
18
19
  n.length > 0 ? n.forEach((n) => {
19
20
  t.push({
@@ -26,42 +27,42 @@ var d = (d) => {
26
27
  });
27
28
  }), t;
28
29
  }, [
29
- f,
30
30
  p,
31
- m
32
- ]), E = s(() => (h?.profiles ?? []).map((e) => {
31
+ m,
32
+ h
33
+ ]), D = c(() => (g?.profiles ?? []).map((e) => {
33
34
  let n = `${t} ${e.name}`;
34
35
  return {
35
36
  command: n,
36
37
  skill: {
37
38
  name: e.name,
38
39
  type: "agentskills",
39
- content: e.model ? `Switch to ${e.model}` : "Switch to this LLM profile",
40
+ content: e.model ? `Switch to ${r(e.model)}` : "Switch to this LLM profile",
40
41
  triggers: [n]
41
42
  }
42
43
  };
43
- }), [h?.profiles]), D = s(() => {
44
- let e = x === "model-profile" ? E : T;
45
- if (!y) return e;
46
- let t = y.toLowerCase();
44
+ }), [g?.profiles]), O = c(() => {
45
+ let e = S === "model-profile" ? D : E;
46
+ if (!b) return e;
47
+ let t = b.toLowerCase();
47
48
  return e.filter((e) => e.command.toLowerCase().includes(t) || e.skill.name.toLowerCase().includes(t) || e.skill.content?.toLowerCase().includes(t));
48
49
  }, [
49
- x,
50
+ S,
51
+ D,
50
52
  E,
51
- T,
52
- y
53
- ]), O = c(_);
54
- O.current = _;
55
- let k = c(D);
56
- k.current = D;
57
- let A = c(C);
58
- A.current = C, o(() => {
59
- w(0);
60
- }, [y]);
61
- let j = c(null), M = a(() => {
62
- let e = d.current;
53
+ b
54
+ ]), k = l(v);
55
+ k.current = v;
56
+ let A = l(O);
57
+ A.current = O;
58
+ let j = l(w);
59
+ j.current = w, s(() => {
60
+ T(0);
61
+ }, [b]);
62
+ let M = l(null), N = o(() => {
63
+ let e = f.current;
63
64
  if (!e) return null;
64
- let t = (e.innerText || "").replace(/[\n\r]+$/, ""), n = u(e);
65
+ let t = (e.innerText || "").replace(/[\n\r]+$/, ""), n = d(e);
65
66
  if (n < 0) return null;
66
67
  let r = t.slice(0, n), i = r.match(/(^|\s)(\/model(?:\s+\S*)?)$/);
67
68
  if (i) {
@@ -82,21 +83,21 @@ var d = (d) => {
82
83
  start: s,
83
84
  end: l
84
85
  };
85
- }, [d]), N = a(() => {
86
- let e = M(), t = e?.kind === "model-profile" ? E.length > 0 || g : T.length > 0;
87
- e !== null && t ? (S(e.kind), b(e.text), j.current = {
86
+ }, [f]), P = o(() => {
87
+ let e = N(), t = e?.kind === "model-profile" ? D.length > 0 || _ : E.length > 0;
88
+ e !== null && t ? (C(e.kind), x(e.text), M.current = {
88
89
  start: e.start,
89
90
  end: e.end
90
- }, v(!0)) : (v(!1), b(""), S("command"), j.current = null);
91
+ }, y(!0)) : (y(!1), x(""), C("command"), M.current = null);
91
92
  }, [
92
- M,
93
- g,
94
- E.length,
95
- T.length
96
- ]), P = a((e) => {
97
- let t = d.current;
93
+ N,
94
+ _,
95
+ D.length,
96
+ E.length
97
+ ]), F = o((e) => {
98
+ let t = f.current;
98
99
  if (!t) return;
99
- let n = j.current, r = (t.innerText || "").replace(/[\n\r]+$/, ""), i = `${e.command} `;
100
+ let n = M.current, r = (t.innerText || "").replace(/[\n\r]+$/, ""), i = `${e.command} `;
100
101
  if (n) {
101
102
  t.textContent = r.slice(0, n.start) + i + r.slice(n.end);
102
103
  let e = n.start + i.length, a = t.firstChild;
@@ -109,37 +110,37 @@ var d = (d) => {
109
110
  let e = document.createRange(), n = window.getSelection();
110
111
  e.selectNodeContents(t), e.collapse(!1), n?.removeAllRanges(), n?.addRange(e);
111
112
  }
112
- v(!1), b(""), S("command"), w(0), j.current = null, t.dispatchEvent(new InputEvent("input", { bubbles: !0 })), t.focus();
113
- }, [d]);
113
+ y(!1), x(""), C("command"), T(0), M.current = null, t.dispatchEvent(new InputEvent("input", { bubbles: !0 })), t.focus();
114
+ }, [f]);
114
115
  return {
115
- isMenuOpen: _,
116
- filteredItems: D,
117
- selectedIndex: C,
118
- updateSlashMenu: N,
119
- selectItem: P,
120
- handleSlashKeyDown: a((e) => {
121
- let t = k.current;
122
- if (!O.current || t.length === 0) return !1;
116
+ isMenuOpen: v,
117
+ filteredItems: O,
118
+ selectedIndex: w,
119
+ updateSlashMenu: P,
120
+ selectItem: F,
121
+ handleSlashKeyDown: o((e) => {
122
+ let t = A.current;
123
+ if (!k.current || t.length === 0) return !1;
123
124
  switch (e.key) {
124
- case "ArrowDown": return e.preventDefault(), w((e) => e < t.length - 1 ? e + 1 : 0), !0;
125
- case "ArrowUp": return e.preventDefault(), w((e) => e > 0 ? e - 1 : t.length - 1), !0;
125
+ case "ArrowDown": return e.preventDefault(), T((e) => e < t.length - 1 ? e + 1 : 0), !0;
126
+ case "ArrowUp": return e.preventDefault(), T((e) => e > 0 ? e - 1 : t.length - 1), !0;
126
127
  case "Enter":
127
128
  case "Tab": {
128
- let n = t[A.current];
129
- return n ? (e.preventDefault(), P(n), !0) : !1;
129
+ let n = t[j.current];
130
+ return n ? (e.preventDefault(), F(n), !0) : !1;
130
131
  }
131
- case "Escape": return e.preventDefault(), v(!1), !0;
132
+ case "Escape": return e.preventDefault(), y(!1), !0;
132
133
  case "ArrowLeft":
133
134
  case "ArrowRight":
134
135
  case "Home":
135
- case "End": return v(!1), !1;
136
+ case "End": return y(!1), !1;
136
137
  default: return !1;
137
138
  }
138
- }, [P]),
139
- closeMenu: a(() => v(!1), [])
139
+ }, [F]),
140
+ closeMenu: o(() => y(!1), [])
140
141
  };
141
142
  };
142
143
  //#endregion
143
- export { d as useSlashCommand };
144
+ export { f as useSlashCommand };
144
145
 
145
146
  //# sourceMappingURL=use-slash-command.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-slash-command.js","names":[],"sources":["../../../src/hooks/chat/use-slash-command.ts"],"sourcesContent":["import { useState, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport { SkillInfo } from \"#/types/settings\";\nimport { Microagent } from \"#/api/open-hands.types\";\nimport { BUILT_IN_COMMANDS, MODEL_COMMAND } from \"#/utils/constants\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\n\nexport type SlashCommandSkill = SkillInfo | Microagent;\n\nexport interface SlashCommandItem {\n skill: SlashCommandSkill;\n /** The slash command string, e.g. \"/random-number\" */\n command: string;\n}\n\ntype SlashCompletionKind = \"command\" | \"model-profile\";\n\n/** Get the cursor's character offset within a contentEditable element. */\nfunction getCursorOffset(element: HTMLElement): number {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return -1;\n const range = selection.getRangeAt(0);\n const preRange = range.cloneRange();\n preRange.selectNodeContents(element);\n preRange.setEnd(range.startContainer, range.startOffset);\n return preRange.toString().length;\n}\n\n/**\n * Hook for managing slash command autocomplete in the chat input.\n * Detects when user types \"/\" and provides filtered skill suggestions.\n * Only skills with explicit \"/\" triggers (TaskTrigger) appear in the menu.\n */\nexport const useSlashCommand = (\n chatInputRef: React.RefObject<HTMLDivElement | null>,\n) => {\n // Scope the skill catalog to this conversation's attached workspace so the\n // slash menu lists the same project skills that were loaded into it.\n const { data: skills, isLoading: isSkillsLoading } = useConversationSkills();\n const isCloud = useActiveBackend().backend.kind === \"cloud\";\n const { data: profilesData, isLoading: isProfilesLoading } = useLlmProfiles();\n const [isMenuOpen, setIsMenuOpen] = useState(false);\n const [filterText, setFilterText] = useState(\"\");\n const [completionKind, setCompletionKind] =\n useState<SlashCompletionKind>(\"command\");\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n // Build slash command items from built-in commands + skills:\n // - Built-in commands (like /new) are included for V1 conversations\n // - /new is cloud-only — local backends don't surface it\n // - /model lists/switches LLM profiles; both local and cloud support them\n // - Skills with explicit \"/\" triggers use those triggers\n // - AgentSkills without \"/\" triggers get a derived \"/<name>\" command\n const slashItems = useMemo(() => {\n const items: SlashCommandItem[] = BUILT_IN_COMMANDS.filter((cmd) => {\n if (cmd.command === \"/new\") return isCloud;\n return true;\n });\n\n // Wait for skills to finish initial load so all commands appear together\n if (isSkillsLoading) return items;\n\n if (!skills) return items;\n skills.forEach((skill) => {\n const triggers = skill.triggers || [];\n const slashTriggers = triggers.filter((t) => t.startsWith(\"/\"));\n\n if (slashTriggers.length > 0) {\n // Skill has explicit slash triggers\n slashTriggers.forEach((trigger) => {\n items.push({ skill, command: trigger });\n });\n } else if (skill.type === \"agentskills\") {\n // AgentSkills without slash triggers get a derived command\n items.push({ skill, command: `/${skill.name}` });\n }\n });\n return items;\n }, [skills, isSkillsLoading, isCloud]);\n\n const modelProfileItems = useMemo<SlashCommandItem[]>(() => {\n return (profilesData?.profiles ?? []).map((profile) => {\n const command = `${MODEL_COMMAND} ${profile.name}`;\n return {\n command,\n skill: {\n name: profile.name,\n type: \"agentskills\",\n content: profile.model\n ? `Switch to ${profile.model}`\n : \"Switch to this LLM profile\",\n triggers: [command],\n },\n };\n });\n }, [profilesData?.profiles]);\n\n // Filter items based on user input after \"/\"\n const filteredItems = useMemo(() => {\n const sourceItems =\n completionKind === \"model-profile\" ? modelProfileItems : slashItems;\n if (!filterText) return sourceItems;\n const lower = filterText.toLowerCase();\n return sourceItems.filter(\n (item) =>\n item.command.toLowerCase().includes(lower) ||\n item.skill.name.toLowerCase().includes(lower) ||\n item.skill.content?.toLowerCase().includes(lower),\n );\n }, [completionKind, modelProfileItems, slashItems, filterText]);\n\n // Keep refs in sync so handleSlashKeyDown always reads the latest values,\n // avoiding stale closures from React's batched state updates.\n const isMenuOpenRef = useRef(isMenuOpen);\n isMenuOpenRef.current = isMenuOpen;\n const filteredItemsRef = useRef(filteredItems);\n filteredItemsRef.current = filteredItems;\n const selectedIndexRef = useRef(selectedIndex);\n selectedIndexRef.current = selectedIndex;\n\n // Reset selected index when the filter text changes\n useEffect(() => {\n setSelectedIndex(0);\n }, [filterText]);\n\n // Track the character range of the current slash word so selectItem can\n // replace only that portion instead of wiping the entire input.\n const slashRangeRef = useRef<{ start: number; end: number } | null>(null);\n\n // Detect a slash word at the cursor position.\n // Returns the filter text (characters after \"/\") and the range of the\n // slash word within the full input text, or null if no slash word found.\n const getSlashText = useCallback((): {\n kind: SlashCompletionKind;\n text: string;\n start: number;\n end: number;\n } | null => {\n const element = chatInputRef.current;\n if (!element) return null;\n\n // Strip trailing newlines that contentEditable can produce, but preserve\n // spaces so \"/command \" (after selection) won't re-trigger the menu.\n const text = (element.innerText || \"\").replace(/[\\n\\r]+$/, \"\");\n const cursor = getCursorOffset(element);\n if (cursor < 0) return null;\n\n const textBeforeCursor = text.slice(0, cursor);\n\n const modelMatch = textBeforeCursor.match(/(^|\\s)(\\/model(?:\\s+\\S*)?)$/);\n if (modelMatch) {\n const modelCommand = modelMatch[2];\n const start = textBeforeCursor.length - modelCommand.length;\n const afterCursor = text.slice(cursor);\n const trailing = afterCursor.match(/^\\S*/);\n const end = cursor + (trailing ? trailing[0].length : 0);\n\n return {\n kind: \"model-profile\",\n text: modelCommand.replace(/^\\/model(?:\\s+)?/, \"\"),\n start,\n end,\n };\n }\n\n // Match a \"/\" preceded by whitespace or at position 0, followed by\n // non-whitespace characters, ending right at the cursor.\n const match = textBeforeCursor.match(/(^|\\s)(\\/\\S*)$/);\n if (!match) return null;\n\n const slashWord = match[2]; // e.g. \"/hel\"\n const start = textBeforeCursor.length - slashWord.length;\n // The end of the slash word extends past the cursor to include any\n // contiguous non-whitespace characters (covers the case where the\n // cursor sits in the middle of a word).\n const afterCursor = text.slice(cursor);\n const trailing = afterCursor.match(/^\\S*/);\n const end = cursor + (trailing ? trailing[0].length : 0);\n\n return { kind: \"command\", text: slashWord.slice(1), start, end }; // strip leading \"/\"\n }, [chatInputRef]);\n\n // Update the menu state based on current input\n const updateSlashMenu = useCallback(() => {\n const result = getSlashText();\n const hasItems =\n result?.kind === \"model-profile\"\n ? modelProfileItems.length > 0 || isProfilesLoading\n : slashItems.length > 0;\n\n if (result !== null && hasItems) {\n setCompletionKind(result.kind);\n setFilterText(result.text);\n slashRangeRef.current = { start: result.start, end: result.end };\n setIsMenuOpen(true);\n } else {\n setIsMenuOpen(false);\n setFilterText(\"\");\n setCompletionKind(\"command\");\n slashRangeRef.current = null;\n }\n }, [\n getSlashText,\n isProfilesLoading,\n modelProfileItems.length,\n slashItems.length,\n ]);\n\n // Select an item and replace only the slash word with the command\n const selectItem = useCallback(\n (item: SlashCommandItem) => {\n const element = chatInputRef.current;\n if (!element) return;\n\n const slashRange = slashRangeRef.current;\n const currentText = (element.innerText || \"\").replace(/[\\n\\r]+$/, \"\");\n const replacement = `${item.command} `;\n\n if (slashRange) {\n // Splice the command into the text, replacing only the slash word\n element.textContent =\n currentText.slice(0, slashRange.start) +\n replacement +\n currentText.slice(slashRange.end);\n\n // Position cursor right after the inserted command + space\n const cursorPos = slashRange.start + replacement.length;\n const textNode = element.firstChild;\n if (textNode) {\n const range = document.createRange();\n const sel = window.getSelection();\n const offset = Math.min(cursorPos, textNode.textContent!.length);\n range.setStart(textNode, offset);\n range.collapse(true);\n sel?.removeAllRanges();\n sel?.addRange(range);\n }\n } else {\n // Fallback: replace everything (e.g. if range tracking failed)\n element.textContent = replacement;\n const range = document.createRange();\n const sel = window.getSelection();\n range.selectNodeContents(element);\n range.collapse(false);\n sel?.removeAllRanges();\n sel?.addRange(range);\n }\n\n setIsMenuOpen(false);\n setFilterText(\"\");\n setCompletionKind(\"command\");\n setSelectedIndex(0);\n slashRangeRef.current = null;\n\n // Trigger a native InputEvent so React's onInput fires (for smartResize etc.)\n element.dispatchEvent(new InputEvent(\"input\", { bubbles: true }));\n\n // Restore focus so keyboard events (Enter to submit) work after selection\n element.focus();\n },\n [chatInputRef],\n );\n\n // Handle keyboard navigation in the menu.\n // Uses refs to always read the latest state, avoiding stale closures.\n const handleSlashKeyDown = useCallback(\n (e: React.KeyboardEvent): boolean => {\n const items = filteredItemsRef.current;\n if (!isMenuOpenRef.current || items.length === 0) return false;\n\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n setSelectedIndex((prev) => (prev < items.length - 1 ? prev + 1 : 0));\n return true;\n case \"ArrowUp\":\n e.preventDefault();\n setSelectedIndex((prev) => (prev > 0 ? prev - 1 : items.length - 1));\n return true;\n case \"Enter\":\n case \"Tab\": {\n const item = items[selectedIndexRef.current];\n if (!item) return false;\n e.preventDefault();\n selectItem(item);\n return true;\n }\n case \"Escape\":\n e.preventDefault();\n setIsMenuOpen(false);\n return true;\n // Cursor-movement keys: close the menu to avoid acting on a stale\n // slash-word range, but don't consume the event so the cursor moves.\n case \"ArrowLeft\":\n case \"ArrowRight\":\n case \"Home\":\n case \"End\":\n setIsMenuOpen(false);\n return false;\n default:\n return false;\n }\n },\n [selectItem],\n );\n\n const closeMenu = useCallback(() => setIsMenuOpen(false), []);\n\n return {\n isMenuOpen,\n filteredItems,\n selectedIndex,\n updateSlashMenu,\n selectItem,\n handleSlashKeyDown,\n closeMenu,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-slash-command.js","names":[],"sources":["../../../src/hooks/chat/use-slash-command.ts"],"sourcesContent":["import { useState, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport { SkillInfo } from \"#/types/settings\";\nimport { Microagent } from \"#/api/open-hands.types\";\nimport { BUILT_IN_COMMANDS, MODEL_COMMAND } from \"#/utils/constants\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\nimport { formatModelNameForDisplay } from \"#/utils/format-model-name\";\n\nexport type SlashCommandSkill = SkillInfo | Microagent;\n\nexport interface SlashCommandItem {\n skill: SlashCommandSkill;\n /** The slash command string, e.g. \"/random-number\" */\n command: string;\n}\n\ntype SlashCompletionKind = \"command\" | \"model-profile\";\n\n/** Get the cursor's character offset within a contentEditable element. */\nfunction getCursorOffset(element: HTMLElement): number {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return -1;\n const range = selection.getRangeAt(0);\n const preRange = range.cloneRange();\n preRange.selectNodeContents(element);\n preRange.setEnd(range.startContainer, range.startOffset);\n return preRange.toString().length;\n}\n\n/**\n * Hook for managing slash command autocomplete in the chat input.\n * Detects when user types \"/\" and provides filtered skill suggestions.\n * Only skills with explicit \"/\" triggers (TaskTrigger) appear in the menu.\n */\nexport const useSlashCommand = (\n chatInputRef: React.RefObject<HTMLDivElement | null>,\n) => {\n // Scope the skill catalog to this conversation's attached workspace so the\n // slash menu lists the same project skills that were loaded into it.\n const { data: skills, isLoading: isSkillsLoading } = useConversationSkills();\n const isCloud = useActiveBackend().backend.kind === \"cloud\";\n const { data: profilesData, isLoading: isProfilesLoading } = useLlmProfiles();\n const [isMenuOpen, setIsMenuOpen] = useState(false);\n const [filterText, setFilterText] = useState(\"\");\n const [completionKind, setCompletionKind] =\n useState<SlashCompletionKind>(\"command\");\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n // Build slash command items from built-in commands + skills:\n // - Built-in commands (like /new) are included for V1 conversations\n // - /new is cloud-only — local backends don't surface it\n // - /model lists/switches LLM profiles; both local and cloud support them\n // - Skills with explicit \"/\" triggers use those triggers\n // - AgentSkills without \"/\" triggers get a derived \"/<name>\" command\n const slashItems = useMemo(() => {\n const items: SlashCommandItem[] = BUILT_IN_COMMANDS.filter((cmd) => {\n if (cmd.command === \"/new\") return isCloud;\n return true;\n });\n\n // Wait for skills to finish initial load so all commands appear together\n if (isSkillsLoading) return items;\n\n if (!skills) return items;\n skills.forEach((skill) => {\n const triggers = skill.triggers || [];\n const slashTriggers = triggers.filter((t) => t.startsWith(\"/\"));\n\n if (slashTriggers.length > 0) {\n // Skill has explicit slash triggers\n slashTriggers.forEach((trigger) => {\n items.push({ skill, command: trigger });\n });\n } else if (skill.type === \"agentskills\") {\n // AgentSkills without slash triggers get a derived command\n items.push({ skill, command: `/${skill.name}` });\n }\n });\n return items;\n }, [skills, isSkillsLoading, isCloud]);\n\n const modelProfileItems = useMemo<SlashCommandItem[]>(() => {\n return (profilesData?.profiles ?? []).map((profile) => {\n const command = `${MODEL_COMMAND} ${profile.name}`;\n return {\n command,\n skill: {\n name: profile.name,\n type: \"agentskills\",\n content: profile.model\n ? `Switch to ${formatModelNameForDisplay(profile.model)}`\n : \"Switch to this LLM profile\",\n triggers: [command],\n },\n };\n });\n }, [profilesData?.profiles]);\n\n // Filter items based on user input after \"/\"\n const filteredItems = useMemo(() => {\n const sourceItems =\n completionKind === \"model-profile\" ? modelProfileItems : slashItems;\n if (!filterText) return sourceItems;\n const lower = filterText.toLowerCase();\n return sourceItems.filter(\n (item) =>\n item.command.toLowerCase().includes(lower) ||\n item.skill.name.toLowerCase().includes(lower) ||\n item.skill.content?.toLowerCase().includes(lower),\n );\n }, [completionKind, modelProfileItems, slashItems, filterText]);\n\n // Keep refs in sync so handleSlashKeyDown always reads the latest values,\n // avoiding stale closures from React's batched state updates.\n const isMenuOpenRef = useRef(isMenuOpen);\n isMenuOpenRef.current = isMenuOpen;\n const filteredItemsRef = useRef(filteredItems);\n filteredItemsRef.current = filteredItems;\n const selectedIndexRef = useRef(selectedIndex);\n selectedIndexRef.current = selectedIndex;\n\n // Reset selected index when the filter text changes\n useEffect(() => {\n setSelectedIndex(0);\n }, [filterText]);\n\n // Track the character range of the current slash word so selectItem can\n // replace only that portion instead of wiping the entire input.\n const slashRangeRef = useRef<{ start: number; end: number } | null>(null);\n\n // Detect a slash word at the cursor position.\n // Returns the filter text (characters after \"/\") and the range of the\n // slash word within the full input text, or null if no slash word found.\n const getSlashText = useCallback((): {\n kind: SlashCompletionKind;\n text: string;\n start: number;\n end: number;\n } | null => {\n const element = chatInputRef.current;\n if (!element) return null;\n\n // Strip trailing newlines that contentEditable can produce, but preserve\n // spaces so \"/command \" (after selection) won't re-trigger the menu.\n const text = (element.innerText || \"\").replace(/[\\n\\r]+$/, \"\");\n const cursor = getCursorOffset(element);\n if (cursor < 0) return null;\n\n const textBeforeCursor = text.slice(0, cursor);\n\n const modelMatch = textBeforeCursor.match(/(^|\\s)(\\/model(?:\\s+\\S*)?)$/);\n if (modelMatch) {\n const modelCommand = modelMatch[2];\n const start = textBeforeCursor.length - modelCommand.length;\n const afterCursor = text.slice(cursor);\n const trailing = afterCursor.match(/^\\S*/);\n const end = cursor + (trailing ? trailing[0].length : 0);\n\n return {\n kind: \"model-profile\",\n text: modelCommand.replace(/^\\/model(?:\\s+)?/, \"\"),\n start,\n end,\n };\n }\n\n // Match a \"/\" preceded by whitespace or at position 0, followed by\n // non-whitespace characters, ending right at the cursor.\n const match = textBeforeCursor.match(/(^|\\s)(\\/\\S*)$/);\n if (!match) return null;\n\n const slashWord = match[2]; // e.g. \"/hel\"\n const start = textBeforeCursor.length - slashWord.length;\n // The end of the slash word extends past the cursor to include any\n // contiguous non-whitespace characters (covers the case where the\n // cursor sits in the middle of a word).\n const afterCursor = text.slice(cursor);\n const trailing = afterCursor.match(/^\\S*/);\n const end = cursor + (trailing ? trailing[0].length : 0);\n\n return { kind: \"command\", text: slashWord.slice(1), start, end }; // strip leading \"/\"\n }, [chatInputRef]);\n\n // Update the menu state based on current input\n const updateSlashMenu = useCallback(() => {\n const result = getSlashText();\n const hasItems =\n result?.kind === \"model-profile\"\n ? modelProfileItems.length > 0 || isProfilesLoading\n : slashItems.length > 0;\n\n if (result !== null && hasItems) {\n setCompletionKind(result.kind);\n setFilterText(result.text);\n slashRangeRef.current = { start: result.start, end: result.end };\n setIsMenuOpen(true);\n } else {\n setIsMenuOpen(false);\n setFilterText(\"\");\n setCompletionKind(\"command\");\n slashRangeRef.current = null;\n }\n }, [\n getSlashText,\n isProfilesLoading,\n modelProfileItems.length,\n slashItems.length,\n ]);\n\n // Select an item and replace only the slash word with the command\n const selectItem = useCallback(\n (item: SlashCommandItem) => {\n const element = chatInputRef.current;\n if (!element) return;\n\n const slashRange = slashRangeRef.current;\n const currentText = (element.innerText || \"\").replace(/[\\n\\r]+$/, \"\");\n const replacement = `${item.command} `;\n\n if (slashRange) {\n // Splice the command into the text, replacing only the slash word\n element.textContent =\n currentText.slice(0, slashRange.start) +\n replacement +\n currentText.slice(slashRange.end);\n\n // Position cursor right after the inserted command + space\n const cursorPos = slashRange.start + replacement.length;\n const textNode = element.firstChild;\n if (textNode) {\n const range = document.createRange();\n const sel = window.getSelection();\n const offset = Math.min(cursorPos, textNode.textContent!.length);\n range.setStart(textNode, offset);\n range.collapse(true);\n sel?.removeAllRanges();\n sel?.addRange(range);\n }\n } else {\n // Fallback: replace everything (e.g. if range tracking failed)\n element.textContent = replacement;\n const range = document.createRange();\n const sel = window.getSelection();\n range.selectNodeContents(element);\n range.collapse(false);\n sel?.removeAllRanges();\n sel?.addRange(range);\n }\n\n setIsMenuOpen(false);\n setFilterText(\"\");\n setCompletionKind(\"command\");\n setSelectedIndex(0);\n slashRangeRef.current = null;\n\n // Trigger a native InputEvent so React's onInput fires (for smartResize etc.)\n element.dispatchEvent(new InputEvent(\"input\", { bubbles: true }));\n\n // Restore focus so keyboard events (Enter to submit) work after selection\n element.focus();\n },\n [chatInputRef],\n );\n\n // Handle keyboard navigation in the menu.\n // Uses refs to always read the latest state, avoiding stale closures.\n const handleSlashKeyDown = useCallback(\n (e: React.KeyboardEvent): boolean => {\n const items = filteredItemsRef.current;\n if (!isMenuOpenRef.current || items.length === 0) return false;\n\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n setSelectedIndex((prev) => (prev < items.length - 1 ? prev + 1 : 0));\n return true;\n case \"ArrowUp\":\n e.preventDefault();\n setSelectedIndex((prev) => (prev > 0 ? prev - 1 : items.length - 1));\n return true;\n case \"Enter\":\n case \"Tab\": {\n const item = items[selectedIndexRef.current];\n if (!item) return false;\n e.preventDefault();\n selectItem(item);\n return true;\n }\n case \"Escape\":\n e.preventDefault();\n setIsMenuOpen(false);\n return true;\n // Cursor-movement keys: close the menu to avoid acting on a stale\n // slash-word range, but don't consume the event so the cursor moves.\n case \"ArrowLeft\":\n case \"ArrowRight\":\n case \"Home\":\n case \"End\":\n setIsMenuOpen(false);\n return false;\n default:\n return false;\n }\n },\n [selectItem],\n );\n\n const closeMenu = useCallback(() => setIsMenuOpen(false), []);\n\n return {\n isMenuOpen,\n filteredItems,\n selectedIndex,\n updateSlashMenu,\n selectItem,\n handleSlashKeyDown,\n closeMenu,\n };\n};\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ require("../../_virtual/_rolldown/runtime.cjs");const e=require("../../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs"),t=require("../../node_modules/@tanstack/react-query/build/modern/useMutation.cjs"),n=require("../../api/conversation-service/agent-server-conversation-service.api.cjs");var r=()=>{let r=e.useQueryClient();return t.useMutation({mutationFn:e=>n.default.condenseConversation(e.conversationId,e.conversationUrl,e.sessionApiKey),onSettled:(e,t,n)=>{r.invalidateQueries({queryKey:[`conversation-metrics`,n.conversationId]})}})};exports.useCondenseConversation=r;
2
+ //# sourceMappingURL=use-condense-conversation.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-condense-conversation.cjs","names":[],"sources":["../../../src/hooks/mutation/use-condense-conversation.ts"],"sourcesContent":["import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport AgentServerConversationService from \"#/api/conversation-service/agent-server-conversation-service.api\";\n\ninterface CondenseConversationVariables {\n conversationId: string;\n conversationUrl: string | null;\n sessionApiKey: string | null;\n}\n\n/**\n * Manually compact (\"condense\") a conversation's context via\n * `POST /api/conversations/{id}/condense`. Refreshes the usage metrics\n * afterwards so the context meter reflects the shrunken history.\n */\nexport const useCondenseConversation = () => {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (variables: CondenseConversationVariables) =>\n AgentServerConversationService.condenseConversation(\n variables.conversationId,\n variables.conversationUrl,\n variables.sessionApiKey,\n ),\n onSettled: (_, __, variables) => {\n queryClient.invalidateQueries({\n queryKey: [\"conversation-metrics\", variables.conversationId],\n });\n },\n });\n};\n"],"mappings":"0TAcA,IAAa,MAAgC,CAC3C,IAAM,EAAc,EAAA,eAAe,EAEnC,OAAO,EAAA,YAAY,CACjB,WAAa,GACX,EAAA,QAA+B,qBAC7B,EAAU,eACV,EAAU,gBACV,EAAU,aACZ,EACF,WAAY,EAAG,EAAI,IAAc,CAC/B,EAAY,kBAAkB,CAC5B,SAAU,CAAC,uBAAwB,EAAU,cAAc,CAC7D,CAAC,CACH,CACF,CAAC,CACH"}
@@ -0,0 +1,12 @@
1
+ interface CondenseConversationVariables {
2
+ conversationId: string;
3
+ conversationUrl: string | null;
4
+ sessionApiKey: string | null;
5
+ }
6
+ /**
7
+ * Manually compact ("condense") a conversation's context via
8
+ * `POST /api/conversations/{id}/condense`. Refreshes the usage metrics
9
+ * afterwards so the context meter reflects the shrunken history.
10
+ */
11
+ export declare const useCondenseConversation: () => import("@tanstack/react-query").UseMutationResult<void, import("axios").AxiosError<unknown, any>, CondenseConversationVariables, unknown>;
12
+ export {};
@@ -0,0 +1,17 @@
1
+ import { useQueryClient as e } from "../../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js";
2
+ import { useMutation as t } from "../../node_modules/@tanstack/react-query/build/modern/useMutation.js";
3
+ import n from "../../api/conversation-service/agent-server-conversation-service.api.js";
4
+ //#region src/hooks/mutation/use-condense-conversation.ts
5
+ var r = () => {
6
+ let r = e();
7
+ return t({
8
+ mutationFn: (e) => n.condenseConversation(e.conversationId, e.conversationUrl, e.sessionApiKey),
9
+ onSettled: (e, t, n) => {
10
+ r.invalidateQueries({ queryKey: ["conversation-metrics", n.conversationId] });
11
+ }
12
+ });
13
+ };
14
+ //#endregion
15
+ export { r as useCondenseConversation };
16
+
17
+ //# sourceMappingURL=use-condense-conversation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-condense-conversation.js","names":[],"sources":["../../../src/hooks/mutation/use-condense-conversation.ts"],"sourcesContent":["import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport AgentServerConversationService from \"#/api/conversation-service/agent-server-conversation-service.api\";\n\ninterface CondenseConversationVariables {\n conversationId: string;\n conversationUrl: string | null;\n sessionApiKey: string | null;\n}\n\n/**\n * Manually compact (\"condense\") a conversation's context via\n * `POST /api/conversations/{id}/condense`. Refreshes the usage metrics\n * afterwards so the context meter reflects the shrunken history.\n */\nexport const useCondenseConversation = () => {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (variables: CondenseConversationVariables) =>\n AgentServerConversationService.condenseConversation(\n variables.conversationId,\n variables.conversationUrl,\n variables.sessionApiKey,\n ),\n onSettled: (_, __, variables) => {\n queryClient.invalidateQueries({\n queryKey: [\"conversation-metrics\", variables.conversationId],\n });\n },\n });\n};\n"],"mappings":";;;;AAcA,IAAa,UAAgC;CAC3C,IAAM,IAAc,EAAe;CAEnC,OAAO,EAAY;EACjB,aAAa,MACX,EAA+B,qBAC7B,EAAU,gBACV,EAAU,iBACV,EAAU,aACZ;EACF,YAAY,GAAG,GAAI,MAAc;GAC/B,EAAY,kBAAkB,EAC5B,UAAU,CAAC,wBAAwB,EAAU,cAAc,EAC7D,CAAC;EACH;CACF,CAAC;AACH"}
@@ -1,2 +1,2 @@
1
- require("../../_virtual/_rolldown/runtime.cjs");const e=require("../query/query-keys.cjs"),t=require("../../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs"),n=require("../../node_modules/@tanstack/react-query/build/modern/useMutation.cjs"),r=require("../../contexts/active-backend-context.cjs"),i=require("../../api/conversation-metadata-store.cjs"),a=require("../../api/profiles-service/profiles-service.api.cjs"),o=require("../../api/conversation-service/agent-server-conversation-service.api.cjs"),s=require("../use-tracking.cjs"),c=require("../query/use-llm-profiles.cjs"),l=require("../../api/agent-profiles-service/agent-profiles-service.api.cjs"),u=require("../query/use-agent-profiles.cjs"),d=require("../../api/plugins-management-service.cjs"),f=require("../../utils/plugin-display.cjs");var p=[`create-conversation`],m=()=>{let m=t.useQueryClient(),{trackConversationCreated:h}=s.useTracking(),{data:g}=c.useLlmProfiles(),{backend:_,orgId:v}=r.useActiveBackend();return u.useAgentProfiles(),n.useMutation({mutationKey:p,mutationFn:async t=>{let{query:n,conversationInstructions:r,plugins:s,repository:c,workingDir:u,workspaceMode:p,parentConversationId:h,agentType:y,agentProfileId:b}=t,x;try{x=await m.ensureQueryData({queryKey:[...e.AGENT_PROFILES_QUERY_KEYS.all,_.id,v],queryFn:l.default.listProfiles,...e.AGENT_PROFILES_RETRY_OPTIONS})}catch{}let S=b??x?.active_agent_profile_id??void 0,C=S?x?.profiles?.find(e=>e.id===S):void 0,w=_.kind===`cloud`,T=S;if(!w&&C?.name==="default"&&C?.agent_kind===`openhands`)T=void 0;else if(C?.agent_kind===`openhands`&&C.llm_profile_ref){let t=!1;try{t=(await m.ensureQueryData({queryKey:[...e.LLM_PROFILES_QUERY_KEYS.all,_.id,v],queryFn:a.default.listProfiles,retry:!1})).profiles.some(e=>e.name===C.llm_profile_ref)}catch{}t||(console.warn(`Agent profile "${C.name}" references missing LLM profile "${C.llm_profile_ref}"; launching from agent_settings instead.`),T=void 0)}let E=T?[void 0,T,C?.agent_kind]:[],D=await o.default.createConversation(n,r,s,c?{selected_repository:c.name,selected_branch:c.branch??null,git_provider:c.gitProvider}:null,u,p,h,y,...E),O=D.app_conversation_id,k=s?.map(i.toPluginCoordinates)??[],A=k;if(O){let t=[];try{t=await m.ensureQueryData({queryKey:e.PLUGINS_QUERY_KEYS.installed,queryFn:()=>d.default.listInstalledPlugins()})}catch{}let n=new Set(k.map(f.pluginReferenceKey)),r=t.filter(e=>e.enabled).map(e=>({source:e.source,ref:e.resolved_ref??null,repo_path:e.repo_path??null,name:e.name})).filter(e=>!n.has(f.pluginReferenceKey(e)));A=[...k,...r]}let j=T&&C?.agent_kind===`openhands`?C.llm_profile_ref:g?.active_profile??null;if(O&&(j||A.length)){let e=i.getStoredConversationMetadata(O);i.setStoredConversationMetadata(O,{selected_repository:e?.selected_repository??null,selected_branch:e?.selected_branch??null,git_provider:e?.git_provider??null,selected_workspace:e?.selected_workspace??null,workspace_mode:e?.workspace_mode??null,active_profile:j??e?.active_profile??null,plugins:A.length?A:e?.plugins??null})}return{conversation_id:D.app_conversation_id?D.app_conversation_id:`task-${D.id}`,session_api_key:null,url:D.agent_server_url,task_id:D.id}},onSuccess:async(e,t)=>{h({conversationId:e.conversation_id,taskId:e.task_id,hasRepository:!!t.repository,gitProvider:t.repository?.gitProvider,hasWorkspace:!!t.workingDir,workspaceMode:t.workspaceMode,hasInitialQuery:!!t.query,agentType:t.agentType,hasParentConversation:!!t.parentConversationId,entryPoint:t.entryPoint}),m.invalidateQueries({queryKey:[`user`,`conversations`]}),m.invalidateQueries({queryKey:[`start-tasks`]})}})};exports.CREATE_CONVERSATION_MUTATION_KEY=p,exports.useCreateConversation=m;
1
+ require("../../_virtual/_rolldown/runtime.cjs");const e=require("../query/query-keys.cjs"),t=require("../../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs"),n=require("../../node_modules/@tanstack/react-query/build/modern/useMutation.cjs"),r=require("../../contexts/active-backend-context.cjs"),i=require("../../api/conversation-metadata-store.cjs"),a=require("../../api/profiles-service/profiles-service.api.cjs"),o=require("../../api/conversation-service/agent-server-conversation-service.api.cjs"),s=require("../use-tracking.cjs"),c=require("../query/use-llm-profiles.cjs"),l=require("../../api/agent-profiles-service/agent-profiles-service.api.cjs"),u=require("../query/use-agent-profiles.cjs"),d=require("../../api/plugins-management-service.cjs"),f=require("../../utils/plugin-display.cjs");var p=[`create-conversation`],m=()=>{let m=t.useQueryClient(),{trackConversationCreated:h}=s.useTracking(),{data:g}=c.useLlmProfiles(),{backend:_,orgId:v}=r.useActiveBackend();return u.useAgentProfiles(),n.useMutation({mutationKey:p,mutationFn:async t=>{let{query:n,conversationInstructions:r,plugins:s,repository:c,workingDir:u,workspaceMode:p,parentConversationId:h,agentType:y,agentProfileId:b}=t,x;try{x=await m.ensureQueryData({queryKey:[...e.AGENT_PROFILES_QUERY_KEYS.all,_.id,v],queryFn:l.default.listProfiles,...e.AGENT_PROFILES_RETRY_OPTIONS})}catch{}let S=b??x?.active_agent_profile_id??void 0,C=S?x?.profiles?.find(e=>e.id===S):void 0,w=_.kind===`cloud`,T=S;if(!w&&C?.name==="default"&&C?.agent_kind===`openhands`)T=void 0;else if(C?.agent_kind===`openhands`&&C.llm_profile_ref){let t=!1;try{t=(await m.ensureQueryData({queryKey:[...e.LLM_PROFILES_QUERY_KEYS.all,_.id,v],queryFn:a.default.listProfiles,retry:!1})).profiles.some(e=>e.name===C.llm_profile_ref)}catch{}t||(console.warn(`Agent profile "${C.name}" references missing LLM profile "${C.llm_profile_ref}"; launching from agent_settings instead.`),T=void 0)}let E=await o.default.createConversation({initialUserMsg:n,conversationInstructions:r,plugins:s,metadata:c?{selected_repository:c.name,selected_branch:c.branch??null,git_provider:c.gitProvider}:null,workingDirOverride:u,workspaceMode:p,parentConversationId:h,agentType:y,...T?{agentProfileId:T,agentProfileKind:C?.agent_kind}:{}}),D=E.app_conversation_id,O=s?.map(i.toPluginCoordinates)??[],k=O;if(D){let t=[];try{t=await m.ensureQueryData({queryKey:e.PLUGINS_QUERY_KEYS.installed,queryFn:()=>d.default.listInstalledPlugins()})}catch{}let n=new Set(O.map(f.pluginReferenceKey)),r=t.filter(e=>e.enabled).map(e=>({source:e.source,ref:e.resolved_ref??null,repo_path:e.repo_path??null,name:e.name})).filter(e=>!n.has(f.pluginReferenceKey(e)));k=[...O,...r]}let A=T&&C?.agent_kind===`openhands`?C.llm_profile_ref:g?.active_profile??null;if(D&&(A||k.length)){let e=i.getStoredConversationMetadata(D);i.setStoredConversationMetadata(D,{selected_repository:e?.selected_repository??null,selected_branch:e?.selected_branch??null,git_provider:e?.git_provider??null,selected_workspace:e?.selected_workspace??null,workspace_mode:e?.workspace_mode??null,active_profile:A??e?.active_profile??null,plugins:k.length?k:e?.plugins??null})}return{conversation_id:E.app_conversation_id?E.app_conversation_id:`task-${E.id}`,session_api_key:null,url:E.agent_server_url,task_id:E.id}},onSuccess:async(e,t)=>{h({conversationId:e.conversation_id,taskId:e.task_id,hasRepository:!!t.repository,gitProvider:t.repository?.gitProvider,hasWorkspace:!!t.workingDir,workspaceMode:t.workspaceMode,hasInitialQuery:!!t.query,agentType:t.agentType,hasParentConversation:!!t.parentConversationId,entryPoint:t.entryPoint}),m.invalidateQueries({queryKey:[`user`,`conversations`]}),m.invalidateQueries({queryKey:[`start-tasks`]})}})};exports.CREATE_CONVERSATION_MUTATION_KEY=p,exports.useCreateConversation=m;
2
2
  //# sourceMappingURL=use-create-conversation.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-create-conversation.cjs","names":[],"sources":["../../../src/hooks/mutation/use-create-conversation.ts"],"sourcesContent":["import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport AgentServerConversationService from \"#/api/conversation-service/agent-server-conversation-service.api\";\nimport { PluginSpec } from \"#/api/conversation-service/agent-server-conversation-service.types\";\nimport { SuggestedTask } from \"#/utils/types\";\nimport { AgentKind, Provider } from \"#/types/settings\";\nimport { useTracking } from \"#/hooks/use-tracking\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\nimport { useAgentProfiles } from \"#/hooks/query/use-agent-profiles\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport ProfilesService from \"#/api/profiles-service/profiles-service.api\";\nimport AgentProfilesService, {\n WELL_KNOWN_DEFAULT_AGENT_PROFILE_NAME,\n type AgentProfileListResponse,\n} from \"#/api/agent-profiles-service/agent-profiles-service.api\";\nimport PluginsManagementService, {\n type InstalledPluginInfo,\n} from \"#/api/plugins-management-service\";\nimport {\n PLUGINS_QUERY_KEYS,\n LLM_PROFILES_QUERY_KEYS,\n AGENT_PROFILES_QUERY_KEYS,\n AGENT_PROFILES_RETRY_OPTIONS,\n} from \"#/hooks/query/query-keys\";\nimport { pluginReferenceKey } from \"#/utils/plugin-display\";\nimport {\n getStoredConversationMetadata,\n setStoredConversationMetadata,\n toPluginCoordinates,\n type WorkspaceMode,\n} from \"#/api/conversation-metadata-store\";\n\nexport interface CreateConversationVariables {\n query?: string;\n repository?: {\n name: string;\n gitProvider: Provider;\n branch?: string;\n };\n suggestedTask?: SuggestedTask;\n conversationInstructions?: string;\n parentConversationId?: string;\n agentType?: \"default\" | \"plan\";\n plugins?: PluginSpec[];\n workingDir?: string;\n workspaceMode?: WorkspaceMode;\n // Launch from a specific AgentProfile (local backend). When omitted, the\n // active AgentProfile (if any) is used so home-composed conversations\n // launch from the user's selected profile (#3727).\n agentProfileId?: string;\n entryPoint?: string; // analytics only; not forwarded to the service\n}\n\nexport const CREATE_CONVERSATION_MUTATION_KEY = [\"create-conversation\"];\n\ninterface CreateConversationResponse {\n conversation_id: string;\n session_api_key: string | null;\n url: string | null;\n task_id?: string;\n}\n\nexport const useCreateConversation = () => {\n const queryClient = useQueryClient();\n const { trackConversationCreated } = useTracking();\n // Cache-warm on the home page (the profile picker reads the same query).\n // Stamped onto the conversation at creation so the switcher can show the\n // exact profile even when several profiles share a model (#1082).\n const { data: llmProfiles } = useLlmProfiles();\n // Warm the agent-profiles cache too — the launch path below awaits the same\n // query via ensureQueryData, so a warm cache makes home-launch instant. The\n // hook's maybe-unresolved data is deliberately NOT read at launch time:\n // activation is pointer-only (it never writes agent_settings), so racing a\n // cold cache into the agent_settings fallback would silently launch the\n // wrong agent.\n const { backend, orgId } = useActiveBackend();\n useAgentProfiles();\n\n return useMutation({\n mutationKey: CREATE_CONVERSATION_MUTATION_KEY,\n mutationFn: async (\n variables: CreateConversationVariables,\n ): Promise<CreateConversationResponse> => {\n const {\n query,\n conversationInstructions,\n plugins,\n repository,\n workingDir,\n workspaceMode,\n parentConversationId,\n agentType,\n agentProfileId,\n } = variables;\n\n // The active AgentProfile is the default launch profile for new\n // conversations (#3727), on both local and cloud (cloud gained\n // /api/agent-profiles in OpenHands #15060, #3730). Await the list from\n // the shared query cache: a send fired before the home query resolves\n // must still launch from the active profile, not fall through to the\n // agent_settings path. Degrades safely: if the fetch errors (older\n // backend without the surface), this stays undefined and creation falls\n // back to the encrypted agent_settings launch path.\n let agentProfiles: AgentProfileListResponse | undefined;\n try {\n agentProfiles = await queryClient.ensureQueryData({\n queryKey: [...AGENT_PROFILES_QUERY_KEYS.all, backend.id, orgId],\n queryFn: AgentProfilesService.listProfiles,\n ...AGENT_PROFILES_RETRY_OPTIONS,\n });\n } catch {\n // Profiles unavailable → legacy agent_settings launch.\n }\n\n const requestedAgentProfileId =\n agentProfileId ?? agentProfiles?.active_agent_profile_id ?? undefined;\n\n // Fall back to the legacy agent_settings launch when the resolved agent\n // profile can't resolve its LLM. The agent-server seeds a `default`\n // openhands profile whose `llm_profile_ref` can point at an LLM profile\n // that doesn't exist (fresh store, or one configured with named profiles\n // only); launching from it 404s (\"LLM profile '<ref>' not found\") and\n // would brick home-launch. agent_settings reflects the active LLM, so the\n // fallback degrades cleanly until the seed mirrors it (SDK #3933).\n // ACP profiles carry no llm_profile_ref, so they're never gated here.\n const resolvedAgentProfile = requestedAgentProfileId\n ? agentProfiles?.profiles?.find(\n (profile) => profile.id === requestedAgentProfileId,\n )\n : undefined;\n // Cloud has no `agent_settings` payload to fall back to — the downgrade\n // below only makes sense on local, where it exists and carries the\n // canvas-only enrichments. Gating it here keeps cloud always launching\n // from the resolved profile id, so the conversation gets\n // `launched_agent_profile` stamped and the profile's config applied\n // (#1571 review).\n const isCloud = backend.kind === \"cloud\";\n let effectiveAgentProfileId = requestedAgentProfileId;\n if (\n !isCloud &&\n resolvedAgentProfile?.name === WELL_KNOWN_DEFAULT_AGENT_PROFILE_NAME &&\n resolvedAgentProfile?.agent_kind === \"openhands\"\n ) {\n // The seeded OpenHands `default` profile is the enriched baseline, not a\n // deliberate profile pick — it mirrors global agent_settings. Launch it\n // via agent_settings so the canvas-only enrichments the profile-resolution\n // path drops survive for the common home-launch: the <RUNTIME_SERVICES>\n // system-message suffix and project-skill loading (buildAgentContext).\n // Named profiles are deliberate custom configs and still use the profile\n // path (accepting that enrichment boundary).\n // Trade-off: per-profile fields set on `default` itself don't apply on\n // home-launch — custom per-profile config belongs in a named profile.\n //\n // Scoped to OpenHands: an ACP `default` must keep the profile path.\n // Activation is pointer-only, so global agent_settings is stale (often\n // still OpenHands) when an ACP profile is active — launching it via\n // agent_settings would start the wrong agent. ACP carries no\n // <RUNTIME_SERVICES> enrichment, so there's nothing to preserve.\n //\n // Scoped to local: cloud never writes agent_settings, so it always\n // resolves `default` server-side via agent_profile_id (validated below).\n effectiveAgentProfileId = undefined;\n } else if (\n resolvedAgentProfile?.agent_kind === \"openhands\" &&\n resolvedAgentProfile.llm_profile_ref\n ) {\n // Await the LLM-profile list rather than reading the maybe-unresolved\n // `useLlmProfiles()` result: a send fired before that query loads (or\n // after it errors) must still validate the ref, not launch blind.\n let llmProfileExists = false;\n try {\n const llm = await queryClient.ensureQueryData({\n queryKey: [...LLM_PROFILES_QUERY_KEYS.all, backend.id, orgId],\n queryFn: ProfilesService.listProfiles,\n // Match the agent-profiles fetch above: on a backend where this\n // errors, fall back to agent_settings immediately rather than\n // stalling the send through the default exponential backoff.\n retry: false,\n });\n llmProfileExists = llm.profiles.some(\n (profile) => profile.name === resolvedAgentProfile.llm_profile_ref,\n );\n } catch {\n // List unavailable → can't validate → fall back to agent_settings.\n }\n if (!llmProfileExists) {\n // Downgrade is silent in the UI; leave a diagnosable trace.\n console.warn(\n `Agent profile \"${resolvedAgentProfile.name}\" references missing ` +\n `LLM profile \"${resolvedAgentProfile.llm_profile_ref}\"; ` +\n \"launching from agent_settings instead.\",\n );\n effectiveAgentProfileId = undefined;\n }\n }\n\n // Only extend the call with the profile tail when launching from a\n // profile, so a plain create stays byte-identical to the legacy\n // agent_settings path (#3727). sandboxId is unused here.\n // TODO(#1587): createConversation has grown to 11 positional params;\n // refactor it to an options object so this position-skipping tail isn't\n // needed.\n const profileArgs: [undefined, string, AgentKind | undefined] | [] =\n effectiveAgentProfileId\n ? [\n undefined,\n effectiveAgentProfileId,\n resolvedAgentProfile?.agent_kind,\n ]\n : [];\n\n const conversation =\n await AgentServerConversationService.createConversation(\n query,\n conversationInstructions,\n plugins,\n repository\n ? {\n selected_repository: repository.name,\n selected_branch: repository.branch ?? null,\n git_provider: repository.gitProvider,\n }\n : null,\n workingDir,\n workspaceMode,\n parentConversationId,\n agentType,\n ...profileArgs,\n );\n\n // Stamp the active LLM profile onto the (local) conversation so the\n // chat switcher shows the exact profile even when several profiles\n // share a model (#1082). Cloud conversations don't use local profiles\n // (app_conversation_id stays null until the sandbox is READY). Merge so\n // the repo/workspace metadata the service just persisted is preserved.\n const localConversationId = conversation.app_conversation_id;\n // Snapshot the conversation's plugins into client-side metadata so the\n // in-conversation plugins view can show what's loaded (coordinates only\n // — strip parameters, which may carry secrets). The agent-server doesn't\n // return a live conversation's loaded plugins, so this snapshot is the\n // source for that view. Two sources, deduped by coordinates:\n // 1. plugins explicitly attached at creation (e.g. the /launch flow);\n // 2. enabled installed plugins, which the SDK auto-loads into every new\n // local conversation (see use-set-plugin-enabled).\n const explicitPlugins = plugins?.map(toPluginCoordinates) ?? [];\n let attachedPlugins: PluginSpec[] = explicitPlugins;\n if (localConversationId) {\n let installed: InstalledPluginInfo[] = [];\n try {\n installed = await queryClient.ensureQueryData({\n queryKey: PLUGINS_QUERY_KEYS.installed,\n queryFn: () => PluginsManagementService.listInstalledPlugins(),\n });\n } catch {\n // Best-effort: never let plugin lookup block conversation creation.\n }\n const seen = new Set(explicitPlugins.map(pluginReferenceKey));\n const enabledInstalled = installed\n .filter((plugin) => plugin.enabled)\n .map((plugin) => ({\n source: plugin.source,\n ref: plugin.resolved_ref ?? null,\n repo_path: plugin.repo_path ?? null,\n // Keep the human-friendly name so the plugins view shows e.g.\n // \"city-weather\" rather than deriving \"local\" from the source.\n name: plugin.name,\n }))\n .filter((plugin) => !seen.has(pluginReferenceKey(plugin)));\n attachedPlugins = [...explicitPlugins, ...enabledInstalled];\n }\n // A launch from a named OpenHands profile runs that profile's\n // `llm_profile_ref`, which can differ from the standalone active LLM\n // profile — stamp the ref so the switcher pill names the exact profile\n // the conversation runs (#1082). The agent_settings path (the `default`\n // baseline or a dangling ref, where effectiveAgentProfileId is cleared)\n // runs the active LLM, so it keeps `active_profile`. ACP profiles carry\n // no LLM profile, so they fall through to the active-profile stamp\n // (unused by the ACP model chip).\n const activeProfile =\n effectiveAgentProfileId &&\n resolvedAgentProfile?.agent_kind === \"openhands\"\n ? resolvedAgentProfile.llm_profile_ref\n : (llmProfiles?.active_profile ?? null);\n if (localConversationId && (activeProfile || attachedPlugins.length)) {\n const prev = getStoredConversationMetadata(localConversationId);\n setStoredConversationMetadata(localConversationId, {\n selected_repository: prev?.selected_repository ?? null,\n selected_branch: prev?.selected_branch ?? null,\n git_provider: prev?.git_provider ?? null,\n selected_workspace: prev?.selected_workspace ?? null,\n workspace_mode: prev?.workspace_mode ?? null,\n active_profile: activeProfile ?? prev?.active_profile ?? null,\n plugins: attachedPlugins.length\n ? attachedPlugins\n : (prev?.plugins ?? null),\n });\n }\n\n // OpenHands cloud pattern: when the start task isn't immediately\n // READY (cloud sandbox is still provisioning),\n // app_conversation_id is null. We return a `task-{id}` URL so the\n // conversation route's useTaskPolling can drive it to READY and\n // then redirect to the real `/conversations/{app_conversation_id}`.\n const conversationId = conversation.app_conversation_id\n ? conversation.app_conversation_id\n : `task-${conversation.id}`;\n\n return {\n conversation_id: conversationId,\n session_api_key: null,\n url: conversation.agent_server_url,\n task_id: conversation.id,\n };\n },\n onSuccess: async (data, variables) => {\n trackConversationCreated({\n conversationId: data.conversation_id,\n taskId: data.task_id,\n hasRepository: !!variables.repository,\n gitProvider: variables.repository?.gitProvider,\n hasWorkspace: !!variables.workingDir,\n workspaceMode: variables.workspaceMode,\n hasInitialQuery: !!variables.query,\n agentType: variables.agentType,\n hasParentConversation: !!variables.parentConversationId,\n entryPoint: variables.entryPoint,\n });\n\n // Invalidate (rather than remove) so the existing paginated list stays\n // rendered while a background refetch picks up the new conversation.\n // `removeQueries` would wipe the cache and force the panel back to its\n // initial loading state, dropping loaded pages and scroll position.\n queryClient.invalidateQueries({\n queryKey: [\"user\", \"conversations\"],\n });\n // The cloud path returns a start task (no app_conversation_id\n // yet); the sidebar surfaces those via `useStartTasks` which doesn't\n // poll, so invalidate it explicitly so the in-flight task shows up\n // in the conversation list immediately.\n queryClient.invalidateQueries({\n queryKey: [\"start-tasks\"],\n });\n },\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-create-conversation.cjs","names":[],"sources":["../../../src/hooks/mutation/use-create-conversation.ts"],"sourcesContent":["import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport AgentServerConversationService from \"#/api/conversation-service/agent-server-conversation-service.api\";\nimport { PluginSpec } from \"#/api/conversation-service/agent-server-conversation-service.types\";\nimport { SuggestedTask } from \"#/utils/types\";\nimport { Provider } from \"#/types/settings\";\nimport { useTracking } from \"#/hooks/use-tracking\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\nimport { useAgentProfiles } from \"#/hooks/query/use-agent-profiles\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport ProfilesService from \"#/api/profiles-service/profiles-service.api\";\nimport AgentProfilesService, {\n WELL_KNOWN_DEFAULT_AGENT_PROFILE_NAME,\n type AgentProfileListResponse,\n} from \"#/api/agent-profiles-service/agent-profiles-service.api\";\nimport PluginsManagementService, {\n type InstalledPluginInfo,\n} from \"#/api/plugins-management-service\";\nimport {\n PLUGINS_QUERY_KEYS,\n LLM_PROFILES_QUERY_KEYS,\n AGENT_PROFILES_QUERY_KEYS,\n AGENT_PROFILES_RETRY_OPTIONS,\n} from \"#/hooks/query/query-keys\";\nimport { pluginReferenceKey } from \"#/utils/plugin-display\";\nimport {\n getStoredConversationMetadata,\n setStoredConversationMetadata,\n toPluginCoordinates,\n type WorkspaceMode,\n} from \"#/api/conversation-metadata-store\";\n\nexport interface CreateConversationVariables {\n query?: string;\n repository?: {\n name: string;\n gitProvider: Provider;\n branch?: string;\n };\n suggestedTask?: SuggestedTask;\n conversationInstructions?: string;\n parentConversationId?: string;\n agentType?: \"default\" | \"plan\";\n plugins?: PluginSpec[];\n workingDir?: string;\n workspaceMode?: WorkspaceMode;\n // Launch from a specific AgentProfile (local backend). When omitted, the\n // active AgentProfile (if any) is used so home-composed conversations\n // launch from the user's selected profile (#3727).\n agentProfileId?: string;\n entryPoint?: string; // analytics only; not forwarded to the service\n}\n\nexport const CREATE_CONVERSATION_MUTATION_KEY = [\"create-conversation\"];\n\ninterface CreateConversationResponse {\n conversation_id: string;\n session_api_key: string | null;\n url: string | null;\n task_id?: string;\n}\n\nexport const useCreateConversation = () => {\n const queryClient = useQueryClient();\n const { trackConversationCreated } = useTracking();\n // Cache-warm on the home page (the profile picker reads the same query).\n // Stamped onto the conversation at creation so the switcher can show the\n // exact profile even when several profiles share a model (#1082).\n const { data: llmProfiles } = useLlmProfiles();\n // Warm the agent-profiles cache too — the launch path below awaits the same\n // query via ensureQueryData, so a warm cache makes home-launch instant. The\n // hook's maybe-unresolved data is deliberately NOT read at launch time:\n // activation is pointer-only (it never writes agent_settings), so racing a\n // cold cache into the agent_settings fallback would silently launch the\n // wrong agent.\n const { backend, orgId } = useActiveBackend();\n useAgentProfiles();\n\n return useMutation({\n mutationKey: CREATE_CONVERSATION_MUTATION_KEY,\n mutationFn: async (\n variables: CreateConversationVariables,\n ): Promise<CreateConversationResponse> => {\n const {\n query,\n conversationInstructions,\n plugins,\n repository,\n workingDir,\n workspaceMode,\n parentConversationId,\n agentType,\n agentProfileId,\n } = variables;\n\n // The active AgentProfile is the default launch profile for new\n // conversations (#3727), on both local and cloud (cloud gained\n // /api/agent-profiles in OpenHands #15060, #3730). Await the list from\n // the shared query cache: a send fired before the home query resolves\n // must still launch from the active profile, not fall through to the\n // agent_settings path. Degrades safely: if the fetch errors (older\n // backend without the surface), this stays undefined and creation falls\n // back to the encrypted agent_settings launch path.\n let agentProfiles: AgentProfileListResponse | undefined;\n try {\n agentProfiles = await queryClient.ensureQueryData({\n queryKey: [...AGENT_PROFILES_QUERY_KEYS.all, backend.id, orgId],\n queryFn: AgentProfilesService.listProfiles,\n ...AGENT_PROFILES_RETRY_OPTIONS,\n });\n } catch {\n // Profiles unavailable → legacy agent_settings launch.\n }\n\n const requestedAgentProfileId =\n agentProfileId ?? agentProfiles?.active_agent_profile_id ?? undefined;\n\n // Fall back to the legacy agent_settings launch when the resolved agent\n // profile can't resolve its LLM. The agent-server seeds a `default`\n // openhands profile whose `llm_profile_ref` can point at an LLM profile\n // that doesn't exist (fresh store, or one configured with named profiles\n // only); launching from it 404s (\"LLM profile '<ref>' not found\") and\n // would brick home-launch. agent_settings reflects the active LLM, so the\n // fallback degrades cleanly until the seed mirrors it (SDK #3933).\n // ACP profiles carry no llm_profile_ref, so they're never gated here.\n const resolvedAgentProfile = requestedAgentProfileId\n ? agentProfiles?.profiles?.find(\n (profile) => profile.id === requestedAgentProfileId,\n )\n : undefined;\n // Cloud has no `agent_settings` payload to fall back to — the downgrade\n // below only makes sense on local, where it exists and carries the\n // canvas-only enrichments. Gating it here keeps cloud always launching\n // from the resolved profile id, so the conversation gets\n // `launched_agent_profile` stamped and the profile's config applied\n // (#1571 review).\n const isCloud = backend.kind === \"cloud\";\n let effectiveAgentProfileId = requestedAgentProfileId;\n if (\n !isCloud &&\n resolvedAgentProfile?.name === WELL_KNOWN_DEFAULT_AGENT_PROFILE_NAME &&\n resolvedAgentProfile?.agent_kind === \"openhands\"\n ) {\n // The seeded OpenHands `default` profile is the enriched baseline, not a\n // deliberate profile pick — it mirrors global agent_settings. Launch it\n // via agent_settings so the canvas-only enrichments the profile-resolution\n // path drops survive for the common home-launch: the <RUNTIME_SERVICES>\n // system-message suffix and project-skill loading (buildAgentContext).\n // Named profiles are deliberate custom configs and still use the profile\n // path (accepting that enrichment boundary).\n // Trade-off: per-profile fields set on `default` itself don't apply on\n // home-launch — custom per-profile config belongs in a named profile.\n //\n // Scoped to OpenHands: an ACP `default` must keep the profile path.\n // Activation is pointer-only, so global agent_settings is stale (often\n // still OpenHands) when an ACP profile is active — launching it via\n // agent_settings would start the wrong agent. ACP carries no\n // <RUNTIME_SERVICES> enrichment, so there's nothing to preserve.\n //\n // Scoped to local: cloud never writes agent_settings, so it always\n // resolves `default` server-side via agent_profile_id (validated below).\n effectiveAgentProfileId = undefined;\n } else if (\n resolvedAgentProfile?.agent_kind === \"openhands\" &&\n resolvedAgentProfile.llm_profile_ref\n ) {\n // Await the LLM-profile list rather than reading the maybe-unresolved\n // `useLlmProfiles()` result: a send fired before that query loads (or\n // after it errors) must still validate the ref, not launch blind.\n let llmProfileExists = false;\n try {\n const llm = await queryClient.ensureQueryData({\n queryKey: [...LLM_PROFILES_QUERY_KEYS.all, backend.id, orgId],\n queryFn: ProfilesService.listProfiles,\n // Match the agent-profiles fetch above: on a backend where this\n // errors, fall back to agent_settings immediately rather than\n // stalling the send through the default exponential backoff.\n retry: false,\n });\n llmProfileExists = llm.profiles.some(\n (profile) => profile.name === resolvedAgentProfile.llm_profile_ref,\n );\n } catch {\n // List unavailable → can't validate → fall back to agent_settings.\n }\n if (!llmProfileExists) {\n // Downgrade is silent in the UI; leave a diagnosable trace.\n console.warn(\n `Agent profile \"${resolvedAgentProfile.name}\" references missing ` +\n `LLM profile \"${resolvedAgentProfile.llm_profile_ref}\"; ` +\n \"launching from agent_settings instead.\",\n );\n effectiveAgentProfileId = undefined;\n }\n }\n\n // Only extend the call with the profile fields when launching from a\n // profile, so a plain create stays byte-identical to the legacy\n // agent_settings path (#3727). sandboxId is unused here.\n const conversation =\n await AgentServerConversationService.createConversation({\n initialUserMsg: query,\n conversationInstructions,\n plugins,\n metadata: repository\n ? {\n selected_repository: repository.name,\n selected_branch: repository.branch ?? null,\n git_provider: repository.gitProvider,\n }\n : null,\n workingDirOverride: workingDir,\n workspaceMode,\n parentConversationId,\n agentType,\n ...(effectiveAgentProfileId\n ? {\n agentProfileId: effectiveAgentProfileId,\n agentProfileKind: resolvedAgentProfile?.agent_kind,\n }\n : {}),\n });\n\n // Stamp the active LLM profile onto the (local) conversation so the\n // chat switcher shows the exact profile even when several profiles\n // share a model (#1082). Cloud conversations don't use local profiles\n // (app_conversation_id stays null until the sandbox is READY). Merge so\n // the repo/workspace metadata the service just persisted is preserved.\n const localConversationId = conversation.app_conversation_id;\n // Snapshot the conversation's plugins into client-side metadata so the\n // in-conversation plugins view can show what's loaded (coordinates only\n // — strip parameters, which may carry secrets). The agent-server doesn't\n // return a live conversation's loaded plugins, so this snapshot is the\n // source for that view. Two sources, deduped by coordinates:\n // 1. plugins explicitly attached at creation (e.g. the /launch flow);\n // 2. enabled installed plugins, which the SDK auto-loads into every new\n // local conversation (see use-set-plugin-enabled).\n const explicitPlugins = plugins?.map(toPluginCoordinates) ?? [];\n let attachedPlugins: PluginSpec[] = explicitPlugins;\n if (localConversationId) {\n let installed: InstalledPluginInfo[] = [];\n try {\n installed = await queryClient.ensureQueryData({\n queryKey: PLUGINS_QUERY_KEYS.installed,\n queryFn: () => PluginsManagementService.listInstalledPlugins(),\n });\n } catch {\n // Best-effort: never let plugin lookup block conversation creation.\n }\n const seen = new Set(explicitPlugins.map(pluginReferenceKey));\n const enabledInstalled = installed\n .filter((plugin) => plugin.enabled)\n .map((plugin) => ({\n source: plugin.source,\n ref: plugin.resolved_ref ?? null,\n repo_path: plugin.repo_path ?? null,\n // Keep the human-friendly name so the plugins view shows e.g.\n // \"city-weather\" rather than deriving \"local\" from the source.\n name: plugin.name,\n }))\n .filter((plugin) => !seen.has(pluginReferenceKey(plugin)));\n attachedPlugins = [...explicitPlugins, ...enabledInstalled];\n }\n // A launch from a named OpenHands profile runs that profile's\n // `llm_profile_ref`, which can differ from the standalone active LLM\n // profile — stamp the ref so the switcher pill names the exact profile\n // the conversation runs (#1082). The agent_settings path (the `default`\n // baseline or a dangling ref, where effectiveAgentProfileId is cleared)\n // runs the active LLM, so it keeps `active_profile`. ACP profiles carry\n // no LLM profile, so they fall through to the active-profile stamp\n // (unused by the ACP model chip).\n const activeProfile =\n effectiveAgentProfileId &&\n resolvedAgentProfile?.agent_kind === \"openhands\"\n ? resolvedAgentProfile.llm_profile_ref\n : (llmProfiles?.active_profile ?? null);\n if (localConversationId && (activeProfile || attachedPlugins.length)) {\n const prev = getStoredConversationMetadata(localConversationId);\n setStoredConversationMetadata(localConversationId, {\n selected_repository: prev?.selected_repository ?? null,\n selected_branch: prev?.selected_branch ?? null,\n git_provider: prev?.git_provider ?? null,\n selected_workspace: prev?.selected_workspace ?? null,\n workspace_mode: prev?.workspace_mode ?? null,\n active_profile: activeProfile ?? prev?.active_profile ?? null,\n plugins: attachedPlugins.length\n ? attachedPlugins\n : (prev?.plugins ?? null),\n });\n }\n\n // OpenHands cloud pattern: when the start task isn't immediately\n // READY (cloud sandbox is still provisioning),\n // app_conversation_id is null. We return a `task-{id}` URL so the\n // conversation route's useTaskPolling can drive it to READY and\n // then redirect to the real `/conversations/{app_conversation_id}`.\n const conversationId = conversation.app_conversation_id\n ? conversation.app_conversation_id\n : `task-${conversation.id}`;\n\n return {\n conversation_id: conversationId,\n session_api_key: null,\n url: conversation.agent_server_url,\n task_id: conversation.id,\n };\n },\n onSuccess: async (data, variables) => {\n trackConversationCreated({\n conversationId: data.conversation_id,\n taskId: data.task_id,\n hasRepository: !!variables.repository,\n gitProvider: variables.repository?.gitProvider,\n hasWorkspace: !!variables.workingDir,\n workspaceMode: variables.workspaceMode,\n hasInitialQuery: !!variables.query,\n agentType: variables.agentType,\n hasParentConversation: !!variables.parentConversationId,\n entryPoint: variables.entryPoint,\n });\n\n // Invalidate (rather than remove) so the existing paginated list stays\n // rendered while a background refetch picks up the new conversation.\n // `removeQueries` would wipe the cache and force the panel back to its\n // initial loading state, dropping loaded pages and scroll position.\n queryClient.invalidateQueries({\n queryKey: [\"user\", \"conversations\"],\n });\n // The cloud path returns a start task (no app_conversation_id\n // yet); the sidebar surfaces those via `useStartTasks` which doesn't\n // poll, so invalidate it explicitly so the in-flight task shows up\n // in the conversation list immediately.\n queryClient.invalidateQueries({\n queryKey: [\"start-tasks\"],\n });\n },\n });\n};\n"],"mappings":"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"}
@@ -46,16 +46,25 @@ var v = ["create-conversation"], y = () => {
46
46
  } catch {}
47
47
  e || (console.warn(`Agent profile "${O.name}" references missing LLM profile "${O.llm_profile_ref}"; launching from agent_settings instead.`), A = void 0);
48
48
  }
49
- let j = A ? [
50
- void 0,
51
- A,
52
- O?.agent_kind
53
- ] : [], M = await d.createConversation(a, o, f, p ? {
54
- selected_repository: p.name,
55
- selected_branch: p.branch ?? null,
56
- git_provider: p.gitProvider
57
- } : null, h, v, b, w, ...j), N = M.app_conversation_id, P = f?.map(l) ?? [], F = P;
58
- if (N) {
49
+ let j = await d.createConversation({
50
+ initialUserMsg: a,
51
+ conversationInstructions: o,
52
+ plugins: f,
53
+ metadata: p ? {
54
+ selected_repository: p.name,
55
+ selected_branch: p.branch ?? null,
56
+ git_provider: p.gitProvider
57
+ } : null,
58
+ workingDirOverride: h,
59
+ workspaceMode: v,
60
+ parentConversationId: b,
61
+ agentType: w,
62
+ ...A ? {
63
+ agentProfileId: A,
64
+ agentProfileKind: O?.agent_kind
65
+ } : {}
66
+ }), M = j.app_conversation_id, N = f?.map(l) ?? [], P = N;
67
+ if (M) {
59
68
  let e = [];
60
69
  try {
61
70
  e = await y.ensureQueryData({
@@ -63,32 +72,32 @@ var v = ["create-conversation"], y = () => {
63
72
  queryFn: () => g.listInstalledPlugins()
64
73
  });
65
74
  } catch {}
66
- let t = new Set(P.map(_)), n = e.filter((e) => e.enabled).map((e) => ({
75
+ let t = new Set(N.map(_)), n = e.filter((e) => e.enabled).map((e) => ({
67
76
  source: e.source,
68
77
  ref: e.resolved_ref ?? null,
69
78
  repo_path: e.repo_path ?? null,
70
79
  name: e.name
71
80
  })).filter((e) => !t.has(_(e)));
72
- F = [...P, ...n];
81
+ P = [...N, ...n];
73
82
  }
74
- let I = A && O?.agent_kind === "openhands" ? O.llm_profile_ref : x?.active_profile ?? null;
75
- if (N && (I || F.length)) {
76
- let e = s(N);
77
- c(N, {
83
+ let F = A && O?.agent_kind === "openhands" ? O.llm_profile_ref : x?.active_profile ?? null;
84
+ if (M && (F || P.length)) {
85
+ let e = s(M);
86
+ c(M, {
78
87
  selected_repository: e?.selected_repository ?? null,
79
88
  selected_branch: e?.selected_branch ?? null,
80
89
  git_provider: e?.git_provider ?? null,
81
90
  selected_workspace: e?.selected_workspace ?? null,
82
91
  workspace_mode: e?.workspace_mode ?? null,
83
- active_profile: I ?? e?.active_profile ?? null,
84
- plugins: F.length ? F : e?.plugins ?? null
92
+ active_profile: F ?? e?.active_profile ?? null,
93
+ plugins: P.length ? P : e?.plugins ?? null
85
94
  });
86
95
  }
87
96
  return {
88
- conversation_id: M.app_conversation_id ? M.app_conversation_id : `task-${M.id}`,
97
+ conversation_id: j.app_conversation_id ? j.app_conversation_id : `task-${j.id}`,
89
98
  session_api_key: null,
90
- url: M.agent_server_url,
91
- task_id: M.id
99
+ url: j.agent_server_url,
100
+ task_id: j.id
92
101
  };
93
102
  },
94
103
  onSuccess: async (e, t) => {