@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 +1 @@
1
- {"version":3,"file":"use-create-conversation.js","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":";;;;;;;;;;;;;;AAoDA,IAAa,IAAmC,CAAC,qBAAqB,GASzD,UAA8B;CACzC,IAAM,IAAc,EAAe,GAC7B,EAAE,gCAA6B,EAAY,GAI3C,EAAE,MAAM,MAAgB,EAAe,GAOvC,EAAE,YAAS,aAAU,EAAiB;CAG5C,OAFA,EAAiB,GAEV,EAAY;EACjB,aAAa;EACb,YAAY,OACV,MACwC;GACxC,IAAM,EACJ,UACA,6BACA,YACA,eACA,eACA,kBACA,yBACA,cACA,sBACE,GAUA;GACJ,IAAI;IACF,IAAgB,MAAM,EAAY,gBAAgB;KAChD,UAAU;MAAC,GAAG,EAA0B;MAAK,EAAQ;MAAI;KAAK;KAC9D,SAAS,EAAqB;KAC9B,GAAG;IACL,CAAC;GACH,QAAQ,CAER;GAEA,IAAM,IACJ,KAAkB,GAAe,2BAA2B,KAAA,GAUxD,IAAuB,IACzB,GAAe,UAAU,MACtB,MAAY,EAAQ,OAAO,CAC9B,IACA,KAAA,GAOE,IAAU,EAAQ,SAAS,SAC7B,IAA0B;GAC9B,IACE,CAAC,KACD,GAAsB,SAAA,aACtB,GAAsB,eAAe,aAoBrC,IAA0B,KAAA;QACrB,IACL,GAAsB,eAAe,eACrC,EAAqB,iBACrB;IAIA,IAAI,IAAmB;IACvB,IAAI;KASF,KAAmB,MARD,EAAY,gBAAgB;MAC5C,UAAU;OAAC,GAAG,EAAwB;OAAK,EAAQ;OAAI;MAAK;MAC5D,SAAS,EAAgB;MAIzB,OAAO;KACT,CAAC,GACsB,SAAS,MAC7B,MAAY,EAAQ,SAAS,EAAqB,eACrD;IACF,QAAQ,CAER;IACA,AAAK,MAEH,QAAQ,KACN,kBAAkB,EAAqB,KAAK,oCAC1B,EAAqB,gBAAgB,0CAEzD,GACA,IAA0B,KAAA;GAE9B;GAQA,IAAM,IACJ,IACI;IACE,KAAA;IACA;IACA,GAAsB;GACxB,IACA,CAAC,GAED,IACJ,MAAM,EAA+B,mBACnC,GACA,GACA,GACA,IACI;IACE,qBAAqB,EAAW;IAChC,iBAAiB,EAAW,UAAU;IACtC,cAAc,EAAW;GAC3B,IACA,MACJ,GACA,GACA,GACA,GACA,GAAG,CACL,GAOI,IAAsB,EAAa,qBASnC,IAAkB,GAAS,IAAI,CAAmB,KAAK,CAAC,GAC1D,IAAgC;GACpC,IAAI,GAAqB;IACvB,IAAI,IAAmC,CAAC;IACxC,IAAI;KACF,IAAY,MAAM,EAAY,gBAAgB;MAC5C,UAAU,EAAmB;MAC7B,eAAe,EAAyB,qBAAqB;KAC/D,CAAC;IACH,QAAQ,CAER;IACA,IAAM,IAAO,IAAI,IAAI,EAAgB,IAAI,CAAkB,CAAC,GACtD,IAAmB,EACtB,QAAQ,MAAW,EAAO,OAAO,EACjC,KAAK,OAAY;KAChB,QAAQ,EAAO;KACf,KAAK,EAAO,gBAAgB;KAC5B,WAAW,EAAO,aAAa;KAG/B,MAAM,EAAO;IACf,EAAE,EACD,QAAQ,MAAW,CAAC,EAAK,IAAI,EAAmB,CAAM,CAAC,CAAC;IAC3D,IAAkB,CAAC,GAAG,GAAiB,GAAG,CAAgB;GAC5D;GASA,IAAM,IACJ,KACA,GAAsB,eAAe,cACjC,EAAqB,kBACpB,GAAa,kBAAkB;GACtC,IAAI,MAAwB,KAAiB,EAAgB,SAAS;IACpE,IAAM,IAAO,EAA8B,CAAmB;IAC9D,EAA8B,GAAqB;KACjD,qBAAqB,GAAM,uBAAuB;KAClD,iBAAiB,GAAM,mBAAmB;KAC1C,cAAc,GAAM,gBAAgB;KACpC,oBAAoB,GAAM,sBAAsB;KAChD,gBAAgB,GAAM,kBAAkB;KACxC,gBAAgB,KAAiB,GAAM,kBAAkB;KACzD,SAAS,EAAgB,SACrB,IACC,GAAM,WAAW;IACxB,CAAC;GACH;GAWA,OAAO;IACL,iBALqB,EAAa,sBAChC,EAAa,sBACb,QAAQ,EAAa;IAIvB,iBAAiB;IACjB,KAAK,EAAa;IAClB,SAAS,EAAa;GACxB;EACF;EACA,WAAW,OAAO,GAAM,MAAc;GAyBpC,AAxBA,EAAyB;IACvB,gBAAgB,EAAK;IACrB,QAAQ,EAAK;IACb,eAAe,CAAC,CAAC,EAAU;IAC3B,aAAa,EAAU,YAAY;IACnC,cAAc,CAAC,CAAC,EAAU;IAC1B,eAAe,EAAU;IACzB,iBAAiB,CAAC,CAAC,EAAU;IAC7B,WAAW,EAAU;IACrB,uBAAuB,CAAC,CAAC,EAAU;IACnC,YAAY,EAAU;GACxB,CAAC,GAMD,EAAY,kBAAkB,EAC5B,UAAU,CAAC,QAAQ,eAAe,EACpC,CAAC,GAKD,EAAY,kBAAkB,EAC5B,UAAU,CAAC,aAAa,EAC1B,CAAC;EACH;CACF,CAAC;AACH"}
1
+ {"version":3,"file":"use-create-conversation.js","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":";;;;;;;;;;;;;;AAoDA,IAAa,IAAmC,CAAC,qBAAqB,GASzD,UAA8B;CACzC,IAAM,IAAc,EAAe,GAC7B,EAAE,gCAA6B,EAAY,GAI3C,EAAE,MAAM,MAAgB,EAAe,GAOvC,EAAE,YAAS,aAAU,EAAiB;CAG5C,OAFA,EAAiB,GAEV,EAAY;EACjB,aAAa;EACb,YAAY,OACV,MACwC;GACxC,IAAM,EACJ,UACA,6BACA,YACA,eACA,eACA,kBACA,yBACA,cACA,sBACE,GAUA;GACJ,IAAI;IACF,IAAgB,MAAM,EAAY,gBAAgB;KAChD,UAAU;MAAC,GAAG,EAA0B;MAAK,EAAQ;MAAI;KAAK;KAC9D,SAAS,EAAqB;KAC9B,GAAG;IACL,CAAC;GACH,QAAQ,CAER;GAEA,IAAM,IACJ,KAAkB,GAAe,2BAA2B,KAAA,GAUxD,IAAuB,IACzB,GAAe,UAAU,MACtB,MAAY,EAAQ,OAAO,CAC9B,IACA,KAAA,GAOE,IAAU,EAAQ,SAAS,SAC7B,IAA0B;GAC9B,IACE,CAAC,KACD,GAAsB,SAAA,aACtB,GAAsB,eAAe,aAoBrC,IAA0B,KAAA;QACrB,IACL,GAAsB,eAAe,eACrC,EAAqB,iBACrB;IAIA,IAAI,IAAmB;IACvB,IAAI;KASF,KAAmB,MARD,EAAY,gBAAgB;MAC5C,UAAU;OAAC,GAAG,EAAwB;OAAK,EAAQ;OAAI;MAAK;MAC5D,SAAS,EAAgB;MAIzB,OAAO;KACT,CAAC,GACsB,SAAS,MAC7B,MAAY,EAAQ,SAAS,EAAqB,eACrD;IACF,QAAQ,CAER;IACA,AAAK,MAEH,QAAQ,KACN,kBAAkB,EAAqB,KAAK,oCAC1B,EAAqB,gBAAgB,0CAEzD,GACA,IAA0B,KAAA;GAE9B;GAKA,IAAM,IACJ,MAAM,EAA+B,mBAAmB;IACtD,gBAAgB;IAChB;IACA;IACA,UAAU,IACN;KACE,qBAAqB,EAAW;KAChC,iBAAiB,EAAW,UAAU;KACtC,cAAc,EAAW;IAC3B,IACA;IACJ,oBAAoB;IACpB;IACA;IACA;IACA,GAAI,IACA;KACE,gBAAgB;KAChB,kBAAkB,GAAsB;IAC1C,IACA,CAAC;GACP,CAAC,GAOG,IAAsB,EAAa,qBASnC,IAAkB,GAAS,IAAI,CAAmB,KAAK,CAAC,GAC1D,IAAgC;GACpC,IAAI,GAAqB;IACvB,IAAI,IAAmC,CAAC;IACxC,IAAI;KACF,IAAY,MAAM,EAAY,gBAAgB;MAC5C,UAAU,EAAmB;MAC7B,eAAe,EAAyB,qBAAqB;KAC/D,CAAC;IACH,QAAQ,CAER;IACA,IAAM,IAAO,IAAI,IAAI,EAAgB,IAAI,CAAkB,CAAC,GACtD,IAAmB,EACtB,QAAQ,MAAW,EAAO,OAAO,EACjC,KAAK,OAAY;KAChB,QAAQ,EAAO;KACf,KAAK,EAAO,gBAAgB;KAC5B,WAAW,EAAO,aAAa;KAG/B,MAAM,EAAO;IACf,EAAE,EACD,QAAQ,MAAW,CAAC,EAAK,IAAI,EAAmB,CAAM,CAAC,CAAC;IAC3D,IAAkB,CAAC,GAAG,GAAiB,GAAG,CAAgB;GAC5D;GASA,IAAM,IACJ,KACA,GAAsB,eAAe,cACjC,EAAqB,kBACpB,GAAa,kBAAkB;GACtC,IAAI,MAAwB,KAAiB,EAAgB,SAAS;IACpE,IAAM,IAAO,EAA8B,CAAmB;IAC9D,EAA8B,GAAqB;KACjD,qBAAqB,GAAM,uBAAuB;KAClD,iBAAiB,GAAM,mBAAmB;KAC1C,cAAc,GAAM,gBAAgB;KACpC,oBAAoB,GAAM,sBAAsB;KAChD,gBAAgB,GAAM,kBAAkB;KACxC,gBAAgB,KAAiB,GAAM,kBAAkB;KACzD,SAAS,EAAgB,SACrB,IACC,GAAM,WAAW;IACxB,CAAC;GACH;GAWA,OAAO;IACL,iBALqB,EAAa,sBAChC,EAAa,sBACb,QAAQ,EAAa;IAIvB,iBAAiB;IACjB,KAAK,EAAa;IAClB,SAAS,EAAa;GACxB;EACF;EACA,WAAW,OAAO,GAAM,MAAc;GAyBpC,AAxBA,EAAyB;IACvB,gBAAgB,EAAK;IACrB,QAAQ,EAAK;IACb,eAAe,CAAC,CAAC,EAAU;IAC3B,aAAa,EAAU,YAAY;IACnC,cAAc,CAAC,CAAC,EAAU;IAC1B,eAAe,EAAU;IACzB,iBAAiB,CAAC,CAAC,EAAU;IAC7B,WAAW,EAAU;IACrB,uBAAuB,CAAC,CAAC,EAAU;IACnC,YAAY,EAAU;GACxB,CAAC,GAMD,EAAY,kBAAkB,EAC5B,UAAU,CAAC,QAAQ,eAAe,EACpC,CAAC,GAKD,EAAY,kBAAkB,EAC5B,UAAU,CAAC,aAAa,EAC1B,CAAC;EACH;CACF,CAAC;AACH"}
@@ -1,2 +1,2 @@
1
- require("../../_virtual/_rolldown/runtime.cjs");const e=require("../../node_modules/react-i18next/dist/es/useTranslation.cjs"),t=require("../../i18n/declaration.cjs"),n=require("../../context/navigation-context.cjs"),r=require("../../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs"),i=require("../../node_modules/@tanstack/react-query/build/modern/useMutation.cjs"),a=require("../../node_modules/react-hot-toast/dist/index.cjs"),o=require("../../utils/custom-toast-handlers.cjs"),s=require("../../api/conversation-service/agent-server-conversation-service.api.cjs"),c=require("../query/use-active-conversation.cjs"),l=require("../use-tracking.cjs");var u=()=>{let u=r.useQueryClient(),{navigate:d}=n.useNavigation(),{t:f}=e.useTranslation(`openhands`),{data:p}=c.useActiveConversation(),{trackConversationCreated:m}=l.useTracking();return i.useMutation({mutationFn:async()=>{if(!p?.id)throw Error(`No active conversation`);let e=await s.default.createConversation(void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,p.sandbox_id??void 0);if(e.status===`ERROR`)throw Error(e.detail||`Failed to create new conversation`);return{newConversationId:e.app_conversation_id?e.app_conversation_id:`task-${e.id}`,oldConversationId:p.id,taskId:e.id}},onMutate:()=>{a.zt.loading(f(t.I18nKey.CONVERSATION$CLEARING),{...o.TOAST_OPTIONS,id:`clear-conversation`})},onSuccess:e=>{m({conversationId:e.newConversationId,taskId:e.taskId,hasRepository:!1,hasWorkspace:!1,hasInitialQuery:!1,hasParentConversation:!1,entryPoint:`new_command`}),a.zt.dismiss(`clear-conversation`),o.displaySuccessToast(f(t.I18nKey.CONVERSATION$CLEAR_SUCCESS)),d(`/conversations/${e.newConversationId}`),u.invalidateQueries({queryKey:[`user`,`conversations`]}),u.invalidateQueries({queryKey:[`v1-batch-get-app-conversations`]})},onError:e=>{a.zt.dismiss(`clear-conversation`);let n=f(t.I18nKey.CONVERSATION$CLEAR_UNKNOWN_ERROR);e instanceof Error?n=e.message:typeof e==`string`&&(n=e),o.displayErrorToast(f(t.I18nKey.CONVERSATION$CLEAR_FAILED,{error:n}))}})};exports.useNewConversationCommand=u;
1
+ require("../../_virtual/_rolldown/runtime.cjs");const e=require("../../node_modules/react-i18next/dist/es/useTranslation.cjs"),t=require("../../i18n/declaration.cjs"),n=require("../../context/navigation-context.cjs"),r=require("../../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs"),i=require("../../node_modules/@tanstack/react-query/build/modern/useMutation.cjs"),a=require("../../node_modules/react-hot-toast/dist/index.cjs"),o=require("../../utils/custom-toast-handlers.cjs"),s=require("../../api/conversation-service/agent-server-conversation-service.api.cjs"),c=require("../query/use-active-conversation.cjs"),l=require("../use-tracking.cjs");var u=()=>{let u=r.useQueryClient(),{navigate:d}=n.useNavigation(),{t:f}=e.useTranslation(`openhands`),{data:p}=c.useActiveConversation(),{trackConversationCreated:m}=l.useTracking();return i.useMutation({mutationFn:async()=>{if(!p?.id)throw Error(`No active conversation`);let e=await s.default.createConversation({sandboxId:p.sandbox_id??void 0});if(e.status===`ERROR`)throw Error(e.detail||`Failed to create new conversation`);return{newConversationId:e.app_conversation_id?e.app_conversation_id:`task-${e.id}`,oldConversationId:p.id,taskId:e.id}},onMutate:()=>{a.zt.loading(f(t.I18nKey.CONVERSATION$CLEARING),{...o.TOAST_OPTIONS,id:`clear-conversation`})},onSuccess:e=>{m({conversationId:e.newConversationId,taskId:e.taskId,hasRepository:!1,hasWorkspace:!1,hasInitialQuery:!1,hasParentConversation:!1,entryPoint:`new_command`}),a.zt.dismiss(`clear-conversation`),o.displaySuccessToast(f(t.I18nKey.CONVERSATION$CLEAR_SUCCESS)),d(`/conversations/${e.newConversationId}`),u.invalidateQueries({queryKey:[`user`,`conversations`]}),u.invalidateQueries({queryKey:[`v1-batch-get-app-conversations`]})},onError:e=>{a.zt.dismiss(`clear-conversation`);let n=f(t.I18nKey.CONVERSATION$CLEAR_UNKNOWN_ERROR);e instanceof Error?n=e.message:typeof e==`string`&&(n=e),o.displayErrorToast(f(t.I18nKey.CONVERSATION$CLEAR_FAILED,{error:n}))}})};exports.useNewConversationCommand=u;
2
2
  //# sourceMappingURL=use-new-conversation-command.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-new-conversation-command.cjs","names":[],"sources":["../../../src/hooks/mutation/use-new-conversation-command.ts"],"sourcesContent":["import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport toast from \"react-hot-toast\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport AgentServerConversationService from \"#/api/conversation-service/agent-server-conversation-service.api\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n TOAST_OPTIONS,\n} from \"#/utils/custom-toast-handlers\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useTracking } from \"#/hooks/use-tracking\";\n\nexport const useNewConversationCommand = () => {\n const queryClient = useQueryClient();\n const { navigate } = useNavigation();\n const { t } = useTranslation(\"openhands\");\n const { data: conversation } = useActiveConversation();\n const { trackConversationCreated } = useTracking();\n\n const mutation = useMutation({\n mutationFn: async () => {\n if (!conversation?.id) {\n throw new Error(\"No active conversation\");\n }\n\n // /new reuses the parent conversation's sandbox (matches OpenHands\n // cloud behavior); it is NOT a sub-conversation, so parent_conversation_id\n // and agent_type stay undefined.\n const startTask = await AgentServerConversationService.createConversation(\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n conversation.sandbox_id ?? undefined,\n );\n\n if (startTask.status === \"ERROR\") {\n throw new Error(\n startTask.detail || \"Failed to create new conversation\",\n );\n }\n\n // Cloud returns a WORKING task (no app_conversation_id yet);\n // navigate to /conversations/task-{id} so useTaskPolling drives it\n // to READY. Local creates synchronously — app_conversation_id is\n // already set, so we navigate straight to it.\n const newConversationId = startTask.app_conversation_id\n ? startTask.app_conversation_id\n : `task-${startTask.id}`;\n\n return {\n newConversationId,\n oldConversationId: conversation.id,\n taskId: startTask.id,\n };\n },\n onMutate: () => {\n toast.loading(t(I18nKey.CONVERSATION$CLEARING), {\n ...TOAST_OPTIONS,\n id: \"clear-conversation\",\n });\n },\n onSuccess: (data) => {\n trackConversationCreated({\n conversationId: data.newConversationId,\n taskId: data.taskId,\n hasRepository: false,\n hasWorkspace: false,\n hasInitialQuery: false,\n hasParentConversation: false,\n entryPoint: \"new_command\",\n });\n\n toast.dismiss(\"clear-conversation\");\n displaySuccessToast(t(I18nKey.CONVERSATION$CLEAR_SUCCESS));\n navigate(`/conversations/${data.newConversationId}`);\n\n queryClient.invalidateQueries({\n queryKey: [\"user\", \"conversations\"],\n });\n queryClient.invalidateQueries({\n queryKey: [\"v1-batch-get-app-conversations\"],\n });\n },\n onError: (error) => {\n toast.dismiss(\"clear-conversation\");\n let clearError = t(I18nKey.CONVERSATION$CLEAR_UNKNOWN_ERROR);\n if (error instanceof Error) {\n clearError = error.message;\n } else if (typeof error === \"string\") {\n clearError = error;\n }\n displayErrorToast(\n t(I18nKey.CONVERSATION$CLEAR_FAILED, { error: clearError }),\n );\n },\n });\n\n return mutation;\n};\n"],"mappings":"kqBAcA,IAAa,MAAkC,CAC7C,IAAM,EAAc,EAAA,eAAe,EAC7B,CAAE,YAAa,EAAA,cAAc,EAC7B,CAAE,KAAM,EAAA,eAAe,WAAW,EAClC,CAAE,KAAM,GAAiB,EAAA,sBAAsB,EAC/C,CAAE,4BAA6B,EAAA,YAAY,EAqFjD,OAnFiB,EAAA,YAAY,CAC3B,WAAY,SAAY,CACtB,GAAI,CAAC,GAAc,GACjB,MAAU,MAAM,wBAAwB,EAM1C,IAAM,EAAY,MAAM,EAAA,QAA+B,mBACrD,IAAA,GACA,IAAA,GACA,IAAA,GACA,IAAA,GACA,IAAA,GACA,IAAA,GACA,IAAA,GACA,IAAA,GACA,EAAa,YAAc,IAAA,EAC7B,EAEA,GAAI,EAAU,SAAW,QACvB,MAAU,MACR,EAAU,QAAU,mCACtB,EAWF,MAAO,CACL,kBALwB,EAAU,oBAChC,EAAU,oBACV,QAAQ,EAAU,KAIpB,kBAAmB,EAAa,GAChC,OAAQ,EAAU,EACpB,CACF,EACA,aAAgB,CACd,EAAA,GAAM,QAAQ,EAAE,EAAA,QAAQ,qBAAqB,EAAG,CAC9C,GAAG,EAAA,cACH,GAAI,oBACN,CAAC,CACH,EACA,UAAY,GAAS,CACnB,EAAyB,CACvB,eAAgB,EAAK,kBACrB,OAAQ,EAAK,OACb,cAAe,GACf,aAAc,GACd,gBAAiB,GACjB,sBAAuB,GACvB,WAAY,aACd,CAAC,EAED,EAAA,GAAM,QAAQ,oBAAoB,EAClC,EAAA,oBAAoB,EAAE,EAAA,QAAQ,0BAA0B,CAAC,EACzD,EAAS,kBAAkB,EAAK,mBAAmB,EAEnD,EAAY,kBAAkB,CAC5B,SAAU,CAAC,OAAQ,eAAe,CACpC,CAAC,EACD,EAAY,kBAAkB,CAC5B,SAAU,CAAC,gCAAgC,CAC7C,CAAC,CACH,EACA,QAAU,GAAU,CAClB,EAAA,GAAM,QAAQ,oBAAoB,EAClC,IAAI,EAAa,EAAE,EAAA,QAAQ,gCAAgC,EACvD,aAAiB,MACnB,EAAa,EAAM,QACV,OAAO,GAAU,WAC1B,EAAa,GAEf,EAAA,kBACE,EAAE,EAAA,QAAQ,0BAA2B,CAAE,MAAO,CAAW,CAAC,CAC5D,CACF,CACF,CAEO,CACT"}
