@openhands/agent-canvas 1.0.0-rc.2 → 1.0.0-rc.3

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 (296) hide show
  1. package/README.md +2 -2
  2. package/README.windows.md +2 -2
  3. package/build/assets/acp-providers-C55k29rf.js +1 -0
  4. package/build/assets/{add-backend-modal-CIfhseZn.js → add-backend-modal-BdYxoUdL.js} +1 -1
  5. package/build/assets/agent-server-conversation-service.api-js3oYcdU.js +5 -0
  6. package/build/assets/{agent-settings-B6htMeS2.js → agent-settings-BNrffu3I.js} +1 -1
  7. package/build/assets/{alert-banner-D41ZKDZT.js → alert-banner-BzU93oDh.js} +1 -1
  8. package/build/assets/{analytics-consent-form-modal-TINgM_jV.js → analytics-consent-form-modal-Ce-_Skcd.js} +1 -1
  9. package/build/assets/{api-key-entry-screen-Di1vHgIU.js → api-key-entry-screen-CGyS-Cna.js} +1 -1
  10. package/build/assets/{app-settings-CjCa1MOB.js → app-settings-DmOs4oik.js} +1 -1
  11. package/build/assets/{automation-detail-DPoxzTdV.js → automation-detail-DLbCVJCw.js} +1 -1
  12. package/build/assets/{automations-list-DwUEe2Ea.js → automations-list-Ces5shz5.js} +1 -1
  13. package/build/assets/{backend-form-modal-B6q897ZX.js → backend-form-modal-BUy-PzZN.js} +1 -1
  14. package/build/assets/{backend-synced-settings-badge-BwTawSCE.js → backend-synced-settings-badge-1A63yxGs.js} +1 -1
  15. package/build/assets/browser-B8bp1IqT.js +5 -0
  16. package/build/assets/{browser-tab-DiRTKik8.js → browser-tab-CiBRWB4X.js} +1 -1
  17. package/build/assets/chat-send-button-qKFZuB9E.js +1 -0
  18. package/build/assets/{circle-plus-check-toggle-B3_W6-nt.js → circle-plus-check-toggle-CboDp7XB.js} +1 -1
  19. package/build/assets/{condenser-settings-DczjwkIp.js → condenser-settings-FCBjvqSo.js} +1 -1
  20. package/build/assets/conversation-CT8AvxEH.js +1 -0
  21. package/build/assets/conversation-panel-DqDDs4WZ.js +1 -0
  22. package/build/assets/conversation-service.api-y_eB_43m.js +1 -0
  23. package/build/assets/conversation-store-CiYGBud3.js +6 -0
  24. package/build/assets/conversation-vNuLKgz6.js +19 -0
  25. package/build/assets/conversation-websocket-context-Bb4XBXoc.js +3 -0
  26. package/build/assets/{device-verify-BVl4GEvt.js → device-verify-BOQz2LJQ.js} +1 -1
  27. package/build/assets/{edit-automation-modal-kc_FzbzK.js → edit-automation-modal-C-oC5tis.js} +1 -1
  28. package/build/assets/{entry.client-CWkbusD1.js → entry.client-Db3BpFL_.js} +2 -2
  29. package/build/assets/{enum-filter-dropdown-DlY0Q3fj.js → enum-filter-dropdown-DFwoVtOw.js} +1 -1
  30. package/build/assets/{extensions-hub-NbQnt-cn.js → extensions-hub-BxZbAtjP.js} +1 -1
  31. package/build/assets/extensions-navigation-BIb-vAa2.js +1 -0
  32. package/build/assets/{files-tab-mK7Mdyuf.js → files-tab-DpulQlIo.js} +1 -1
  33. package/build/assets/{git-control-bar-branch-button-C1qmab0K.js → git-control-bar-branch-button-D1uam-nI.js} +1 -1
  34. package/build/assets/home-sJAFzI6v.js +1 -0
  35. package/build/assets/install-server-modal-BjEzlLF5.js +1 -0
  36. package/build/assets/{launch-BADsYeGp.js → launch-DgtB1JTX.js} +1 -1
  37. package/build/assets/llm-settings-B8kPJ0Of.js +1 -0
  38. package/build/assets/llm-settings-CjUpPsvA.js +1 -0
  39. package/build/assets/{manage-backends-modal-sH7l5NgI.js → manage-backends-modal-CTA-2x4F.js} +1 -1
  40. package/build/assets/manifest-d3e8504d.js +1 -0
  41. package/build/assets/{markdown-renderer-CZq_UdmE.js → markdown-renderer-oOUs3tw5.js} +1 -1
  42. package/build/assets/{mcp-DdQ72_AO.js → mcp-kJYdM8aJ.js} +1 -1
  43. package/build/assets/messages-BFJXB6MW.js +36 -0
  44. package/build/assets/model-selector-z_QOzaRV.js +1 -0
  45. package/build/assets/{onboarding-DCL9stdH.js → onboarding-CZ_7nd-M.js} +1 -1
  46. package/build/assets/{path-utils-CNd_jqv_.js → path-utils-0KWEiRs9.js} +1 -1
  47. package/build/assets/{planner-tab-QBnZgIXd.js → planner-tab-CNmJiZ22.js} +1 -1
  48. package/build/assets/{recommended-automations-launcher-B01jchhe.js → recommended-automations-launcher-B1kfmFTQ.js} +8 -10
  49. package/build/assets/{root-BBV8Ew9E.js → root-CIZ7Rv1X.js} +2 -2
  50. package/build/assets/root-layout-B5ijp9At.js +2 -0
  51. package/build/assets/{sdk-section-page-BQKe3asw.js → sdk-section-page-DTyvCc52.js} +1 -1
  52. package/build/assets/{sdk-settings-schema-DoRnefvb.js → sdk-settings-schema-B0KrqqPX.js} +1 -1
  53. package/build/assets/{secrets-settings-D2EfzdpC.js → secrets-settings-BQNSDLKS.js} +1 -1
  54. package/build/assets/{settings-B7jVceyu.js → settings-BUlJrO_h.js} +1 -1
  55. package/build/assets/{settings-dropdown-input-BD7ziSoR.js → settings-dropdown-input-BUk4m23x.js} +1 -1
  56. package/build/assets/{settings-index-Xj0v9Oas.js → settings-index-DE91Eahc.js} +1 -1
  57. package/build/assets/{settings-modal-CDBy1S9S.js → settings-modal-CCaPYVqW.js} +1 -1
  58. package/build/assets/{settings-service.api-CTQ-LpAA.js → settings-service.api-4u2RKC8k.js} +1 -1
  59. package/build/assets/{settings-switch-CSHSqH99.js → settings-switch-BQiAS9ga.js} +1 -1
  60. package/build/assets/{settings-utils-BCbzc6-u.js → settings-utils-chxTa1vn.js} +1 -1
  61. package/build/assets/{shared-conversation-BHEbOdHj.js → shared-conversation-sBPLAawM.js} +1 -1
  62. package/build/assets/{sidebar-mobile-menu-toggle-YYPXGikp.js → sidebar-mobile-menu-toggle-BDXWzhyB.js} +1 -1
  63. package/build/assets/{sidebar-nav-link-CiXbBMQx.js → sidebar-nav-link-Bhlzlhp8.js} +1 -1
  64. package/build/assets/{skill-card-pill-row-BXILn-GK.js → skill-card-pill-row-Bg5joQf6.js} +1 -1
  65. package/build/assets/{skills-plugins-Bs5HiF1O.js → skills-plugins-fihjo1KZ.js} +1 -1
  66. package/build/assets/{skills-settings-CQYxMmWf.js → skills-settings-NQnuMwZP.js} +1 -1
  67. package/build/assets/{styled-tooltip-DEr7oa0m.js → styled-tooltip-GXy1qxsO.js} +1 -1
  68. package/build/assets/{task-list-tab-R9N3Wd-U.js → task-list-tab-Hl9BuVfq.js} +1 -1
  69. package/build/assets/telemetry-j9SLrtY7.js +2 -0
  70. package/build/assets/{terminal-BTM3UFcQ.js → terminal-DRwe8--D.js} +1 -1
  71. package/build/assets/{use-active-conversation-BY5F6A1G.js → use-active-conversation-DJGoI9Mc.js} +1 -1
  72. package/build/assets/{use-agent-settings-schema-CsuMq16G.js → use-agent-settings-schema-DtusObuC.js} +1 -1
  73. package/build/assets/{use-agent-state-DX5NKEa_.js → use-agent-state-BXgWhFh6.js} +1 -1
  74. package/build/assets/{use-create-conversation-4iJytCT1.js → use-create-conversation-CzvaVA5A.js} +1 -1
  75. package/build/assets/use-event-store-DSpvASbC.js +1 -0
  76. package/build/assets/{use-get-secrets-BMnFFBUx.js → use-get-secrets-DiLgP147.js} +1 -1
  77. package/build/assets/use-handle-plan-click-CUZwmKIk.js +1 -0
  78. package/build/assets/{use-launch-skill-in-chat-BoqKmEHC.js → use-launch-skill-in-chat-ClRJlIx7.js} +1 -1
  79. package/build/assets/use-runtime-is-ready-CWkGQFsb.js +1 -0
  80. package/build/assets/{use-save-settings-hK6LYt0s.js → use-save-settings-CP23emUY.js} +1 -1
  81. package/build/assets/use-settings-0qFqC-r6.js +1 -0
  82. package/build/assets/{use-settings-nav-items-oZ-BlOWX.js → use-settings-nav-items-C6YxUn4h.js} +1 -1
  83. package/build/assets/{use-task-list-DydbuRFM.js → use-task-list-JPudBRv3.js} +1 -1
  84. package/build/assets/{use-tracking-DQU60djN.js → use-tracking-CjLZgh8X.js} +1 -1
  85. package/build/assets/{use-unified-vscode-url-D2Buvmxj.js → use-unified-vscode-url-DSn2tT08.js} +1 -1
  86. package/build/assets/{use-user-conversation-DwOGM1lc.js → use-user-conversation-CQ5IwnZk.js} +1 -1
  87. package/build/assets/{vendor~browser-3J6WDaAB.js → vendor~browser-Dwwc84Zf.js} +1 -1
  88. package/build/assets/{vendor~browser-tab-DYZ-OmbT.js → vendor~browser-tab-Bhohe29F.js} +1 -1
  89. package/build/assets/{vendor~files-tab-Diy4WrQz.js → vendor~files-tab-B447_Zns.js} +1 -1
  90. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CWwn0K2j.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CQQAW8hY.js} +1 -1
  91. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-dZ3D8RVL.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DFsI4CLy.js} +1 -1
  92. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BighOCzm.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DcvlNgbn.js} +1 -1
  93. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-D13hiNGV.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-ojk_J4bB.js} +1 -1
  94. package/build/assets/{vendor~launch-D65Vw0VZ.js → vendor~launch-BdXJCmwc.js} +1 -1
  95. package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-BJPgfJoU.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-DToubnIU.js} +1 -1
  96. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~jpfhx3ls-BkicN-14.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~jpfhx3ls-zdl_Rltz.js} +2 -2
  97. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~settings~settings-index~agen~jxrvuot9-Cwz6a1DC.js → vendor~root-layout~home~conversation-panel~conversation~launch~settings~settings-index~agen~jxrvuot9-BaCzvZac.js} +1 -1
  98. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-C37jLHRk.js → vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-BwbkftxT.js} +1 -1
  99. package/build/assets/{vendor~root-layout~home~mcp~automations-list-JQ-neDIa.js → vendor~root-layout~home~mcp~automations-list-CtdIEhjQ.js} +1 -1
  100. package/build/assets/{vendor~root-layout~home~mcp~automations-list-BTTZ58Mb.js → vendor~root-layout~home~mcp~automations-list-DGOI7kQz.js} +1 -1
  101. package/build/assets/{vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-UYEKKX0Y.js → vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-iPAfRWNQ.js} +2 -2
  102. package/build/assets/{verification-settings-Rabe5TpK.js → verification-settings-Cm02KmeI.js} +1 -1
  103. package/build/assets/{vscode-tab-zLD5Z-PP.js → vscode-tab-AF70Yke0.js} +1 -1
  104. package/build/index.html +4 -4
  105. package/build/locales/ar/openhands.json +1 -1
  106. package/build/locales/ca/openhands.json +1 -1
  107. package/build/locales/de/openhands.json +1 -1
  108. package/build/locales/en/openhands.json +1 -1
  109. package/build/locales/es/openhands.json +1 -1
  110. package/build/locales/fr/openhands.json +1 -1
  111. package/build/locales/it/openhands.json +1 -1
  112. package/build/locales/ja/openhands.json +1 -1
  113. package/build/locales/ko-KR/openhands.json +1 -1
  114. package/build/locales/no/openhands.json +1 -1
  115. package/build/locales/pt/openhands.json +1 -1
  116. package/build/locales/tr/openhands.json +1 -1
  117. package/build/locales/uk/openhands.json +1 -1
  118. package/build/locales/zh-CN/openhands.json +1 -1
  119. package/build/locales/zh-TW/openhands.json +1 -1
  120. package/config/defaults.json +1 -1
  121. package/dist/api/agent-server-adapter.cjs +3 -3
  122. package/dist/api/agent-server-adapter.cjs.map +1 -1
  123. package/dist/api/agent-server-adapter.js +90 -85
  124. package/dist/api/agent-server-adapter.js.map +1 -1
  125. package/dist/api/app-preferences-store.cjs.map +1 -1
  126. package/dist/api/app-preferences-store.d.ts +6 -2
  127. package/dist/api/app-preferences-store.js.map +1 -1
  128. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs +1 -1
  129. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs.map +1 -1
  130. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js +9 -9
  131. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js.map +1 -1
  132. package/dist/components/conversation-events/chat/event-message.cjs +1 -1
  133. package/dist/components/conversation-events/chat/event-message.cjs.map +1 -1
  134. package/dist/components/conversation-events/chat/event-message.js +80 -71
  135. package/dist/components/conversation-events/chat/event-message.js.map +1 -1
  136. package/dist/components/features/automations/recommended-automations-launcher.d.ts +7 -1
  137. package/dist/components/features/home/workspace-selection-form.d.ts +1 -0
  138. package/dist/components/features/onboarding/steps/setup-llm-step.d.ts +8 -0
  139. package/dist/components/features/sidebar/sidebar.cjs +1 -1
  140. package/dist/components/features/sidebar/sidebar.js +6 -6
  141. package/dist/components/features/skills/extensions-navigation.cjs +1 -1
  142. package/dist/components/features/skills/extensions-navigation.cjs.map +1 -1
  143. package/dist/components/features/skills/extensions-navigation.d.ts +1 -1
  144. package/dist/components/features/skills/extensions-navigation.js +27 -29
  145. package/dist/components/features/skills/extensions-navigation.js.map +1 -1
  146. package/dist/i18n/translation.cjs +1 -1
  147. package/dist/i18n/translation.cjs.map +1 -1
  148. package/dist/i18n/translation.js +15 -15
  149. package/dist/i18n/translation.js.map +1 -1
  150. package/dist/locales/ar/openhands.json +1 -1
  151. package/dist/locales/ca/openhands.json +1 -1
  152. package/dist/locales/de/openhands.json +1 -1
  153. package/dist/locales/en/openhands.json +1 -1
  154. package/dist/locales/es/openhands.json +1 -1
  155. package/dist/locales/fr/openhands.json +1 -1
  156. package/dist/locales/it/openhands.json +1 -1
  157. package/dist/locales/ja/openhands.json +1 -1
  158. package/dist/locales/ko-KR/openhands.json +1 -1
  159. package/dist/locales/no/openhands.json +1 -1
  160. package/dist/locales/pt/openhands.json +1 -1
  161. package/dist/locales/tr/openhands.json +1 -1
  162. package/dist/locales/uk/openhands.json +1 -1
  163. package/dist/locales/zh-CN/openhands.json +1 -1
  164. package/dist/locales/zh-TW/openhands.json +1 -1
  165. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.cjs +1 -1
  166. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.cjs.map +1 -1
  167. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.js +10 -1
  168. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.js.map +1 -1
  169. package/dist/package.cjs +1 -1
  170. package/dist/package.cjs.map +1 -1
  171. package/dist/package.js +2 -2
  172. package/dist/package.js.map +1 -1
  173. package/dist/routes/llm-settings.cjs +1 -1
  174. package/dist/routes/llm-settings.cjs.map +1 -1
  175. package/dist/routes/llm-settings.js +21 -21
  176. package/dist/routes/llm-settings.js.map +1 -1
  177. package/dist/types/agent-server/core/events/index.d.ts +1 -0
  178. package/dist/types/agent-server/core/events/streaming-delta-event.d.ts +7 -0
  179. package/dist/types/agent-server/core/openhands-event.d.ts +2 -2
  180. package/dist/types/agent-server/type-guards.cjs +1 -1
  181. package/dist/types/agent-server/type-guards.cjs.map +1 -1
  182. package/dist/types/agent-server/type-guards.d.ts +2 -0
  183. package/dist/types/agent-server/type-guards.js +3 -3
  184. package/dist/types/agent-server/type-guards.js.map +1 -1
  185. package/dist/utils/handle-event-for-ui.cjs +1 -1
  186. package/dist/utils/handle-event-for-ui.cjs.map +1 -1
  187. package/dist/utils/handle-event-for-ui.js +69 -13
  188. package/dist/utils/handle-event-for-ui.js.map +1 -1
  189. package/dist/utils/mcp-config.cjs +1 -1
  190. package/dist/utils/mcp-config.cjs.map +1 -1
  191. package/dist/utils/mcp-config.js +27 -19
  192. package/dist/utils/mcp-config.js.map +1 -1
  193. package/dist/utils/mcp-marketplace-utils.cjs +1 -1
  194. package/dist/utils/mcp-marketplace-utils.cjs.map +1 -1
  195. package/dist/utils/mcp-marketplace-utils.js +38 -18
  196. package/dist/utils/mcp-marketplace-utils.js.map +1 -1
  197. package/dist/utils/normalize-display-model.cjs +1 -1
  198. package/dist/utils/normalize-display-model.cjs.map +1 -1
  199. package/dist/utils/normalize-display-model.js +8 -7
  200. package/dist/utils/normalize-display-model.js.map +1 -1
  201. package/dist/utils/openhands-llm.cjs +1 -1
  202. package/dist/utils/openhands-llm.cjs.map +1 -1
  203. package/dist/utils/openhands-llm.d.ts +13 -0
  204. package/dist/utils/openhands-llm.js +9 -3
  205. package/dist/utils/openhands-llm.js.map +1 -1
  206. package/package.json +2 -2
  207. package/scripts/check-sdk-version-sync.mjs +6 -6
  208. package/scripts/dev-safe.mjs +53 -118
  209. package/scripts/dev-with-automation.mjs +58 -4
  210. package/scripts/runtime-services-info.mjs +199 -0
  211. package/scripts/static-server.mjs +42 -4
  212. package/build/assets/acp-providers-DZEi8wDz.js +0 -1
  213. package/build/assets/agent-server-conversation-service.api-B82pNNTm.js +0 -5
  214. package/build/assets/browser-DTei6kki.js +0 -5
  215. package/build/assets/chat-send-button-06dIuWXm.js +0 -1
  216. package/build/assets/conversation-CBlJiDaV.js +0 -19
  217. package/build/assets/conversation-Dss8XCN_.js +0 -1
  218. package/build/assets/conversation-panel-B5sVpsz5.js +0 -1
  219. package/build/assets/conversation-service.api-B4s-xIOK.js +0 -1
  220. package/build/assets/conversation-store-kHcewy1E.js +0 -1
  221. package/build/assets/conversation-websocket-context-C2yKCqvj.js +0 -3
  222. package/build/assets/extensions-navigation-oOk5yl8X.js +0 -1
  223. package/build/assets/home-ChuA06Hv.js +0 -1
  224. package/build/assets/install-server-modal--lZ1HSHB.js +0 -1
  225. package/build/assets/llm-settings-D477P0Lg.js +0 -1
  226. package/build/assets/llm-settings-DtlQ7i4C.js +0 -1
  227. package/build/assets/manifest-17af0b17.js +0 -1
  228. package/build/assets/messages-luW9zf1w.js +0 -36
  229. package/build/assets/middleware-B5rcobhi.js +0 -6
  230. package/build/assets/model-selector-DzQRgNGZ.js +0 -1
  231. package/build/assets/root-layout-pQASEqtQ.js +0 -2
  232. package/build/assets/sidebar-store-B76R2gP8.js +0 -1
  233. package/build/assets/telemetry-DCrd7gnV.js +0 -2
  234. package/build/assets/use-event-store-Rw1YbvLm.js +0 -1
  235. package/build/assets/use-handle-plan-click-DYd5a6zN.js +0 -1
  236. package/build/assets/use-runtime-is-ready-DP-KKHO6.js +0 -1
  237. package/build/assets/use-settings-Clf0Y_P3.js +0 -1
  238. /package/build/assets/{automation-LZB0MjdV.js → automation-BzmydDjr.js} +0 -0
  239. /package/build/assets/{browser-store-BjhV_9wS.js → browser-store-C5uQbbIi.js} +0 -0
  240. /package/build/assets/{checkmark-BB7QCG5T.js → checkmark-SEZPnU2I.js} +0 -0
  241. /package/build/assets/{chevron-left-small-CuuwpRi9.js → chevron-left-small-x9_-ucHG.js} +0 -0
  242. /package/build/assets/{close-Cz0OAgTy.js → close-CbOsKMRg.js} +0 -0
  243. /package/build/assets/{code-tag-Cz9AIz-X.js → code-tag-C0vR_IQH.js} +0 -0
  244. /package/build/assets/{command-store-DAd3K0d_.js → command-store-BUWgE-vZ.js} +0 -0
  245. /package/build/assets/{confirmation-modal-C_lds1Tb.js → confirmation-modal-BPgWqWRI.js} +0 -0
  246. /package/build/assets/{context-menu-list-item-DhG1Ln5m.js → context-menu-list-item-CHWCx1Mc.js} +0 -0
  247. /package/build/assets/{conversation-state-store-BUU90dVq.js → conversation-state-store-DpgQaK_O.js} +0 -0
  248. /package/build/assets/{conversation-tab-empty-state-5bW9CQke.js → conversation-tab-empty-state-Ba5hbJhn.js} +0 -0
  249. /package/build/assets/{copy-CA1Dblua.js → copy-CAxUvM-U.js} +0 -0
  250. /package/build/assets/{dist-CBUfAk0Z.js → dist-CeJSjcAI.js} +0 -0
  251. /package/build/assets/{ellipsis-button-DRRmCrWi.js → ellipsis-button-CiLx8dqc.js} +0 -0
  252. /package/build/assets/{environment-switch-overlay-BrHKX6_Z.js → environment-switch-overlay-Cow6h62p.js} +0 -0
  253. /package/build/assets/{file-DM0ihEsO.js → file-BJCSojij.js} +0 -0
  254. /package/build/assets/{files-tab-store-QlUCuW8b.js → files-tab-store-CZAEwv3x.js} +0 -0
  255. /package/build/assets/{folder-UGYUKpqb.js → folder-wShAU0y7.js} +0 -0
  256. /package/build/assets/{git-status-mapper-N4-7eaeC.js → git-status-mapper-C3rfzUex.js} +0 -0
  257. /package/build/assets/{globe-2otpEmVh.js → globe-CQ_5xwpo.js} +0 -0
  258. /package/build/assets/{handle-capture-consent-OitMkDHc.js → handle-capture-consent-DDnXMC9Y.js} +0 -0
  259. /package/build/assets/{iconBase-B_5IRYeZ.js → iconBase-1A_WRQ4E.js} +0 -0
  260. /package/build/assets/{lesson-plan-5O2tVbD1.js → lesson-plan-B607buca.js} +0 -0
  261. /package/build/assets/{link-external-kU6aFXU6.js → link-external-DCsHkAj4.js} +0 -0
  262. /package/build/assets/{map-provider-BHow6ugd.js → map-provider-XSFHmdDs.js} +0 -0
  263. /package/build/assets/{modal-close-button-BCvw9IUN.js → modal-close-button-DY-rVmld.js} +0 -0
  264. /package/build/assets/{plan-components-BRiIX8Wn.js → plan-components-DsiDjcDi.js} +0 -0
  265. /package/build/assets/{sdk-settings-field-metadata-CtO73dY6.js → sdk-settings-field-metadata-CETNItbo.js} +0 -0
  266. /package/build/assets/{search-Cbh-hHBu.js → search-BqXT2Ied.js} +0 -0
  267. /package/build/assets/{secrets-service-DEIB-Cfk.js → secrets-service-rJqZtDmI.js} +0 -0
  268. /package/build/assets/{settings-KgLvVrSm.js → settings-BgL2HUsU.js} +0 -0
  269. /package/build/assets/{settings-gear-xGs_SPgZ.js → settings-gear-DFmoMp-6.js} +0 -0
  270. /package/build/assets/{settings-input-CPr7vX81.js → settings-input-DsoZj8Dm.js} +0 -0
  271. /package/build/assets/{settings-like-page-layout-classes-GknosJgv.js → settings-like-page-layout-classes-DENKlZpD.js} +0 -0
  272. /package/build/assets/{settings-list-classes-CYDn4jUg.js → settings-list-classes-D8VAVZmi.js} +0 -0
  273. /package/build/assets/{settings-section-header-context-aD2iq1gD.js → settings-section-header-context-D61smD-W.js} +0 -0
  274. /package/build/assets/{skills-CCaEu1KQ.js → skills-BDOWVle-.js} +0 -0
  275. /package/build/assets/{switch-skeleton-C87Tx3Tc.js → switch-skeleton-QpdcdxRP.js} +0 -0
  276. /package/build/assets/{terminal-DQJ6IJUd.js → terminal-BUww3Ssl.js} +0 -0
  277. /package/build/assets/{toggle-switch-C-7juZ1u.js → toggle-switch-DDr-DnEc.js} +0 -0
  278. /package/build/assets/{typography-U1gkzkXo.js → typography-Cx7uw7z3.js} +0 -0
  279. /package/build/assets/{u-check-circle-lbkXL2z4.js → u-check-circle-CftRwky1.js} +0 -0
  280. /package/build/assets/{u-check-circle-half-CirnoxXG.js → u-check-circle-half-sGVk0BtL.js} +0 -0
  281. /package/build/assets/{u-circuit-Danff2ks.js → u-circuit-Cg9tH5qb.js} +0 -0
  282. /package/build/assets/{u-edit-CH5nNya1.js → u-edit-foF02hwH.js} +0 -0
  283. /package/build/assets/{use-breakpoint-2sN462wJ.js → use-breakpoint-Dt2knceC.js} +0 -0
  284. /package/build/assets/{use-click-outside-element-_vianyPb.js → use-click-outside-element-Bu2A3s59.js} +0 -0
  285. /package/build/assets/{use-is-authed-DrocXcet.js → use-is-authed-fNsj-Adj.js} +0 -0
  286. /package/build/assets/{use-llm-profiles-BhZRf-NX.js → use-llm-profiles-CyNVoVqm.js} +0 -0
  287. /package/build/assets/{use-skills-v8pQ02ze.js → use-skills-BWHATXK-.js} +0 -0
  288. /package/build/assets/{v4-BMWDcIWQ.js → v4-BygpdDmc.js} +0 -0
  289. /package/build/assets/{vendor~browser-C3GKF4mj.js → vendor~browser-BYEwwJqV.js} +0 -0
  290. /package/build/assets/{vendor~conversation-panel~conversation~alert-banner-DMcFTqbt.js → vendor~conversation-panel~conversation~alert-banner-BnHToS5O.js} +0 -0
  291. /package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Cntsv2EN.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-B4oeCCli.js} +0 -0
  292. /package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DTosGXG7.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-D8cqyq4k.js} +0 -0
  293. /package/build/assets/{vendor~terminal-CnKZILnC.js → vendor~terminal-aeP3PnKf.js} +0 -0
  294. /package/build/assets/{vscode-url-helper-CwQPl6QN.js → vscode-url-helper-DOCkV_-G.js} +0 -0
  295. /package/build/assets/{waiting-for-runtime-message-B1Dzhtj5.js → waiting-for-runtime-message-Bg27u9JB.js} +0 -0
  296. /package/build/assets/{x-mark-CmcVOTk2.js → x-mark-Cn-YJVbN.js} +0 -0
