@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
@@ -21,6 +21,10 @@ import {
21
21
  isProcessRunning,
22
22
  signalProcessTree,
23
23
  } from "./dev-process-utils.mjs";
24
+ // buildRuntimeServicesInfo moved to its own dependency-free module so the
25
+ // Docker entrypoint can run it as a CLI. Re-exported below for back-compat
26
+ // (dev-with-automation.mjs and tests still import it from here).
27
+ import { buildRuntimeServicesInfo } from "./runtime-services-info.mjs";
24
28
 
25
29
  // ── Centralized config (single source of truth for versions, ports, etc.) ───
26
30
  const __dev_safe_dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -31,6 +35,32 @@ const SHARED_DEFAULTS = JSON.parse(
31
35
  ),
32
36
  );
33
37
 
38
+ /**
39
+ * Extract the pinned commit SHA for @openhands/extensions from package.json.
40
+ * Returns the 40-char hex SHA when the dependency is a git+https URL with a
41
+ * commit hash fragment (e.g. "git+https://…#62594156…"), null otherwise.
42
+ * @returns {string | null}
43
+ */
44
+ function getExtensionsRef() {
45
+ try {
46
+ const pkg = JSON.parse(
47
+ readFileSync(
48
+ path.join(__dev_safe_dirname, "..", "package.json"),
49
+ "utf-8",
50
+ ),
51
+ );
52
+ const url =
53
+ (pkg.dependencies ?? pkg.devDependencies ?? {})["@openhands/extensions"] ??
54
+ "";
55
+ return url.match(/#([0-9a-f]{40})$/i)?.[1] ?? null;
56
+ } catch {
57
+ return null;
58
+ }
59
+ }
60
+
61
+ /** Pinned extensions commit SHA derived from package.json, or null if not pinned. */
62
+ export const DEFAULT_EXTENSIONS_REF = getExtensionsRef();
63
+
34
64
  const DEFAULT_BACKEND_PORT = SHARED_DEFAULTS.ports.agentServer;
35
65
  const DEFAULT_VITE_PORT = 3001;
36
66
  const DEFAULT_WAIT_TIMEOUT_MS = 30_000;
@@ -389,7 +419,7 @@ export function validateFrontendDependencies(
389
419
  * edits are picked up without a manual reinstall. The agent-server itself
390
420
  * is rebuilt from local source on each invocation (--reinstall).
391
421
  * - OH_AGENT_SERVER_GIT_REF: Git commit SHA or branch name
392
- * - OH_AGENT_SERVER_VERSION: Specific PyPI version (e.g., "1.24.0")
422
+ * - OH_AGENT_SERVER_VERSION: Specific PyPI version (e.g., "1.25.0")
393
423
  *
394
424
  * If none are set, defaults to the released version specified by
395
425
  * DEFAULT_AGENT_SERVER_VERSION. Set OH_AGENT_SERVER_GIT_REF to use a
@@ -426,14 +456,23 @@ export function buildAgentServerCommand(env = process.env) {
426
456
  );
427
457
  source = `local (${localPath})`;
428
458
  } else if (gitRef) {
429
- // Use git ref with subdirectory syntax for uv workspace monorepo
459
+ // Use git ref with subdirectory syntax for uv workspace monorepo.
430
460
  // The software-agent-sdk repo has packages in subdirectories:
431
- // openhands-agent-server/, openhands-tools/, openhands-workspace/
461
+ // openhands-agent-server/, openhands-sdk/, openhands-tools/, openhands-workspace/
462
+ // All four must come from the same ref so inter-package APIs stay in sync.
463
+ //
464
+ // --reinstall is required because the git branch may carry the same version
465
+ // string as the current PyPI release (e.g. both "1.25.0"). Without it, uv
466
+ // silently reuses the cached PyPI wheels and the git ref is never actually
467
+ // used, even though it was explicitly requested.
432
468
  const baseGitUrl = `git+${AGENT_SERVER_GIT_REPO}@${gitRef}`;
433
469
  uvxArgs.push(
470
+ "--reinstall",
434
471
  "--from",
435
472
  `${baseGitUrl}#subdirectory=openhands-agent-server`,
436
473
  "--with",
474
+ `${baseGitUrl}#subdirectory=openhands-sdk`,
475
+ "--with",
437
476
  `${baseGitUrl}#subdirectory=openhands-tools`,
438
477
  "--with",
439
478
  `${baseGitUrl}#subdirectory=openhands-workspace`,
@@ -697,124 +736,20 @@ export function buildAgentServerEnv(config) {
697
736
  // Make the host tools/ directory importable so the agent-server can
698
737
  // resolve modules listed in tool_module_qualnames (e.g. canvas_ui_tool).
699
738
  OH_EXTRA_PYTHON_PATH: config.canvasToolsDir,
739
+ // Tell the agent-server which extensions commit to use for the public
740
+ // skills catalog. Derived from the @openhands/extensions pin in
741
+ // package.json; the SDK skips network polling when it already has this
742
+ // SHA cached. Only injected when the caller has not already set it.
743
+ ...(DEFAULT_EXTENSIONS_REF && !process.env.EXTENSIONS_REF
744
+ ? { EXTENSIONS_REF: DEFAULT_EXTENSIONS_REF }
745
+ : {}),
700
746
  };
701
747
  }
702
748
 
703
- /**
704
- * Build a structured description of the dev-stack services that are
705
- * reachable from inside the agent's sandbox. The frontend forwards this
706
- * (verbatim, as a JSON string in `VITE_RUNTIME_SERVICES_INFO`) and renders
707
- * it into the system prompt via `AgentContext.system_message_suffix`, so
708
- * the agent sees a `<RUNTIME_SERVICES>` block listing what's available
709
- * without having to probe.
710
- *
711
- * URLs are written from the *agent's* point of view. The agent-server
712
- * runs on the host, so the host alias is "localhost".
713
- *
714
- * @param {object} options
715
- * @param {string} [options.mode] - Human-readable dev mode label (e.g. "dev:safe").
716
- * @param {string} [options.agentHostAlias="localhost"] - Hostname the agent
717
- * uses to reach services running on the host machine.
718
- * @param {number} [options.agentServerPort] - Port the agent-server listens on.
719
- * Required at runtime; the function throws if missing because the resulting
720
- * URL would otherwise bake `undefined` into the agent's system prompt.
721
- * Typed as optional only so TypeScript callers can negative-test the guard.
722
- * @param {number} [options.ingressPort] - Ingress port (omit if no ingress).
723
- * @param {number} [options.frontendPort] - Frontend port (Vite dev server
724
- * or static-file server). Omit if no frontend is exposed.
725
- * @param {number} [options.vitePort] - Deprecated alias for `frontendPort`,
726
- * accepted for backward compat with older launchers. Remove after one release.
727
- * @param {"vite"|"static"} [options.frontendKind="vite"] - Whether the
728
- * frontend port hosts Vite or a static build. Only affects the
729
- * description shown to the agent.
730
- * @param {object} [options.automation] - Automation backend info. Skipped
731
- * entirely if `.port` is missing, so passing `{}` is safe.
732
- * @param {number} [options.automation.port] - Automation backend port.
733
- * @param {string} [options.automation.apiPrefix="/api/automation"] - Path
734
- * prefix all automation routes are mounted under.
735
- * @param {string} [options.automation.authEnvVar="OPENHANDS_AUTOMATION_API_KEY"]
736
- * - Env var holding the API key.
737
- * @returns {object} A JSON-serializable runtime services info object.
738
- */
739
- export function buildRuntimeServicesInfo(options) {
740
- const {
741
- mode,
742
- agentHostAlias = "localhost",
743
- agentServerPort,
744
- ingressPort,
745
- // Accept legacy `vitePort` for one release so external callers keep working.
746
- vitePort,
747
- frontendPort = vitePort,
748
- frontendKind = "vite",
749
- automation,
750
- } = options;
751
-
752
- if (agentServerPort === undefined || agentServerPort === null) {
753
- // Without this the URL becomes `http://localhost:undefined` and ends up
754
- // verbatim in the agent's system prompt, which is worse than failing fast.
755
- throw new Error(
756
- "buildRuntimeServicesInfo: agentServerPort is required " +
757
- "(otherwise the agent_server URL would be `http://localhost:undefined`).",
758
- );
759
- }
760
-
761
- const services = {
762
- agent_server: {
763
- description:
764
- "The OpenHands Agent Server this agent is running inside. " +
765
- "Tool calls (terminal, file_editor, browser, etc.) execute here.",
766
- // From the agent's POV, the agent-server it's *inside* is on
767
- // localhost, regardless of where the host is.
768
- url_from_agent: `http://localhost:${agentServerPort}`,
769
- },
770
- };
771
-
772
- if (ingressPort !== undefined) {
773
- services.ingress = {
774
- description:
775
- "Unified entry point. Routes /api/automation/* to the automation " +
776
- "backend, /api/* and /sockets to the agent-server, and /* to the " +
777
- "frontend.",
778
- url_from_agent: `http://${agentHostAlias}:${ingressPort}`,
779
- };
780
- }
781
-
782
- if (frontendPort !== undefined) {
783
- services.frontend = {
784
- kind: frontendKind,
785
- description:
786
- frontendKind === "static"
787
- ? "Static-file server hosting the agent-canvas production build."
788
- : "Vite dev server hosting the agent-canvas frontend.",
789
- url_from_agent: `http://${agentHostAlias}:${frontendPort}`,
790
- };
791
- }
792
-
793
- // Require an explicit port so we don't bake `:undefined` into the
794
- // automation URL when the caller passes `automation: {}`.
795
- if (automation?.port !== undefined && automation.port !== null) {
796
- const apiPrefix = automation.apiPrefix ?? "/api/automation";
797
- const authEnvVar = automation.authEnvVar ?? "OPENHANDS_AUTOMATION_API_KEY";
798
- const baseUrl = `http://${agentHostAlias}:${automation.port}`;
799
- services.automation = {
800
- description:
801
- "OpenHands Automations service. All routes are mounted under " +
802
- `'${apiPrefix}'. Authenticate with header ` +
803
- `'X-Session-API-Key: $${authEnvVar}'.`,
804
- url_from_agent: baseUrl,
805
- api_prefix: apiPrefix,
806
- docs_url: `${baseUrl}${apiPrefix}/docs`,
807
- openapi_url: `${baseUrl}${apiPrefix}/openapi.json`,
808
- auth_env_var: authEnvVar,
809
- };
810
- }
811
-
812
- return {
813
- mode,
814
- agent_host_alias: agentHostAlias,
815
- services,
816
- };
817
- }
749
+ // Re-export so existing importers (dev-with-automation.mjs, tests) keep
750
+ // resolving `buildRuntimeServicesInfo` from this module. The implementation
751
+ // now lives in ./runtime-services-info.mjs (imported at the top of this file).
752
+ export { buildRuntimeServicesInfo };
818
753
 
819
754
  export function buildNpmScriptCommand(
820
755
  scriptName,
@@ -119,6 +119,38 @@ function logError(message) {
119
119
  console.error(`${c.red}✗${c.reset} ${message}`);
120
120
  }
121
121
 
122
+ /**
123
+ * Parse one JSON log line produced by the SDK's JsonFormatter and return a
124
+ * single-line human-readable string + an appropriate ANSI color.
125
+ *
126
+ * Returns null for non-JSON lines so callers can fall back to the raw text.
127
+ *
128
+ * @param {string} rawLine
129
+ * @returns {{ text: string; color: string } | null}
130
+ */
131
+ function parseAgentServerLogLine(rawLine) {
132
+ try {
133
+ const obj = JSON.parse(rawLine);
134
+ if (!obj.levelname || obj.message === undefined) return null;
135
+ const level = obj.levelname.padEnd(8);
136
+ const location =
137
+ obj.filename && obj.lineno ? ` ${obj.filename}:${obj.lineno}` : "";
138
+ const text = `${level} ${obj.message}${location}`;
139
+ const lvl = obj.levelname;
140
+ const color =
141
+ lvl === "DEBUG"
142
+ ? c.dim
143
+ : lvl === "WARNING"
144
+ ? c.yellow
145
+ : lvl === "ERROR" || lvl === "CRITICAL"
146
+ ? c.red
147
+ : c.blue;
148
+ return { text, color };
149
+ } catch {
150
+ return null;
151
+ }
152
+ }
153
+
122
154
  // ═══════════════════════════════════════════════════════════════════════════
123
155
  // Configuration
124
156
  // ═══════════════════════════════════════════════════════════════════════════
@@ -521,6 +553,7 @@ function spawnService(name, command, args, options = {}) {
521
553
  );
522
554
 
523
555
  const color = options.color || c.reset;
556
+ const parseLogLine = options.parseLogLine;
524
557
 
525
558
  proc.stdout.on("data", (data) => {
526
559
  data
@@ -528,7 +561,8 @@ function spawnService(name, command, args, options = {}) {
528
561
  .split("\n")
529
562
  .filter(Boolean)
530
563
  .forEach((line) => {
531
- logService(name, line.trim(), color);
564
+ const parsed = parseLogLine ? parseLogLine(line.trim()) : null;
565
+ logService(name, parsed ? parsed.text : line.trim(), parsed ? parsed.color : color);
532
566
  });
533
567
  });
534
568
 
@@ -538,7 +572,8 @@ function spawnService(name, command, args, options = {}) {
538
572
  .split("\n")
539
573
  .filter(Boolean)
540
574
  .forEach((line) => {
541
- logService(name, line.trim(), c.yellow);
575
+ const parsed = parseLogLine ? parseLogLine(line.trim()) : null;
576
+ logService(name, parsed ? parsed.text : line.trim(), parsed ? parsed.color : c.yellow);
542
577
  });
543
578
  });
544
579
 
@@ -699,6 +734,11 @@ function startAgentServer(config) {
699
734
  // Ensure the agent-server uses the resolved key from config. This is
700
735
  // LOCAL_BACKEND_API_KEY when set, or the auto-generated persisted key.
701
736
  OH_SESSION_API_KEYS_0: config.sessionApiKey,
737
+ // Emit structured JSON log lines instead of Rich-formatted output.
738
+ // Rich wraps long messages across multiple lines and prepends its own
739
+ // timestamp; LOG_JSON=true produces one JSON object per record which
740
+ // parseAgentServerLogLine re-formats into a clean single-line entry.
741
+ LOG_JSON: "true",
702
742
  };
703
743
 
704
744
  spawnService(
@@ -715,6 +755,7 @@ function startAgentServer(config) {
715
755
  cwd: safeConfig.workspacesPath,
716
756
  env: agentServerEnv,
717
757
  color: c.blue,
758
+ parseLogLine: parseAgentServerLogLine,
718
759
  },
719
760
  );
720
761
  }
@@ -796,8 +837,10 @@ function startAutomationBackend(config) {
796
837
  join(config.stateDir, "workspaces"),
797
838
  // Session API key for self-hosted auth — shared with agent-server via X-Session-API-Key header
798
839
  AUTOMATION_LOCAL_API_KEY: config.sessionApiKey,
799
- // CORS: allow localhost origins for dev
800
- AUTOMATION_CORS_ORIGINS: `http://localhost:${config.ingressPort},http://127.0.0.1:${config.ingressPort},http://localhost:3001,http://127.0.0.1:3001`,
840
+ // CORS: allow localhost origins for dev, unless explicitly overridden.
841
+ AUTOMATION_CORS_ORIGINS:
842
+ process.env.AUTOMATION_CORS_ORIGINS ||
843
+ `http://localhost:${config.ingressPort},http://127.0.0.1:${config.ingressPort},http://localhost:3001,http://127.0.0.1:3001`,
801
844
  FILE_STORE: "local",
802
845
  LOCAL_STORAGE_PATH: join(config.stateDir, "storage"),
803
846
  OPENHANDS_SUPPRESS_BANNER: "1",
@@ -1269,6 +1312,13 @@ function startStaticFrontend(config, staticDir) {
1269
1312
  logService("static", `Starting on port ${config.vitePort}...`, c.magenta);
1270
1313
  logService("static", `Serving from: ${staticDir}`, c.dim);
1271
1314
 
1315
+ // Build the runtime-services info JSON so the pre-built frontend can
1316
+ // populate the agent's <RUNTIME_SERVICES> system-prompt block without
1317
+ // VITE_RUNTIME_SERVICES_INFO baked in at build time.
1318
+ const runtimeServicesInfo = config.launchAgentServer
1319
+ ? JSON.stringify(buildAutomationRuntimeServicesInfo(config))
1320
+ : null;
1321
+
1272
1322
  const staticServerScript = join(projectRoot, "scripts", "static-server.mjs");
1273
1323
  spawnService(
1274
1324
  "static",
@@ -1288,6 +1338,10 @@ function startStaticFrontend(config, staticDir) {
1288
1338
  ...(config.launchAgentServer && config.isPublic
1289
1339
  ? ["--auth-required"]
1290
1340
  : []),
1341
+ // Inject runtime-services info so the agent knows what's reachable.
1342
+ ...(runtimeServicesInfo
1343
+ ? ["--runtime-services-info", runtimeServicesInfo]
1344
+ : []),
1291
1345
  // Proxy routes only to services that this launch mode started.
1292
1346
  ...buildRouteArgs(getLocalServiceRoutes(config)),
1293
1347
  // Reject known API prefixes that have no backend — returns 503
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Single source of truth for the `<RUNTIME_SERVICES>` block.
3
+ *
4
+ * Builds a structured description of the services that are reachable from
5
+ * inside the agent's sandbox. The frontend forwards it (verbatim, as a JSON
6
+ * string) and renders it into the system prompt via
7
+ * `AgentContext.system_message_suffix`, so the agent sees a
8
+ * `<RUNTIME_SERVICES>` block listing what's available without having to probe.
9
+ *
10
+ * Two callers share this one definition:
11
+ * - the dev launchers (scripts/dev-*.mjs), which know the stack as a set of
12
+ * ports and bake the result into `VITE_RUNTIME_SERVICES_INFO` at build time;
13
+ * - docker/entrypoint.sh, which runs this file as a CLI (see the bottom of
14
+ * this module) because in a container the URLs are *runtime* config — the
15
+ * ports and base URLs are overridable at `docker run` and therefore cannot
16
+ * be baked into the image at build time. The JSON it prints is injected
17
+ * into index.html at serve time by scripts/static-server.mjs.
18
+ *
19
+ * URLs are written from the *agent's* point of view (i.e. as the agent should
20
+ * curl/fetch them from inside its sandbox), which is deliberately not the
21
+ * browser's point of view.
22
+ */
23
+
24
+ import process from "node:process";
25
+ import { pathToFileURL } from "node:url";
26
+
27
+ /**
28
+ * @param {object} options
29
+ * @param {string} [options.mode] - Human-readable mode label (e.g. "dev:safe").
30
+ * @param {string} [options.agentHostAlias="localhost"] - Hostname the agent
31
+ * uses to reach host-side services (ingress, frontend, port-derived
32
+ * automation). Also surfaced as `agent_host_alias`.
33
+ * @param {number} [options.agentServerPort] - Port the agent-server listens on.
34
+ * Used to derive the agent_server URL when `agentServerUrl` is not given.
35
+ * @param {string} [options.agentServerUrl] - Explicit agent_server URL, from
36
+ * the agent's POV. Takes precedence over `agentServerPort`; used by the
37
+ * Docker image, which serves over `127.0.0.1` to avoid IPv6 loopback issues
38
+ * and honors an overridable `AGENT_SERVER_URL`. One of `agentServerUrl` /
39
+ * `agentServerPort` is required (else the URL would be `:undefined`).
40
+ * @param {number} [options.ingressPort] - Ingress port (omit if no ingress).
41
+ * @param {number} [options.frontendPort] - Frontend port (Vite dev server
42
+ * or static-file server). Omit if no frontend is exposed.
43
+ * @param {number} [options.vitePort] - Deprecated alias for `frontendPort`,
44
+ * accepted for backward compat with older launchers. Remove after one release.
45
+ * @param {"vite"|"static"} [options.frontendKind="vite"] - Whether the
46
+ * frontend port hosts Vite or a static build. Only affects the description.
47
+ * @param {object} [options.automation] - Automation backend info. Skipped
48
+ * entirely unless `.url` or `.port` is provided, so passing `{}` is safe.
49
+ * @param {string} [options.automation.url] - Explicit automation base URL, from
50
+ * the agent's POV. Takes precedence over `.port`; used by the Docker image to
51
+ * honor an overridable `AUTOMATION_BASE_URL`.
52
+ * @param {number} [options.automation.port] - Automation backend port (used to
53
+ * derive the base URL when `.url` is not given).
54
+ * @param {string} [options.automation.apiPrefix="/api/automation"] - Path
55
+ * prefix all automation routes are mounted under.
56
+ * @param {string} [options.automation.authEnvVar="OPENHANDS_AUTOMATION_API_KEY"]
57
+ * - Env var holding the API key.
58
+ * @returns {object} A JSON-serializable runtime services info object.
59
+ */
60
+ export function buildRuntimeServicesInfo(options) {
61
+ const {
62
+ mode,
63
+ agentHostAlias = "localhost",
64
+ agentServerPort,
65
+ agentServerUrl,
66
+ ingressPort,
67
+ // Accept legacy `vitePort` for one release so external callers keep working.
68
+ vitePort,
69
+ frontendPort = vitePort,
70
+ frontendKind = "vite",
71
+ automation,
72
+ } = options;
73
+
74
+ // Prefer an explicit URL (containers reach the agent-server over a specific
75
+ // host/scheme), else derive it from the port. From the agent's POV the
76
+ // agent-server it's *inside* is on the loopback host, regardless of where
77
+ // the host machine is.
78
+ const agentServerUrlResolved =
79
+ agentServerUrl ??
80
+ (agentServerPort != null ? `http://localhost:${agentServerPort}` : null);
81
+ if (!agentServerUrlResolved) {
82
+ // Without this the URL becomes `http://localhost:undefined` and ends up
83
+ // verbatim in the agent's system prompt, which is worse than failing fast.
84
+ throw new Error(
85
+ "buildRuntimeServicesInfo: agentServerPort or agentServerUrl is required " +
86
+ "(otherwise the agent_server URL would be `http://localhost:undefined`).",
87
+ );
88
+ }
89
+
90
+ const services = {
91
+ agent_server: {
92
+ description:
93
+ "The OpenHands Agent Server this agent is running inside. " +
94
+ "Tool calls (terminal, file_editor, browser, etc.) execute here.",
95
+ url_from_agent: agentServerUrlResolved,
96
+ },
97
+ };
98
+
99
+ if (ingressPort !== undefined) {
100
+ services.ingress = {
101
+ description:
102
+ "Unified entry point. Routes /api/automation/* to the automation " +
103
+ "backend, /api/* and /sockets to the agent-server, and /* to the " +
104
+ "frontend.",
105
+ url_from_agent: `http://${agentHostAlias}:${ingressPort}`,
106
+ };
107
+ }
108
+
109
+ if (frontendPort !== undefined) {
110
+ services.frontend = {
111
+ kind: frontendKind,
112
+ description:
113
+ frontendKind === "static"
114
+ ? "Static-file server hosting the agent-canvas production build."
115
+ : "Vite dev server hosting the agent-canvas frontend.",
116
+ url_from_agent: `http://${agentHostAlias}:${frontendPort}`,
117
+ };
118
+ }
119
+
120
+ // Prefer an explicit base URL, else derive from the port. Require one of the
121
+ // two so we don't bake `:undefined` into the URL when the caller passes
122
+ // `automation: {}`.
123
+ const automationBaseUrl =
124
+ automation?.url ??
125
+ (automation?.port != null
126
+ ? `http://${agentHostAlias}:${automation.port}`
127
+ : null);
128
+ if (automationBaseUrl) {
129
+ const apiPrefix = automation.apiPrefix ?? "/api/automation";
130
+ const authEnvVar = automation.authEnvVar ?? "OPENHANDS_AUTOMATION_API_KEY";
131
+ services.automation = {
132
+ description:
133
+ "OpenHands Automations service. All routes are mounted under " +
134
+ `'${apiPrefix}'. Authenticate with header ` +
135
+ `'X-Session-API-Key: $${authEnvVar}'.`,
136
+ url_from_agent: automationBaseUrl,
137
+ api_prefix: apiPrefix,
138
+ docs_url: `${automationBaseUrl}${apiPrefix}/docs`,
139
+ openapi_url: `${automationBaseUrl}${apiPrefix}/openapi.json`,
140
+ auth_env_var: authEnvVar,
141
+ };
142
+ }
143
+
144
+ return {
145
+ mode,
146
+ agent_host_alias: agentHostAlias,
147
+ services,
148
+ };
149
+ }
150
+
151
+ // ─────────────────────────────────────────────────────────────────────────────
152
+ // CLI — used by docker/entrypoint.sh to emit the JSON at container startup.
153
+ // ─────────────────────────────────────────────────────────────────────────────
154
+
155
+ export function parseArgs(argv) {
156
+ const options = { automation: {} };
157
+ for (let i = 0; i < argv.length; i++) {
158
+ const flag = argv[i];
159
+ switch (flag) {
160
+ case "--mode":
161
+ options.mode = argv[++i];
162
+ break;
163
+ case "--agent-host-alias":
164
+ options.agentHostAlias = argv[++i];
165
+ break;
166
+ case "--agent-server-url":
167
+ options.agentServerUrl = argv[++i] || undefined;
168
+ break;
169
+ case "--automation-url":
170
+ options.automation.url = argv[++i] || undefined;
171
+ break;
172
+ case "--automation-api-prefix":
173
+ options.automation.apiPrefix = argv[++i];
174
+ break;
175
+ case "--automation-auth-env":
176
+ options.automation.authEnvVar = argv[++i];
177
+ break;
178
+ default:
179
+ throw new Error(`Unknown flag: ${flag}`);
180
+ }
181
+ }
182
+ // Omit the automation entry entirely when no URL was supplied, rather than
183
+ // advertising a backend the agent cannot reach.
184
+ if (!options.automation.url) delete options.automation;
185
+ return options;
186
+ }
187
+
188
+ const isMainModule =
189
+ process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href;
190
+
191
+ if (isMainModule) {
192
+ try {
193
+ const options = parseArgs(process.argv.slice(2));
194
+ process.stdout.write(JSON.stringify(buildRuntimeServicesInfo(options)));
195
+ } catch (err) {
196
+ console.error(err instanceof Error ? err.message : err);
197
+ process.exit(1);
198
+ }
199
+ }
@@ -75,6 +75,7 @@ export function parseArgs(argv = process.argv.slice(2)) {
75
75
  rejectPrefixes: [],
76
76
  sessionApiKey: null,
77
77
  authRequired: false,
78
+ runtimeServicesInfo: null,
78
79
  };
79
80
 
80
81
  for (let i = 0; i < argv.length; i++) {
@@ -110,6 +111,9 @@ export function parseArgs(argv = process.argv.slice(2)) {
110
111
  case "--session-api-key":
111
112
  config.sessionApiKey = argv[++i] || null;
112
113
  break;
114
+ case "--runtime-services-info":
115
+ config.runtimeServicesInfo = argv[++i] || null;
116
+ break;
113
117
  case "--auth-required":
114
118
  config.authRequired = true;
115
119
  break;
@@ -167,6 +171,12 @@ OPTIONS:
167
171
  --auth-required Inject authRequired flag into index.html so the
168
172
  pre-built frontend shows the API key entry screen
169
173
  (public mode) without VITE_AUTH_REQUIRED baked in.
174
+ --runtime-services-info <json>
175
+ Inject a JSON description of the local runtime
176
+ services into index.html so the pre-built
177
+ frontend can populate the agent's
178
+ <RUNTIME_SERVICES> system-prompt block without
179
+ VITE_RUNTIME_SERVICES_INFO baked in.
170
180
  --reject-prefix <prefix> Return 503 for requests matching <prefix>
171
181
  instead of SPA-fallbacking to index.html;
172
182
  may be repeated. Useful in --frontend-only
@@ -208,8 +218,19 @@ ROUTING:
208
218
  * - `authRequired`: sets `window.__AGENT_CANVAS_AUTH_REQUIRED__ = true` so the
209
219
  * pre-built frontend shows the API key entry screen (public mode) without
210
220
  * VITE_AUTH_REQUIRED baked in.
221
+ *
222
+ * - `runtimeServicesInfo`: a JSON string describing the local services
223
+ * (agent-server, automation, …), exposed as
224
+ * `window.__AGENT_CANVAS_RUNTIME_SERVICES_INFO__`. Read by
225
+ * `parseRuntimeServicesInfo()` in `agent-server-adapter.ts` as a fallback
226
+ * when `VITE_RUNTIME_SERVICES_INFO` is empty, so static builds (Docker /
227
+ * published binary) still populate the agent's `<RUNTIME_SERVICES>` block.
211
228
  */
212
- function makeConfigInjectionScript(sessionApiKey, authRequired) {
229
+ function makeConfigInjectionScript(
230
+ sessionApiKey,
231
+ authRequired,
232
+ runtimeServicesInfo,
233
+ ) {
213
234
  const parts = [];
214
235
 
215
236
  if (sessionApiKey) {
@@ -236,6 +257,16 @@ function makeConfigInjectionScript(sessionApiKey, authRequired) {
236
257
  parts.push(`window.__AGENT_CANVAS_AUTH_REQUIRED__=true;`);
237
258
  }
238
259
 
260
+ if (runtimeServicesInfo) {
261
+ // Stored as the raw JSON string so the browser-side parser
262
+ // (parseRuntimeServicesInfo) can JSON.parse it exactly like the
263
+ // VITE_RUNTIME_SERVICES_INFO env var. JSON.stringify produces a safe JS
264
+ // string literal for the inline <script>.
265
+ parts.push(
266
+ `window.__AGENT_CANVAS_RUNTIME_SERVICES_INFO__=${JSON.stringify(runtimeServicesInfo)};`,
267
+ );
268
+ }
269
+
239
270
  if (parts.length === 0) return "";
240
271
 
241
272
  return `<script>(function(){${parts.join("")}}());</script>`;
@@ -249,7 +280,7 @@ async function serveInjectedIndexHtml(
249
280
  req,
250
281
  res,
251
282
  indexPath,
252
- { sessionApiKey, authRequired } = {},
283
+ { sessionApiKey, authRequired, runtimeServicesInfo } = {},
253
284
  ) {
254
285
  let content;
255
286
  try {
@@ -258,7 +289,11 @@ async function serveInjectedIndexHtml(
258
289
  return false;
259
290
  }
260
291
 
261
- const script = makeConfigInjectionScript(sessionApiKey, authRequired);
292
+ const script = makeConfigInjectionScript(
293
+ sessionApiKey,
294
+ authRequired,
295
+ runtimeServicesInfo,
296
+ );
262
297
  // Inject right before </head> so the key is available before any app code runs.
263
298
  // replace() targets the first (and only) </head> in well-formed HTML.
264
299
  const injected = content.includes("</head>")
@@ -500,7 +535,9 @@ async function handleStatic(
500
535
  }
501
536
 
502
537
  const needsInjection =
503
- injectionOpts.sessionApiKey || injectionOpts.authRequired;
538
+ injectionOpts.sessionApiKey ||
539
+ injectionOpts.authRequired ||
540
+ injectionOpts.runtimeServicesInfo;
504
541
 
505
542
  // Serve index.html with runtime config injection when configured.
506
543
  if (needsInjection && filePath.endsWith("index.html")) {
@@ -553,6 +590,7 @@ export function startStaticServer(config) {
553
590
  const injectionOpts = {
554
591
  sessionApiKey: config.sessionApiKey || null,
555
592
  authRequired: config.authRequired || false,
593
+ runtimeServicesInfo: config.runtimeServicesInfo || null,
556
594
  };
557
595
  const rejectPrefixes = config.rejectPrefixes ?? [];
558
596
 
@@ -1 +0,0 @@
1
- import{t as e}from"./declaration-IA661TBv.js";import{t}from"./vendor~root-layout~home~conversation-panel~conversation~launch~settings~settings-index~agen~jxrvuot9-Cwz6a1DC.js";var n=`cli-generic`,r=new Set([`default`,`default (recommended)`]);function i(e){if(typeof e!=`string`)return null;let t=e.trim();return!t||r.has(t.toLowerCase())||t===`acp-managed`?null:t}function a(e){for(let t of[e.runtimeName,e.runtimeId,e.configured,e.sdkLlm]){let e=i(t);if(e)return e}return e.providerDefault??null}var o={"claude-code":{icon:`claude-code`,description_key:e.ONBOARDING$AGENT_CLAUDE_CODE_DESCRIPTION},codex:{icon:`codex`,description_key:e.ONBOARDING$AGENT_CODEX_DESCRIPTION},"gemini-cli":{icon:`gemini`,description_key:e.ONBOARDING$AGENT_GEMINI_CLI_DESCRIPTION}},s=Object.entries(o).map(([e,n])=>{let r=t(e);return{key:e,display_name:r?.display_name??e,default_command:r?[...r.default_command]:[],available_models:r?.available_models?.map(e=>({id:e.id,label:e.label})),default_model:r?.default_model??void 0,description_key:n.description_key,icon:n.icon}}),c=`custom`;function l(n){let r=n?t(n):null;if(!r)return[];let i=[];return r.api_key_env_var&&i.push({name:r.api_key_env_var,secret:!0,hint_key:e.ONBOARDING$ACP_SECRET_API_KEY_HINT}),r.base_url_env_var&&i.push({name:r.base_url_env_var,hint_key:e.ONBOARDING$ACP_SECRET_BASE_URL_HINT}),i}function u(e){if(e)return s.find(t=>t.key===e)}function d(e){let t=u(e);return t?t.display_name:null}function f(e){return u(e)?.icon??`cli-generic`}function p(e,t){return t?u(e)?.available_models?.find(e=>e.id===t)?.label??t:null}function m(e,t={}){if(e===`openhands`)return{agent_kind:`openhands`};let n=e===c,r=n?void 0:u(e);if(!n&&!r&&!t.allowUnknownServer)return null;let i=t.model===void 0?r?.default_model??null:t.model;return{agent_kind:`acp`,acp_server:e,acp_command:t.command??[],acp_args:[],acp_model:i??null}}export{u as a,p as c,m as i,f as l,s as n,d as o,n as r,l as s,c as t,a as u};