1
+ {"version":3,"file":"use-new-conversation-command.cjs","names":[],"sources":["../../../src/hooks/mutation/use-new-conversation-command.ts"],"sourcesContent":["import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport toast from \"react-hot-toast\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport AgentServerConversationService from \"#/api/conversation-service/agent-server-conversation-service.api\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n TOAST_OPTIONS,\n} from \"#/utils/custom-toast-handlers\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useTracking } from \"#/hooks/use-tracking\";\n\nexport const useNewConversationCommand = () => {\n const queryClient = useQueryClient();\n const { navigate } = useNavigation();\n const { t } = useTranslation(\"openhands\");\n const { data: conversation } = useActiveConversation();\n const { trackConversationCreated } = useTracking();\n\n const mutation = useMutation({\n mutationFn: async () => {\n if (!conversation?.id) {\n throw new Error(\"No active conversation\");\n }\n\n // /new reuses the parent conversation's sandbox (matches OpenHands\n // cloud behavior); it is NOT a sub-conversation, so parent_conversation_id\n // and agent_type stay undefined.\n const startTask = await AgentServerConversationService.createConversation(\n {\n sandboxId: conversation.sandbox_id ?? undefined,\n },\n );\n\n if (startTask.status === \"ERROR\") {\n throw new Error(\n startTask.detail || \"Failed to create new conversation\",\n );\n }\n\n // Cloud returns a WORKING task (no app_conversation_id yet);\n // navigate to /conversations/task-{id} so useTaskPolling drives it\n // to READY. Local creates synchronously — app_conversation_id is\n // already set, so we navigate straight to it.\n const newConversationId = startTask.app_conversation_id\n ? startTask.app_conversation_id\n : `task-${startTask.id}`;\n\n return {\n newConversationId,\n oldConversationId: conversation.id,\n taskId: startTask.id,\n };\n },\n onMutate: () => {\n toast.loading(t(I18nKey.CONVERSATION$CLEARING), {\n ...TOAST_OPTIONS,\n id: \"clear-conversation\",\n });\n },\n onSuccess: (data) => {\n trackConversationCreated({\n conversationId: data.newConversationId,\n taskId: data.taskId,\n hasRepository: false,\n hasWorkspace: false,\n hasInitialQuery: false,\n hasParentConversation: false,\n entryPoint: \"new_command\",\n });\n\n toast.dismiss(\"clear-conversation\");\n displaySuccessToast(t(I18nKey.CONVERSATION$CLEAR_SUCCESS));\n navigate(`/conversations/${data.newConversationId}`);\n\n queryClient.invalidateQueries({\n queryKey: [\"user\", \"conversations\"],\n });\n queryClient.invalidateQueries({\n queryKey: [\"v1-batch-get-app-conversations\"],\n });\n },\n onError: (error) => {\n toast.dismiss(\"clear-conversation\");\n let clearError = t(I18nKey.CONVERSATION$CLEAR_UNKNOWN_ERROR);\n if (error instanceof Error) {\n clearError = error.message;\n } else if (typeof error === \"string\") {\n clearError = error;\n }\n displayErrorToast(\n t(I18nKey.CONVERSATION$CLEAR_FAILED, { error: clearError }),\n );\n },\n });\n\n return mutation;\n};\n"],"mappings":"kqBAcA,IAAa,MAAkC,CAC7C,IAAM,EAAc,EAAA,eAAe,EAC7B,CAAE,YAAa,EAAA,cAAc,EAC7B,CAAE,KAAM,EAAA,eAAe,WAAW,EAClC,CAAE,KAAM,GAAiB,EAAA,sBAAsB,EAC/C,CAAE,4BAA6B,EAAA,YAAY,EA+EjD,OA7EiB,EAAA,YAAY,CAC3B,WAAY,SAAY,CACtB,GAAI,CAAC,GAAc,GACjB,MAAU,MAAM,wBAAwB,EAM1C,IAAM,EAAY,MAAM,EAAA,QAA+B,mBACrD,CACE,UAAW,EAAa,YAAc,IAAA,EACxC,CACF,EAEA,GAAI,EAAU,SAAW,QACvB,MAAU,MACR,EAAU,QAAU,mCACtB,EAWF,MAAO,CACL,kBALwB,EAAU,oBAChC,EAAU,oBACV,QAAQ,EAAU,KAIpB,kBAAmB,EAAa,GAChC,OAAQ,EAAU,EACpB,CACF,EACA,aAAgB,CACd,EAAA,GAAM,QAAQ,EAAE,EAAA,QAAQ,qBAAqB,EAAG,CAC9C,GAAG,EAAA,cACH,GAAI,oBACN,CAAC,CACH,EACA,UAAY,GAAS,CACnB,EAAyB,CACvB,eAAgB,EAAK,kBACrB,OAAQ,EAAK,OACb,cAAe,GACf,aAAc,GACd,gBAAiB,GACjB,sBAAuB,GACvB,WAAY,aACd,CAAC,EAED,EAAA,GAAM,QAAQ,oBAAoB,EAClC,EAAA,oBAAoB,EAAE,EAAA,QAAQ,0BAA0B,CAAC,EACzD,EAAS,kBAAkB,EAAK,mBAAmB,EAEnD,EAAY,kBAAkB,CAC5B,SAAU,CAAC,OAAQ,eAAe,CACpC,CAAC,EACD,EAAY,kBAAkB,CAC5B,SAAU,CAAC,gCAAgC,CAC7C,CAAC,CACH,EACA,QAAU,GAAU,CAClB,EAAA,GAAM,QAAQ,oBAAoB,EAClC,IAAI,EAAa,EAAE,EAAA,QAAQ,gCAAgC,EACvD,aAAiB,MACnB,EAAa,EAAM,QACV,OAAO,GAAU,WAC1B,EAAa,GAEf,EAAA,kBACE,EAAE,EAAA,QAAQ,0BAA2B,CAAE,MAAO,CAAW,CAAC,CAC5D,CACF,CACF,CAEO,CACT"}
@@ -14,7 +14,7 @@ var f = () => {
14
14
  return i({
15
15
  mutationFn: async () => {
16
16
  if (!h?.id) throw Error("No active conversation");
17
- let e = await l.createConversation(void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, h.sandbox_id ?? void 0);
17
+ let e = await l.createConversation({ sandboxId: h.sandbox_id ?? void 0 });
18
18
  if (e.status === "ERROR") throw Error(e.detail || "Failed to create new conversation");
19
19
  return {
20
20
  newConversationId: e.app_conversation_id ? e.app_conversation_id : `task-${e.id}`,
@@ -1 +1 @@
1
- {"version":3,"file":"use-new-conversation-command.js","names":[],"sources":["../../../src/hooks/mutation/use-new-conversation-command.ts"],"sourcesContent":["import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport toast from \"react-hot-toast\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport AgentServerConversationService from \"#/api/conversation-service/agent-server-conversation-service.api\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n TOAST_OPTIONS,\n} from \"#/utils/custom-toast-handlers\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useTracking } from \"#/hooks/use-tracking\";\n\nexport const useNewConversationCommand = () => {\n const queryClient = useQueryClient();\n const { navigate } = useNavigation();\n const { t } = useTranslation(\"openhands\");\n const { data: conversation } = useActiveConversation();\n const { trackConversationCreated } = useTracking();\n\n const mutation = useMutation({\n mutationFn: async () => {\n if (!conversation?.id) {\n throw new Error(\"No active conversation\");\n }\n\n // /new reuses the parent conversation's sandbox (matches OpenHands\n // cloud behavior); it is NOT a sub-conversation, so parent_conversation_id\n // and agent_type stay undefined.\n const startTask = await AgentServerConversationService.createConversation(\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n conversation.sandbox_id ?? undefined,\n );\n\n if (startTask.status === \"ERROR\") {\n throw new Error(\n startTask.detail || \"Failed to create new conversation\",\n );\n }\n\n // Cloud returns a WORKING task (no app_conversation_id yet);\n // navigate to /conversations/task-{id} so useTaskPolling drives it\n // to READY. Local creates synchronously — app_conversation_id is\n // already set, so we navigate straight to it.\n const newConversationId = startTask.app_conversation_id\n ? startTask.app_conversation_id\n : `task-${startTask.id}`;\n\n return {\n newConversationId,\n oldConversationId: conversation.id,\n taskId: startTask.id,\n };\n },\n onMutate: () => {\n toast.loading(t(I18nKey.CONVERSATION$CLEARING), {\n ...TOAST_OPTIONS,\n id: \"clear-conversation\",\n });\n },\n onSuccess: (data) => {\n trackConversationCreated({\n conversationId: data.newConversationId,\n taskId: data.taskId,\n hasRepository: false,\n hasWorkspace: false,\n hasInitialQuery: false,\n hasParentConversation: false,\n entryPoint: \"new_command\",\n });\n\n toast.dismiss(\"clear-conversation\");\n displaySuccessToast(t(I18nKey.CONVERSATION$CLEAR_SUCCESS));\n navigate(`/conversations/${data.newConversationId}`);\n\n queryClient.invalidateQueries({\n queryKey: [\"user\", \"conversations\"],\n });\n queryClient.invalidateQueries({\n queryKey: [\"v1-batch-get-app-conversations\"],\n });\n },\n onError: (error) => {\n toast.dismiss(\"clear-conversation\");\n let clearError = t(I18nKey.CONVERSATION$CLEAR_UNKNOWN_ERROR);\n if (error instanceof Error) {\n clearError = error.message;\n } else if (typeof error === \"string\") {\n clearError = error;\n }\n displayErrorToast(\n t(I18nKey.CONVERSATION$CLEAR_FAILED, { error: clearError }),\n );\n },\n });\n\n return mutation;\n};\n"],"mappings":";;;;;;;;;;;AAcA,IAAa,UAAkC;CAC7C,IAAM,IAAc,EAAe,GAC7B,EAAE,gBAAa,EAAc,GAC7B,EAAE,SAAM,EAAe,WAAW,GAClC,EAAE,MAAM,MAAiB,EAAsB,GAC/C,EAAE,gCAA6B,EAAY;CAqFjD,OAnFiB,EAAY;EAC3B,YAAY,YAAY;GACtB,IAAI,CAAC,GAAc,IACjB,MAAU,MAAM,wBAAwB;GAM1C,IAAM,IAAY,MAAM,EAA+B,mBACrD,KAAA,GACA,KAAA,GACA,KAAA,GACA,KAAA,GACA,KAAA,GACA,KAAA,GACA,KAAA,GACA,KAAA,GACA,EAAa,cAAc,KAAA,CAC7B;GAEA,IAAI,EAAU,WAAW,SACvB,MAAU,MACR,EAAU,UAAU,mCACtB;GAWF,OAAO;IACL,mBALwB,EAAU,sBAChC,EAAU,sBACV,QAAQ,EAAU;IAIpB,mBAAmB,EAAa;IAChC,QAAQ,EAAU;GACpB;EACF;EACA,gBAAgB;GACd,EAAM,QAAQ,EAAE,EAAQ,qBAAqB,GAAG;IAC9C,GAAG;IACH,IAAI;GACN,CAAC;EACH;EACA,YAAY,MAAS;GAkBnB,AAjBA,EAAyB;IACvB,gBAAgB,EAAK;IACrB,QAAQ,EAAK;IACb,eAAe;IACf,cAAc;IACd,iBAAiB;IACjB,uBAAuB;IACvB,YAAY;GACd,CAAC,GAED,EAAM,QAAQ,oBAAoB,GAClC,EAAoB,EAAE,EAAQ,0BAA0B,CAAC,GACzD,EAAS,kBAAkB,EAAK,mBAAmB,GAEnD,EAAY,kBAAkB,EAC5B,UAAU,CAAC,QAAQ,eAAe,EACpC,CAAC,GACD,EAAY,kBAAkB,EAC5B,UAAU,CAAC,gCAAgC,EAC7C,CAAC;EACH;EACA,UAAU,MAAU;GAClB,EAAM,QAAQ,oBAAoB;GAClC,IAAI,IAAa,EAAE,EAAQ,gCAAgC;GAM3D,AALI,aAAiB,QACnB,IAAa,EAAM,UACV,OAAO,KAAU,aAC1B,IAAa,IAEf,EACE,EAAE,EAAQ,2BAA2B,EAAE,OAAO,EAAW,CAAC,CAC5D;EACF;CACF,CAEO;AACT"}
1
+ {"version":3,"file":"use-new-conversation-command.js","names":[],"sources":["../../../src/hooks/mutation/use-new-conversation-command.ts"],"sourcesContent":["import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport toast from \"react-hot-toast\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport AgentServerConversationService from \"#/api/conversation-service/agent-server-conversation-service.api\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n TOAST_OPTIONS,\n} from \"#/utils/custom-toast-handlers\";\nimport { useNavigation } from \"#/context/navigation-context\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useTracking } from \"#/hooks/use-tracking\";\n\nexport const useNewConversationCommand = () => {\n const queryClient = useQueryClient();\n const { navigate } = useNavigation();\n const { t } = useTranslation(\"openhands\");\n const { data: conversation } = useActiveConversation();\n const { trackConversationCreated } = useTracking();\n\n const mutation = useMutation({\n mutationFn: async () => {\n if (!conversation?.id) {\n throw new Error(\"No active conversation\");\n }\n\n // /new reuses the parent conversation's sandbox (matches OpenHands\n // cloud behavior); it is NOT a sub-conversation, so parent_conversation_id\n // and agent_type stay undefined.\n const startTask = await AgentServerConversationService.createConversation(\n {\n sandboxId: conversation.sandbox_id ?? undefined,\n },\n );\n\n if (startTask.status === \"ERROR\") {\n throw new Error(\n startTask.detail || \"Failed to create new conversation\",\n );\n }\n\n // Cloud returns a WORKING task (no app_conversation_id yet);\n // navigate to /conversations/task-{id} so useTaskPolling drives it\n // to READY. Local creates synchronously — app_conversation_id is\n // already set, so we navigate straight to it.\n const newConversationId = startTask.app_conversation_id\n ? startTask.app_conversation_id\n : `task-${startTask.id}`;\n\n return {\n newConversationId,\n oldConversationId: conversation.id,\n taskId: startTask.id,\n };\n },\n onMutate: () => {\n toast.loading(t(I18nKey.CONVERSATION$CLEARING), {\n ...TOAST_OPTIONS,\n id: \"clear-conversation\",\n });\n },\n onSuccess: (data) => {\n trackConversationCreated({\n conversationId: data.newConversationId,\n taskId: data.taskId,\n hasRepository: false,\n hasWorkspace: false,\n hasInitialQuery: false,\n hasParentConversation: false,\n entryPoint: \"new_command\",\n });\n\n toast.dismiss(\"clear-conversation\");\n displaySuccessToast(t(I18nKey.CONVERSATION$CLEAR_SUCCESS));\n navigate(`/conversations/${data.newConversationId}`);\n\n queryClient.invalidateQueries({\n queryKey: [\"user\", \"conversations\"],\n });\n queryClient.invalidateQueries({\n queryKey: [\"v1-batch-get-app-conversations\"],\n });\n },\n onError: (error) => {\n toast.dismiss(\"clear-conversation\");\n let clearError = t(I18nKey.CONVERSATION$CLEAR_UNKNOWN_ERROR);\n if (error instanceof Error) {\n clearError = error.message;\n } else if (typeof error === \"string\") {\n clearError = error;\n }\n displayErrorToast(\n t(I18nKey.CONVERSATION$CLEAR_FAILED, { error: clearError }),\n );\n },\n });\n\n return mutation;\n};\n"],"mappings":";;;;;;;;;;;AAcA,IAAa,UAAkC;CAC7C,IAAM,IAAc,EAAe,GAC7B,EAAE,gBAAa,EAAc,GAC7B,EAAE,SAAM,EAAe,WAAW,GAClC,EAAE,MAAM,MAAiB,EAAsB,GAC/C,EAAE,gCAA6B,EAAY;CA+EjD,OA7EiB,EAAY;EAC3B,YAAY,YAAY;GACtB,IAAI,CAAC,GAAc,IACjB,MAAU,MAAM,wBAAwB;GAM1C,IAAM,IAAY,MAAM,EAA+B,mBACrD,EACE,WAAW,EAAa,cAAc,KAAA,EACxC,CACF;GAEA,IAAI,EAAU,WAAW,SACvB,MAAU,MACR,EAAU,UAAU,mCACtB;GAWF,OAAO;IACL,mBALwB,EAAU,sBAChC,EAAU,sBACV,QAAQ,EAAU;IAIpB,mBAAmB,EAAa;IAChC,QAAQ,EAAU;GACpB;EACF;EACA,gBAAgB;GACd,EAAM,QAAQ,EAAE,EAAQ,qBAAqB,GAAG;IAC9C,GAAG;IACH,IAAI;GACN,CAAC;EACH;EACA,YAAY,MAAS;GAkBnB,AAjBA,EAAyB;IACvB,gBAAgB,EAAK;IACrB,QAAQ,EAAK;IACb,eAAe;IACf,cAAc;IACd,iBAAiB;IACjB,uBAAuB;IACvB,YAAY;GACd,CAAC,GAED,EAAM,QAAQ,oBAAoB,GAClC,EAAoB,EAAE,EAAQ,0BAA0B,CAAC,GACzD,EAAS,kBAAkB,EAAK,mBAAmB,GAEnD,EAAY,kBAAkB,EAC5B,UAAU,CAAC,QAAQ,eAAe,EACpC,CAAC,GACD,EAAY,kBAAkB,EAC5B,UAAU,CAAC,gCAAgC,EAC7C,CAAC;EACH;EACA,UAAU,MAAU;GAClB,EAAM,QAAQ,oBAAoB;GAClC,IAAI,IAAa,EAAE,EAAQ,gCAAgC;GAM3D,AALI,aAAiB,QACnB,IAAa,EAAM,UACV,OAAO,KAAU,aAC1B,IAAa,IAEf,EACE,EAAE,EAAQ,2BAA2B,EAAE,OAAO,EAAW,CAAC,CAC5D;EACF;CACF,CAEO;AACT"}
@@ -1,2 +1,2 @@
1
- require("../../_virtual/_rolldown/runtime.cjs");const e=require("../../node_modules/@tanstack/react-query/build/modern/useQuery.cjs"),t=require("../../api/conversation-service/agent-server-conversation-service.api.cjs"),n=require("../../utils/conversation-metrics.cjs");var r=(r,i,a,o=!0)=>{let s=e.useQuery({queryKey:[`conversation-metrics`,r,i,a],queryFn:async()=>{if(!r)throw Error(`Conversation ID is required`);return n.getCombinedMetrics(await t.default.getRuntimeConversation(r,i,a))},enabled:o&&!!r&&!!i,staleTime:1e3*30,gcTime:1e3*60*5,refetchInterval:1e3*30,retry:!1});return{data:s.data,isLoading:s.isLoading,error:s.error}};exports.useConversationMetrics=r;
1
+ require("../../_virtual/_rolldown/runtime.cjs");const e=require("../../node_modules/@tanstack/react-query/build/modern/useQuery.cjs"),t=require("../../api/conversation-service/agent-server-conversation-service.api.cjs"),n=require("../../utils/conversation-metrics.cjs");var r=(r,i,a,o=!0)=>{let s=e.useQuery({queryKey:[`conversation-metrics`,r,i,a],queryFn:async()=>{if(!r)throw Error(`Conversation ID is required`);return n.getCombinedMetrics(await t.default.getRuntimeConversation(r,i,a))},enabled:o&&!!r,staleTime:1e3*30,gcTime:1e3*60*5,refetchInterval:1e3*30,retry:!1});return{data:s.data,isLoading:s.isLoading,error:s.error}};exports.useConversationMetrics=r;
2
2
  //# sourceMappingURL=use-conversation-metrics.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-conversation-metrics.cjs","names":[],"sources":["../../../src/hooks/query/use-conversation-metrics.ts"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport AgentServerConversationService from \"#/api/conversation-service/agent-server-conversation-service.api\";\nimport { getCombinedMetrics } from \"#/utils/conversation-metrics\";\nimport type { MetricsSnapshot } from \"#/api/conversation-service/agent-server-conversation-service.types\";\n\nexport const useConversationMetrics = (\n conversationId: string | null | undefined,\n conversationUrl: string | null | undefined,\n sessionApiKey: string | null | undefined,\n enabled: boolean = true,\n): {\n data: MetricsSnapshot | undefined;\n isLoading: boolean;\n error: unknown;\n} => {\n const query = useQuery({\n queryKey: [\n \"conversation-metrics\",\n conversationId,\n conversationUrl,\n sessionApiKey,\n ],\n queryFn: async () => {\n if (!conversationId) throw new Error(\"Conversation ID is required\");\n const conversationInfo =\n await AgentServerConversationService.getRuntimeConversation(\n conversationId,\n conversationUrl,\n sessionApiKey,\n );\n return getCombinedMetrics(conversationInfo);\n },\n enabled: enabled && !!conversationId && !!conversationUrl,\n staleTime: 1000 * 30,\n gcTime: 1000 * 60 * 5,\n refetchInterval: 1000 * 30,\n retry: false,\n });\n\n return {\n data: query.data,\n isLoading: query.isLoading,\n error: query.error,\n };\n};\n"],"mappings":"8QAKA,IAAa,GACX,EACA,EACA,EACA,EAAmB,KAKhB,CACH,IAAM,EAAQ,EAAA,SAAS,CACrB,SAAU,CACR,uBACA,EACA,EACA,CACF,EACA,QAAS,SAAY,CACnB,GAAI,CAAC,EAAgB,MAAU,MAAM,6BAA6B,EAOlE,OAAO,EAAA,mBAAmB,MALlB,EAAA,QAA+B,uBACnC,EACA,EACA,CACF,CACwC,CAC5C,EACA,QAAS,GAAW,CAAC,CAAC,GAAkB,CAAC,CAAC,EAC1C,UAAW,IAAO,GAClB,OAAQ,IAAO,GAAK,EACpB,gBAAiB,IAAO,GACxB,MAAO,EACT,CAAC,EAED,MAAO,CACL,KAAM,EAAM,KACZ,UAAW,EAAM,UACjB,MAAO,EAAM,KACf,CACF"}
1
+ {"version":3,"file":"use-conversation-metrics.cjs","names":[],"sources":["../../../src/hooks/query/use-conversation-metrics.ts"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport AgentServerConversationService from \"#/api/conversation-service/agent-server-conversation-service.api\";\nimport { getCombinedMetrics } from \"#/utils/conversation-metrics\";\nimport type { MetricsSnapshot } from \"#/api/conversation-service/agent-server-conversation-service.types\";\n\nexport const useConversationMetrics = (\n conversationId: string | null | undefined,\n conversationUrl: string | null | undefined,\n sessionApiKey: string | null | undefined,\n enabled: boolean = true,\n): {\n data: MetricsSnapshot | undefined;\n isLoading: boolean;\n error: unknown;\n} => {\n const query = useQuery({\n queryKey: [\n \"conversation-metrics\",\n conversationId,\n conversationUrl,\n sessionApiKey,\n ],\n queryFn: async () => {\n if (!conversationId) throw new Error(\"Conversation ID is required\");\n const conversationInfo =\n await AgentServerConversationService.getRuntimeConversation(\n conversationId,\n conversationUrl,\n sessionApiKey,\n );\n return getCombinedMetrics(conversationInfo);\n },\n // conversation_url is only set for cloud conversations; local ones are\n // served by the ConversationClient fallback in getRuntimeConversation.\n // Gating on it left local conversations with no REST snapshot at all\n // (zeros after a page reload until live WS metrics arrived).\n enabled: enabled && !!conversationId,\n staleTime: 1000 * 30,\n gcTime: 1000 * 60 * 5,\n refetchInterval: 1000 * 30,\n retry: false,\n });\n\n return {\n data: query.data,\n isLoading: query.isLoading,\n error: query.error,\n };\n};\n"],"mappings":"8QAKA,IAAa,GACX,EACA,EACA,EACA,EAAmB,KAKhB,CACH,IAAM,EAAQ,EAAA,SAAS,CACrB,SAAU,CACR,uBACA,EACA,EACA,CACF,EACA,QAAS,SAAY,CACnB,GAAI,CAAC,EAAgB,MAAU,MAAM,6BAA6B,EAOlE,OAAO,EAAA,mBAAmB,MALlB,EAAA,QAA+B,uBACnC,EACA,EACA,CACF,CACwC,CAC5C,EAKA,QAAS,GAAW,CAAC,CAAC,EACtB,UAAW,IAAO,GAClB,OAAQ,IAAO,GAAK,EACpB,gBAAiB,IAAO,GACxB,MAAO,EACT,CAAC,EAED,MAAO,CACL,KAAM,EAAM,KACZ,UAAW,EAAM,UACjB,MAAO,EAAM,KACf,CACF"}
@@ -14,7 +14,7 @@ var r = (r, i, a, o = !0) => {
14
14
  if (!r) throw Error("Conversation ID is required");
15
15
  return n(await t.getRuntimeConversation(r, i, a));
16
16
  },
17
- enabled: o && !!r && !!i,
17
+ enabled: o && !!r,
18
18
  staleTime: 1e3 * 30,
19
19
  gcTime: 1e3 * 60 * 5,
20
20
  refetchInterval: 1e3 * 30,
@@ -1 +1 @@
1
- {"version":3,"file":"use-conversation-metrics.js","names":[],"sources":["../../../src/hooks/query/use-conversation-metrics.ts"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport AgentServerConversationService from \"#/api/conversation-service/agent-server-conversation-service.api\";\nimport { getCombinedMetrics } from \"#/utils/conversation-metrics\";\nimport type { MetricsSnapshot } from \"#/api/conversation-service/agent-server-conversation-service.types\";\n\nexport const useConversationMetrics = (\n conversationId: string | null | undefined,\n conversationUrl: string | null | undefined,\n sessionApiKey: string | null | undefined,\n enabled: boolean = true,\n): {\n data: MetricsSnapshot | undefined;\n isLoading: boolean;\n error: unknown;\n} => {\n const query = useQuery({\n queryKey: [\n \"conversation-metrics\",\n conversationId,\n conversationUrl,\n sessionApiKey,\n ],\n queryFn: async () => {\n if (!conversationId) throw new Error(\"Conversation ID is required\");\n const conversationInfo =\n await AgentServerConversationService.getRuntimeConversation(\n conversationId,\n conversationUrl,\n sessionApiKey,\n );\n return getCombinedMetrics(conversationInfo);\n },\n enabled: enabled && !!conversationId && !!conversationUrl,\n staleTime: 1000 * 30,\n gcTime: 1000 * 60 * 5,\n refetchInterval: 1000 * 30,\n retry: false,\n });\n\n return {\n data: query.data,\n isLoading: query.isLoading,\n error: query.error,\n };\n};\n"],"mappings":";;;;AAKA,IAAa,KACX,GACA,GACA,GACA,IAAmB,OAKhB;CACH,IAAM,IAAQ,EAAS;EACrB,UAAU;GACR;GACA;GACA;GACA;EACF;EACA,SAAS,YAAY;GACnB,IAAI,CAAC,GAAgB,MAAU,MAAM,6BAA6B;GAOlE,OAAO,EAAmB,MALlB,EAA+B,uBACnC,GACA,GACA,CACF,CACwC;EAC5C;EACA,SAAS,KAAW,CAAC,CAAC,KAAkB,CAAC,CAAC;EAC1C,WAAW,MAAO;EAClB,QAAQ,MAAO,KAAK;EACpB,iBAAiB,MAAO;EACxB,OAAO;CACT,CAAC;CAED,OAAO;EACL,MAAM,EAAM;EACZ,WAAW,EAAM;EACjB,OAAO,EAAM;CACf;AACF"}
1
+ {"version":3,"file":"use-conversation-metrics.js","names":[],"sources":["../../../src/hooks/query/use-conversation-metrics.ts"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport AgentServerConversationService from \"#/api/conversation-service/agent-server-conversation-service.api\";\nimport { getCombinedMetrics } from \"#/utils/conversation-metrics\";\nimport type { MetricsSnapshot } from \"#/api/conversation-service/agent-server-conversation-service.types\";\n\nexport const useConversationMetrics = (\n conversationId: string | null | undefined,\n conversationUrl: string | null | undefined,\n sessionApiKey: string | null | undefined,\n enabled: boolean = true,\n): {\n data: MetricsSnapshot | undefined;\n isLoading: boolean;\n error: unknown;\n} => {\n const query = useQuery({\n queryKey: [\n \"conversation-metrics\",\n conversationId,\n conversationUrl,\n sessionApiKey,\n ],\n queryFn: async () => {\n if (!conversationId) throw new Error(\"Conversation ID is required\");\n const conversationInfo =\n await AgentServerConversationService.getRuntimeConversation(\n conversationId,\n conversationUrl,\n sessionApiKey,\n );\n return getCombinedMetrics(conversationInfo);\n },\n // conversation_url is only set for cloud conversations; local ones are\n // served by the ConversationClient fallback in getRuntimeConversation.\n // Gating on it left local conversations with no REST snapshot at all\n // (zeros after a page reload until live WS metrics arrived).\n enabled: enabled && !!conversationId,\n staleTime: 1000 * 30,\n gcTime: 1000 * 60 * 5,\n refetchInterval: 1000 * 30,\n retry: false,\n });\n\n return {\n data: query.data,\n isLoading: query.isLoading,\n error: query.error,\n };\n};\n"],"mappings":";;;;AAKA,IAAa,KACX,GACA,GACA,GACA,IAAmB,OAKhB;CACH,IAAM,IAAQ,EAAS;EACrB,UAAU;GACR;GACA;GACA;GACA;EACF;EACA,SAAS,YAAY;GACnB,IAAI,CAAC,GAAgB,MAAU,MAAM,6BAA6B;GAOlE,OAAO,EAAmB,MALlB,EAA+B,uBACnC,GACA,GACA,CACF,CACwC;EAC5C;EAKA,SAAS,KAAW,CAAC,CAAC;EACtB,WAAW,MAAO;EAClB,QAAQ,MAAO,KAAK;EACpB,iBAAiB,MAAO;EACxB,OAAO;CACT,CAAC;CAED,OAAO;EACL,MAAM,EAAM;EACZ,WAAW,EAAM;EACjB,OAAO,EAAM;CACf;AACF"}
@@ -0,0 +1,2 @@
1
+ require("../../_virtual/_rolldown/runtime.cjs");const e=require("../../node_modules/@tanstack/react-query/build/modern/useQuery.cjs"),t=require("../../contexts/active-backend-context.cjs"),n=require("../../api/llm-balance-service.cjs");var r=r=>{let{backend:i}=t.useActiveBackend();return e.useQuery({queryKey:[`llm-balance`,i.id,r],queryFn:()=>n.default.getBalance(),enabled:i.kind!==`cloud`&&!!r,staleTime:1/0,gcTime:1e3*60*5,retry:!1,refetchOnWindowFocus:!1})};exports.useLLMBalance=r;
2
+ //# sourceMappingURL=use-llm-balance.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-llm-balance.cjs","names":[],"sources":["../../../src/hooks/query/use-llm-balance.ts"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport LLMBalanceService from \"#/api/llm-balance-service\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\n\n/**\n * Provider credit balance for the active local agent server.\n *\n * Fetched once per conversation load (the query key includes the\n * conversation id); use `refetch()` for the manual refresh affordance.\n * `data === null` means the server/provider doesn't support balance\n * reporting (404) — hide the UI. Errors also hide the UI (`retry: false`,\n * consumers check `isError`).\n */\nexport const useLLMBalance = (conversationId: string | null | undefined) => {\n const { backend } = useActiveBackend();\n\n return useQuery({\n queryKey: [\"llm-balance\", backend.id, conversationId],\n queryFn: () => LLMBalanceService.getBalance(),\n // Cloud conversations talk to the hosted app API, which has no\n // /api/llm/balance endpoint — don't probe it.\n enabled: backend.kind !== \"cloud\" && !!conversationId,\n staleTime: Infinity,\n gcTime: 1000 * 60 * 5,\n retry: false,\n refetchOnWindowFocus: false,\n });\n};\n"],"mappings":"4OAaA,IAAa,EAAiB,GAA8C,CAC1E,GAAM,CAAE,WAAY,EAAA,iBAAiB,EAErC,OAAO,EAAA,SAAS,CACd,SAAU,CAAC,cAAe,EAAQ,GAAI,CAAc,EACpD,YAAe,EAAA,QAAkB,WAAW,EAG5C,QAAS,EAAQ,OAAS,SAAW,CAAC,CAAC,EACvC,UAAW,IACX,OAAQ,IAAO,GAAK,EACpB,MAAO,GACP,qBAAsB,EACxB,CAAC,CACH"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Provider credit balance for the active local agent server.
3
+ *
4
+ * Fetched once per conversation load (the query key includes the
5
+ * conversation id); use `refetch()` for the manual refresh affordance.
6
+ * `data === null` means the server/provider doesn't support balance
7
+ * reporting (404) — hide the UI. Errors also hide the UI (`retry: false`,
8
+ * consumers check `isError`).
9
+ */
10
+ export declare const useLLMBalance: (conversationId: string | null | undefined) => import("@tanstack/react-query").UseQueryResult<NoInfer<import("#/api/llm-balance-service").LLMBalance | null>, import("axios").AxiosError<unknown, any>>;
@@ -0,0 +1,24 @@
1
+ import { useQuery as e } from "../../node_modules/@tanstack/react-query/build/modern/useQuery.js";
2
+ import { useActiveBackend as t } from "../../contexts/active-backend-context.js";
3
+ import n from "../../api/llm-balance-service.js";
4
+ //#region src/hooks/query/use-llm-balance.ts
5
+ var r = (r) => {
6
+ let { backend: i } = t();
7
+ return e({
8
+ queryKey: [
9
+ "llm-balance",
10
+ i.id,
11
+ r
12
+ ],
13
+ queryFn: () => n.getBalance(),
14
+ enabled: i.kind !== "cloud" && !!r,
15
+ staleTime: Infinity,
16
+ gcTime: 1e3 * 60 * 5,
17
+ retry: !1,
18
+ refetchOnWindowFocus: !1
19
+ });
20
+ };
21
+ //#endregion
22
+ export { r as useLLMBalance };
23
+
24
+ //# sourceMappingURL=use-llm-balance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-llm-balance.js","names":[],"sources":["../../../src/hooks/query/use-llm-balance.ts"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport LLMBalanceService from \"#/api/llm-balance-service\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\n\n/**\n * Provider credit balance for the active local agent server.\n *\n * Fetched once per conversation load (the query key includes the\n * conversation id); use `refetch()` for the manual refresh affordance.\n * `data === null` means the server/provider doesn't support balance\n * reporting (404) — hide the UI. Errors also hide the UI (`retry: false`,\n * consumers check `isError`).\n */\nexport const useLLMBalance = (conversationId: string | null | undefined) => {\n const { backend } = useActiveBackend();\n\n return useQuery({\n queryKey: [\"llm-balance\", backend.id, conversationId],\n queryFn: () => LLMBalanceService.getBalance(),\n // Cloud conversations talk to the hosted app API, which has no\n // /api/llm/balance endpoint — don't probe it.\n enabled: backend.kind !== \"cloud\" && !!conversationId,\n staleTime: Infinity,\n gcTime: 1000 * 60 * 5,\n retry: false,\n refetchOnWindowFocus: false,\n });\n};\n"],"mappings":";;;;AAaA,IAAa,KAAiB,MAA8C;CAC1E,IAAM,EAAE,eAAY,EAAiB;CAErC,OAAO,EAAS;EACd,UAAU;GAAC;GAAe,EAAQ;GAAI;EAAc;EACpD,eAAe,EAAkB,WAAW;EAG5C,SAAS,EAAQ,SAAS,WAAW,CAAC,CAAC;EACvC,WAAW;EACX,QAAQ,MAAO,KAAK;EACpB,OAAO;EACP,sBAAsB;CACxB,CAAC;AACH"}
@@ -1,2 +1,2 @@
1
- require("../../_virtual/_rolldown/runtime.cjs");const e=require("../../node_modules/@tanstack/react-query/build/modern/useQuery.cjs"),t=require("../../api/config-service/config-service.api.cjs"),n=require("./use-verified-models.cjs");var r=()=>e.useQuery({queryKey:[`config`,`providers`],queryFn:async({client:e})=>{let r=await e.fetchQuery({queryKey:n.VERIFIED_MODELS_QUERY_KEY,queryFn:n.fetchVerifiedModelsByProvider,staleTime:n.VERIFIED_MODELS_STALE_TIME});return(await t.default.searchProviders({limit:100},r)).items},staleTime:n.VERIFIED_MODELS_STALE_TIME,gcTime:n.VERIFIED_MODELS_GC_TIME});exports.useSearchProviders=r;
1
+ require("../../_virtual/_rolldown/runtime.cjs");const e=require("../../node_modules/@tanstack/react-query/build/modern/useQuery.cjs"),t=require("../../api/config-service/config-service.api.cjs"),n=require("./use-verified-models.cjs");var r=()=>e.useQuery({queryKey:[`config`,`providers`],queryFn:async({client:e})=>{let r=await e.fetchQuery({queryKey:n.VERIFIED_MODELS_QUERY_KEY,queryFn:n.fetchVerifiedModelsByProvider,staleTime:n.VERIFIED_MODELS_STALE_TIME});return(await t.default.searchProviders({},r)).items},staleTime:n.VERIFIED_MODELS_STALE_TIME,gcTime:n.VERIFIED_MODELS_GC_TIME});exports.useSearchProviders=r;
2
2
  //# sourceMappingURL=use-search-providers.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-search-providers.cjs","names":[],"sources":["../../../src/hooks/query/use-search-providers.ts"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport ConfigService from \"#/api/config-service/config-service.api\";\nimport type { LLMProvider } from \"#/api/config-service/config-service.types\";\nimport {\n VERIFIED_MODELS_GC_TIME,\n VERIFIED_MODELS_QUERY_KEY,\n VERIFIED_MODELS_STALE_TIME,\n fetchVerifiedModelsByProvider,\n} from \"./use-verified-models\";\n\nexport const useSearchProviders = () =>\n useQuery({\n queryKey: [\"config\", \"providers\"],\n queryFn: async ({ client }): Promise<LLMProvider[]> => {\n const verifiedByProvider = await client.fetchQuery({\n queryKey: VERIFIED_MODELS_QUERY_KEY,\n queryFn: fetchVerifiedModelsByProvider,\n staleTime: VERIFIED_MODELS_STALE_TIME,\n });\n // Providers are a small set; fetch all in one call with a high limit.\n const page = await ConfigService.searchProviders(\n { limit: 100 },\n verifiedByProvider,\n );\n return page.items;\n },\n staleTime: VERIFIED_MODELS_STALE_TIME,\n gcTime: VERIFIED_MODELS_GC_TIME,\n });\n"],"mappings":"0OAUA,IAAa,MACX,EAAA,SAAS,CACP,SAAU,CAAC,SAAU,WAAW,EAChC,QAAS,MAAO,CAAE,YAAqC,CACrD,IAAM,EAAqB,MAAM,EAAO,WAAW,CACjD,SAAU,EAAA,0BACV,QAAS,EAAA,8BACT,UAAW,EAAA,0BACb,CAAC,EAMD,OAAO,MAJY,EAAA,QAAc,gBAC/B,CAAE,MAAO,GAAI,EACb,CACF,GACY,KACd,EACA,UAAW,EAAA,2BACX,OAAQ,EAAA,uBACV,CAAC"}
1
+ {"version":3,"file":"use-search-providers.cjs","names":[],"sources":["../../../src/hooks/query/use-search-providers.ts"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport ConfigService from \"#/api/config-service/config-service.api\";\nimport type { LLMProvider } from \"#/api/config-service/config-service.types\";\nimport {\n VERIFIED_MODELS_GC_TIME,\n VERIFIED_MODELS_QUERY_KEY,\n VERIFIED_MODELS_STALE_TIME,\n fetchVerifiedModelsByProvider,\n} from \"./use-verified-models\";\n\nexport const useSearchProviders = () =>\n useQuery({\n queryKey: [\"config\", \"providers\"],\n queryFn: async ({ client }): Promise<LLMProvider[]> => {\n const verifiedByProvider = await client.fetchQuery({\n queryKey: VERIFIED_MODELS_QUERY_KEY,\n queryFn: fetchVerifiedModelsByProvider,\n staleTime: VERIFIED_MODELS_STALE_TIME,\n });\n // Fetch every provider in one call. Passing no limit is deliberate:\n // litellm exposes ~150 providers, so any fixed cap silently truncates\n // the picker: `openrouter` sorts past position 100 and disappears.\n const page = await ConfigService.searchProviders({}, verifiedByProvider);\n return page.items;\n },\n staleTime: VERIFIED_MODELS_STALE_TIME,\n gcTime: VERIFIED_MODELS_GC_TIME,\n });\n"],"mappings":"0OAUA,IAAa,MACX,EAAA,SAAS,CACP,SAAU,CAAC,SAAU,WAAW,EAChC,QAAS,MAAO,CAAE,YAAqC,CACrD,IAAM,EAAqB,MAAM,EAAO,WAAW,CACjD,SAAU,EAAA,0BACV,QAAS,EAAA,8BACT,UAAW,EAAA,0BACb,CAAC,EAKD,OAAO,MADY,EAAA,QAAc,gBAAgB,CAAC,EAAG,CAAkB,GAC3D,KACd,EACA,UAAW,EAAA,2BACX,OAAQ,EAAA,uBACV,CAAC"}
@@ -10,7 +10,7 @@ var o = () => e({
10
10
  queryFn: a,
11
11
  staleTime: i
12
12
  });
13
- return (await t.searchProviders({ limit: 100 }, n)).items;
13
+ return (await t.searchProviders({}, n)).items;
14
14
  },
15
15
  staleTime: i,
16
16
  gcTime: n
@@ -1 +1 @@
1
- {"version":3,"file":"use-search-providers.js","names":[],"sources":["../../../src/hooks/query/use-search-providers.ts"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport ConfigService from \"#/api/config-service/config-service.api\";\nimport type { LLMProvider } from \"#/api/config-service/config-service.types\";\nimport {\n VERIFIED_MODELS_GC_TIME,\n VERIFIED_MODELS_QUERY_KEY,\n VERIFIED_MODELS_STALE_TIME,\n fetchVerifiedModelsByProvider,\n} from \"./use-verified-models\";\n\nexport const useSearchProviders = () =>\n useQuery({\n queryKey: [\"config\", \"providers\"],\n queryFn: async ({ client }): Promise<LLMProvider[]> => {\n const verifiedByProvider = await client.fetchQuery({\n queryKey: VERIFIED_MODELS_QUERY_KEY,\n queryFn: fetchVerifiedModelsByProvider,\n staleTime: VERIFIED_MODELS_STALE_TIME,\n });\n // Providers are a small set; fetch all in one call with a high limit.\n const page = await ConfigService.searchProviders(\n { limit: 100 },\n verifiedByProvider,\n );\n return page.items;\n },\n staleTime: VERIFIED_MODELS_STALE_TIME,\n gcTime: VERIFIED_MODELS_GC_TIME,\n });\n"],"mappings":";;;;AAUA,IAAa,UACX,EAAS;CACP,UAAU,CAAC,UAAU,WAAW;CAChC,SAAS,OAAO,EAAE,gBAAqC;EACrD,IAAM,IAAqB,MAAM,EAAO,WAAW;GACjD,UAAU;GACV,SAAS;GACT,WAAW;EACb,CAAC;EAMD,QAAO,MAJY,EAAc,gBAC/B,EAAE,OAAO,IAAI,GACb,CACF,GACY;CACd;CACA,WAAW;CACX,QAAQ;AACV,CAAC"}
1
+ {"version":3,"file":"use-search-providers.js","names":[],"sources":["../../../src/hooks/query/use-search-providers.ts"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport ConfigService from \"#/api/config-service/config-service.api\";\nimport type { LLMProvider } from \"#/api/config-service/config-service.types\";\nimport {\n VERIFIED_MODELS_GC_TIME,\n VERIFIED_MODELS_QUERY_KEY,\n VERIFIED_MODELS_STALE_TIME,\n fetchVerifiedModelsByProvider,\n} from \"./use-verified-models\";\n\nexport const useSearchProviders = () =>\n useQuery({\n queryKey: [\"config\", \"providers\"],\n queryFn: async ({ client }): Promise<LLMProvider[]> => {\n const verifiedByProvider = await client.fetchQuery({\n queryKey: VERIFIED_MODELS_QUERY_KEY,\n queryFn: fetchVerifiedModelsByProvider,\n staleTime: VERIFIED_MODELS_STALE_TIME,\n });\n // Fetch every provider in one call. Passing no limit is deliberate:\n // litellm exposes ~150 providers, so any fixed cap silently truncates\n // the picker: `openrouter` sorts past position 100 and disappears.\n const page = await ConfigService.searchProviders({}, verifiedByProvider);\n return page.items;\n },\n staleTime: VERIFIED_MODELS_STALE_TIME,\n gcTime: VERIFIED_MODELS_GC_TIME,\n });\n"],"mappings":";;;;AAUA,IAAa,UACX,EAAS;CACP,UAAU,CAAC,UAAU,WAAW;CAChC,SAAS,OAAO,EAAE,gBAAqC;EACrD,IAAM,IAAqB,MAAM,EAAO,WAAW;GACjD,UAAU;GACV,SAAS;GACT,WAAW;EACb,CAAC;EAKD,QAAO,MADY,EAAc,gBAAgB,CAAC,GAAG,CAAkB,GAC3D;CACd;CACA,WAAW;CACX,QAAQ;AACV,CAAC"}
@@ -0,0 +1,2 @@
1
+ require("../_virtual/_rolldown/runtime.cjs");const e=require("../types/agent-server/type-guards.cjs"),t=require("../stores/use-event-store.cjs"),n=require("../stores/metrics-store.cjs");let r=require("react");var i=2500,a=9e4;function o(e,t,n){return{beforeToken:e,afterToken:t,savedToken:Math.max(0,e-t),outcome:n}}function s({beforeToken:s,baselineEventIds:c,onComplete:l,timeoutMs:u=a}){let d=(0,r.useRef)(l);d.current=l,(0,r.useEffect)(()=>{if(s===null)return;let r=!1,a=!1,l,f=c?new Set(c):new Set(t.useEventStore.getState().eventIds),p=()=>n.default.getState().usage?.per_turn_token??s,m=(e,t)=>{r||(r=!0,d.current(o(s,e,t)))},h=()=>{let e=p();return a&&e<s?(m(e,`compacted`),!0):!1},g=()=>{clearTimeout(l),l=setTimeout(()=>{m(p(),`no_change`)},i)},_=()=>{for(let n of t.useEventStore.getState().events){let t=`id`in n?n.id:void 0;if(t!==void 0){if(f.has(t))continue;f.add(t)}if(e.isCondensationEvent(n)){a=!0,h()||g();return}}};_();let v=t.useEventStore.subscribe(()=>{r||_()}),y=n.default.subscribe(()=>{r||h()&&clearTimeout(l)}),b=setTimeout(()=>{m(p(),a?`no_change`:`timeout`)},u);return()=>{r=!0,v(),y(),clearTimeout(l),clearTimeout(b)}},[s,c,u])}exports.useAwaitContextCompaction=s;
2
+ //# sourceMappingURL=use-await-context-compaction.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-await-context-compaction.cjs","names":[],"sources":["../../src/hooks/use-await-context-compaction.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport useMetricsStore from \"#/stores/metrics-store\";\nimport { useEventStore } from \"#/stores/use-event-store\";\nimport { isCondensationEvent } from \"#/types/agent-server/type-guards\";\n\n/** How long to wait after a Condensation event for a lower per_turn_token. */\nconst METRICS_SETTLE_MS = 2_500;\n/** Give up waiting for condensation / metrics and surface whatever we have. */\nconst DEFAULT_TIMEOUT_MS = 90_000;\n\nexport type ContextCompactionOutcome = \"compacted\" | \"no_change\" | \"timeout\";\n\nexport interface ContextCompactionResult {\n beforeToken: number;\n afterToken: number;\n savedToken: number;\n /**\n * \"compacted\" — a Condensation event landed and per_turn_token dropped.\n * \"no_change\" — a Condensation event landed but no token drop was measured.\n * \"timeout\" — no Condensation event arrived in time; compaction did not\n * happen (or was never processed), so this is a failure, not a no-op.\n */\n outcome: ContextCompactionOutcome;\n}\n\nexport function buildContextCompactionResult(\n beforeToken: number,\n afterToken: number,\n outcome: ContextCompactionOutcome,\n): ContextCompactionResult {\n return {\n beforeToken,\n afterToken,\n savedToken: Math.max(0, beforeToken - afterToken),\n outcome,\n };\n}\n\ninterface UseAwaitContextCompactionOptions {\n /**\n * Snapshot of `per_turn_token` taken when compaction was requested.\n * Pass `null` when not awaiting a result.\n */\n beforeToken: number | null;\n /**\n * Event ids that predate the compaction *request*. The condense POST can\n * return only after the server already emitted its Condensation event, so\n * snapshotting \"known\" ids when this effect starts would miss fast\n * condensations; the baseline must be captured before the request fires.\n * When omitted, falls back to the ids present when the effect starts.\n */\n baselineEventIds?: Set<string | number> | null;\n onComplete: (result: ContextCompactionResult) => void;\n timeoutMs?: number;\n}\n\n/**\n * Waits for a post-request Condensation event (and ideally a lower\n * `per_turn_token` in the live metrics store), then reports how many tokens\n * were freed. The HTTP `/condense` ack only means work *started*.\n */\nexport function useAwaitContextCompaction({\n beforeToken,\n baselineEventIds,\n onComplete,\n timeoutMs = DEFAULT_TIMEOUT_MS,\n}: UseAwaitContextCompactionOptions) {\n const onCompleteRef = useRef(onComplete);\n onCompleteRef.current = onComplete;\n\n useEffect(() => {\n if (beforeToken === null) {\n return undefined;\n }\n\n let completed = false;\n let sawCondensation = false;\n let settleTimer: ReturnType<typeof setTimeout> | undefined;\n const knownEventIds = baselineEventIds\n ? new Set(baselineEventIds)\n : new Set(useEventStore.getState().eventIds);\n\n const readAfterToken = () =>\n useMetricsStore.getState().usage?.per_turn_token ?? beforeToken;\n\n const finish = (afterToken: number, outcome: ContextCompactionOutcome) => {\n if (completed) {\n return;\n }\n completed = true;\n onCompleteRef.current(\n buildContextCompactionResult(beforeToken, afterToken, outcome),\n );\n };\n\n const finishFromMetricsIfReady = () => {\n const afterToken = readAfterToken();\n if (sawCondensation && afterToken < beforeToken) {\n finish(afterToken, \"compacted\");\n return true;\n }\n return false;\n };\n\n const scheduleSettleFinish = () => {\n clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n finish(readAfterToken(), \"no_change\");\n }, METRICS_SETTLE_MS);\n };\n\n const scanForNewCondensation = () => {\n for (const event of useEventStore.getState().events) {\n const eventId = \"id\" in event ? event.id : undefined;\n if (eventId !== undefined) {\n if (knownEventIds.has(eventId)) {\n continue;\n }\n knownEventIds.add(eventId);\n }\n if (!isCondensationEvent(event)) {\n continue;\n }\n sawCondensation = true;\n if (!finishFromMetricsIfReady()) {\n scheduleSettleFinish();\n }\n return;\n }\n };\n\n scanForNewCondensation();\n\n const unsubscribeEvents = useEventStore.subscribe(() => {\n if (completed) {\n return;\n }\n scanForNewCondensation();\n });\n\n const unsubscribeMetrics = useMetricsStore.subscribe(() => {\n if (completed) {\n return;\n }\n if (finishFromMetricsIfReady()) {\n clearTimeout(settleTimer);\n }\n });\n\n const timeoutTimer = setTimeout(() => {\n // No Condensation event in time means the compaction never landed —\n // a failure, not a \"nothing to compact\" no-op.\n finish(readAfterToken(), sawCondensation ? \"no_change\" : \"timeout\");\n }, timeoutMs);\n\n return () => {\n completed = true;\n unsubscribeEvents();\n unsubscribeMetrics();\n clearTimeout(settleTimer);\n clearTimeout(timeoutTimer);\n };\n }, [beforeToken, baselineEventIds, timeoutMs]);\n}\n"],"mappings":"iNAMA,IAAM,EAAoB,KAEpB,EAAqB,IAiB3B,SAAgB,EACd,EACA,EACA,EACyB,CACzB,MAAO,CACL,cACA,aACA,WAAY,KAAK,IAAI,EAAG,EAAc,CAAU,EAChD,SACF,CACF,CAyBA,SAAgB,EAA0B,CACxC,cACA,mBACA,aACA,YAAY,GACuB,CACnC,IAAM,GAAA,EAAA,EAAA,QAAuB,CAAU,EACvC,EAAc,QAAU,GAExB,EAAA,EAAA,eAAgB,CACd,GAAI,IAAgB,KAClB,OAGF,IAAI,EAAY,GACZ,EAAkB,GAClB,EACE,EAAgB,EAClB,IAAI,IAAI,CAAgB,EACxB,IAAI,IAAI,EAAA,cAAc,SAAS,EAAE,QAAQ,EAEvC,MACJ,EAAA,QAAgB,SAAS,EAAE,OAAO,gBAAkB,EAEhD,GAAU,EAAoB,IAAsC,CACpE,IAGJ,EAAY,GACZ,EAAc,QACZ,EAA6B,EAAa,EAAY,CAAO,CAC/D,EACF,EAEM,MAAiC,CACrC,IAAM,EAAa,EAAe,EAKlC,OAJI,GAAmB,EAAa,GAClC,EAAO,EAAY,WAAW,EACvB,IAEF,EACT,EAEM,MAA6B,CACjC,aAAa,CAAW,EACxB,EAAc,eAAiB,CAC7B,EAAO,EAAe,EAAG,WAAW,CACtC,EAAG,CAAiB,CACtB,EAEM,MAA+B,CACnC,IAAK,IAAM,KAAS,EAAA,cAAc,SAAS,EAAE,OAAQ,CACnD,IAAM,EAAU,OAAQ,EAAQ,EAAM,GAAK,IAAA,GAC3C,GAAI,IAAY,IAAA,GAAW,CACzB,GAAI,EAAc,IAAI,CAAO,EAC3B,SAEF,EAAc,IAAI,CAAO,CAC3B,CACK,KAAA,oBAAoB,CAAK,EAI9B,CADA,EAAkB,GACb,EAAyB,GAC5B,EAAqB,EAEvB,MAFuB,CAGzB,CACF,EAEA,EAAuB,EAEvB,IAAM,EAAoB,EAAA,cAAc,cAAgB,CAClD,GAGJ,EAAuB,CACzB,CAAC,EAEK,EAAqB,EAAA,QAAgB,cAAgB,CACrD,GAGA,EAAyB,GAC3B,aAAa,CAAW,CAE5B,CAAC,EAEK,EAAe,eAAiB,CAGpC,EAAO,EAAe,EAAG,EAAkB,YAAc,SAAS,CACpE,EAAG,CAAS,EAEZ,UAAa,CACX,EAAY,GACZ,EAAkB,EAClB,EAAmB,EACnB,aAAa,CAAW,EACxB,aAAa,CAAY,CAC3B,CACF,EAAG,CAAC,EAAa,EAAkB,CAAS,CAAC,CAC/C"}
@@ -0,0 +1,38 @@
1
+ export type ContextCompactionOutcome = "compacted" | "no_change" | "timeout";
2
+ export interface ContextCompactionResult {
3
+ beforeToken: number;
4
+ afterToken: number;
5
+ savedToken: number;
6
+ /**
7
+ * "compacted" — a Condensation event landed and per_turn_token dropped.
8
+ * "no_change" — a Condensation event landed but no token drop was measured.
9
+ * "timeout" — no Condensation event arrived in time; compaction did not
10
+ * happen (or was never processed), so this is a failure, not a no-op.
11
+ */
12
+ outcome: ContextCompactionOutcome;
13
+ }
14
+ export declare function buildContextCompactionResult(beforeToken: number, afterToken: number, outcome: ContextCompactionOutcome): ContextCompactionResult;
15
+ interface UseAwaitContextCompactionOptions {
16
+ /**
17
+ * Snapshot of `per_turn_token` taken when compaction was requested.
18
+ * Pass `null` when not awaiting a result.
19
+ */
20
+ beforeToken: number | null;
21
+ /**
22
+ * Event ids that predate the compaction *request*. The condense POST can
23
+ * return only after the server already emitted its Condensation event, so
24
+ * snapshotting "known" ids when this effect starts would miss fast
25
+ * condensations; the baseline must be captured before the request fires.
26
+ * When omitted, falls back to the ids present when the effect starts.
27
+ */
28
+ baselineEventIds?: Set<string | number> | null;
29
+ onComplete: (result: ContextCompactionResult) => void;
30
+ timeoutMs?: number;
31
+ }
32
+ /**
33
+ * Waits for a post-request Condensation event (and ideally a lower
34
+ * `per_turn_token` in the live metrics store), then reports how many tokens
35
+ * were freed. The HTTP `/condense` ack only means work *started*.
36
+ */
37
+ export declare function useAwaitContextCompaction({ beforeToken, baselineEventIds, onComplete, timeoutMs, }: UseAwaitContextCompactionOptions): void;
38
+ export {};
@@ -0,0 +1,61 @@
1
+ import { isCondensationEvent as e } from "../types/agent-server/type-guards.js";
2
+ import { useEventStore as t } from "../stores/use-event-store.js";
3
+ import n from "../stores/metrics-store.js";
4
+ import { useEffect as r, useRef as i } from "react";
5
+ //#region src/hooks/use-await-context-compaction.ts
6
+ var a = 2500, o = 9e4;
7
+ function s(e, t, n) {
8
+ return {
9
+ beforeToken: e,
10
+ afterToken: t,
11
+ savedToken: Math.max(0, e - t),
12
+ outcome: n
13
+ };
14
+ }
15
+ function c({ beforeToken: c, baselineEventIds: l, onComplete: u, timeoutMs: d = o }) {
16
+ let f = i(u);
17
+ f.current = u, r(() => {
18
+ if (c === null) return;
19
+ let r = !1, i = !1, o, u = l ? new Set(l) : new Set(t.getState().eventIds), p = () => n.getState().usage?.per_turn_token ?? c, m = (e, t) => {
20
+ r || (r = !0, f.current(s(c, e, t)));
21
+ }, h = () => {
22
+ let e = p();
23
+ return i && e < c ? (m(e, "compacted"), !0) : !1;
24
+ }, g = () => {
25
+ clearTimeout(o), o = setTimeout(() => {
26
+ m(p(), "no_change");
27
+ }, a);
28
+ }, _ = () => {
29
+ for (let n of t.getState().events) {
30
+ let t = "id" in n ? n.id : void 0;
31
+ if (t !== void 0) {
32
+ if (u.has(t)) continue;
33
+ u.add(t);
34
+ }
35
+ if (e(n)) {
36
+ i = !0, h() || g();
37
+ return;
38
+ }
39
+ }
40
+ };
41
+ _();
42
+ let v = t.subscribe(() => {
43
+ r || _();
44
+ }), y = n.subscribe(() => {
45
+ r || h() && clearTimeout(o);
46
+ }), b = setTimeout(() => {
47
+ m(p(), i ? "no_change" : "timeout");
48
+ }, d);
49
+ return () => {
50
+ r = !0, v(), y(), clearTimeout(o), clearTimeout(b);
51
+ };
52
+ }, [
53
+ c,
54
+ l,
55
+ d
56
+ ]);
57
+ }
58
+ //#endregion
59
+ export { c as useAwaitContextCompaction };
60
+
61
+ //# sourceMappingURL=use-await-context-compaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-await-context-compaction.js","names":[],"sources":["../../src/hooks/use-await-context-compaction.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport useMetricsStore from \"#/stores/metrics-store\";\nimport { useEventStore } from \"#/stores/use-event-store\";\nimport { isCondensationEvent } from \"#/types/agent-server/type-guards\";\n\n/** How long to wait after a Condensation event for a lower per_turn_token. */\nconst METRICS_SETTLE_MS = 2_500;\n/** Give up waiting for condensation / metrics and surface whatever we have. */\nconst DEFAULT_TIMEOUT_MS = 90_000;\n\nexport type ContextCompactionOutcome = \"compacted\" | \"no_change\" | \"timeout\";\n\nexport interface ContextCompactionResult {\n beforeToken: number;\n afterToken: number;\n savedToken: number;\n /**\n * \"compacted\" — a Condensation event landed and per_turn_token dropped.\n * \"no_change\" — a Condensation event landed but no token drop was measured.\n * \"timeout\" — no Condensation event arrived in time; compaction did not\n * happen (or was never processed), so this is a failure, not a no-op.\n */\n outcome: ContextCompactionOutcome;\n}\n\nexport function buildContextCompactionResult(\n beforeToken: number,\n afterToken: number,\n outcome: ContextCompactionOutcome,\n): ContextCompactionResult {\n return {\n beforeToken,\n afterToken,\n savedToken: Math.max(0, beforeToken - afterToken),\n outcome,\n };\n}\n\ninterface UseAwaitContextCompactionOptions {\n /**\n * Snapshot of `per_turn_token` taken when compaction was requested.\n * Pass `null` when not awaiting a result.\n */\n beforeToken: number | null;\n /**\n * Event ids that predate the compaction *request*. The condense POST can\n * return only after the server already emitted its Condensation event, so\n * snapshotting \"known\" ids when this effect starts would miss fast\n * condensations; the baseline must be captured before the request fires.\n * When omitted, falls back to the ids present when the effect starts.\n */\n baselineEventIds?: Set<string | number> | null;\n onComplete: (result: ContextCompactionResult) => void;\n timeoutMs?: number;\n}\n\n/**\n * Waits for a post-request Condensation event (and ideally a lower\n * `per_turn_token` in the live metrics store), then reports how many tokens\n * were freed. The HTTP `/condense` ack only means work *started*.\n */\nexport function useAwaitContextCompaction({\n beforeToken,\n baselineEventIds,\n onComplete,\n timeoutMs = DEFAULT_TIMEOUT_MS,\n}: UseAwaitContextCompactionOptions) {\n const onCompleteRef = useRef(onComplete);\n onCompleteRef.current = onComplete;\n\n useEffect(() => {\n if (beforeToken === null) {\n return undefined;\n }\n\n let completed = false;\n let sawCondensation = false;\n let settleTimer: ReturnType<typeof setTimeout> | undefined;\n const knownEventIds = baselineEventIds\n ? new Set(baselineEventIds)\n : new Set(useEventStore.getState().eventIds);\n\n const readAfterToken = () =>\n useMetricsStore.getState().usage?.per_turn_token ?? beforeToken;\n\n const finish = (afterToken: number, outcome: ContextCompactionOutcome) => {\n if (completed) {\n return;\n }\n completed = true;\n onCompleteRef.current(\n buildContextCompactionResult(beforeToken, afterToken, outcome),\n );\n };\n\n const finishFromMetricsIfReady = () => {\n const afterToken = readAfterToken();\n if (sawCondensation && afterToken < beforeToken) {\n finish(afterToken, \"compacted\");\n return true;\n }\n return false;\n };\n\n const scheduleSettleFinish = () => {\n clearTimeout(settleTimer);\n settleTimer = setTimeout(() => {\n finish(readAfterToken(), \"no_change\");\n }, METRICS_SETTLE_MS);\n };\n\n const scanForNewCondensation = () => {\n for (const event of useEventStore.getState().events) {\n const eventId = \"id\" in event ? event.id : undefined;\n if (eventId !== undefined) {\n if (knownEventIds.has(eventId)) {\n continue;\n }\n knownEventIds.add(eventId);\n }\n if (!isCondensationEvent(event)) {\n continue;\n }\n sawCondensation = true;\n if (!finishFromMetricsIfReady()) {\n scheduleSettleFinish();\n }\n return;\n }\n };\n\n scanForNewCondensation();\n\n const unsubscribeEvents = useEventStore.subscribe(() => {\n if (completed) {\n return;\n }\n scanForNewCondensation();\n });\n\n const unsubscribeMetrics = useMetricsStore.subscribe(() => {\n if (completed) {\n return;\n }\n if (finishFromMetricsIfReady()) {\n clearTimeout(settleTimer);\n }\n });\n\n const timeoutTimer = setTimeout(() => {\n // No Condensation event in time means the compaction never landed —\n // a failure, not a \"nothing to compact\" no-op.\n finish(readAfterToken(), sawCondensation ? \"no_change\" : \"timeout\");\n }, timeoutMs);\n\n return () => {\n completed = true;\n unsubscribeEvents();\n unsubscribeMetrics();\n clearTimeout(settleTimer);\n clearTimeout(timeoutTimer);\n };\n }, [beforeToken, baselineEventIds, timeoutMs]);\n}\n"],"mappings":";;;;;AAMA,IAAM,IAAoB,MAEpB,IAAqB;AAiB3B,SAAgB,EACd,GACA,GACA,GACyB;CACzB,OAAO;EACL;EACA;EACA,YAAY,KAAK,IAAI,GAAG,IAAc,CAAU;EAChD;CACF;AACF;AAyBA,SAAgB,EAA0B,EACxC,gBACA,qBACA,eACA,eAAY,KACuB;CACnC,IAAM,IAAgB,EAAO,CAAU;CAGvC,AAFA,EAAc,UAAU,GAExB,QAAgB;EACd,IAAI,MAAgB,MAClB;EAGF,IAAI,IAAY,IACZ,IAAkB,IAClB,GACE,IAAgB,IAClB,IAAI,IAAI,CAAgB,IACxB,IAAI,IAAI,EAAc,SAAS,EAAE,QAAQ,GAEvC,UACJ,EAAgB,SAAS,EAAE,OAAO,kBAAkB,GAEhD,KAAU,GAAoB,MAAsC;GACpE,MAGJ,IAAY,IACZ,EAAc,QACZ,EAA6B,GAAa,GAAY,CAAO,CAC/D;EACF,GAEM,UAAiC;GACrC,IAAM,IAAa,EAAe;GAKlC,OAJI,KAAmB,IAAa,KAClC,EAAO,GAAY,WAAW,GACvB,MAEF;EACT,GAEM,UAA6B;GAEjC,AADA,aAAa,CAAW,GACxB,IAAc,iBAAiB;IAC7B,EAAO,EAAe,GAAG,WAAW;GACtC,GAAG,CAAiB;EACtB,GAEM,UAA+B;GACnC,KAAK,IAAM,KAAS,EAAc,SAAS,EAAE,QAAQ;IACnD,IAAM,IAAU,QAAQ,IAAQ,EAAM,KAAK,KAAA;IAC3C,IAAI,MAAY,KAAA,GAAW;KACzB,IAAI,EAAc,IAAI,CAAO,GAC3B;KAEF,EAAc,IAAI,CAAO;IAC3B;IACK,MAAoB,CAAK,GAI9B;KADA,IAAkB,IACb,EAAyB,KAC5B,EAAqB;KAEvB;IAFuB;GAGzB;EACF;EAEA,EAAuB;EAEvB,IAAM,IAAoB,EAAc,gBAAgB;GAClD,KAGJ,EAAuB;EACzB,CAAC,GAEK,IAAqB,EAAgB,gBAAgB;GACrD,KAGA,EAAyB,KAC3B,aAAa,CAAW;EAE5B,CAAC,GAEK,IAAe,iBAAiB;GAGpC,EAAO,EAAe,GAAG,IAAkB,cAAc,SAAS;EACpE,GAAG,CAAS;EAEZ,aAAa;GAKX,AAJA,IAAY,IACZ,EAAkB,GAClB,EAAmB,GACnB,aAAa,CAAW,GACxB,aAAa,CAAY;EAC3B;CACF,GAAG;EAAC;EAAa;EAAkB;CAAS,CAAC;AAC/C"}
@@ -0,0 +1,2 @@
1
+ const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../node_modules/react-i18next/dist/es/useTranslation.cjs"),n=require("../i18n/declaration.cjs"),r=require("../types/agent-state.cjs"),i=require("../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs"),a=require("../utils/retrieve-axios-error-message.cjs"),o=require("../utils/custom-toast-handlers.cjs"),s=require("../stores/use-event-store.cjs"),c=require("../stores/metrics-store.cjs"),l=require("./query/use-active-conversation.cjs"),u=require("./use-agent-state.cjs"),d=require("./mutation/use-condense-conversation.cjs"),f=require("./use-await-context-compaction.cjs"),p=require("../utils/format-token-count.cjs");let m=require("react");m=e.__toESM(m,1);function h(e=0){let{t:h}=t.useTranslation(`openhands`),g=i.useQueryClient(),{data:_}=l.useActiveConversation(),{curAgentState:v}=u.useAgentState(),{mutate:y,isPending:b}=d.useCondenseConversation(),[x,S]=m.default.useState(null),C=m.default.useRef(null),w=v===r.AgentState.RUNNING||v===r.AgentState.LOADING,T=b||x!==null,E=!_?.id||w||T,D=h(n.I18nKey.CONVERSATION$COMPACT_CONTEXT_DESCRIPTION),O=m.default.useEffectEvent(e=>{if(S(null),C.current=null,_?.id&&g.invalidateQueries({queryKey:[`conversation-metrics`,_.id]}),e.outcome===`timeout`){o.displayErrorToast(h(n.I18nKey.CONVERSATION$COMPACT_CONTEXT_FAILED));return}if(e.savedToken>0){o.displaySuccessToast(h(n.I18nKey.CONVERSATION$COMPACT_CONTEXT_COMPLETE,{saved:p.formatCompactTokenCount(e.savedToken),before:p.formatCompactTokenCount(e.beforeToken),after:p.formatCompactTokenCount(e.afterToken)}));return}o.displaySuccessToast(h(n.I18nKey.CONVERSATION$COMPACT_CONTEXT_COMPLETE_NO_CHANGE))});return f.useAwaitContextCompaction({beforeToken:x,baselineEventIds:x===null?null:C.current,onComplete:O}),{handleCompact:()=>{if(!_?.id||T)return;let t=c.default.getState().usage?.per_turn_token??e;C.current=new Set(s.useEventStore.getState().eventIds),y({conversationId:_.id,conversationUrl:_.conversation_url,sessionApiKey:_.session_api_key},{onSuccess:()=>{S(t),o.displaySuccessToast(h(n.I18nKey.CONVERSATION$COMPACT_CONTEXT_STARTED))},onError:e=>{S(null),C.current=null,o.displayErrorToast(a.retrieveAxiosErrorMessage(e)||h(n.I18nKey.CONVERSATION$COMPACT_CONTEXT_FAILED))}})},isCompacting:T,isDisabled:E,description:D}}exports.useCompactContextAction=h;
2
+ //# sourceMappingURL=use-compact-context-action.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-compact-context-action.cjs","names":[],"sources":["../../src/hooks/use-compact-context-action.ts"],"sourcesContent":["import React from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\nimport { useCondenseConversation } from \"#/hooks/mutation/use-condense-conversation\";\nimport {\n type ContextCompactionResult,\n useAwaitContextCompaction,\n} from \"#/hooks/use-await-context-compaction\";\nimport { AgentState } from \"#/types/agent-state\";\nimport useMetricsStore from \"#/stores/metrics-store\";\nimport { useEventStore } from \"#/stores/use-event-store\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { formatCompactTokenCount } from \"#/utils/format-token-count\";\nimport { retrieveAxiosErrorMessage } from \"#/utils/retrieve-axios-error-message\";\n\n/**\n * Shared compact/condense action used by the Usage panel CTA and the\n * composer context-window popover.\n */\nexport function useCompactContextAction(perTurnToken: number = 0) {\n const { t } = useTranslation(\"openhands\");\n const queryClient = useQueryClient();\n const { data: conversation } = useActiveConversation();\n const { curAgentState } = useAgentState();\n const { mutate: condense, isPending } = useCondenseConversation();\n const [beforeToken, setBeforeToken] = React.useState<number | null>(null);\n const baselineEventIdsRef = React.useRef<Set<string | number> | null>(null);\n\n const isAgentBusy =\n curAgentState === AgentState.RUNNING ||\n curAgentState === AgentState.LOADING;\n const isCompacting = isPending || beforeToken !== null;\n const isDisabled = !conversation?.id || isAgentBusy || isCompacting;\n const description = t(I18nKey.CONVERSATION$COMPACT_CONTEXT_DESCRIPTION);\n\n const handleCompactionComplete = React.useEffectEvent(\n (result: ContextCompactionResult) => {\n setBeforeToken(null);\n baselineEventIdsRef.current = null;\n if (conversation?.id) {\n queryClient.invalidateQueries({\n queryKey: [\"conversation-metrics\", conversation.id],\n });\n }\n\n if (result.outcome === \"timeout\") {\n displayErrorToast(t(I18nKey.CONVERSATION$COMPACT_CONTEXT_FAILED));\n return;\n }\n\n if (result.savedToken > 0) {\n displaySuccessToast(\n t(I18nKey.CONVERSATION$COMPACT_CONTEXT_COMPLETE, {\n saved: formatCompactTokenCount(result.savedToken),\n before: formatCompactTokenCount(result.beforeToken),\n after: formatCompactTokenCount(result.afterToken),\n }),\n );\n return;\n }\n\n displaySuccessToast(\n t(I18nKey.CONVERSATION$COMPACT_CONTEXT_COMPLETE_NO_CHANGE),\n );\n },\n );\n\n useAwaitContextCompaction({\n beforeToken,\n baselineEventIds: beforeToken !== null ? baselineEventIdsRef.current : null,\n onComplete: handleCompactionComplete,\n });\n\n const handleCompact = () => {\n if (!conversation?.id || isCompacting) return;\n\n const snapshot =\n useMetricsStore.getState().usage?.per_turn_token ?? perTurnToken;\n // The condense POST can return only after the server already emitted its\n // Condensation event, so the await baseline must be captured *before* the\n // request fires, not when the post-ack effect starts.\n baselineEventIdsRef.current = new Set(useEventStore.getState().eventIds);\n\n condense(\n {\n conversationId: conversation.id,\n conversationUrl: conversation.conversation_url,\n sessionApiKey: conversation.session_api_key,\n },\n {\n onSuccess: () => {\n setBeforeToken(snapshot);\n displaySuccessToast(t(I18nKey.CONVERSATION$COMPACT_CONTEXT_STARTED));\n },\n onError: (error) => {\n setBeforeToken(null);\n baselineEventIdsRef.current = null;\n displayErrorToast(\n retrieveAxiosErrorMessage(error) ||\n t(I18nKey.CONVERSATION$COMPACT_CONTEXT_FAILED),\n );\n },\n },\n );\n };\n\n return {\n handleCompact,\n isCompacting,\n isDisabled,\n description,\n };\n}\n"],"mappings":"wuBAyBA,SAAgB,EAAwB,EAAuB,EAAG,CAChE,GAAM,CAAE,KAAM,EAAA,eAAe,WAAW,EAClC,EAAc,EAAA,eAAe,EAC7B,CAAE,KAAM,GAAiB,EAAA,sBAAsB,EAC/C,CAAE,iBAAkB,EAAA,cAAc,EAClC,CAAE,OAAQ,EAAU,aAAc,EAAA,wBAAwB,EAC1D,CAAC,EAAa,GAAkB,EAAA,QAAM,SAAwB,IAAI,EAClE,EAAsB,EAAA,QAAM,OAAoC,IAAI,EAEpE,EACJ,IAAkB,EAAA,WAAW,SAC7B,IAAkB,EAAA,WAAW,QACzB,EAAe,GAAa,IAAgB,KAC5C,EAAa,CAAC,GAAc,IAAM,GAAe,EACjD,EAAc,EAAE,EAAA,QAAQ,wCAAwC,EAEhE,EAA2B,EAAA,QAAM,eACpC,GAAoC,CASnC,GARA,EAAe,IAAI,EACnB,EAAoB,QAAU,KAC1B,GAAc,IAChB,EAAY,kBAAkB,CAC5B,SAAU,CAAC,uBAAwB,EAAa,EAAE,CACpD,CAAC,EAGC,EAAO,UAAY,UAAW,CAChC,EAAA,kBAAkB,EAAE,EAAA,QAAQ,mCAAmC,CAAC,EAChE,MACF,CAEA,GAAI,EAAO,WAAa,EAAG,CACzB,EAAA,oBACE,EAAE,EAAA,QAAQ,sCAAuC,CAC/C,MAAO,EAAA,wBAAwB,EAAO,UAAU,EAChD,OAAQ,EAAA,wBAAwB,EAAO,WAAW,EAClD,MAAO,EAAA,wBAAwB,EAAO,UAAU,CAClD,CAAC,CACH,EACA,MACF,CAEA,EAAA,oBACE,EAAE,EAAA,QAAQ,+CAA+C,CAC3D,CACF,CACF,EAyCA,OAvCA,EAAA,0BAA0B,CACxB,cACA,iBAAkB,IAAgB,KAAqC,KAA9B,EAAoB,QAC7D,WAAY,CACd,CAAC,EAmCM,CACL,kBAlC0B,CAC1B,GAAI,CAAC,GAAc,IAAM,EAAc,OAEvC,IAAM,EACJ,EAAA,QAAgB,SAAS,EAAE,OAAO,gBAAkB,EAItD,EAAoB,QAAU,IAAI,IAAI,EAAA,cAAc,SAAS,EAAE,QAAQ,EAEvE,EACE,CACE,eAAgB,EAAa,GAC7B,gBAAiB,EAAa,iBAC9B,cAAe,EAAa,eAC9B,EACA,CACE,cAAiB,CACf,EAAe,CAAQ,EACvB,EAAA,oBAAoB,EAAE,EAAA,QAAQ,oCAAoC,CAAC,CACrE,EACA,QAAU,GAAU,CAClB,EAAe,IAAI,EACnB,EAAoB,QAAU,KAC9B,EAAA,kBACE,EAAA,0BAA0B,CAAK,GAC7B,EAAE,EAAA,QAAQ,mCAAmC,CACjD,CACF,CACF,CACF,CACF,EAIE,eACA,aACA,aACF,CACF"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shared compact/condense action used by the Usage panel CTA and the
3
+ * composer context-window popover.
4
+ */
5
+ export declare function useCompactContextAction(perTurnToken?: number): {
6
+ handleCompact: () => void;
7
+ isCompacting: boolean;
8
+ isDisabled: boolean;
9
+ description: string;
10
+ };
@@ -0,0 +1,61 @@
1
+ import { useTranslation as e } from "../node_modules/react-i18next/dist/es/useTranslation.js";
2
+ import { I18nKey as t } from "../i18n/declaration.js";
3
+ import { AgentState as n } from "../types/agent-state.js";
4
+ import { useQueryClient as r } from "../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js";
5
+ import { retrieveAxiosErrorMessage as i } from "../utils/retrieve-axios-error-message.js";
6
+ import { displayErrorToast as a, displaySuccessToast as o } from "../utils/custom-toast-handlers.js";
7
+ import { useEventStore as s } from "../stores/use-event-store.js";
8
+ import c from "../stores/metrics-store.js";
9
+ import { useActiveConversation as l } from "./query/use-active-conversation.js";
10
+ import { useAgentState as u } from "./use-agent-state.js";
11
+ import { useCondenseConversation as d } from "./mutation/use-condense-conversation.js";
12
+ import { useAwaitContextCompaction as f } from "./use-await-context-compaction.js";
13
+ import { formatCompactTokenCount as p } from "../utils/format-token-count.js";
14
+ import m from "react";
15
+ //#region src/hooks/use-compact-context-action.ts
16
+ function h(h = 0) {
17
+ let { t: g } = e("openhands"), _ = r(), { data: v } = l(), { curAgentState: y } = u(), { mutate: b, isPending: x } = d(), [S, C] = m.useState(null), w = m.useRef(null), T = y === n.RUNNING || y === n.LOADING, E = x || S !== null, D = !v?.id || T || E, O = g(t.CONVERSATION$COMPACT_CONTEXT_DESCRIPTION), k = m.useEffectEvent((e) => {
18
+ if (C(null), w.current = null, v?.id && _.invalidateQueries({ queryKey: ["conversation-metrics", v.id] }), e.outcome === "timeout") {
19
+ a(g(t.CONVERSATION$COMPACT_CONTEXT_FAILED));
20
+ return;
21
+ }
22
+ if (e.savedToken > 0) {
23
+ o(g(t.CONVERSATION$COMPACT_CONTEXT_COMPLETE, {
24
+ saved: p(e.savedToken),
25
+ before: p(e.beforeToken),
26
+ after: p(e.afterToken)
27
+ }));
28
+ return;
29
+ }
30
+ o(g(t.CONVERSATION$COMPACT_CONTEXT_COMPLETE_NO_CHANGE));
31
+ });
32
+ return f({
33
+ beforeToken: S,
34
+ baselineEventIds: S === null ? null : w.current,
35
+ onComplete: k
36
+ }), {
37
+ handleCompact: () => {
38
+ if (!v?.id || E) return;
39
+ let e = c.getState().usage?.per_turn_token ?? h;
40
+ w.current = new Set(s.getState().eventIds), b({
41
+ conversationId: v.id,
42
+ conversationUrl: v.conversation_url,
43
+ sessionApiKey: v.session_api_key
44
+ }, {
45
+ onSuccess: () => {
46
+ C(e), o(g(t.CONVERSATION$COMPACT_CONTEXT_STARTED));
47
+ },
48
+ onError: (e) => {
49
+ C(null), w.current = null, a(i(e) || g(t.CONVERSATION$COMPACT_CONTEXT_FAILED));
50
+ }
51
+ });
52
+ },
53
+ isCompacting: E,
54
+ isDisabled: D,
55
+ description: O
56
+ };
57
+ }
58
+ //#endregion
59
+ export { h as useCompactContextAction };
60
+
61
+ //# sourceMappingURL=use-compact-context-action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-compact-context-action.js","names":[],"sources":["../../src/hooks/use-compact-context-action.ts"],"sourcesContent":["import React from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\nimport { useCondenseConversation } from \"#/hooks/mutation/use-condense-conversation\";\nimport {\n type ContextCompactionResult,\n useAwaitContextCompaction,\n} from \"#/hooks/use-await-context-compaction\";\nimport { AgentState } from \"#/types/agent-state\";\nimport useMetricsStore from \"#/stores/metrics-store\";\nimport { useEventStore } from \"#/stores/use-event-store\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { formatCompactTokenCount } from \"#/utils/format-token-count\";\nimport { retrieveAxiosErrorMessage } from \"#/utils/retrieve-axios-error-message\";\n\n/**\n * Shared compact/condense action used by the Usage panel CTA and the\n * composer context-window popover.\n */\nexport function useCompactContextAction(perTurnToken: number = 0) {\n const { t } = useTranslation(\"openhands\");\n const queryClient = useQueryClient();\n const { data: conversation } = useActiveConversation();\n const { curAgentState } = useAgentState();\n const { mutate: condense, isPending } = useCondenseConversation();\n const [beforeToken, setBeforeToken] = React.useState<number | null>(null);\n const baselineEventIdsRef = React.useRef<Set<string | number> | null>(null);\n\n const isAgentBusy =\n curAgentState === AgentState.RUNNING ||\n curAgentState === AgentState.LOADING;\n const isCompacting = isPending || beforeToken !== null;\n const isDisabled = !conversation?.id || isAgentBusy || isCompacting;\n const description = t(I18nKey.CONVERSATION$COMPACT_CONTEXT_DESCRIPTION);\n\n const handleCompactionComplete = React.useEffectEvent(\n (result: ContextCompactionResult) => {\n setBeforeToken(null);\n baselineEventIdsRef.current = null;\n if (conversation?.id) {\n queryClient.invalidateQueries({\n queryKey: [\"conversation-metrics\", conversation.id],\n });\n }\n\n if (result.outcome === \"timeout\") {\n displayErrorToast(t(I18nKey.CONVERSATION$COMPACT_CONTEXT_FAILED));\n return;\n }\n\n if (result.savedToken > 0) {\n displaySuccessToast(\n t(I18nKey.CONVERSATION$COMPACT_CONTEXT_COMPLETE, {\n saved: formatCompactTokenCount(result.savedToken),\n before: formatCompactTokenCount(result.beforeToken),\n after: formatCompactTokenCount(result.afterToken),\n }),\n );\n return;\n }\n\n displaySuccessToast(\n t(I18nKey.CONVERSATION$COMPACT_CONTEXT_COMPLETE_NO_CHANGE),\n );\n },\n );\n\n useAwaitContextCompaction({\n beforeToken,\n baselineEventIds: beforeToken !== null ? baselineEventIdsRef.current : null,\n onComplete: handleCompactionComplete,\n });\n\n const handleCompact = () => {\n if (!conversation?.id || isCompacting) return;\n\n const snapshot =\n useMetricsStore.getState().usage?.per_turn_token ?? perTurnToken;\n // The condense POST can return only after the server already emitted its\n // Condensation event, so the await baseline must be captured *before* the\n // request fires, not when the post-ack effect starts.\n baselineEventIdsRef.current = new Set(useEventStore.getState().eventIds);\n\n condense(\n {\n conversationId: conversation.id,\n conversationUrl: conversation.conversation_url,\n sessionApiKey: conversation.session_api_key,\n },\n {\n onSuccess: () => {\n setBeforeToken(snapshot);\n displaySuccessToast(t(I18nKey.CONVERSATION$COMPACT_CONTEXT_STARTED));\n },\n onError: (error) => {\n setBeforeToken(null);\n baselineEventIdsRef.current = null;\n displayErrorToast(\n retrieveAxiosErrorMessage(error) ||\n t(I18nKey.CONVERSATION$COMPACT_CONTEXT_FAILED),\n );\n },\n },\n );\n };\n\n return {\n handleCompact,\n isCompacting,\n isDisabled,\n description,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;AAyBA,SAAgB,EAAwB,IAAuB,GAAG;CAChE,IAAM,EAAE,SAAM,EAAe,WAAW,GAClC,IAAc,EAAe,GAC7B,EAAE,MAAM,MAAiB,EAAsB,GAC/C,EAAE,qBAAkB,EAAc,GAClC,EAAE,QAAQ,GAAU,iBAAc,EAAwB,GAC1D,CAAC,GAAa,KAAkB,EAAM,SAAwB,IAAI,GAClE,IAAsB,EAAM,OAAoC,IAAI,GAEpE,IACJ,MAAkB,EAAW,WAC7B,MAAkB,EAAW,SACzB,IAAe,KAAa,MAAgB,MAC5C,IAAa,CAAC,GAAc,MAAM,KAAe,GACjD,IAAc,EAAE,EAAQ,wCAAwC,GAEhE,IAA2B,EAAM,gBACpC,MAAoC;EASnC,IARA,EAAe,IAAI,GACnB,EAAoB,UAAU,MAC1B,GAAc,MAChB,EAAY,kBAAkB,EAC5B,UAAU,CAAC,wBAAwB,EAAa,EAAE,EACpD,CAAC,GAGC,EAAO,YAAY,WAAW;GAChC,EAAkB,EAAE,EAAQ,mCAAmC,CAAC;GAChE;EACF;EAEA,IAAI,EAAO,aAAa,GAAG;GACzB,EACE,EAAE,EAAQ,uCAAuC;IAC/C,OAAO,EAAwB,EAAO,UAAU;IAChD,QAAQ,EAAwB,EAAO,WAAW;IAClD,OAAO,EAAwB,EAAO,UAAU;GAClD,CAAC,CACH;GACA;EACF;EAEA,EACE,EAAE,EAAQ,+CAA+C,CAC3D;CACF,CACF;CAyCA,OAvCA,EAA0B;EACxB;EACA,kBAAkB,MAAgB,OAAqC,OAA9B,EAAoB;EAC7D,YAAY;CACd,CAAC,GAmCM;EACL,qBAlC0B;GAC1B,IAAI,CAAC,GAAc,MAAM,GAAc;GAEvC,IAAM,IACJ,EAAgB,SAAS,EAAE,OAAO,kBAAkB;GAMtD,AAFA,EAAoB,UAAU,IAAI,IAAI,EAAc,SAAS,EAAE,QAAQ,GAEvE,EACE;IACE,gBAAgB,EAAa;IAC7B,iBAAiB,EAAa;IAC9B,eAAe,EAAa;GAC9B,GACA;IACE,iBAAiB;KAEf,AADA,EAAe,CAAQ,GACvB,EAAoB,EAAE,EAAQ,oCAAoC,CAAC;IACrE;IACA,UAAU,MAAU;KAGlB,AAFA,EAAe,IAAI,GACnB,EAAoB,UAAU,MAC9B,EACE,EAA0B,CAAK,KAC7B,EAAE,EAAQ,mCAAmC,CACjD;IACF;GACF,CACF;EACF;EAIE;EACA;EACA;CACF;AACF"}
@@ -0,0 +1,2 @@
1
+ require("../_virtual/_rolldown/runtime.cjs");const e=require("../stores/metrics-store.cjs"),t=require("./query/use-active-conversation.cjs"),n=require("./query/use-conversation-metrics.cjs");let r=require("react");function i(e){let t=e?.context_window??0;return t<=0?null:{perTurnToken:e?.per_turn_token??0,contextWindow:t}}function a(){let a=e.default(e=>e.usage),{data:o}=t.useActiveConversation(),{data:s}=n.useConversationMetrics(o?.id,o?.conversation_url,o?.session_api_key,!!o?.id);return(0,r.useMemo)(()=>i(a)||i(s?.accumulated_token_usage??null),[a,s])}exports.useContextWindowUsage=a;
2
+ //# sourceMappingURL=use-context-window-usage.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-context-window-usage.cjs","names":[],"sources":["../../src/hooks/use-context-window-usage.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport useMetricsStore from \"#/stores/metrics-store\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useConversationMetrics } from \"#/hooks/query/use-conversation-metrics\";\n\nexport interface ContextWindowUsage {\n perTurnToken: number;\n contextWindow: number;\n}\n\nfunction toContextWindowUsage(\n usage:\n | {\n per_turn_token?: number | null;\n context_window?: number | null;\n }\n | null\n | undefined,\n): ContextWindowUsage | null {\n const contextWindow = usage?.context_window ?? 0;\n if (contextWindow <= 0) {\n return null;\n }\n\n return {\n perTurnToken: usage?.per_turn_token ?? 0,\n contextWindow,\n };\n}\n\nexport function useContextWindowUsage(): ContextWindowUsage | null {\n const storeUsage = useMetricsStore((state) => state.usage);\n const { data: conversation } = useActiveConversation();\n\n const { data: conversationMetrics } = useConversationMetrics(\n conversation?.id,\n conversation?.conversation_url,\n conversation?.session_api_key,\n Boolean(conversation?.id),\n );\n\n return useMemo(() => {\n const fromStore = toContextWindowUsage(storeUsage);\n if (fromStore) {\n return fromStore;\n }\n\n return toContextWindowUsage(\n conversationMetrics?.accumulated_token_usage ?? null,\n );\n }, [storeUsage, conversationMetrics]);\n}\n"],"mappings":"sNAUA,SAAS,EACP,EAO2B,CAC3B,IAAM,EAAgB,GAAO,gBAAkB,EAK/C,OAJI,GAAiB,EACZ,KAGF,CACL,aAAc,GAAO,gBAAkB,EACvC,eACF,CACF,CAEA,SAAgB,GAAmD,CACjE,IAAM,EAAa,EAAA,QAAiB,GAAU,EAAM,KAAK,EACnD,CAAE,KAAM,GAAiB,EAAA,sBAAsB,EAE/C,CAAE,KAAM,GAAwB,EAAA,uBACpC,GAAc,GACd,GAAc,iBACd,GAAc,gBACd,EAAQ,GAAc,EACxB,EAEA,OAAA,EAAA,EAAA,aACoB,EAAqB,CACnC,GAIG,EACL,GAAqB,yBAA2B,IAClD,EACC,CAAC,EAAY,CAAmB,CAAC,CACtC"}