@@ -1,5 +1,5 @@
1
- require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../types/agent-server/core/base/common.cjs`),t=require(`./agent-server-config.cjs`),n=require(`./backend-registry/active-store.cjs`),r=require(`./agent-server-client-options.cjs`),i=require(`./backend-registry/auth.cjs`),a=require(`./conversation-metadata-store.cjs`),o=require(`../services/settings.cjs`),s=require(`../constants/acp-providers.cjs`),c=require(`./agent-server-compatibility.cjs`),l=require(`./settings-service/settings-service.api.cjs`);var u=`canvas_ui`,d=`canvas_ui_tool`,f=[`terminal`,`file_editor`,`task_tracker`,u],p=`browser_tool_set`,m=`task_tool_set`;function h(){return!0}function g(){let e=(void 0)?.trim();if(!e)return null;try{let t=JSON.parse(e);return!t||typeof t!=`object`?null:t}catch{return null}}function _(){let e=g();if(!e?.services)return;let t=[];t.push(`<RUNTIME_SERVICES>`),e.mode?t.push(`You are running inside an agent-canvas dev stack started in '${e.mode}' mode.`):t.push(`You are running inside an agent-canvas dev stack.`),t.push(`The following services are reachable from your sandbox. URLs are written`,`from your point of view (i.e., as you should curl/fetch them).`,``);let{agent_server:n,ingress:r,automation:i}=e.services,a=e.services.frontend??e.services.vite;n?.url_from_agent&&t.push(`* Agent Server (you): ${n.url_from_agent}`,` ${n.description??`The agent-server hosting your tool calls.`}`),r?.url_from_agent&&t.push(`* Ingress: ${r.url_from_agent}`,` ${r.description??`Unified entry point for browser-facing traffic.`}`),a?.url_from_agent&&t.push(`* Frontend: ${a.url_from_agent}`,` ${a.description??`Frontend dev server.`}`),i?.url_from_agent?(t.push(`* Automation backend: ${i.url_from_agent}`,` ${i.description??`OpenHands Automations service.`}`),i.docs_url&&t.push(` Docs: ${i.docs_url}`),i.openapi_url&&t.push(` OpenAPI: ${i.openapi_url}`),i.auth_env_var&&t.push(` Auth: header 'X-Session-API-Key: $${i.auth_env_var}'`)):t.push(`* Automation backend: not running in this dev mode (skip /api/automation calls).`);let o=n?.url_from_agent;return t.push(``,`Trust this block over guessing: do not assume any other URLs are running.`),o&&t.push(`In particular, ${o} inside your sandbox is the Agent Server`,`you are running inside of — NOT the automation backend.`),t.push(`</RUNTIME_SERVICES>`),t.join(`
2
- `)}function v(e){let{host:t}=r.getAgentServerClientOptions();return`${t}/api/conversations/${e}`}function y(e){return`Conversation ${e.slice(0,5)}`}function b(n){let i=a.getStoredConversationMetadata(n.id),c=n.agent?.kind===`ACPAgent`,l=c?n.tags?.acpserver??null:null;return{id:n.id,created_by_user_id:null,selected_repository:i?.selected_repository??null,selected_branch:i?.selected_branch??null,git_provider:i?.git_provider??null,selected_workspace:i?.selected_workspace??null,active_profile:i?.active_profile??null,title:n.title?.trim()?n.title:y(n.id),trigger:null,pr_number:[],agent_kind:c?`acp`:`openhands`,acp_server:l,llm_model:c?s.resolveEffectiveAcpModel({runtimeName:n.current_model_name,runtimeId:n.current_model_id,configured:n.agent?.acp_model,sdkLlm:n.agent?.llm?.model}):n.agent?.llm?.model??o.DEFAULT_SETTINGS.llm_model,metrics:n.metrics?{accumulated_cost:n.metrics.accumulated_cost??null,max_budget_per_task:n.metrics.max_budget_per_task??null,accumulated_token_usage:n.metrics.accumulated_token_usage?{prompt_tokens:n.metrics.accumulated_token_usage.prompt_tokens??0,completion_tokens:n.metrics.accumulated_token_usage.completion_tokens??0,cache_read_tokens:n.metrics.accumulated_token_usage.cache_read_tokens??0,cache_write_tokens:n.metrics.accumulated_token_usage.cache_write_tokens??0,context_window:n.metrics.accumulated_token_usage.context_window??0,per_turn_token:n.metrics.accumulated_token_usage.per_turn_token??0}:null}:null,created_at:n.created_at,updated_at:n.updated_at,execution_status:n.execution_status??e.ExecutionStatus.IDLE,sandbox_status:n.sandbox_status??null,conversation_url:v(n.id),session_api_key:r.getAgentServerClientOptions().apiKey??null,sandbox_id:null,workspace:{working_dir:n.workspace?.working_dir??t.getAgentServerWorkingDir()},public:!1,sub_conversation_ids:[]}}function x(e){return{items:e.items.map(b),next_page_id:e.next_page_id??null}}var S=[`acp_command`,`acp_args`,`acp_model`,`acp_session_mode`,`acp_prompt_timeout`],C=`acpserver`,w=new Set([`schema_version`,`agent_settings`,`workspace`,`conversation_id`,`initial_message`,`plugins`]);function T(e){return!e||typeof e!=`object`||Array.isArray(e)?{}:structuredClone(e)}function E(e){if(typeof e!=`string`)return;let t=e.trim();return t.length>0?t:void 0}function D(e){return e.confirmation_mode===!0?e.security_analyzer===`llm`?{kind:`ConfirmRisky`,threshold:`HIGH`,confirm_unknown:!0}:{kind:`AlwaysConfirm`}:{kind:`NeverConfirm`}}function O(e){switch(e.security_analyzer){case`llm`:return{kind:`LLMSecurityAnalyzer`};case`pattern`:return{kind:`PatternSecurityAnalyzer`};case`policy_rail`:return{kind:`PolicyRailSecurityAnalyzer`};default:return}}function k(e){return!!e&&typeof e==`object`&&!Array.isArray(e)&&typeof e.name==`string`}function A(e,t){return e===p?h()&&c.isAgentServerToolAvailable(e):e===m?t.enable_sub_agents===!0&&c.isAgentServerToolAvailable(e):!0}function j(e){let t=new Map;for(let e of f)t.set(e,{name:e,params:{}});for(let n of[p,m])A(n,e)&&t.set(n,{name:n,params:{}});let n=e.tools;if(Array.isArray(n)&&n.every(e=>k(e)))for(let r of n)A(r.name,e)&&t.set(r.name,{name:r.name,params:T(r.params)});return Array.from(t.values())}function M(e,t){let n=[e?.trim(),t?.trim()].filter(Boolean);return n.length===0?null:{role:`user`,content:[{type:`text`,text:n.join(`
1
+ require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../types/agent-server/core/base/common.cjs`),t=require(`./agent-server-config.cjs`),n=require(`./backend-registry/active-store.cjs`),r=require(`./agent-server-client-options.cjs`),i=require(`./backend-registry/auth.cjs`),a=require(`../node_modules/@openhands/typescript-client/dist/models/acp.cjs`);require(`../node_modules/@openhands/typescript-client/dist/index.cjs`);const o=require(`./conversation-metadata-store.cjs`),s=require(`../services/settings.cjs`),c=require(`../constants/acp-providers.cjs`),l=require(`./agent-server-compatibility.cjs`),u=require(`./settings-service/settings-service.api.cjs`);var d=`canvas_ui`,f=`canvas_ui_tool`,p=[`terminal`,`file_editor`,`task_tracker`,d],m=`browser_tool_set`,h=`task_tool_set`;function g(){return!0}function _(){let e=(void 0)?.trim();if(e)return e;if(typeof window<`u`){let e=window.__AGENT_CANVAS_RUNTIME_SERVICES_INFO__;if(typeof e==`string`)return e.trim()||null}return null}function v(){let e=_();if(!e)return null;try{let t=JSON.parse(e);return!t||typeof t!=`object`?null:t}catch{return null}}function y(){let e=v();if(!e?.services)return;let t=[];t.push(`<RUNTIME_SERVICES>`),e.mode?t.push(`You are running inside an agent-canvas dev stack started in '${e.mode}' mode.`):t.push(`You are running inside an agent-canvas dev stack.`),t.push(`The following services are reachable from your sandbox. URLs are written`,`from your point of view (i.e., as you should curl/fetch them).`,``);let{agent_server:n,ingress:r,automation:i}=e.services,a=e.services.frontend??e.services.vite;n?.url_from_agent&&t.push(`* Agent Server (you): ${n.url_from_agent}`,` ${n.description??`The agent-server hosting your tool calls.`}`),r?.url_from_agent&&t.push(`* Ingress: ${r.url_from_agent}`,` ${r.description??`Unified entry point for browser-facing traffic.`}`),a?.url_from_agent&&t.push(`* Frontend: ${a.url_from_agent}`,` ${a.description??`Frontend dev server.`}`),i?.url_from_agent?(t.push(`* Automation backend: ${i.url_from_agent}`,` ${i.description??`OpenHands Automations service.`}`),i.docs_url&&t.push(` Docs: ${i.docs_url}`),i.openapi_url&&t.push(` OpenAPI: ${i.openapi_url}`),i.auth_env_var&&t.push(` Auth: header 'X-Session-API-Key: $${i.auth_env_var}'`)):t.push(`* Automation backend: not running in this dev mode (skip /api/automation calls).`);let o=n?.url_from_agent;return t.push(``,`Trust this block over guessing: do not assume any other URLs are running.`),o&&t.push(`In particular, ${o} inside your sandbox is the Agent Server`,`you are running inside of — NOT the automation backend.`),t.push(`</RUNTIME_SERVICES>`),t.join(`
2
+ `)}function b(e){let{host:t}=r.getAgentServerClientOptions();return`${t}/api/conversations/${e}`}function x(e){return`Conversation ${e.slice(0,5)}`}function S(n){let i=o.getStoredConversationMetadata(n.id),a=n.agent?.kind===`ACPAgent`,l=a?n.tags?.acpserver??null:null;return{id:n.id,created_by_user_id:null,selected_repository:i?.selected_repository??null,selected_branch:i?.selected_branch??null,git_provider:i?.git_provider??null,selected_workspace:i?.selected_workspace??null,active_profile:i?.active_profile??null,title:n.title?.trim()?n.title:x(n.id),trigger:null,pr_number:[],agent_kind:a?`acp`:`openhands`,acp_server:l,llm_model:a?c.resolveEffectiveAcpModel({runtimeName:n.current_model_name,runtimeId:n.current_model_id,configured:n.agent?.acp_model,sdkLlm:n.agent?.llm?.model}):n.agent?.llm?.model??s.DEFAULT_SETTINGS.llm_model,metrics:n.metrics?{accumulated_cost:n.metrics.accumulated_cost??null,max_budget_per_task:n.metrics.max_budget_per_task??null,accumulated_token_usage:n.metrics.accumulated_token_usage?{prompt_tokens:n.metrics.accumulated_token_usage.prompt_tokens??0,completion_tokens:n.metrics.accumulated_token_usage.completion_tokens??0,cache_read_tokens:n.metrics.accumulated_token_usage.cache_read_tokens??0,cache_write_tokens:n.metrics.accumulated_token_usage.cache_write_tokens??0,context_window:n.metrics.accumulated_token_usage.context_window??0,per_turn_token:n.metrics.accumulated_token_usage.per_turn_token??0}:null}:null,created_at:n.created_at,updated_at:n.updated_at,execution_status:n.execution_status??e.ExecutionStatus.IDLE,sandbox_status:n.sandbox_status??null,conversation_url:b(n.id),session_api_key:r.getAgentServerClientOptions().apiKey??null,sandbox_id:null,workspace:{working_dir:n.workspace?.working_dir??t.getAgentServerWorkingDir()},public:!1,sub_conversation_ids:[]}}function C(e){return{items:e.items.map(S),next_page_id:e.next_page_id??null}}var w=`acpserver`,T=new Set([`schema_version`,`agent_settings`,`workspace`,`conversation_id`,`initial_message`,`plugins`]);function E(e){return!e||typeof e!=`object`||Array.isArray(e)?{}:structuredClone(e)}function D(e){if(typeof e!=`string`)return;let t=e.trim();return t.length>0?t:void 0}function O(e){return e.confirmation_mode===!0?e.security_analyzer===`llm`?{kind:`ConfirmRisky`,threshold:`HIGH`,confirm_unknown:!0}:{kind:`AlwaysConfirm`}:{kind:`NeverConfirm`}}function k(e){switch(e.security_analyzer){case`llm`:return{kind:`LLMSecurityAnalyzer`};case`pattern`:return{kind:`PatternSecurityAnalyzer`};case`policy_rail`:return{kind:`PolicyRailSecurityAnalyzer`};default:return}}function A(e){return!!e&&typeof e==`object`&&!Array.isArray(e)&&typeof e.name==`string`}function j(e,t){return e===m?g()&&l.isAgentServerToolAvailable(e):e===h?t.enable_sub_agents===!0&&l.isAgentServerToolAvailable(e):!0}function M(e){let t=new Map;for(let e of p)t.set(e,{name:e,params:{}});for(let n of[m,h])j(n,e)&&t.set(n,{name:n,params:{}});let n=e.tools;if(Array.isArray(n)&&n.every(e=>A(e)))for(let r of n)j(r.name,e)&&t.set(r.name,{name:r.name,params:E(r.params)});return Array.from(t.values())}function N(e,t){let n=[e?.trim(),t?.trim()].filter(Boolean);return n.length===0?null:{role:`user`,content:[{type:`text`,text:n.join(`
3
3
 
4
- `)}],run:!0}}function N(e){let n=_();return{...T(e.agent_context),load_public_skills:t.shouldLoadPublicSkills(),load_user_skills:!0,load_project_skills:!0,...n?{system_message_suffix:n}:{}}}function P(e){return T(e.agent_settings).agent_kind===`acp`}function F(e){let t=T(e.agent_settings).acp_server;return typeof t==`string`&&t.length>0?t:void 0}function I(e){let t=e.acp_command;if(!(Array.isArray(t)&&t.length===0)&&t!==void 0)return t;let n=s.getAcpProvider(typeof e.acp_server==`string`?e.acp_server:void 0);return n?[...n.default_command]:t}function L(e){let t=T(e.agent_settings),n={agent_kind:`acp`,agent_context:N(t)};for(let e of S){if(e===`acp_model`)continue;let r=e===`acp_command`?I(t):t[e];r!=null&&(n[e]=r)}let r=T(t.mcp_config);Object.keys(r).length>0&&`mcpServers`in r&&(n.mcp_config=r);let i=s.getAcpProvider(typeof t.acp_server==`string`?t.acp_server:void 0),a=s.resolveEffectiveAcpModel({configured:t.acp_model,providerDefault:i?.default_model});return a&&(n.acp_model=a),n}function R(e){let t=T(e.agent_settings),n=T(t.llm);n.model=typeof n.model==`string`&&n.model.trim().length>0?n.model:o.DEFAULT_SETTINGS.llm_model;let r=E(n.api_key);r?n.api_key=r:delete n.api_key;let i=E(n.base_url);i?n.base_url=i:delete n.base_url;let a=T(t.mcp_config);(Object.keys(a).length===0||!(`mcpServers`in a))&&delete t.mcp_config,delete t.acp_server;for(let e of S)delete t[e];return delete t.acp_env,{...t,llm:n,agent_context:N(t),tools:j(t)}}function z(e){return P(e)?L(e):R(e)}function B(e){let{settings:n,query:r,conversationInstructions:i,plugins:a,workingDir:o}=e,s=T(n.conversation_settings),c=M(r,i);return w.forEach(e=>delete s[e]),{...s,workspace:{kind:`LocalWorkspace`,working_dir:o??t.getAgentServerWorkingDir()},...c?{initial_message:c}:{},...a?.length?{plugins:a.map(e=>({source:e.source,...e.ref?{ref:e.ref}:{},...e.repo_path?{repo_path:e.repo_path}:{}}))}:{}}}function V(e){let t=e.encryptedAgentSettings?{...e.settings,agent_settings:e.encryptedAgentSettings}:e.settings,r=P(t),a=z(t),o=r?F(t):void 0,s=B(e.encryptedConversationSettings?{...e,settings:{...e.settings,conversation_settings:e.encryptedConversationSettings}}:e),c={agent_settings:a,workspace:s.workspace,confirmation_policy:D(s),max_iterations:typeof s.max_iterations==`number`?s.max_iterations:500,stuck_detection:!0,autotitle:!0,worktree:!0};o&&(c.tags={[C]:o}),e.secretsEncrypted&&(c.secrets_encrypted=!0),e.conversationId&&(c.conversation_id=e.conversationId);let l=O(s);if(l&&(c.security_analyzer=l),s.initial_message&&(c.initial_message=s.initial_message),s.plugins&&(c.plugins=s.plugins),s.hook_config&&(c.hook_config=s.hook_config),c.tool_module_qualnames={[u]:d,...s.tool_module_qualnames??{}},s.agent_definitions&&(c.agent_definitions=s.agent_definitions),e.customSecrets&&e.customSecrets.length>0){let t=n.getEffectiveLocalBackend(),a=t?i.buildAuthHeaders(t):{},o={};for(let t of e.customSecrets){let e={kind:`LookupSecret`,url:`/api/settings/secrets/${encodeURIComponent(t.name)}`,description:t.description};Object.keys(a).length>0&&(e.headers=a),o[t.name]=e}c.secrets=o,r&&(c.agent_settings.agent_context={...c.agent_settings.agent_context,secrets:o})}return c}async function H(e){let{SecretsService:t}=await Promise.resolve().then(()=>require(`./secrets-service.cjs`)),[n,r]=await Promise.all([l.default.getSettingsForConversation(),t.getSecrets()]),{agentSettings:i,conversationSettings:a,secretsEncrypted:o}=n;return V({...e,encryptedAgentSettings:i,encryptedConversationSettings:a,secretsEncrypted:o,customSecrets:r})}function U(){return{hooks:[]}}exports.buildStartConversationRequestWithEncryptedSettings=H,exports.emptyHooksResponse=U,exports.getDefaultConversationTitle=y,exports.toAppConversation=b,exports.toConversationPage=x;
4
+ `)}],run:!0}}function P(e){let n=y();return{...E(e.agent_context),load_public_skills:t.shouldLoadPublicSkills(),load_user_skills:!0,load_project_skills:!0,...n?{system_message_suffix:n}:{}}}function F(e){return E(e.agent_settings).agent_kind===`acp`}function I(e){let t=E(e.agent_settings).acp_server;return typeof t==`string`&&t.length>0?t:void 0}function L(e){let t=e.acp_command;if(!(Array.isArray(t)&&t.length===0)&&t!==void 0)return t;let n=c.getAcpProvider(typeof e.acp_server==`string`?e.acp_server:void 0);return n?[...n.default_command]:t}function R(e){let t=E(e.agent_settings),n={agent_kind:`acp`,agent_context:P(t)};for(let e of a.ACP_SETTINGS_KEYS){if(e===`acp_model`||e===`acp_env`)continue;let r=e===`acp_command`?L(t):t[e];r!=null&&(n[e]=r)}let r=E(t.mcp_config);Object.keys(r).length>0&&`mcpServers`in r&&(n.mcp_config=r);let i=c.getAcpProvider(typeof t.acp_server==`string`?t.acp_server:void 0),o=c.resolveEffectiveAcpModel({configured:t.acp_model,providerDefault:i?.default_model});return o&&(n.acp_model=o),n}function z(e){let t=E(e.agent_settings),n=E(t.llm);n.model=typeof n.model==`string`&&n.model.trim().length>0?n.model:s.DEFAULT_SETTINGS.llm_model;let r=D(n.api_key);r?n.api_key=r:delete n.api_key;let i=D(n.base_url);i?n.base_url=i:delete n.base_url;let o=E(t.mcp_config);(Object.keys(o).length===0||!(`mcpServers`in o))&&delete t.mcp_config,delete t.acp_server;for(let e of a.ACP_SETTINGS_KEYS)delete t[e];return delete t.acp_env,{...t,llm:n,agent_context:P(t),tools:M(t)}}function B(e){return F(e)?R(e):z(e)}function V(e){let{settings:n,query:r,conversationInstructions:i,plugins:a,workingDir:o}=e,s=E(n.conversation_settings),c=N(r,i);return T.forEach(e=>delete s[e]),{...s,workspace:{kind:`LocalWorkspace`,working_dir:o??t.getAgentServerWorkingDir()},...c?{initial_message:c}:{},...a?.length?{plugins:a.map(e=>({source:e.source,...e.ref?{ref:e.ref}:{},...e.repo_path?{repo_path:e.repo_path}:{}}))}:{}}}function H(e){let t=e.encryptedAgentSettings?{...e.settings,agent_settings:e.encryptedAgentSettings}:e.settings,r=F(t),a=B(t),o=r?I(t):void 0,s=V(e.encryptedConversationSettings?{...e,settings:{...e.settings,conversation_settings:e.encryptedConversationSettings}}:e),c={agent_settings:a,workspace:s.workspace,confirmation_policy:O(s),max_iterations:typeof s.max_iterations==`number`?s.max_iterations:500,stuck_detection:!0,autotitle:!0,worktree:!0};o&&(c.tags={[w]:o}),e.secretsEncrypted&&(c.secrets_encrypted=!0),e.conversationId&&(c.conversation_id=e.conversationId);let l=k(s);if(l&&(c.security_analyzer=l),s.initial_message&&(c.initial_message=s.initial_message),s.plugins&&(c.plugins=s.plugins),s.hook_config&&(c.hook_config=s.hook_config),c.tool_module_qualnames={[d]:f,...s.tool_module_qualnames??{}},s.agent_definitions&&(c.agent_definitions=s.agent_definitions),e.customSecrets&&e.customSecrets.length>0){let t=n.getEffectiveLocalBackend(),a=t?i.buildAuthHeaders(t):{},o={};for(let t of e.customSecrets){let e={kind:`LookupSecret`,url:`/api/settings/secrets/${encodeURIComponent(t.name)}`,description:t.description};Object.keys(a).length>0&&(e.headers=a),o[t.name]=e}c.secrets=o,r&&(c.agent_settings.agent_context={...c.agent_settings.agent_context,secrets:o})}return c}async function U(e){let{SecretsService:t}=await Promise.resolve().then(()=>require(`./secrets-service.cjs`)),[n,r]=await Promise.all([u.default.getSettingsForConversation(),t.getSecrets()]),{agentSettings:i,conversationSettings:a,secretsEncrypted:o}=n;return H({...e,encryptedAgentSettings:i,encryptedConversationSettings:a,secretsEncrypted:o,customSecrets:r})}function W(){return{hooks:[]}}exports.buildStartConversationRequestWithEncryptedSettings=U,exports.emptyHooksResponse=W,exports.getDefaultConversationTitle=x,exports.toAppConversation=S,exports.toConversationPage=C;
5
5
  //# sourceMappingURL=agent-server-adapter.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-server-adapter.cjs","names":[],"sources":["../../src/api/agent-server-adapter.ts"],"sourcesContent":["import { DEFAULT_SETTINGS } from \"#/services/settings\";\nimport { ExecutionStatus } from \"#/types/agent-server/core\";\nimport { Settings, SettingsValue } from \"#/types/settings\";\nimport {\n getAcpProvider,\n resolveEffectiveAcpModel,\n} from \"#/constants/acp-providers\";\nimport { getAgentServerClientOptions } from \"./agent-server-client-options\";\nimport { isAgentServerToolAvailable } from \"./agent-server-compatibility\";\nimport {\n getAgentServerWorkingDir,\n shouldLoadPublicSkills,\n} from \"./agent-server-config\";\nimport { getEffectiveLocalBackend } from \"./backend-registry/active-store\";\nimport { buildAuthHeaders } from \"./backend-registry/auth\";\nimport {\n GetHooksResponse,\n PluginSpec,\n AppConversation,\n AppConversationPage,\n SandboxStatus,\n} from \"./conversation-service/agent-server-conversation-service.types\";\nimport SettingsService from \"./settings-service/settings-service.api\";\nimport { getStoredConversationMetadata } from \"./conversation-metadata-store\";\n\nexport interface DirectConversationInfo {\n id: string;\n title?: string | null;\n created_at: string;\n updated_at: string;\n execution_status?: string | null;\n /** Cloud-only sandbox lifecycle state. Omitted / null for local agent-server conversations. */\n sandbox_status?: string | null;\n metrics?: {\n accumulated_cost?: number | null;\n max_budget_per_task?: number | null;\n accumulated_token_usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n cache_read_tokens?: number;\n cache_write_tokens?: number;\n context_window?: number;\n per_turn_token?: number;\n } | null;\n } | null;\n agent?: {\n /**\n * Pydantic discriminator from the SDK union: ``\"ACPAgent\"`` for ACP CLI\n * subprocesses (model lives on the subprocess via ``acp_model``),\n * ``\"Agent\"`` for direct litellm. Read by {@link toAppConversation}.\n */\n kind?: string | null;\n acp_model?: string | null;\n llm?: {\n model?: string | null;\n } | null;\n } | null;\n current_model_id?: string | null;\n current_model_name?: string | null;\n workspace?: {\n working_dir?: string | null;\n } | null;\n /**\n * Arbitrary string-keyed conversation tags surfaced by the agent-server\n * (see ``ConversationInfo.tags``). Canvas only consumes one key today —\n * ``ACP_SERVER_TAG_KEY`` (\"acpserver\") — but the field is typed as a\n * generic record so future readers don't need another wire-shape change.\n * Keys are constrained to ``^[a-z0-9]+$`` by the agent-server validator;\n * values are opaque strings.\n */\n tags?: Record<string, string> | null;\n}\n\n// Module qualname for the Canvas-UI tool. The agent-server imports this via\n// tool_module_qualnames; the host directory is exposed via OH_EXTRA_PYTHON_PATH\n// (see scripts/dev-safe.mjs).\nconst CANVAS_UI_TOOL_NAME = \"canvas_ui\";\nconst CANVAS_UI_TOOL_MODULE = \"canvas_ui_tool\";\n\nconst DEFAULT_TOOL_NAMES = [\n \"terminal\",\n \"file_editor\",\n \"task_tracker\",\n CANVAS_UI_TOOL_NAME,\n];\nconst BROWSER_TOOL_SET_NAME = \"browser_tool_set\";\nconst TASK_TOOL_SET_NAME = \"task_tool_set\";\n\nfunction browserToolsEnabled() {\n return import.meta.env.VITE_ENABLE_BROWSER_TOOLS !== \"false\";\n}\n\n/**\n * Shape of `VITE_RUNTIME_SERVICES_INFO` (set by the dev launchers in\n * scripts/dev-*.mjs). All URLs are written from the agent's point of view,\n * not the browser's. The block is rendered into the agent's system prompt\n * via `AgentContext.system_message_suffix` so the agent knows what's\n * reachable from inside its sandbox without having to probe.\n */\ninterface RuntimeServicesInfo {\n mode?: string;\n agent_host_alias?: string;\n services?: {\n agent_server?: { description?: string; url_from_agent?: string };\n ingress?: { description?: string; url_from_agent?: string };\n frontend?: {\n kind?: \"vite\" | \"static\";\n description?: string;\n url_from_agent?: string;\n };\n // `vite` is the legacy key name for the frontend entry, accepted for\n // one release while older dev-stack launchers may still emit it.\n vite?: { description?: string; url_from_agent?: string };\n automation?: {\n description?: string;\n url_from_agent?: string;\n api_prefix?: string;\n docs_url?: string;\n openapi_url?: string;\n auth_env_var?: string;\n };\n };\n}\n\nfunction parseRuntimeServicesInfo(): RuntimeServicesInfo | null {\n const raw = import.meta.env.VITE_RUNTIME_SERVICES_INFO?.trim();\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw) as RuntimeServicesInfo;\n if (!parsed || typeof parsed !== \"object\") return null;\n return parsed;\n } catch {\n // Malformed JSON: ignore and fall back to no runtime info, rather than\n // tearing down conversation creation over a misconfigured dev env var.\n return null;\n }\n}\n\n/**\n * Render the runtime services info into a markdown block suitable for\n * appending to the system prompt via `AgentContext.system_message_suffix`.\n *\n * Returns `undefined` when no runtime info is configured, so callers can\n * safely omit the field on production builds (where the launcher doesn't\n * set `VITE_RUNTIME_SERVICES_INFO`).\n */\nexport function buildRuntimeServicesSystemSuffix(): string | undefined {\n const info = parseRuntimeServicesInfo();\n if (!info?.services) return undefined;\n\n const lines: string[] = [];\n lines.push(\"<RUNTIME_SERVICES>\");\n if (info.mode) {\n lines.push(\n `You are running inside an agent-canvas dev stack started in '${info.mode}' mode.`,\n );\n } else {\n lines.push(\"You are running inside an agent-canvas dev stack.\");\n }\n lines.push(\n \"The following services are reachable from your sandbox. URLs are written\",\n \"from your point of view (i.e., as you should curl/fetch them).\",\n \"\",\n );\n\n const { agent_server, ingress, automation } = info.services;\n // Accept `frontend` (current key) or `vite` (legacy key) for the\n // frontend service entry. The legacy fallback can be removed once all\n // launchers in this repo emit `frontend`.\n const frontend = info.services.frontend ?? info.services.vite;\n\n if (agent_server?.url_from_agent) {\n lines.push(\n `* Agent Server (you): ${agent_server.url_from_agent}`,\n ` ${agent_server.description ?? \"The agent-server hosting your tool calls.\"}`,\n );\n }\n if (ingress?.url_from_agent) {\n lines.push(\n `* Ingress: ${ingress.url_from_agent}`,\n ` ${ingress.description ?? \"Unified entry point for browser-facing traffic.\"}`,\n );\n }\n if (frontend?.url_from_agent) {\n lines.push(\n `* Frontend: ${frontend.url_from_agent}`,\n ` ${frontend.description ?? \"Frontend dev server.\"}`,\n );\n }\n if (automation?.url_from_agent) {\n lines.push(\n `* Automation backend: ${automation.url_from_agent}`,\n ` ${automation.description ?? \"OpenHands Automations service.\"}`,\n );\n if (automation.docs_url) {\n lines.push(` Docs: ${automation.docs_url}`);\n }\n if (automation.openapi_url) {\n lines.push(` OpenAPI: ${automation.openapi_url}`);\n }\n if (automation.auth_env_var) {\n // X-Session-API-Key is the local convention shared by the agent-server\n // and automation backend (see openhands-automation auth.py).\n lines.push(\n ` Auth: header 'X-Session-API-Key: $${automation.auth_env_var}'`,\n );\n }\n } else {\n lines.push(\n \"* Automation backend: not running in this dev mode (skip /api/automation calls).\",\n );\n }\n\n // Anchor the \"don't guess\" warning to the actual agent-server URL for\n // this stack instead of a hardcoded port. The agent-server listens on\n // different ports across dev modes, and baking the wrong port into the\n // system prompt is exactly the kind of confusion this block is meant to\n // prevent.\n const agentServerUrl = agent_server?.url_from_agent;\n lines.push(\n \"\",\n \"Trust this block over guessing: do not assume any other URLs are running.\",\n );\n if (agentServerUrl) {\n lines.push(\n `In particular, ${agentServerUrl} inside your sandbox is the Agent Server`,\n \"you are running inside of — NOT the automation backend.\",\n );\n }\n lines.push(\"</RUNTIME_SERVICES>\");\n\n return lines.join(\"\\n\");\n}\n\nexport function toConversationUrl(conversationId: string): string {\n // Local-format conversation URL — points at whichever local agent-server\n // is actually serving the conversation (the bundled one when the active\n // selection is cloud).\n const { host } = getAgentServerClientOptions();\n return `${host}/api/conversations/${conversationId}`;\n}\n\n// TODO(i18n): extract \"Conversation\" once we add CONVERSATION$DEFAULT_TITLE\n// with `{{shortId}}` interpolation. Kept as a literal for now to keep the\n// fallback inside this pure adapter rather than fanning out to display sites.\nexport function getDefaultConversationTitle(conversationId: string): string {\n return `Conversation ${conversationId.slice(0, 5)}`;\n}\n\nexport function toAppConversation(\n info: DirectConversationInfo,\n): AppConversation {\n const metadata = getStoredConversationMetadata(info.id);\n // ACPAgent conversations carry a sentinel ``llm`` on older SDKs. Prefer the\n // runtime model fields when available, then the configured ``acp_model`` that\n // Canvas saves for built-in providers. ``agent_kind`` still gates model\n // switching, so surfacing this string is display-only.\n const isAcp = info.agent?.kind === \"ACPAgent\";\n // Only surface ``acp_server`` for ACP conversations even if the wire\n // payload accidentally carries an ``acpserver`` tag on an OpenHands\n // conversation — the chip is identity info for the ACP CLI subprocess,\n // and showing it on a non-ACP conversation would be a lie.\n const acpServer = isAcp ? (info.tags?.[ACP_SERVER_TAG_KEY] ?? null) : null;\n return {\n id: info.id,\n created_by_user_id: null,\n selected_repository: metadata?.selected_repository ?? null,\n selected_branch: metadata?.selected_branch ?? null,\n git_provider: metadata?.git_provider ?? null,\n selected_workspace: metadata?.selected_workspace ?? null,\n active_profile: metadata?.active_profile ?? null,\n title: info.title?.trim()\n ? info.title\n : getDefaultConversationTitle(info.id),\n trigger: null,\n pr_number: [],\n agent_kind: isAcp ? \"acp\" : \"openhands\",\n acp_server: acpServer,\n // Chip path: no ``providerDefault`` — the chip must distinguish\n // \"no concrete model\" (fall back to the provider display name in\n // ConversationCardFooter) from \"default\" (would lie about what's\n // running on the subprocess).\n llm_model: isAcp\n ? resolveEffectiveAcpModel({\n runtimeName: info.current_model_name,\n runtimeId: info.current_model_id,\n configured: info.agent?.acp_model,\n sdkLlm: info.agent?.llm?.model,\n })\n : (info.agent?.llm?.model ?? DEFAULT_SETTINGS.llm_model),\n metrics: info.metrics\n ? {\n accumulated_cost: info.metrics.accumulated_cost ?? null,\n max_budget_per_task: info.metrics.max_budget_per_task ?? null,\n accumulated_token_usage: info.metrics.accumulated_token_usage\n ? {\n prompt_tokens:\n info.metrics.accumulated_token_usage.prompt_tokens ?? 0,\n completion_tokens:\n info.metrics.accumulated_token_usage.completion_tokens ?? 0,\n cache_read_tokens:\n info.metrics.accumulated_token_usage.cache_read_tokens ?? 0,\n cache_write_tokens:\n info.metrics.accumulated_token_usage.cache_write_tokens ?? 0,\n context_window:\n info.metrics.accumulated_token_usage.context_window ?? 0,\n per_turn_token:\n info.metrics.accumulated_token_usage.per_turn_token ?? 0,\n }\n : null,\n }\n : null,\n created_at: info.created_at,\n updated_at: info.updated_at,\n execution_status:\n (info.execution_status as AppConversation[\"execution_status\"]) ??\n ExecutionStatus.IDLE,\n sandbox_status: (info.sandbox_status as SandboxStatus | null) ?? null,\n conversation_url: toConversationUrl(info.id),\n session_api_key: getAgentServerClientOptions().apiKey ?? null,\n sandbox_id: null,\n workspace: {\n working_dir: info.workspace?.working_dir ?? getAgentServerWorkingDir(),\n },\n public: false,\n sub_conversation_ids: [],\n };\n}\n\nexport function toConversationPage(data: {\n items: DirectConversationInfo[];\n next_page_id?: string | null;\n}): AppConversationPage {\n return {\n items: data.items.map(toAppConversation),\n next_page_id: data.next_page_id ?? null,\n };\n}\n\ntype SettingsRecord = Record<string, unknown>;\n\ninterface AgentToolSpec {\n name: string;\n params: SettingsRecord;\n}\n\ntype AgentSettingsPayload = SettingsRecord & {\n llm?: SettingsRecord;\n agent_context: SettingsRecord;\n tools?: AgentToolSpec[];\n};\n\ninterface LocalWorkspacePayload {\n kind: \"LocalWorkspace\";\n working_dir: string;\n}\n\ninterface InitialMessagePayload {\n role: \"user\";\n content: Array<{ type: \"text\"; text: string }>;\n run: true;\n}\n\ntype ConversationSettingsPayload = SettingsRecord & {\n workspace: LocalWorkspacePayload;\n initial_message?: InitialMessagePayload;\n};\n\nconst ACP_SETTINGS_KEYS = [\n \"acp_command\",\n \"acp_args\",\n \"acp_model\",\n \"acp_session_mode\",\n \"acp_prompt_timeout\",\n] as const;\n\nexport const ACP_SERVER_TAG_KEY = \"acpserver\";\n\nconst CONVERSATION_SETTINGS_METADATA_KEYS = new Set([\n \"schema_version\",\n \"agent_settings\",\n \"workspace\",\n \"conversation_id\",\n \"initial_message\",\n \"plugins\",\n]);\n\nfunction toRecord(value: unknown): SettingsRecord {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return {};\n }\n\n return structuredClone(value as SettingsRecord);\n}\n\nfunction normalizeSecretString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction getConversationConfirmationPolicy(\n conversationSettings: SettingsRecord,\n) {\n if (conversationSettings.confirmation_mode !== true) {\n return { kind: \"NeverConfirm\" };\n }\n\n if (conversationSettings.security_analyzer === \"llm\") {\n return { kind: \"ConfirmRisky\", threshold: \"HIGH\", confirm_unknown: true };\n }\n\n return { kind: \"AlwaysConfirm\" };\n}\n\nfunction getConversationSecurityAnalyzer(conversationSettings: SettingsRecord) {\n switch (conversationSettings.security_analyzer) {\n case \"llm\":\n return { kind: \"LLMSecurityAnalyzer\" };\n case \"pattern\":\n return { kind: \"PatternSecurityAnalyzer\" };\n case \"policy_rail\":\n return { kind: \"PolicyRailSecurityAnalyzer\" };\n default:\n return undefined;\n }\n}\n\nfunction isToolRecord(\n value: unknown,\n): value is { name: string; params?: unknown } {\n return (\n !!value &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n typeof (value as { name?: unknown }).name === \"string\"\n );\n}\n\nfunction shouldIncludeTool(name: string, agentSettings: SettingsRecord) {\n if (name === BROWSER_TOOL_SET_NAME) {\n return browserToolsEnabled() && isAgentServerToolAvailable(name);\n }\n\n if (name === TASK_TOOL_SET_NAME) {\n return (\n agentSettings.enable_sub_agents === true &&\n isAgentServerToolAvailable(name)\n );\n }\n\n return true;\n}\n\nfunction getAgentTools(agentSettings: SettingsRecord): AgentToolSpec[] {\n const tools = new Map<string, AgentToolSpec>();\n\n for (const name of DEFAULT_TOOL_NAMES) {\n tools.set(name, { name, params: {} });\n }\n\n for (const name of [BROWSER_TOOL_SET_NAME, TASK_TOOL_SET_NAME]) {\n if (shouldIncludeTool(name, agentSettings)) {\n tools.set(name, { name, params: {} });\n }\n }\n\n const configuredTools = agentSettings.tools;\n if (\n Array.isArray(configuredTools) &&\n configuredTools.every((tool) => isToolRecord(tool))\n ) {\n for (const tool of configuredTools) {\n if (shouldIncludeTool(tool.name, agentSettings)) {\n tools.set(tool.name, {\n name: tool.name,\n params: toRecord(tool.params),\n });\n }\n }\n }\n\n return Array.from(tools.values());\n}\n\nfunction buildInitialMessage(\n query?: string,\n conversationInstructions?: string,\n): InitialMessagePayload | null {\n const parts = [query?.trim(), conversationInstructions?.trim()].filter(\n Boolean,\n );\n if (parts.length === 0) {\n return null;\n }\n\n return {\n role: \"user\",\n content: [{ type: \"text\", text: parts.join(\"\\n\\n\") }],\n run: true,\n };\n}\n\nfunction buildAgentContext(agentSettings: SettingsRecord): SettingsRecord {\n const runtimeServicesSuffix = buildRuntimeServicesSystemSuffix();\n return {\n ...toRecord(agentSettings.agent_context),\n load_public_skills: shouldLoadPublicSkills(),\n load_user_skills: true,\n load_project_skills: true,\n ...(runtimeServicesSuffix\n ? { system_message_suffix: runtimeServicesSuffix }\n : {}),\n };\n}\n\nfunction isAcpAgent(settings: Settings): boolean {\n const agentSettings = toRecord(settings.agent_settings);\n return agentSettings.agent_kind === \"acp\";\n}\n\nfunction getAcpServerTag(settings: Settings): string | undefined {\n const agentSettings = toRecord(settings.agent_settings);\n const value = agentSettings.acp_server;\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction resolveAcpCommand(agentSettings: SettingsRecord): unknown {\n const cmd = agentSettings.acp_command;\n const isEmpty = Array.isArray(cmd) && cmd.length === 0;\n const noCommand = cmd === undefined;\n if (!isEmpty && !noCommand) {\n return cmd;\n }\n\n const serverKey =\n typeof agentSettings.acp_server === \"string\"\n ? agentSettings.acp_server\n : undefined;\n const provider = getAcpProvider(serverKey);\n return provider ? [...provider.default_command] : cmd;\n}\n\nfunction buildConfiguredAcpAgentSettings(\n settings: Settings,\n): AgentSettingsPayload {\n const agentSettings = toRecord(settings.agent_settings);\n const payload: AgentSettingsPayload = {\n agent_kind: \"acp\",\n agent_context: buildAgentContext(agentSettings),\n };\n\n for (const key of ACP_SETTINGS_KEYS) {\n // ``acp_model`` is resolved separately below so a saved ``null`` still\n // falls back to the provider's default rather than being dropped.\n if (key === \"acp_model\") continue;\n const value =\n key === \"acp_command\"\n ? resolveAcpCommand(agentSettings)\n : agentSettings[key];\n if (value !== undefined && value !== null) {\n payload[key] = value;\n }\n }\n\n // ``mcp_config`` is a *shared* field (not in ACP_SETTINGS_KEYS): forward it\n // so the ACP subprocess connects to the configured MCP servers at session\n // creation. Only include it when it actually carries servers — an empty or\n // malformed value is dropped rather than sending ``mcp_config: {}``.\n const mcpConfig = toRecord(agentSettings.mcp_config);\n if (Object.keys(mcpConfig).length > 0 && \"mcpServers\" in mcpConfig) {\n payload.mcp_config = mcpConfig;\n }\n\n // Saved settings may carry ``acp_model: null`` (existing users predating\n // the default-model registry, or saved fields the agent-server stripped).\n // Fall back to the provider's ``default_model`` so the conversation starts\n // with whatever the Settings → Agent UI shows — without that, the form's\n // displayed default would silently not take effect at runtime until the\n // user re-saved the page.\n const serverKey =\n typeof agentSettings.acp_server === \"string\"\n ? agentSettings.acp_server\n : undefined;\n const provider = getAcpProvider(serverKey);\n const effectiveModel = resolveEffectiveAcpModel({\n configured: agentSettings.acp_model as string | null | undefined,\n providerDefault: provider?.default_model,\n });\n if (effectiveModel) {\n payload.acp_model = effectiveModel;\n }\n\n return payload;\n}\n\nfunction buildConfiguredOpenHandsAgentSettings(\n settings: Settings,\n): AgentSettingsPayload {\n const agentSettings = toRecord(settings.agent_settings);\n const llm = toRecord(agentSettings.llm);\n\n llm.model =\n typeof llm.model === \"string\" && llm.model.trim().length > 0\n ? llm.model\n : DEFAULT_SETTINGS.llm_model;\n\n const apiKey = normalizeSecretString(llm.api_key);\n if (apiKey) {\n llm.api_key = apiKey;\n } else {\n delete llm.api_key;\n }\n\n const baseUrl = normalizeSecretString(llm.base_url);\n if (baseUrl) {\n llm.base_url = baseUrl;\n } else {\n delete llm.base_url;\n }\n\n const mcpConfig = toRecord(agentSettings.mcp_config);\n if (Object.keys(mcpConfig).length === 0 || !(\"mcpServers\" in mcpConfig)) {\n delete agentSettings.mcp_config;\n }\n\n delete agentSettings.acp_server;\n for (const key of ACP_SETTINGS_KEYS) {\n delete agentSettings[key];\n }\n // ``acp_env`` is no longer a forwarded ACP setting (provider creds ride the\n // Secrets panel), but a legacy value may linger on persisted settings —\n // scrub it so it never leaks onto the OpenHands payload.\n delete agentSettings.acp_env;\n\n return {\n ...agentSettings,\n llm,\n agent_context: buildAgentContext(agentSettings),\n tools: getAgentTools(agentSettings),\n };\n}\n\nfunction buildConfiguredAgentSettings(\n settings: Settings,\n): AgentSettingsPayload {\n return isAcpAgent(settings)\n ? buildConfiguredAcpAgentSettings(settings)\n : buildConfiguredOpenHandsAgentSettings(settings);\n}\n\nfunction buildConfiguredConversationSettings(options: {\n settings: Settings;\n query?: string;\n conversationInstructions?: string;\n plugins?: PluginSpec[];\n workingDir?: string;\n}): ConversationSettingsPayload {\n const { settings, query, conversationInstructions, plugins, workingDir } =\n options;\n const conversationSettings = toRecord(settings.conversation_settings);\n const initialMessage = buildInitialMessage(query, conversationInstructions);\n\n CONVERSATION_SETTINGS_METADATA_KEYS.forEach(\n (key) => delete conversationSettings[key],\n );\n\n const payload: ConversationSettingsPayload = {\n ...conversationSettings,\n workspace: {\n kind: \"LocalWorkspace\",\n working_dir: workingDir ?? getAgentServerWorkingDir(),\n },\n ...(initialMessage ? { initial_message: initialMessage } : {}),\n ...(plugins?.length\n ? {\n plugins: plugins.map((plugin) => ({\n source: plugin.source,\n ...(plugin.ref ? { ref: plugin.ref } : {}),\n ...(plugin.repo_path ? { repo_path: plugin.repo_path } : {}),\n })),\n }\n : {}),\n };\n\n return payload;\n}\n\ninterface LookupSecret {\n kind: \"LookupSecret\";\n url: string;\n headers?: Record<string, string>;\n description?: string;\n}\n\ntype StartConversationPayload = Record<string, unknown> & {\n agent_settings: AgentSettingsPayload;\n workspace: LocalWorkspacePayload;\n confirmation_policy: SettingsRecord;\n security_analyzer?: SettingsRecord;\n initial_message?: InitialMessagePayload;\n max_iterations: number;\n stuck_detection: true;\n autotitle: true;\n worktree: true;\n secrets_encrypted?: true;\n conversation_id?: string;\n secrets?: Record<string, LookupSecret>;\n tags?: Record<string, string>;\n tool_module_qualnames?: Record<string, string>;\n};\n\nexport interface StartConversationOptions {\n settings: Settings;\n query?: string;\n conversationInstructions?: string;\n plugins?: PluginSpec[];\n conversationId?: string;\n workingDir?: string;\n encryptedAgentSettings?: Record<string, SettingsValue>;\n encryptedConversationSettings?: Record<string, SettingsValue>;\n secretsEncrypted?: boolean;\n customSecrets?: Array<{ name: string; description?: string }>;\n}\n\nexport function buildStartConversationRequest(\n options: StartConversationOptions,\n): StartConversationPayload {\n const sourceAgentSettings = options.encryptedAgentSettings\n ? { ...options.settings, agent_settings: options.encryptedAgentSettings }\n : options.settings;\n\n const acpMode = isAcpAgent(sourceAgentSettings);\n const agentSettings = buildConfiguredAgentSettings(sourceAgentSettings);\n const acpServerTag = acpMode\n ? getAcpServerTag(sourceAgentSettings)\n : undefined;\n\n const sourceConversationOptions = options.encryptedConversationSettings\n ? {\n ...options,\n settings: {\n ...options.settings,\n conversation_settings: options.encryptedConversationSettings,\n },\n }\n : options;\n\n const conversationSettings = buildConfiguredConversationSettings(\n sourceConversationOptions,\n );\n\n const payload: StartConversationPayload = {\n agent_settings: agentSettings,\n workspace: conversationSettings.workspace,\n confirmation_policy:\n getConversationConfirmationPolicy(conversationSettings),\n max_iterations:\n typeof conversationSettings.max_iterations === \"number\"\n ? conversationSettings.max_iterations\n : 500,\n stuck_detection: true,\n autotitle: true,\n worktree: true,\n };\n\n if (acpServerTag) {\n payload.tags = { [ACP_SERVER_TAG_KEY]: acpServerTag };\n }\n\n if (options.secretsEncrypted) {\n payload.secrets_encrypted = true;\n }\n\n if (options.conversationId) {\n payload.conversation_id = options.conversationId;\n }\n\n const securityAnalyzer =\n getConversationSecurityAnalyzer(conversationSettings);\n if (securityAnalyzer) {\n payload.security_analyzer = securityAnalyzer;\n }\n\n if (conversationSettings.initial_message) {\n payload.initial_message = conversationSettings.initial_message;\n }\n\n if (conversationSettings.plugins) {\n payload.plugins = conversationSettings.plugins;\n }\n\n if (conversationSettings.hook_config) {\n payload.hook_config = conversationSettings.hook_config;\n }\n\n payload.tool_module_qualnames = {\n [CANVAS_UI_TOOL_NAME]: CANVAS_UI_TOOL_MODULE,\n ...((conversationSettings.tool_module_qualnames as\n | Record<string, string>\n | undefined) ?? {}),\n };\n\n if (conversationSettings.agent_definitions) {\n payload.agent_definitions = conversationSettings.agent_definitions;\n }\n\n if (options.customSecrets && options.customSecrets.length > 0) {\n const backend = getEffectiveLocalBackend();\n const headers = backend ? buildAuthHeaders(backend) : {};\n\n const secrets: Record<string, LookupSecret> = {};\n for (const secret of options.customSecrets) {\n const lookupSecret: LookupSecret = {\n kind: \"LookupSecret\",\n url: `/api/settings/secrets/${encodeURIComponent(secret.name)}`,\n description: secret.description,\n };\n\n if (Object.keys(headers).length > 0) {\n lookupSecret.headers = headers;\n }\n\n secrets[secret.name] = lookupSecret;\n }\n\n payload.secrets = secrets;\n\n if (acpMode) {\n payload.agent_settings.agent_context = {\n ...payload.agent_settings.agent_context,\n secrets,\n };\n }\n }\n\n return payload;\n}\n\nexport async function buildStartConversationRequestWithEncryptedSettings(options: {\n settings: Settings;\n query?: string;\n conversationInstructions?: string;\n plugins?: PluginSpec[];\n conversationId?: string;\n workingDir?: string;\n}): Promise<Record<string, unknown>> {\n const { SecretsService } = await import(\"./secrets-service\");\n\n const [settingsResult, customSecrets] = await Promise.all([\n SettingsService.getSettingsForConversation(),\n SecretsService.getSecrets(),\n ]);\n\n const { agentSettings, conversationSettings, secretsEncrypted } =\n settingsResult;\n\n return buildStartConversationRequest({\n ...options,\n encryptedAgentSettings: agentSettings,\n encryptedConversationSettings: conversationSettings,\n secretsEncrypted,\n customSecrets,\n });\n}\n\nexport function emptyHooksResponse(): GetHooksResponse {\n return { hooks: [] };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent-server-adapter.cjs","names":[],"sources":["../../src/api/agent-server-adapter.ts"],"sourcesContent":["import { ACP_SETTINGS_KEYS } from \"@openhands/typescript-client\";\nimport { DEFAULT_SETTINGS } from \"#/services/settings\";\nimport { ExecutionStatus } from \"#/types/agent-server/core\";\nimport { Settings, SettingsValue } from \"#/types/settings\";\nimport {\n getAcpProvider,\n resolveEffectiveAcpModel,\n} from \"#/constants/acp-providers\";\nimport { getAgentServerClientOptions } from \"./agent-server-client-options\";\nimport { isAgentServerToolAvailable } from \"./agent-server-compatibility\";\nimport {\n getAgentServerWorkingDir,\n shouldLoadPublicSkills,\n} from \"./agent-server-config\";\nimport { getEffectiveLocalBackend } from \"./backend-registry/active-store\";\nimport { buildAuthHeaders } from \"./backend-registry/auth\";\nimport {\n GetHooksResponse,\n PluginSpec,\n AppConversation,\n AppConversationPage,\n SandboxStatus,\n} from \"./conversation-service/agent-server-conversation-service.types\";\nimport SettingsService from \"./settings-service/settings-service.api\";\nimport { getStoredConversationMetadata } from \"./conversation-metadata-store\";\n\nexport interface DirectConversationInfo {\n id: string;\n title?: string | null;\n created_at: string;\n updated_at: string;\n execution_status?: string | null;\n /** Cloud-only sandbox lifecycle state. Omitted / null for local agent-server conversations. */\n sandbox_status?: string | null;\n metrics?: {\n accumulated_cost?: number | null;\n max_budget_per_task?: number | null;\n accumulated_token_usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n cache_read_tokens?: number;\n cache_write_tokens?: number;\n context_window?: number;\n per_turn_token?: number;\n } | null;\n } | null;\n agent?: {\n /**\n * Pydantic discriminator from the SDK union: ``\"ACPAgent\"`` for ACP CLI\n * subprocesses (model lives on the subprocess via ``acp_model``),\n * ``\"Agent\"`` for direct litellm. Read by {@link toAppConversation}.\n */\n kind?: string | null;\n acp_model?: string | null;\n llm?: {\n model?: string | null;\n } | null;\n } | null;\n current_model_id?: string | null;\n current_model_name?: string | null;\n workspace?: {\n working_dir?: string | null;\n } | null;\n /**\n * Arbitrary string-keyed conversation tags surfaced by the agent-server\n * (see ``ConversationInfo.tags``). Canvas only consumes one key today —\n * ``ACP_SERVER_TAG_KEY`` (\"acpserver\") — but the field is typed as a\n * generic record so future readers don't need another wire-shape change.\n * Keys are constrained to ``^[a-z0-9]+$`` by the agent-server validator;\n * values are opaque strings.\n */\n tags?: Record<string, string> | null;\n}\n\n// Module qualname for the Canvas-UI tool. The agent-server imports this via\n// tool_module_qualnames; the host directory is exposed via OH_EXTRA_PYTHON_PATH\n// (see scripts/dev-safe.mjs).\nconst CANVAS_UI_TOOL_NAME = \"canvas_ui\";\nconst CANVAS_UI_TOOL_MODULE = \"canvas_ui_tool\";\n\nconst DEFAULT_TOOL_NAMES = [\n \"terminal\",\n \"file_editor\",\n \"task_tracker\",\n CANVAS_UI_TOOL_NAME,\n];\nconst BROWSER_TOOL_SET_NAME = \"browser_tool_set\";\nconst TASK_TOOL_SET_NAME = \"task_tool_set\";\n\nfunction browserToolsEnabled() {\n return import.meta.env.VITE_ENABLE_BROWSER_TOOLS !== \"false\";\n}\n\n/**\n * Shape of the runtime services info (set by the dev launchers in\n * scripts/dev-*.mjs as `VITE_RUNTIME_SERVICES_INFO`, or injected at serve time\n * by `scripts/static-server.mjs` for static builds — see\n * `getRawRuntimeServicesInfo`). All URLs are written from the agent's point of\n * view, not the browser's. The block is rendered into the agent's system prompt\n * via `AgentContext.system_message_suffix` so the agent knows what's\n * reachable from inside its sandbox without having to probe.\n */\ninterface RuntimeServicesInfo {\n mode?: string;\n agent_host_alias?: string;\n services?: {\n agent_server?: { description?: string; url_from_agent?: string };\n ingress?: { description?: string; url_from_agent?: string };\n frontend?: {\n kind?: \"vite\" | \"static\";\n description?: string;\n url_from_agent?: string;\n };\n // `vite` is the legacy key name for the frontend entry, accepted for\n // one release while older dev-stack launchers may still emit it.\n vite?: { description?: string; url_from_agent?: string };\n automation?: {\n description?: string;\n url_from_agent?: string;\n api_prefix?: string;\n docs_url?: string;\n openapi_url?: string;\n auth_env_var?: string;\n };\n };\n}\n\n/**\n * Return the raw runtime-services JSON string, consulting two sources in order\n * (mirrors `getBakedSessionApiKey` in agent-server-config.ts):\n * 1. `VITE_RUNTIME_SERVICES_INFO` — baked into the bundle at build time by\n * the dev launchers (`npm run dev`, dev:static).\n * 2. `window.__AGENT_CANVAS_RUNTIME_SERVICES_INFO__` — injected into\n * index.html at serve time by `scripts/static-server.mjs\n * --runtime-services-info <json>`. This is the path used by static builds\n * (the Docker image and the published binary), where the env var is empty\n * in the prebuilt bundle. Without it the `<RUNTIME_SERVICES>` block is\n * missing and the agent cannot reach the local automation backend.\n */\nfunction getRawRuntimeServicesInfo(): string | null {\n const envRaw = import.meta.env.VITE_RUNTIME_SERVICES_INFO?.trim();\n if (envRaw) return envRaw;\n\n if (typeof window !== \"undefined\") {\n const injected = (window as unknown as Record<string, unknown>)\n .__AGENT_CANVAS_RUNTIME_SERVICES_INFO__;\n if (typeof injected === \"string\") {\n return injected.trim() || null;\n }\n }\n\n return null;\n}\n\nfunction parseRuntimeServicesInfo(): RuntimeServicesInfo | null {\n const raw = getRawRuntimeServicesInfo();\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw) as RuntimeServicesInfo;\n if (!parsed || typeof parsed !== \"object\") return null;\n return parsed;\n } catch {\n // Malformed JSON: ignore and fall back to no runtime info, rather than\n // tearing down conversation creation over a misconfigured env var or\n // injected value.\n return null;\n }\n}\n\n/**\n * Render the runtime services info into a markdown block suitable for\n * appending to the system prompt via `AgentContext.system_message_suffix`.\n *\n * Returns `undefined` when no runtime info is configured, so callers can\n * safely omit the field on production builds (where the launcher doesn't\n * set `VITE_RUNTIME_SERVICES_INFO`).\n */\nexport function buildRuntimeServicesSystemSuffix(): string | undefined {\n const info = parseRuntimeServicesInfo();\n if (!info?.services) return undefined;\n\n const lines: string[] = [];\n lines.push(\"<RUNTIME_SERVICES>\");\n if (info.mode) {\n lines.push(\n `You are running inside an agent-canvas dev stack started in '${info.mode}' mode.`,\n );\n } else {\n lines.push(\"You are running inside an agent-canvas dev stack.\");\n }\n lines.push(\n \"The following services are reachable from your sandbox. URLs are written\",\n \"from your point of view (i.e., as you should curl/fetch them).\",\n \"\",\n );\n\n const { agent_server, ingress, automation } = info.services;\n // Accept `frontend` (current key) or `vite` (legacy key) for the\n // frontend service entry. The legacy fallback can be removed once all\n // launchers in this repo emit `frontend`.\n const frontend = info.services.frontend ?? info.services.vite;\n\n if (agent_server?.url_from_agent) {\n lines.push(\n `* Agent Server (you): ${agent_server.url_from_agent}`,\n ` ${agent_server.description ?? \"The agent-server hosting your tool calls.\"}`,\n );\n }\n if (ingress?.url_from_agent) {\n lines.push(\n `* Ingress: ${ingress.url_from_agent}`,\n ` ${ingress.description ?? \"Unified entry point for browser-facing traffic.\"}`,\n );\n }\n if (frontend?.url_from_agent) {\n lines.push(\n `* Frontend: ${frontend.url_from_agent}`,\n ` ${frontend.description ?? \"Frontend dev server.\"}`,\n );\n }\n if (automation?.url_from_agent) {\n lines.push(\n `* Automation backend: ${automation.url_from_agent}`,\n ` ${automation.description ?? \"OpenHands Automations service.\"}`,\n );\n if (automation.docs_url) {\n lines.push(` Docs: ${automation.docs_url}`);\n }\n if (automation.openapi_url) {\n lines.push(` OpenAPI: ${automation.openapi_url}`);\n }\n if (automation.auth_env_var) {\n // X-Session-API-Key is the local convention shared by the agent-server\n // and automation backend (see openhands-automation auth.py).\n lines.push(\n ` Auth: header 'X-Session-API-Key: $${automation.auth_env_var}'`,\n );\n }\n } else {\n lines.push(\n \"* Automation backend: not running in this dev mode (skip /api/automation calls).\",\n );\n }\n\n // Anchor the \"don't guess\" warning to the actual agent-server URL for\n // this stack instead of a hardcoded port. The agent-server listens on\n // different ports across dev modes, and baking the wrong port into the\n // system prompt is exactly the kind of confusion this block is meant to\n // prevent.\n const agentServerUrl = agent_server?.url_from_agent;\n lines.push(\n \"\",\n \"Trust this block over guessing: do not assume any other URLs are running.\",\n );\n if (agentServerUrl) {\n lines.push(\n `In particular, ${agentServerUrl} inside your sandbox is the Agent Server`,\n \"you are running inside of — NOT the automation backend.\",\n );\n }\n lines.push(\"</RUNTIME_SERVICES>\");\n\n return lines.join(\"\\n\");\n}\n\nexport function toConversationUrl(conversationId: string): string {\n // Local-format conversation URL — points at whichever local agent-server\n // is actually serving the conversation (the bundled one when the active\n // selection is cloud).\n const { host } = getAgentServerClientOptions();\n return `${host}/api/conversations/${conversationId}`;\n}\n\n// TODO(i18n): extract \"Conversation\" once we add CONVERSATION$DEFAULT_TITLE\n// with `{{shortId}}` interpolation. Kept as a literal for now to keep the\n// fallback inside this pure adapter rather than fanning out to display sites.\nexport function getDefaultConversationTitle(conversationId: string): string {\n return `Conversation ${conversationId.slice(0, 5)}`;\n}\n\nexport function toAppConversation(\n info: DirectConversationInfo,\n): AppConversation {\n const metadata = getStoredConversationMetadata(info.id);\n // ACPAgent conversations carry a sentinel ``llm`` on older SDKs. Prefer the\n // runtime model fields when available, then the configured ``acp_model`` that\n // Canvas saves for built-in providers. ``agent_kind`` still gates model\n // switching, so surfacing this string is display-only.\n const isAcp = info.agent?.kind === \"ACPAgent\";\n // Only surface ``acp_server`` for ACP conversations even if the wire\n // payload accidentally carries an ``acpserver`` tag on an OpenHands\n // conversation — the chip is identity info for the ACP CLI subprocess,\n // and showing it on a non-ACP conversation would be a lie.\n const acpServer = isAcp ? (info.tags?.[ACP_SERVER_TAG_KEY] ?? null) : null;\n return {\n id: info.id,\n created_by_user_id: null,\n selected_repository: metadata?.selected_repository ?? null,\n selected_branch: metadata?.selected_branch ?? null,\n git_provider: metadata?.git_provider ?? null,\n selected_workspace: metadata?.selected_workspace ?? null,\n active_profile: metadata?.active_profile ?? null,\n title: info.title?.trim()\n ? info.title\n : getDefaultConversationTitle(info.id),\n trigger: null,\n pr_number: [],\n agent_kind: isAcp ? \"acp\" : \"openhands\",\n acp_server: acpServer,\n // Chip path: no ``providerDefault`` — the chip must distinguish\n // \"no concrete model\" (fall back to the provider display name in\n // ConversationCardFooter) from \"default\" (would lie about what's\n // running on the subprocess).\n llm_model: isAcp\n ? resolveEffectiveAcpModel({\n runtimeName: info.current_model_name,\n runtimeId: info.current_model_id,\n configured: info.agent?.acp_model,\n sdkLlm: info.agent?.llm?.model,\n })\n : (info.agent?.llm?.model ?? DEFAULT_SETTINGS.llm_model),\n metrics: info.metrics\n ? {\n accumulated_cost: info.metrics.accumulated_cost ?? null,\n max_budget_per_task: info.metrics.max_budget_per_task ?? null,\n accumulated_token_usage: info.metrics.accumulated_token_usage\n ? {\n prompt_tokens:\n info.metrics.accumulated_token_usage.prompt_tokens ?? 0,\n completion_tokens:\n info.metrics.accumulated_token_usage.completion_tokens ?? 0,\n cache_read_tokens:\n info.metrics.accumulated_token_usage.cache_read_tokens ?? 0,\n cache_write_tokens:\n info.metrics.accumulated_token_usage.cache_write_tokens ?? 0,\n context_window:\n info.metrics.accumulated_token_usage.context_window ?? 0,\n per_turn_token:\n info.metrics.accumulated_token_usage.per_turn_token ?? 0,\n }\n : null,\n }\n : null,\n created_at: info.created_at,\n updated_at: info.updated_at,\n execution_status:\n (info.execution_status as AppConversation[\"execution_status\"]) ??\n ExecutionStatus.IDLE,\n sandbox_status: (info.sandbox_status as SandboxStatus | null) ?? null,\n conversation_url: toConversationUrl(info.id),\n session_api_key: getAgentServerClientOptions().apiKey ?? null,\n sandbox_id: null,\n workspace: {\n working_dir: info.workspace?.working_dir ?? getAgentServerWorkingDir(),\n },\n public: false,\n sub_conversation_ids: [],\n };\n}\n\nexport function toConversationPage(data: {\n items: DirectConversationInfo[];\n next_page_id?: string | null;\n}): AppConversationPage {\n return {\n items: data.items.map(toAppConversation),\n next_page_id: data.next_page_id ?? null,\n };\n}\n\ntype SettingsRecord = Record<string, unknown>;\n\ninterface AgentToolSpec {\n name: string;\n params: SettingsRecord;\n}\n\ntype AgentSettingsPayload = SettingsRecord & {\n llm?: SettingsRecord;\n agent_context: SettingsRecord;\n tools?: AgentToolSpec[];\n};\n\ninterface LocalWorkspacePayload {\n kind: \"LocalWorkspace\";\n working_dir: string;\n}\n\ninterface InitialMessagePayload {\n role: \"user\";\n content: Array<{ type: \"text\"; text: string }>;\n run: true;\n}\n\ntype ConversationSettingsPayload = SettingsRecord & {\n workspace: LocalWorkspacePayload;\n initial_message?: InitialMessagePayload;\n};\n\nexport const ACP_SERVER_TAG_KEY = \"acpserver\";\n\nconst CONVERSATION_SETTINGS_METADATA_KEYS = new Set([\n \"schema_version\",\n \"agent_settings\",\n \"workspace\",\n \"conversation_id\",\n \"initial_message\",\n \"plugins\",\n]);\n\nfunction toRecord(value: unknown): SettingsRecord {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return {};\n }\n\n return structuredClone(value as SettingsRecord);\n}\n\nfunction normalizeSecretString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction getConversationConfirmationPolicy(\n conversationSettings: SettingsRecord,\n) {\n if (conversationSettings.confirmation_mode !== true) {\n return { kind: \"NeverConfirm\" };\n }\n\n if (conversationSettings.security_analyzer === \"llm\") {\n return { kind: \"ConfirmRisky\", threshold: \"HIGH\", confirm_unknown: true };\n }\n\n return { kind: \"AlwaysConfirm\" };\n}\n\nfunction getConversationSecurityAnalyzer(conversationSettings: SettingsRecord) {\n switch (conversationSettings.security_analyzer) {\n case \"llm\":\n return { kind: \"LLMSecurityAnalyzer\" };\n case \"pattern\":\n return { kind: \"PatternSecurityAnalyzer\" };\n case \"policy_rail\":\n return { kind: \"PolicyRailSecurityAnalyzer\" };\n default:\n return undefined;\n }\n}\n\nfunction isToolRecord(\n value: unknown,\n): value is { name: string; params?: unknown } {\n return (\n !!value &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n typeof (value as { name?: unknown }).name === \"string\"\n );\n}\n\nfunction shouldIncludeTool(name: string, agentSettings: SettingsRecord) {\n if (name === BROWSER_TOOL_SET_NAME) {\n return browserToolsEnabled() && isAgentServerToolAvailable(name);\n }\n\n if (name === TASK_TOOL_SET_NAME) {\n return (\n agentSettings.enable_sub_agents === true &&\n isAgentServerToolAvailable(name)\n );\n }\n\n return true;\n}\n\nfunction getAgentTools(agentSettings: SettingsRecord): AgentToolSpec[] {\n const tools = new Map<string, AgentToolSpec>();\n\n for (const name of DEFAULT_TOOL_NAMES) {\n tools.set(name, { name, params: {} });\n }\n\n for (const name of [BROWSER_TOOL_SET_NAME, TASK_TOOL_SET_NAME]) {\n if (shouldIncludeTool(name, agentSettings)) {\n tools.set(name, { name, params: {} });\n }\n }\n\n const configuredTools = agentSettings.tools;\n if (\n Array.isArray(configuredTools) &&\n configuredTools.every((tool) => isToolRecord(tool))\n ) {\n for (const tool of configuredTools) {\n if (shouldIncludeTool(tool.name, agentSettings)) {\n tools.set(tool.name, {\n name: tool.name,\n params: toRecord(tool.params),\n });\n }\n }\n }\n\n return Array.from(tools.values());\n}\n\nfunction buildInitialMessage(\n query?: string,\n conversationInstructions?: string,\n): InitialMessagePayload | null {\n const parts = [query?.trim(), conversationInstructions?.trim()].filter(\n Boolean,\n );\n if (parts.length === 0) {\n return null;\n }\n\n return {\n role: \"user\",\n content: [{ type: \"text\", text: parts.join(\"\\n\\n\") }],\n run: true,\n };\n}\n\nfunction buildAgentContext(agentSettings: SettingsRecord): SettingsRecord {\n const runtimeServicesSuffix = buildRuntimeServicesSystemSuffix();\n return {\n ...toRecord(agentSettings.agent_context),\n load_public_skills: shouldLoadPublicSkills(),\n load_user_skills: true,\n load_project_skills: true,\n ...(runtimeServicesSuffix\n ? { system_message_suffix: runtimeServicesSuffix }\n : {}),\n };\n}\n\nfunction isAcpAgent(settings: Settings): boolean {\n const agentSettings = toRecord(settings.agent_settings);\n return agentSettings.agent_kind === \"acp\";\n}\n\nfunction getAcpServerTag(settings: Settings): string | undefined {\n const agentSettings = toRecord(settings.agent_settings);\n const value = agentSettings.acp_server;\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction resolveAcpCommand(agentSettings: SettingsRecord): unknown {\n const cmd = agentSettings.acp_command;\n const isEmpty = Array.isArray(cmd) && cmd.length === 0;\n const noCommand = cmd === undefined;\n if (!isEmpty && !noCommand) {\n return cmd;\n }\n\n const serverKey =\n typeof agentSettings.acp_server === \"string\"\n ? agentSettings.acp_server\n : undefined;\n const provider = getAcpProvider(serverKey);\n return provider ? [...provider.default_command] : cmd;\n}\n\nfunction buildConfiguredAcpAgentSettings(\n settings: Settings,\n): AgentSettingsPayload {\n const agentSettings = toRecord(settings.agent_settings);\n const payload: AgentSettingsPayload = {\n agent_kind: \"acp\",\n agent_context: buildAgentContext(agentSettings),\n };\n\n for (const key of ACP_SETTINGS_KEYS) {\n // ``acp_model`` is resolved separately below so a saved ``null`` still\n // falls back to the provider's default rather than being dropped.\n if (key === \"acp_model\") continue;\n // ``acp_env`` is deprecated — provider creds now route via agent_context.secrets.\n if (key === \"acp_env\") continue;\n const value =\n key === \"acp_command\"\n ? resolveAcpCommand(agentSettings)\n : agentSettings[key];\n if (value !== undefined && value !== null) {\n payload[key] = value;\n }\n }\n\n // ``mcp_config`` is a *shared* field (not in ACP_SETTINGS_KEYS): forward it\n // so the ACP subprocess connects to the configured MCP servers at session\n // creation. Only include it when it actually carries servers — an empty or\n // malformed value is dropped rather than sending ``mcp_config: {}``.\n const mcpConfig = toRecord(agentSettings.mcp_config);\n if (Object.keys(mcpConfig).length > 0 && \"mcpServers\" in mcpConfig) {\n payload.mcp_config = mcpConfig;\n }\n\n // Saved settings may carry ``acp_model: null`` (existing users predating\n // the default-model registry, or saved fields the agent-server stripped).\n // Fall back to the provider's ``default_model`` so the conversation starts\n // with whatever the Settings → Agent UI shows — without that, the form's\n // displayed default would silently not take effect at runtime until the\n // user re-saved the page.\n const serverKey =\n typeof agentSettings.acp_server === \"string\"\n ? agentSettings.acp_server\n : undefined;\n const provider = getAcpProvider(serverKey);\n const effectiveModel = resolveEffectiveAcpModel({\n configured: agentSettings.acp_model as string | null | undefined,\n providerDefault: provider?.default_model,\n });\n if (effectiveModel) {\n payload.acp_model = effectiveModel;\n }\n\n return payload;\n}\n\nfunction buildConfiguredOpenHandsAgentSettings(\n settings: Settings,\n): AgentSettingsPayload {\n const agentSettings = toRecord(settings.agent_settings);\n const llm = toRecord(agentSettings.llm);\n\n llm.model =\n typeof llm.model === \"string\" && llm.model.trim().length > 0\n ? llm.model\n : DEFAULT_SETTINGS.llm_model;\n\n const apiKey = normalizeSecretString(llm.api_key);\n if (apiKey) {\n llm.api_key = apiKey;\n } else {\n delete llm.api_key;\n }\n\n const baseUrl = normalizeSecretString(llm.base_url);\n if (baseUrl) {\n llm.base_url = baseUrl;\n } else {\n delete llm.base_url;\n }\n\n const mcpConfig = toRecord(agentSettings.mcp_config);\n if (Object.keys(mcpConfig).length === 0 || !(\"mcpServers\" in mcpConfig)) {\n delete agentSettings.mcp_config;\n }\n\n delete agentSettings.acp_server;\n for (const key of ACP_SETTINGS_KEYS) {\n delete agentSettings[key];\n }\n // ``acp_env`` is no longer a forwarded ACP setting (provider creds ride the\n // Secrets panel), but a legacy value may linger on persisted settings —\n // scrub it so it never leaks onto the OpenHands payload.\n delete agentSettings.acp_env;\n\n return {\n ...agentSettings,\n llm,\n agent_context: buildAgentContext(agentSettings),\n tools: getAgentTools(agentSettings),\n };\n}\n\nfunction buildConfiguredAgentSettings(\n settings: Settings,\n): AgentSettingsPayload {\n return isAcpAgent(settings)\n ? buildConfiguredAcpAgentSettings(settings)\n : buildConfiguredOpenHandsAgentSettings(settings);\n}\n\nfunction buildConfiguredConversationSettings(options: {\n settings: Settings;\n query?: string;\n conversationInstructions?: string;\n plugins?: PluginSpec[];\n workingDir?: string;\n}): ConversationSettingsPayload {\n const { settings, query, conversationInstructions, plugins, workingDir } =\n options;\n const conversationSettings = toRecord(settings.conversation_settings);\n const initialMessage = buildInitialMessage(query, conversationInstructions);\n\n CONVERSATION_SETTINGS_METADATA_KEYS.forEach(\n (key) => delete conversationSettings[key],\n );\n\n const payload: ConversationSettingsPayload = {\n ...conversationSettings,\n workspace: {\n kind: \"LocalWorkspace\",\n working_dir: workingDir ?? getAgentServerWorkingDir(),\n },\n ...(initialMessage ? { initial_message: initialMessage } : {}),\n ...(plugins?.length\n ? {\n plugins: plugins.map((plugin) => ({\n source: plugin.source,\n ...(plugin.ref ? { ref: plugin.ref } : {}),\n ...(plugin.repo_path ? { repo_path: plugin.repo_path } : {}),\n })),\n }\n : {}),\n };\n\n return payload;\n}\n\ninterface LookupSecret {\n kind: \"LookupSecret\";\n url: string;\n headers?: Record<string, string>;\n description?: string;\n}\n\ntype StartConversationPayload = Record<string, unknown> & {\n agent_settings: AgentSettingsPayload;\n workspace: LocalWorkspacePayload;\n confirmation_policy: SettingsRecord;\n security_analyzer?: SettingsRecord;\n initial_message?: InitialMessagePayload;\n max_iterations: number;\n stuck_detection: true;\n autotitle: true;\n worktree: true;\n secrets_encrypted?: true;\n conversation_id?: string;\n secrets?: Record<string, LookupSecret>;\n tags?: Record<string, string>;\n tool_module_qualnames?: Record<string, string>;\n};\n\nexport interface StartConversationOptions {\n settings: Settings;\n query?: string;\n conversationInstructions?: string;\n plugins?: PluginSpec[];\n conversationId?: string;\n workingDir?: string;\n encryptedAgentSettings?: Record<string, SettingsValue>;\n encryptedConversationSettings?: Record<string, SettingsValue>;\n secretsEncrypted?: boolean;\n customSecrets?: Array<{ name: string; description?: string }>;\n}\n\nexport function buildStartConversationRequest(\n options: StartConversationOptions,\n): StartConversationPayload {\n const sourceAgentSettings = options.encryptedAgentSettings\n ? { ...options.settings, agent_settings: options.encryptedAgentSettings }\n : options.settings;\n\n const acpMode = isAcpAgent(sourceAgentSettings);\n const agentSettings = buildConfiguredAgentSettings(sourceAgentSettings);\n const acpServerTag = acpMode\n ? getAcpServerTag(sourceAgentSettings)\n : undefined;\n\n const sourceConversationOptions = options.encryptedConversationSettings\n ? {\n ...options,\n settings: {\n ...options.settings,\n conversation_settings: options.encryptedConversationSettings,\n },\n }\n : options;\n\n const conversationSettings = buildConfiguredConversationSettings(\n sourceConversationOptions,\n );\n\n const payload: StartConversationPayload = {\n agent_settings: agentSettings,\n workspace: conversationSettings.workspace,\n confirmation_policy:\n getConversationConfirmationPolicy(conversationSettings),\n max_iterations:\n typeof conversationSettings.max_iterations === \"number\"\n ? conversationSettings.max_iterations\n : 500,\n stuck_detection: true,\n autotitle: true,\n worktree: true,\n };\n\n if (acpServerTag) {\n payload.tags = { [ACP_SERVER_TAG_KEY]: acpServerTag };\n }\n\n if (options.secretsEncrypted) {\n payload.secrets_encrypted = true;\n }\n\n if (options.conversationId) {\n payload.conversation_id = options.conversationId;\n }\n\n const securityAnalyzer =\n getConversationSecurityAnalyzer(conversationSettings);\n if (securityAnalyzer) {\n payload.security_analyzer = securityAnalyzer;\n }\n\n if (conversationSettings.initial_message) {\n payload.initial_message = conversationSettings.initial_message;\n }\n\n if (conversationSettings.plugins) {\n payload.plugins = conversationSettings.plugins;\n }\n\n if (conversationSettings.hook_config) {\n payload.hook_config = conversationSettings.hook_config;\n }\n\n payload.tool_module_qualnames = {\n [CANVAS_UI_TOOL_NAME]: CANVAS_UI_TOOL_MODULE,\n ...((conversationSettings.tool_module_qualnames as\n | Record<string, string>\n | undefined) ?? {}),\n };\n\n if (conversationSettings.agent_definitions) {\n payload.agent_definitions = conversationSettings.agent_definitions;\n }\n\n if (options.customSecrets && options.customSecrets.length > 0) {\n const backend = getEffectiveLocalBackend();\n const headers = backend ? buildAuthHeaders(backend) : {};\n\n const secrets: Record<string, LookupSecret> = {};\n for (const secret of options.customSecrets) {\n const lookupSecret: LookupSecret = {\n kind: \"LookupSecret\",\n url: `/api/settings/secrets/${encodeURIComponent(secret.name)}`,\n description: secret.description,\n };\n\n if (Object.keys(headers).length > 0) {\n lookupSecret.headers = headers;\n }\n\n secrets[secret.name] = lookupSecret;\n }\n\n payload.secrets = secrets;\n\n if (acpMode) {\n payload.agent_settings.agent_context = {\n ...payload.agent_settings.agent_context,\n secrets,\n };\n }\n }\n\n return payload;\n}\n\nexport async function buildStartConversationRequestWithEncryptedSettings(options: {\n settings: Settings;\n query?: string;\n conversationInstructions?: string;\n plugins?: PluginSpec[];\n conversationId?: string;\n workingDir?: string;\n}): Promise<Record<string, unknown>> {\n const { SecretsService } = await import(\"./secrets-service\");\n\n const [settingsResult, customSecrets] = await Promise.all([\n SettingsService.getSettingsForConversation(),\n SecretsService.getSecrets(),\n ]);\n\n const { agentSettings, conversationSettings, secretsEncrypted } =\n settingsResult;\n\n return buildStartConversationRequest({\n ...options,\n encryptedAgentSettings: agentSettings,\n encryptedConversationSettings: conversationSettings,\n secretsEncrypted,\n customSecrets,\n });\n}\n\nexport function emptyHooksResponse(): GetHooksResponse {\n return { hooks: [] };\n}\n"],"mappings":"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"}
@@ -3,23 +3,34 @@ import { getAgentServerWorkingDir as t, shouldLoadPublicSkills as n } from "./ag
3
3
  import { getEffectiveLocalBackend as r } from "./backend-registry/active-store.js";
4
4
  import { getAgentServerClientOptions as i } from "./agent-server-client-options.js";
5
5
  import { buildAuthHeaders as a } from "./backend-registry/auth.js";
6
- import { getStoredConversationMetadata as o } from "./conversation-metadata-store.js";
7
- import { DEFAULT_SETTINGS as s } from "../services/settings.js";
8
- import { getAcpProvider as c, resolveEffectiveAcpModel as l } from "../constants/acp-providers.js";
9
- import { isAgentServerToolAvailable as u } from "./agent-server-compatibility.js";
10
- import d from "./settings-service/settings-service.api.js";
6
+ import { ACP_SETTINGS_KEYS as o } from "../node_modules/@openhands/typescript-client/dist/models/acp.js";
7
+ import "../node_modules/@openhands/typescript-client/dist/index.js";
8
+ import { getStoredConversationMetadata as s } from "./conversation-metadata-store.js";
9
+ import { DEFAULT_SETTINGS as c } from "../services/settings.js";
10
+ import { getAcpProvider as l, resolveEffectiveAcpModel as u } from "../constants/acp-providers.js";
11
+ import { isAgentServerToolAvailable as d } from "./agent-server-compatibility.js";
12
+ import f from "./settings-service/settings-service.api.js";
11
13
  //#region src/api/agent-server-adapter.ts
12
- var f = "canvas_ui", p = "canvas_ui_tool", m = [
14
+ var p = "canvas_ui", m = "canvas_ui_tool", h = [
13
15
  "terminal",
14
16
  "file_editor",
15
17
  "task_tracker",
16
- f
17
- ], h = "browser_tool_set", g = "task_tool_set";
18
- function _() {
18
+ p
19
+ ], g = "browser_tool_set", _ = "task_tool_set";
20
+ function v() {
19
21
  return !0;
20
22
  }
21
- function v() {
23
+ function y() {
22
24
  let e = (void 0)?.trim();
25
+ if (e) return e;
26
+ if (typeof window < "u") {
27
+ let e = window.__AGENT_CANVAS_RUNTIME_SERVICES_INFO__;
28
+ if (typeof e == "string") return e.trim() || null;
29
+ }
30
+ return null;
31
+ }
32
+ function b() {
33
+ let e = y();
23
34
  if (!e) return null;
24
35
  try {
25
36
  let t = JSON.parse(e);
@@ -28,8 +39,8 @@ function v() {
28
39
  return null;
29
40
  }
30
41
  }
31
- function y() {
32
- let e = v();
42
+ function x() {
43
+ let e = b();
33
44
  if (!e?.services) return;
34
45
  let t = [];
35
46
  t.push("<RUNTIME_SERVICES>"), e.mode ? t.push(`You are running inside an agent-canvas dev stack started in '${e.mode}' mode.`) : t.push("You are running inside an agent-canvas dev stack."), t.push("The following services are reachable from your sandbox. URLs are written", "from your point of view (i.e., as you should curl/fetch them).", "");
@@ -38,15 +49,15 @@ function y() {
38
49
  let o = n?.url_from_agent;
39
50
  return t.push("", "Trust this block over guessing: do not assume any other URLs are running."), o && t.push(`In particular, ${o} inside your sandbox is the Agent Server`, "you are running inside of — NOT the automation backend."), t.push("</RUNTIME_SERVICES>"), t.join("\n");
40
51
  }
41
- function b(e) {
52
+ function S(e) {
42
53
  let { host: t } = i();
43
54
  return `${t}/api/conversations/${e}`;
44
55
  }
45
- function x(e) {
56
+ function C(e) {
46
57
  return `Conversation ${e.slice(0, 5)}`;
47
58
  }
48
- function S(n) {
49
- let r = o(n.id), a = n.agent?.kind === "ACPAgent", c = a ? n.tags?.acpserver ?? null : null;
59
+ function w(n) {
60
+ let r = s(n.id), a = n.agent?.kind === "ACPAgent", o = a ? n.tags?.acpserver ?? null : null;
50
61
  return {
51
62
  id: n.id,
52
63
  created_by_user_id: null,
@@ -55,17 +66,17 @@ function S(n) {
55
66
  git_provider: r?.git_provider ?? null,
56
67
  selected_workspace: r?.selected_workspace ?? null,
57
68
  active_profile: r?.active_profile ?? null,
58
- title: n.title?.trim() ? n.title : x(n.id),
69
+ title: n.title?.trim() ? n.title : C(n.id),
59
70
  trigger: null,
60
71
  pr_number: [],
61
72
  agent_kind: a ? "acp" : "openhands",
62
- acp_server: c,
63
- llm_model: a ? l({
73
+ acp_server: o,
74
+ llm_model: a ? u({
64
75
  runtimeName: n.current_model_name,
65
76
  runtimeId: n.current_model_id,
66
77
  configured: n.agent?.acp_model,
67
78
  sdkLlm: n.agent?.llm?.model
68
- }) : n.agent?.llm?.model ?? s.llm_model,
79
+ }) : n.agent?.llm?.model ?? c.llm_model,
69
80
  metrics: n.metrics ? {
70
81
  accumulated_cost: n.metrics.accumulated_cost ?? null,
71
82
  max_budget_per_task: n.metrics.max_budget_per_task ?? null,
@@ -82,7 +93,7 @@ function S(n) {
82
93
  updated_at: n.updated_at,
83
94
  execution_status: n.execution_status ?? e.IDLE,
84
95
  sandbox_status: n.sandbox_status ?? null,
85
- conversation_url: b(n.id),
96
+ conversation_url: S(n.id),
86
97
  session_api_key: i().apiKey ?? null,
87
98
  sandbox_id: null,
88
99
  workspace: { working_dir: n.workspace?.working_dir ?? t() },
@@ -90,19 +101,13 @@ function S(n) {
90
101
  sub_conversation_ids: []
91
102
  };
92
103
  }
93
- function C(e) {
104
+ function T(e) {
94
105
  return {
95
- items: e.items.map(S),
106
+ items: e.items.map(w),
96
107
  next_page_id: e.next_page_id ?? null
97
108
  };
98
109
  }
99
- var w = [
100
- "acp_command",
101
- "acp_args",
102
- "acp_model",
103
- "acp_session_mode",
104
- "acp_prompt_timeout"
105
- ], T = "acpserver", E = new Set([
110
+ var E = "acpserver", D = new Set([
106
111
  "schema_version",
107
112
  "agent_settings",
108
113
  "workspace",
@@ -110,22 +115,22 @@ var w = [
110
115
  "initial_message",
111
116
  "plugins"
112
117
  ]);
113
- function D(e) {
118
+ function O(e) {
114
119
  return !e || typeof e != "object" || Array.isArray(e) ? {} : structuredClone(e);
115
120
  }
116
- function O(e) {
121
+ function k(e) {
117
122
  if (typeof e != "string") return;
118
123
  let t = e.trim();
119
124
  return t.length > 0 ? t : void 0;
120
125
  }
121
- function k(e) {
126
+ function A(e) {
122
127
  return e.confirmation_mode === !0 ? e.security_analyzer === "llm" ? {
123
128
  kind: "ConfirmRisky",
124
129
  threshold: "HIGH",
125
130
  confirm_unknown: !0
126
131
  } : { kind: "AlwaysConfirm" } : { kind: "NeverConfirm" };
127
132
  }
128
- function A(e) {
133
+ function j(e) {
129
134
  switch (e.security_analyzer) {
130
135
  case "llm": return { kind: "LLMSecurityAnalyzer" };
131
136
  case "pattern": return { kind: "PatternSecurityAnalyzer" };
@@ -133,30 +138,30 @@ function A(e) {
133
138
  default: return;
134
139
  }
135
140
  }
136
- function j(e) {
141
+ function M(e) {
137
142
  return !!e && typeof e == "object" && !Array.isArray(e) && typeof e.name == "string";
138
143
  }
139
- function M(e, t) {
140
- return e === h ? _() && u(e) : e === g ? t.enable_sub_agents === !0 && u(e) : !0;
144
+ function N(e, t) {
145
+ return e === g ? v() && d(e) : e === _ ? t.enable_sub_agents === !0 && d(e) : !0;
141
146
  }
142
- function N(e) {
147
+ function P(e) {
143
148
  let t = /* @__PURE__ */ new Map();
144
- for (let e of m) t.set(e, {
149
+ for (let e of h) t.set(e, {
145
150
  name: e,
146
151
  params: {}
147
152
  });
148
- for (let n of [h, g]) M(n, e) && t.set(n, {
153
+ for (let n of [g, _]) N(n, e) && t.set(n, {
149
154
  name: n,
150
155
  params: {}
151
156
  });
152
157
  let n = e.tools;
153
- if (Array.isArray(n) && n.every((e) => j(e))) for (let r of n) M(r.name, e) && t.set(r.name, {
158
+ if (Array.isArray(n) && n.every((e) => M(e))) for (let r of n) N(r.name, e) && t.set(r.name, {
154
159
  name: r.name,
155
- params: D(r.params)
160
+ params: O(r.params)
156
161
  });
157
162
  return Array.from(t.values());
158
163
  }
159
- function P(e, t) {
164
+ function F(e, t) {
160
165
  let n = [e?.trim(), t?.trim()].filter(Boolean);
161
166
  return n.length === 0 ? null : {
162
167
  role: "user",
@@ -167,70 +172,70 @@ function P(e, t) {
167
172
  run: !0
168
173
  };
169
174
  }
170
- function F(e) {
171
- let t = y();
175
+ function I(e) {
176
+ let t = x();
172
177
  return {
173
- ...D(e.agent_context),
178
+ ...O(e.agent_context),
174
179
  load_public_skills: n(),
175
180
  load_user_skills: !0,
176
181
  load_project_skills: !0,
177
182
  ...t ? { system_message_suffix: t } : {}
178
183
  };
179
184
  }
180
- function I(e) {
181
- return D(e.agent_settings).agent_kind === "acp";
182
- }
183
185
  function L(e) {
184
- let t = D(e.agent_settings).acp_server;
185
- return typeof t == "string" && t.length > 0 ? t : void 0;
186
+ return O(e.agent_settings).agent_kind === "acp";
186
187
  }
187
188
  function R(e) {
189
+ let t = O(e.agent_settings).acp_server;
190
+ return typeof t == "string" && t.length > 0 ? t : void 0;
191
+ }
192
+ function z(e) {
188
193
  let t = e.acp_command;
189
194
  if (!(Array.isArray(t) && t.length === 0) && t !== void 0) return t;
190
- let n = c(typeof e.acp_server == "string" ? e.acp_server : void 0);
195
+ let n = l(typeof e.acp_server == "string" ? e.acp_server : void 0);
191
196
  return n ? [...n.default_command] : t;
192
197
  }
193
- function z(e) {
194
- let t = D(e.agent_settings), n = {
198
+ function B(e) {
199
+ let t = O(e.agent_settings), n = {
195
200
  agent_kind: "acp",
196
- agent_context: F(t)
201
+ agent_context: I(t)
197
202
  };
198
- for (let e of w) {
199
- if (e === "acp_model") continue;
200
- let r = e === "acp_command" ? R(t) : t[e];
203
+ for (let e of o) {
204
+ if (e === "acp_model" || e === "acp_env") continue;
205
+ let r = e === "acp_command" ? z(t) : t[e];
201
206
  r != null && (n[e] = r);
202
207
  }
203
- let r = D(t.mcp_config);
208
+ let r = O(t.mcp_config);
204
209
  Object.keys(r).length > 0 && "mcpServers" in r && (n.mcp_config = r);
205
- let i = c(typeof t.acp_server == "string" ? t.acp_server : void 0), a = l({
210
+ let i = l(typeof t.acp_server == "string" ? t.acp_server : void 0), a = u({
206
211
  configured: t.acp_model,
207
212
  providerDefault: i?.default_model
208
213
  });
209
214
  return a && (n.acp_model = a), n;
210
215
  }
211
- function B(e) {
212
- let t = D(e.agent_settings), n = D(t.llm);
213
- n.model = typeof n.model == "string" && n.model.trim().length > 0 ? n.model : s.llm_model;
214
- let r = O(n.api_key);
216
+ function V(e) {
217
+ let t = O(e.agent_settings), n = O(t.llm);
218
+ n.model = typeof n.model == "string" && n.model.trim().length > 0 ? n.model : c.llm_model;
219
+ let r = k(n.api_key);
215
220
  r ? n.api_key = r : delete n.api_key;
216
- let i = O(n.base_url);
221
+ let i = k(n.base_url);
217
222
  i ? n.base_url = i : delete n.base_url;
218
- let a = D(t.mcp_config);
223
+ let a = O(t.mcp_config);
219
224
  (Object.keys(a).length === 0 || !("mcpServers" in a)) && delete t.mcp_config, delete t.acp_server;
220
- for (let e of w) delete t[e];
225
+ for (let e of o) delete t[e];
221
226
  return delete t.acp_env, {
222
227
  ...t,
223
228
  llm: n,
224
- agent_context: F(t),
225
- tools: N(t)
229
+ agent_context: I(t),
230
+ tools: P(t)
226
231
  };
227
232
  }
228
- function V(e) {
229
- return I(e) ? z(e) : B(e);
230
- }
231
233
  function H(e) {
232
- let { settings: n, query: r, conversationInstructions: i, plugins: a, workingDir: o } = e, s = D(n.conversation_settings), c = P(r, i);
233
- return E.forEach((e) => delete s[e]), {
234
+ return L(e) ? B(e) : V(e);
235
+ }
236
+ function U(e) {
237
+ let { settings: n, query: r, conversationInstructions: i, plugins: a, workingDir: o } = e, s = O(n.conversation_settings), c = F(r, i);
238
+ return D.forEach((e) => delete s[e]), {
234
239
  ...s,
235
240
  workspace: {
236
241
  kind: "LocalWorkspace",
@@ -244,11 +249,11 @@ function H(e) {
244
249
  })) } : {}
245
250
  };
246
251
  }
247
- function U(e) {
252
+ function W(e) {
248
253
  let t = e.encryptedAgentSettings ? {
249
254
  ...e.settings,
250
255
  agent_settings: e.encryptedAgentSettings
251
- } : e.settings, n = I(t), i = V(t), o = n ? L(t) : void 0, s = H(e.encryptedConversationSettings ? {
256
+ } : e.settings, n = L(t), i = H(t), o = n ? R(t) : void 0, s = U(e.encryptedConversationSettings ? {
252
257
  ...e,
253
258
  settings: {
254
259
  ...e.settings,
@@ -257,16 +262,16 @@ function U(e) {
257
262
  } : e), c = {
258
263
  agent_settings: i,
259
264
  workspace: s.workspace,
260
- confirmation_policy: k(s),
265
+ confirmation_policy: A(s),
261
266
  max_iterations: typeof s.max_iterations == "number" ? s.max_iterations : 500,
262
267
  stuck_detection: !0,
263
268
  autotitle: !0,
264
269
  worktree: !0
265
270
  };
266
- o && (c.tags = { [T]: o }), e.secretsEncrypted && (c.secrets_encrypted = !0), e.conversationId && (c.conversation_id = e.conversationId);
267
- let l = A(s);
271
+ o && (c.tags = { [E]: o }), e.secretsEncrypted && (c.secrets_encrypted = !0), e.conversationId && (c.conversation_id = e.conversationId);
272
+ let l = j(s);
268
273
  if (l && (c.security_analyzer = l), s.initial_message && (c.initial_message = s.initial_message), s.plugins && (c.plugins = s.plugins), s.hook_config && (c.hook_config = s.hook_config), c.tool_module_qualnames = {
269
- [f]: p,
274
+ [p]: m,
270
275
  ...s.tool_module_qualnames ?? {}
271
276
  }, s.agent_definitions && (c.agent_definitions = s.agent_definitions), e.customSecrets && e.customSecrets.length > 0) {
272
277
  let t = r(), i = t ? a(t) : {}, o = {};
@@ -285,9 +290,9 @@ function U(e) {
285
290
  }
286
291
  return c;
287
292
  }
288
- async function W(e) {
289
- let { SecretsService: t } = await import("./secrets-service.js"), [n, r] = await Promise.all([d.getSettingsForConversation(), t.getSecrets()]), { agentSettings: i, conversationSettings: a, secretsEncrypted: o } = n;
290
- return U({
293
+ async function G(e) {
294
+ let { SecretsService: t } = await import("./secrets-service.js"), [n, r] = await Promise.all([f.getSettingsForConversation(), t.getSecrets()]), { agentSettings: i, conversationSettings: a, secretsEncrypted: o } = n;
295
+ return W({
291
296
  ...e,
292
297
  encryptedAgentSettings: i,
293
298
  encryptedConversationSettings: a,
@@ -295,10 +300,10 @@ async function W(e) {
295
300
  customSecrets: r
296
301
  });
297
302
  }
298
- function G() {
303
+ function K() {
299
304
  return { hooks: [] };
300
305
  }
301
306
  //#endregion
302
- export { W as buildStartConversationRequestWithEncryptedSettings, G as emptyHooksResponse, x as getDefaultConversationTitle, S as toAppConversation, C as toConversationPage };
307
+ export { G as buildStartConversationRequestWithEncryptedSettings, K as emptyHooksResponse, C as getDefaultConversationTitle, w as toAppConversation, T as toConversationPage };
303
308
 
304
309
  //# sourceMappingURL=agent-server-adapter.js.map