@openhands/agent-canvas 1.15.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (739) hide show
  1. package/README.md +15 -1
  2. package/README.windows.md +2 -2
  3. package/build/assets/{acp-providers-BKvmTf82.js → acp-providers-CX3Lh9gj.js} +1 -1
  4. package/build/assets/active-backend-context-CrHTlgvN.js +2 -0
  5. package/build/assets/{agent-context-settings-D3PjSTU1.js → agent-context-settings-DSZlXrLj.js} +1 -1
  6. package/build/assets/{agent-profiles-settings-D4cY5U2T.js → agent-profiles-settings-Dzgb7G9z.js} +1 -1
  7. package/build/assets/agent-server-conversation-service.api-tnqNjbpE.js +86 -0
  8. package/build/assets/agent-settings-DLtsqaOs.js +2 -0
  9. package/build/assets/agent-settings-fFvR-XC2.js +1 -0
  10. package/build/assets/alert-banner-HP6mX-Vr.js +1 -0
  11. package/build/assets/{api-error-message-BJyfWp6p.js → api-error-message-B-XdSk3b.js} +1 -1
  12. package/build/assets/api-key-entry-screen-qTzrmJcr.js +1 -0
  13. package/build/assets/{app-settings-CbHqzQus.js → app-settings-dbnneVaV.js} +1 -1
  14. package/build/assets/automation-detail-BmwlCUAB.js +3 -0
  15. package/build/assets/{automation-export-BRopEHMu.js → automation-export-D3a3of4G.js} +1 -1
  16. package/build/assets/{automation-git-sync-CzyS4cn1.js → automation-git-sync-CprN5DcU.js} +1 -1
  17. package/build/assets/automation-setup-route-C40kXjMY.js +1 -0
  18. package/build/assets/{automation-templates-C_0FZgLG.js → automation-templates-BRppNh99.js} +1 -1
  19. package/build/assets/automations-list-DuNcRawl.js +1 -0
  20. package/build/assets/{back-nav-button-Dm9tIjVf.js → back-nav-button-Cjl_hoxq.js} +1 -1
  21. package/build/assets/backend-form-modal-lhGwzXFI.js +1 -0
  22. package/build/assets/{backend-synced-settings-badge-3fOwg6Bd.js → backend-synced-settings-badge-DPkz30BE.js} +1 -1
  23. package/build/assets/{badge-D4SqUCsR.js → badge-BU3S0VtE.js} +1 -1
  24. package/build/assets/{base-modal-C7_BDl_U.js → base-modal-D_L0oEbG.js} +1 -1
  25. package/build/assets/{bot-C-0Wu7vQ.js → bot-dMYHVfYM.js} +1 -1
  26. package/build/assets/{brand-button-Dxv6PDeN.js → brand-button-BAfk4wGP.js} +1 -1
  27. package/build/assets/browser-DSAo0tz1.js +46 -0
  28. package/build/assets/{browser-tab-BAl4ckJE.js → browser-tab-C9vy56R5.js} +1 -1
  29. package/build/assets/canvas-extension-page-dx1gFrfW.js +1 -0
  30. package/build/assets/canvas-extensions-8A-XhpgP.js +1 -0
  31. package/build/assets/canvas-extensions-runtime-2_x5Ezmi.js +1 -0
  32. package/build/assets/{chat-send-button-DWwR2cgI.js → chat-send-button-MUQqCZCS.js} +1 -1
  33. package/build/assets/check-CS0vmpQQ.js +1 -0
  34. package/build/assets/chevron-down-e1QBpjVy.js +1 -0
  35. package/build/assets/chevron-right-ZG4R5G4Q.js +1 -0
  36. package/build/assets/circle-check-DzWLNsbE.js +1 -0
  37. package/build/assets/{circle-plus-check-toggle-CBh_qomE.js → circle-plus-check-toggle-BO_kFZt3.js} +1 -1
  38. package/build/assets/{cloud-funnel-analytics-287iIERo.js → cloud-funnel-analytics-CztBCCPp.js} +1 -1
  39. package/build/assets/{cog-C4rrw-ZK.js → cog-D-MPQW6G.js} +1 -1
  40. package/build/assets/command-menu--UIlGL72.js +1 -0
  41. package/build/assets/{commits-tab-DZtJgaDM.js → commits-tab-AnZwLvh-.js} +1 -1
  42. package/build/assets/{condenser-settings-BcNmYR4s.js → condenser-settings-DmEOje-7.js} +1 -1
  43. package/build/assets/{confirmation-modal-Bk4JRcCM.js → confirmation-modal-Dv1ktp8K.js} +1 -1
  44. package/build/assets/{context-menu-list-item-lVYETtY5.js → context-menu-list-item-I86vKcmM.js} +1 -1
  45. package/build/assets/conversation-BbGrAO4Z.js +93 -0
  46. package/build/assets/conversation-mYT6NAoj.js +1 -0
  47. package/build/assets/conversation-panel-mYT6NAoj.js +1 -0
  48. package/build/assets/conversation-state-store-B0ImPLHO.js +1 -0
  49. package/build/assets/{conversation-tab-empty-state-HJtkmHZj.js → conversation-tab-empty-state-FIbh_lc8.js} +1 -1
  50. package/build/assets/{copy-to-clipboard-button-Cjkswvnj.js → copy-to-clipboard-button-Ca8iSkkA.js} +1 -1
  51. package/build/assets/{device-verify-EZhHhBT7.js → device-verify-Bhn2e_Ye.js} +1 -1
  52. package/build/assets/{dropdown-classes-DJe-E6MC.js → dropdown-classes-Bc1djN0-.js} +1 -1
  53. package/build/assets/{edit-automation-modal-D-urtv8n.js → edit-automation-modal-DadGbJ2u.js} +1 -1
  54. package/build/assets/empty-state-BoGVDecT.js +1 -0
  55. package/build/assets/{entry.client-C7Bi2tkU.js → entry.client-CqyPPjOq.js} +2 -2
  56. package/build/assets/{enum-filter-dropdown-DliX_Lo0.js → enum-filter-dropdown-Bgca129f.js} +1 -1
  57. package/build/assets/{environment-switch-overlay-CEKrFiMw.js → environment-switch-overlay-BmBRT7gv.js} +1 -1
  58. package/build/assets/{error-state-BALXiBNy.js → error-state-Body8Ngd.js} +1 -1
  59. package/build/assets/extensions-hub-CcDqq_vR.js +1 -0
  60. package/build/assets/extensions-navigation-Cr4yzYk4.js +1 -0
  61. package/build/assets/{external-link-DFpYunfj.js → external-link-DKUlnCQV.js} +1 -1
  62. package/build/assets/files-tab-D4o2VyE_.js +1 -0
  63. package/build/assets/{form-control-classes-CGw40z5h.js → form-control-classes-Bkh5FGrD.js} +1 -1
  64. package/build/assets/format-model-name-CasAP3nd.js +1 -0
  65. package/build/assets/get-git-path-ChKDVHZp.js +1 -0
  66. package/build/assets/{git-repo-dropdown-ai8qaNkD.js → git-repo-dropdown-4ROKl2cB.js} +1 -1
  67. package/build/assets/git-repo-dropdown-BkqzkMmM.js +1 -0
  68. package/build/assets/{highlighted-source-view-C3sxykQi.js → highlighted-source-view-BFRxGT_Q.js} +1 -1
  69. package/build/assets/home-ChpSuepX.js +1 -0
  70. package/build/assets/home-DIsB440S.js +1 -0
  71. package/build/assets/home-automation-run-tooltip-BVNDWjAH.js +1 -0
  72. package/build/assets/home-store-CY9Ej0ux.js +1 -0
  73. package/build/assets/index-home-BdlrFIif.js +1 -0
  74. package/build/assets/info-B6RQawoW.js +1 -0
  75. package/build/assets/install-server-modal-Dpy89p4g.js +1 -0
  76. package/build/assets/kebab-menu-item-content-D8hSNGmm.js +1 -0
  77. package/build/assets/{key-Cn5za3rg.js → key-BmVyxs-2.js} +1 -1
  78. package/build/assets/{launch-C1ieiOGe.js → launch-IrTDEFCs.js} +1 -1
  79. package/build/assets/list-filter-DsEK7NFC.js +1 -0
  80. package/build/assets/{list-todo-Cuu-STFc.js → list-todo-apgLVjMw.js} +1 -1
  81. package/build/assets/llm-not-configured-banner-CIFABh3K.js +27 -0
  82. package/build/assets/llm-settings-B9juXhIa.js +1 -0
  83. package/build/assets/llm-settings-De1d5dfr.js +1 -0
  84. package/build/assets/llm-subscription-service-BpJ0ouQo.js +1 -0
  85. package/build/assets/loader-circle-CC1au6hc.js +1 -0
  86. package/build/assets/{loading-spinner-0L3ZTToZ.js → loading-spinner-BY9N3pOe.js} +1 -1
  87. package/build/assets/manage-backends-modal-BrPV3oB-.js +1 -0
  88. package/build/assets/manifest-80fb1c29.js +1 -0
  89. package/build/assets/{manifest-subpage-layout-BGhiUQbA.js → manifest-subpage-layout-CAOYzrYp.js} +1 -1
  90. package/build/assets/{map-provider-B9LTm23I.js → map-provider-Cu3Zgumb.js} +1 -1
  91. package/build/assets/markdown-renderer-BzTlxI8x.js +8 -0
  92. package/build/assets/{mcp-CKbR4Vft.js → mcp-BTs_SXfZ.js} +1 -1
  93. package/build/assets/{mcp-marketplace-utils-C13fFccR.js → mcp-marketplace-utils-AIBzzHTO.js} +1 -1
  94. package/build/assets/{mcp-page-Bm4K2NQq.js → mcp-page-BEBYqH_K.js} +2 -2
  95. package/build/assets/messages-DKV9cRc2.js +41 -0
  96. package/build/assets/{modal-body-CMOc2tLl.js → modal-body-BxZjsju9.js} +1 -1
  97. package/build/assets/{modal-classes-BAb4Y_BG.js → modal-classes-C8eycCwG.js} +1 -1
  98. package/build/assets/{modal-close-button-CkJ0Ktjj.js → modal-close-button-DDzdRvCs.js} +1 -1
  99. package/build/assets/{mouse-pointer-click-CsgRs_-r.js → mouse-pointer-click-Co2uyaPA.js} +1 -1
  100. package/build/assets/onboarding-DV_OXoeP.js +1 -0
  101. package/build/assets/onboarding-modal-rkyBYkeQ.js +1 -0
  102. package/build/assets/{organization-service.api-C8XpQ0pM.js → organization-service.api-DrYNkEN_.js} +1 -1
  103. package/build/assets/{pencil-Clh1Wjvh.js → pencil-47jAZH_V.js} +1 -1
  104. package/build/assets/pin-By41Vl5J.js +1 -0
  105. package/build/assets/{planner-tab-DQvDU3ap.js → planner-tab-C9uZmhme.js} +1 -1
  106. package/build/assets/{plug-BuQhHSSG.js → plug-CG5HFcNG.js} +1 -1
  107. package/build/assets/plugins-management-service-BMJgC3Ga.js +1 -0
  108. package/build/assets/plus-C7Slq-0I.js +1 -0
  109. package/build/assets/profiles-service.api-ChoKrL0l.js +1 -0
  110. package/build/assets/providers-BhMcY5nv.js +1 -0
  111. package/build/assets/proxy-9Fe1v5na.js +1 -0
  112. package/build/assets/{puzzle-A9pGxxai.js → puzzle-JM_QaRm0.js} +1 -1
  113. package/build/assets/recommended-automations-launcher-6ABrI9Cy.js +1 -0
  114. package/build/assets/{refresh-cw-Bh69DyYO.js → refresh-cw-3q3Frrii.js} +1 -1
  115. package/build/assets/root-Dc8YmC9F.js +2 -0
  116. package/build/assets/root-VDaypvK4.css +1 -0
  117. package/build/assets/root-layout-CXkhSPYh.js +2 -0
  118. package/build/assets/schema-field-D-y9-LDb.js +1 -0
  119. package/build/assets/{sdk-section-page-HTffvm7Q.js → sdk-section-page-BlFiizlG.js} +1 -1
  120. package/build/assets/{secret-form-HTUbYw5o.js → secret-form-BB7the8W.js} +1 -1
  121. package/build/assets/secrets-service-ByZVENbp.js +1 -0
  122. package/build/assets/{secrets-settings-BizaTEr1.js → secrets-settings-B_GpxKW2.js} +1 -1
  123. package/build/assets/{settings-BlmrkwRi.js → settings-C0EWuBtA.js} +1 -1
  124. package/build/assets/settings-CKqk8ZnH.js +1 -0
  125. package/build/assets/{settings-dropdown-input-tM0A0ipy.js → settings-dropdown-input-BcwylHs2.js} +1 -1
  126. package/build/assets/{settings-index-CKq0b0Vg.js → settings-index-5w5UW2K3.js} +1 -1
  127. package/build/assets/{settings-input-C03KUoSC.js → settings-input-Db-1g8Ql.js} +1 -1
  128. package/build/assets/{settings-list-classes-BJ0g8rWj.js → settings-list-classes-BzeSZbF2.js} +1 -1
  129. package/build/assets/{settings-modal-AzEF1QPP.js → settings-modal-DfJ3tcJQ.js} +1 -1
  130. package/build/assets/settings-service.api-DJ1r62Zr.js +1 -0
  131. package/build/assets/{settings-switch-CQE0EGC-.js → settings-switch-CS-dJDmA.js} +1 -1
  132. package/build/assets/{settings-utils-ClYOkbbI.js → settings-utils-UYpEdPuD.js} +1 -1
  133. package/build/assets/shared-conversation-CA5ISEDy.js +1 -0
  134. package/build/assets/{shield-check-CFDViW82.js → shield-check-D2aCRd16.js} +1 -1
  135. package/build/assets/{sidebar-layout-D3hE08wK.js → sidebar-layout-D6fS8-Gl.js} +1 -1
  136. package/build/assets/{sidebar-mobile-menu-toggle-BOtyJHwE.js → sidebar-mobile-menu-toggle-C_fb0Jki.js} +1 -1
  137. package/build/assets/sidebar-nav-link-DQQcMf1A.js +1 -0
  138. package/build/assets/{sidebar-onboarding-checklist-storage-3qYflszY.js → sidebar-onboarding-checklist-storage-BBkeI6Bp.js} +1 -1
  139. package/build/assets/sidebar-store-DGqHkVLw.js +1 -0
  140. package/build/assets/{skill-card-pill-row-CFxjoqxn.js → skill-card-pill-row-B27-xyig.js} +1 -1
  141. package/build/assets/skill-enablement-DXeaImBz.js +1 -0
  142. package/build/assets/skill-filter-w__3UCEE.js +2 -0
  143. package/build/assets/{skill-icon-badge-CPQJ6A-I.js → skill-icon-badge-RQkq8wvl.js} +1 -1
  144. package/build/assets/skill-scope-B42H-XOc.js +1 -0
  145. package/build/assets/skills-plugins-tgF8EiXC.js +1 -0
  146. package/build/assets/skills-settings-BgJ9PaOe.js +1 -0
  147. package/build/assets/{styled-tooltip-Dl06rkpY.js → styled-tooltip-C4jf5Fv9.js} +1 -1
  148. package/build/assets/{task-list-tab-04GNQuii.js → task-list-tab-C5zcaktH.js} +1 -1
  149. package/build/assets/{terminal-Cj0iHIW7.js → terminal-CNElN42a.js} +2 -2
  150. package/build/assets/{toggle-switch-Fd_QGz0r.js → toggle-switch-ChOLXv2n.js} +1 -1
  151. package/build/assets/{trash-2-Dl8_RGz0.js → trash-2-D7K26eDO.js} +1 -1
  152. package/build/assets/{trash-_RMt7Ayc.js → trash-D-HYiVYM.js} +1 -1
  153. package/build/assets/{triangle-alert-SM-q4NU_.js → triangle-alert-CtdXWHUI.js} +1 -1
  154. package/build/assets/{typography-SgFy466J.js → typography-v1KN0tzi.js} +1 -1
  155. package/build/assets/usage-tab-CVDffLPt.js +1 -0
  156. package/build/assets/use-acp-credential-form-XIQmpX6M.js +1 -0
  157. package/build/assets/{use-activate-agent-profile-B2NS8nA5.js → use-activate-agent-profile-BLfmvDiG.js} +1 -1
  158. package/build/assets/use-agent-profiles-Bd9Bvvp1.js +1 -0
  159. package/build/assets/{use-automation-health-BxXdzZMP.js → use-automation-health-E6NZi9rb.js} +1 -1
  160. package/build/assets/{use-automations-zYb0dUny.js → use-automations-xijQKIl9.js} +1 -1
  161. package/build/assets/{use-can-manage-org-profiles-BWMahtUh.js → use-can-manage-org-profiles-CrJP5262.js} +1 -1
  162. package/build/assets/use-canvas-extensions-Bi693ujJ.js +1 -0
  163. package/build/assets/{use-cloud-current-user-id-CPHMDG-C.js → use-cloud-current-user-id-CDfAHpPX.js} +1 -1
  164. package/build/assets/use-config-A9QovgXO.js +1 -0
  165. package/build/assets/{use-create-conversation-DwN5vv2f.js → use-create-conversation-Dx3l7mFZ.js} +1 -1
  166. package/build/assets/use-create-secret-B9cUFWRG.js +1 -0
  167. package/build/assets/{use-get-secrets-BT4ihRwj.js → use-get-secrets-K3jmk-LH.js} +1 -1
  168. package/build/assets/use-is-authed-nTBcM7dE.js +1 -0
  169. package/build/assets/use-llm-configured-BV9nZ1_j.js +1 -0
  170. package/build/assets/use-llm-profiles-BO-P4Oyo.js +1 -0
  171. package/build/assets/use-manifest-capabilities-Cw_flwEz.js +1 -0
  172. package/build/assets/use-onboarding-completion-D8U7k4Qb.js +1 -0
  173. package/build/assets/use-pinned-home-route-CckOZrmb.js +1 -0
  174. package/build/assets/use-plugins-marketplace-7i94Zu3Z.js +1 -0
  175. package/build/assets/use-save-agent-profile-BUjSsDXK.js +1 -0
  176. package/build/assets/{use-save-settings-CUZW6yXP.js → use-save-settings-DYqkKv7T.js} +1 -1
  177. package/build/assets/{use-settings-C5VhGpqd.js → use-settings-DSXLbvBl.js} +1 -1
  178. package/build/assets/{use-settings-nav-items-DHaUu1Dg.js → use-settings-nav-items-CwRw-CmX.js} +1 -1
  179. package/build/assets/use-tracking-D53y3TH9.js +3 -0
  180. package/build/assets/{use-user-conversation-DT0_QCnL.js → use-user-conversation-B9Gebw_g.js} +1 -1
  181. package/build/assets/{useInfiniteQuery-CgeUQPfs.js → useInfiniteQuery-C926xzY4.js} +1 -1
  182. package/build/assets/{useMutation-DFnzkf6f.js → useMutation-B-qc391N.js} +1 -1
  183. package/build/assets/{useQueries-BhbrGEf1.js → useQueries-DlbhlH9I.js} +1 -1
  184. package/build/assets/{useQuery-BXWbZBZl.js → useQuery-BSTgq1rl.js} +1 -1
  185. package/build/assets/utils-CN5ZfZy1.js +1 -0
  186. package/build/assets/{vendor~conversation-panel~conversation-CTvDDiXg.js → vendor~conversation-panel~conversation-C8Fn4XOf.js} +1 -1
  187. package/build/assets/{vendor~entry.client-BFE7Llz9.js → vendor~entry.client-CoCfUXUF.js} +1 -1
  188. package/build/assets/{vendor~entry.client-BaKt_PIp.js → vendor~entry.client-DA2izTjq.js} +1 -1
  189. package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~kepq2zme-ZixYGy6E.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~czjee3a3-DqZDXfg2.js} +1 -1
  190. package/build/assets/{vendor~index-home~home~conversation-panel~conversation-BTyukeM-.js → vendor~index-home~home~conversation-panel~conversation-hWywRBaR.js} +1 -1
  191. package/build/assets/{vendor~root-layout-BlUaZ18v.js → vendor~root-layout-C9Ju9DQg.js} +1 -1
  192. package/build/assets/{vendor~root-layout~conversation-panel~conversation-BYAWJwQX.js → vendor~root-layout~conversation-panel~conversation-BMbMgaGu.js} +1 -1
  193. package/build/assets/{vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-CHaLEBVR.js → vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-BWir3rJs.js} +1 -1
  194. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation-j5MFqfSy.js +1 -0
  195. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~mcp~automations-list~aut~ibfbmr9f-cDuKr-WD.js +1 -0
  196. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~iw7io29p-Dz-MAyNb.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~iyia17eu-Chf7vmKB.js} +1 -1
  197. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hjcjabwg-Dtu7BpYk.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~nj1hli3r-DP9wmsjo.js} +2 -2
  198. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-DonTKfQD.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-CUmIwQCN.js} +117 -13
  199. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~jz4f6vo2-BgxDvUcf.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~jz4f6vo2-C7HiY4Ae.js} +42 -3
  200. package/build/assets/{verification-settings-Bj6bo097.js → verification-settings-gw_q6vkL.js} +1 -1
  201. package/build/assets/{wrench-hi7Q13dF.js → wrench-CUEI1krB.js} +1 -1
  202. package/build/assets/{x-DkgltWa0.js → x-DJdhbdmt.js} +1 -1
  203. package/build/index.html +4 -4
  204. package/build/locales/ar/openhands.json +32 -16
  205. package/build/locales/ca/openhands.json +32 -16
  206. package/build/locales/de/openhands.json +32 -16
  207. package/build/locales/en/openhands.json +32 -16
  208. package/build/locales/es/openhands.json +32 -16
  209. package/build/locales/fr/openhands.json +32 -16
  210. package/build/locales/it/openhands.json +32 -16
  211. package/build/locales/ja/openhands.json +32 -16
  212. package/build/locales/ko-KR/openhands.json +32 -16
  213. package/build/locales/no/openhands.json +32 -16
  214. package/build/locales/pt/openhands.json +32 -16
  215. package/build/locales/tr/openhands.json +32 -16
  216. package/build/locales/uk/openhands.json +32 -16
  217. package/build/locales/zh-CN/openhands.json +32 -16
  218. package/build/locales/zh-TW/openhands.json +32 -16
  219. package/config/defaults.json +9 -5
  220. package/dist/api/agent-profiles-service/profile-field-support.d.ts +26 -0
  221. package/dist/api/agent-server-adapter.cjs +3 -3
  222. package/dist/api/agent-server-adapter.cjs.map +1 -1
  223. package/dist/api/agent-server-adapter.js +118 -116
  224. package/dist/api/agent-server-adapter.js.map +1 -1
  225. package/dist/api/agent-server-compatibility.cjs +1 -1
  226. package/dist/api/agent-server-compatibility.cjs.map +1 -1
  227. package/dist/api/agent-server-compatibility.d.ts +21 -0
  228. package/dist/api/agent-server-compatibility.js +52 -38
  229. package/dist/api/agent-server-compatibility.js.map +1 -1
  230. package/dist/api/agent-server-config.cjs +1 -1
  231. package/dist/api/agent-server-config.cjs.map +1 -1
  232. package/dist/api/agent-server-config.d.ts +26 -0
  233. package/dist/api/agent-server-config.js +18 -5
  234. package/dist/api/agent-server-config.js.map +1 -1
  235. package/dist/api/canvas-extensions-service.cjs +1 -0
  236. package/dist/api/canvas-extensions-service.d.ts +22 -0
  237. package/dist/api/canvas-extensions-service.js +4 -0
  238. package/dist/api/cloud/conversation-service.api.cjs +1 -1
  239. package/dist/api/cloud/conversation-service.api.cjs.map +1 -1
  240. package/dist/api/cloud/conversation-service.api.d.ts +6 -0
  241. package/dist/api/cloud/conversation-service.api.js +14 -6
  242. package/dist/api/cloud/conversation-service.api.js.map +1 -1
  243. package/dist/api/conversation-file-upload.api.cjs +1 -1
  244. package/dist/api/conversation-file-upload.api.js +10 -10
  245. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
  246. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
  247. package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +11 -0
  248. package/dist/api/conversation-service/agent-server-conversation-service.api.js +129 -118
  249. package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
  250. package/dist/api/event-service/event-service.api.cjs +1 -1
  251. package/dist/api/event-service/event-service.api.js +12 -12
  252. package/dist/api/git-service/agent-server-git-service.api.cjs +1 -1
  253. package/dist/api/git-service/agent-server-git-service.api.js +8 -8
  254. package/dist/api/runtime-service/agent-server-runtime-service.cjs +1 -1
  255. package/dist/api/runtime-service/agent-server-runtime-service.js +8 -8
  256. package/dist/api/settings-service/settings-service.api.cjs +1 -1
  257. package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
  258. package/dist/api/settings-service/settings-service.api.d.ts +3 -2
  259. package/dist/api/settings-service/settings-service.api.js +2 -1
  260. package/dist/api/settings-service/settings-service.api.js.map +1 -1
  261. package/dist/components/conversation-events/chat/event-message-components/event-group.cjs +1 -1
  262. package/dist/components/conversation-events/chat/event-message-components/event-group.cjs.map +1 -1
  263. package/dist/components/conversation-events/chat/event-message-components/event-group.js +40 -36
  264. package/dist/components/conversation-events/chat/event-message-components/event-group.js.map +1 -1
  265. package/dist/components/features/automations/automation-card.cjs +1 -1
  266. package/dist/components/features/automations/automation-card.cjs.map +1 -1
  267. package/dist/components/features/automations/automation-card.js +114 -104
  268. package/dist/components/features/automations/automation-card.js.map +1 -1
  269. package/dist/components/features/automations/detail/run-phase.cjs +2 -0
  270. package/dist/components/features/automations/detail/run-phase.cjs.map +1 -0
  271. package/dist/components/features/automations/detail/run-phase.d.ts +89 -0
  272. package/dist/components/features/automations/detail/run-phase.js +72 -0
  273. package/dist/components/features/automations/detail/run-phase.js.map +1 -0
  274. package/dist/components/features/backends/backend-form-modal.cjs +1 -1
  275. package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
  276. package/dist/components/features/backends/backend-form-modal.js +5 -11
  277. package/dist/components/features/backends/backend-form-modal.js.map +1 -1
  278. package/dist/components/features/canvas-extensions/add-canvas-extension-modal.d.ts +6 -0
  279. package/dist/components/features/canvas-extensions/canvas-extension-card.d.ts +9 -0
  280. package/dist/components/features/canvas-extensions/canvas-extensions-runtime.cjs +2 -0
  281. package/dist/components/features/canvas-extensions/canvas-extensions-runtime.cjs.map +1 -0
  282. package/dist/components/features/canvas-extensions/canvas-extensions-runtime.d.ts +23 -0
  283. package/dist/components/features/canvas-extensions/canvas-extensions-runtime.js +19 -0
  284. package/dist/components/features/canvas-extensions/canvas-extensions-runtime.js.map +1 -0
  285. package/dist/components/features/chat/chat-interface.cjs +2 -2
  286. package/dist/components/features/chat/chat-interface.cjs.map +1 -1
  287. package/dist/components/features/chat/chat-interface.js +171 -168
  288. package/dist/components/features/chat/chat-interface.js.map +1 -1
  289. package/dist/components/features/chat/chat-markdown-path-code.cjs +3 -0
  290. package/dist/components/features/chat/chat-markdown-path-code.cjs.map +1 -0
  291. package/dist/components/features/chat/chat-markdown-path-code.d.ts +27 -0
  292. package/dist/components/features/chat/chat-markdown-path-code.js +72 -0
  293. package/dist/components/features/chat/chat-markdown-path-code.js.map +1 -0
  294. package/dist/components/features/chat/path-component.cjs +1 -1
  295. package/dist/components/features/chat/path-component.cjs.map +1 -1
  296. package/dist/components/features/chat/path-component.d.ts +8 -2
  297. package/dist/components/features/chat/path-component.js +33 -21
  298. package/dist/components/features/chat/path-component.js.map +1 -1
  299. package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.cjs +1 -1
  300. package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.cjs.map +1 -1
  301. package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.js +38 -43
  302. package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.js.map +1 -1
  303. package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.cjs +1 -1
  304. package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.cjs.map +1 -1
  305. package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.d.ts +8 -5
  306. package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.js +22 -16
  307. package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.js.map +1 -1
  308. package/dist/components/features/chat/user-message-body.cjs +1 -1
  309. package/dist/components/features/chat/user-message-body.cjs.map +1 -1
  310. package/dist/components/features/chat/user-message-body.d.ts +4 -0
  311. package/dist/components/features/chat/user-message-body.js +30 -24
  312. package/dist/components/features/chat/user-message-body.js.map +1 -1
  313. package/dist/components/features/conversation/conversation-overview-skills-panel.cjs +1 -1
  314. package/dist/components/features/conversation/conversation-overview-skills-panel.cjs.map +1 -1
  315. package/dist/components/features/conversation/conversation-overview-skills-panel.js +63 -81
  316. package/dist/components/features/conversation/conversation-overview-skills-panel.js.map +1 -1
  317. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs +1 -1
  318. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs.map +1 -1
  319. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js +50 -50
  320. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js.map +1 -1
  321. package/dist/components/features/conversation/conversation-tabs/drawer-vscode-link.cjs +1 -1
  322. package/dist/components/features/conversation/conversation-tabs/drawer-vscode-link.cjs.map +1 -1
  323. package/dist/components/features/conversation/conversation-tabs/drawer-vscode-link.d.ts +1 -1
  324. package/dist/components/features/conversation/conversation-tabs/drawer-vscode-link.js +3 -3
  325. package/dist/components/features/conversation/conversation-tabs/drawer-vscode-link.js.map +1 -1
  326. package/dist/components/features/conversation-panel/skills-modal.cjs +1 -1
  327. package/dist/components/features/conversation-panel/skills-modal.cjs.map +1 -1
  328. package/dist/components/features/conversation-panel/skills-modal.js +29 -28
  329. package/dist/components/features/conversation-panel/skills-modal.js.map +1 -1
  330. package/dist/components/features/files-tab/file-content-viewer.cjs +1 -1
  331. package/dist/components/features/files-tab/file-content-viewer.js +5 -5
  332. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.cjs +1 -1
  333. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.cjs.map +1 -1
  334. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js +51 -29
  335. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js.map +1 -1
  336. package/dist/components/features/onboarding/onboarding-host.d.ts +3 -4
  337. package/dist/components/features/onboarding/steps/setup-llm-step.d.ts +5 -9
  338. package/dist/components/features/settings/acp-auth-status-banner.d.ts +23 -6
  339. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.cjs +1 -1
  340. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.js +1 -0
  341. package/dist/components/features/settings/llm-profiles/provider-connection-modal.cjs +1 -1
  342. package/dist/components/features/settings/llm-profiles/provider-connection-modal.js +3 -0
  343. package/dist/components/features/settings/sdk-settings/field-help.cjs +1 -1
  344. package/dist/components/features/settings/sdk-settings/field-help.cjs.map +1 -1
  345. package/dist/components/features/settings/sdk-settings/field-help.d.ts +1 -1
  346. package/dist/components/features/settings/sdk-settings/field-help.js +1 -1
  347. package/dist/components/features/settings/sdk-settings/field-help.js.map +1 -1
  348. package/dist/components/features/settings/sdk-settings/sdk-section-page.cjs +1 -1
  349. package/dist/components/features/settings/sdk-settings/sdk-section-page.js +6 -6
  350. package/dist/components/features/settings/sdk-settings/sdk-section-page.js.map +1 -1
  351. package/dist/components/features/sidebar/sidebar-nav-link.cjs +1 -1
  352. package/dist/components/features/sidebar/sidebar-nav-link.cjs.map +1 -1
  353. package/dist/components/features/sidebar/sidebar-nav-link.d.ts +10 -1
  354. package/dist/components/features/sidebar/sidebar-nav-link.js +54 -36
  355. package/dist/components/features/sidebar/sidebar-nav-link.js.map +1 -1
  356. package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
  357. package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
  358. package/dist/components/features/sidebar/sidebar-rail-body.js +143 -120
  359. package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
  360. package/dist/components/features/sidebar/sidebar.cjs +1 -1
  361. package/dist/components/features/sidebar/sidebar.cjs.map +1 -1
  362. package/dist/components/features/sidebar/sidebar.js +1 -1
  363. package/dist/components/features/sidebar/sidebar.js.map +1 -1
  364. package/dist/components/features/skills/build-skill-pills.cjs +1 -1
  365. package/dist/components/features/skills/build-skill-pills.cjs.map +1 -1
  366. package/dist/components/features/skills/build-skill-pills.js +60 -52
  367. package/dist/components/features/skills/build-skill-pills.js.map +1 -1
  368. package/dist/components/features/skills/extensions-navigation.cjs +1 -1
  369. package/dist/components/features/skills/extensions-navigation.cjs.map +1 -1
  370. package/dist/components/features/skills/extensions-navigation.js +54 -43
  371. package/dist/components/features/skills/extensions-navigation.js.map +1 -1
  372. package/dist/components/features/skills/skill-filter.cjs +1 -1
  373. package/dist/components/features/skills/skill-filter.cjs.map +1 -1
  374. package/dist/components/features/skills/skill-filter.d.ts +8 -3
  375. package/dist/components/features/skills/skill-filter.js +69 -52
  376. package/dist/components/features/skills/skill-filter.js.map +1 -1
  377. package/dist/components/shared/modals/settings/settings-form.cjs +1 -1
  378. package/dist/components/shared/modals/settings/settings-form.js +8 -8
  379. package/dist/config/defaults.cjs +1 -1
  380. package/dist/config/defaults.cjs.map +1 -1
  381. package/dist/config/defaults.js +9 -5
  382. package/dist/config/defaults.js.map +1 -1
  383. package/dist/contexts/conversation-websocket-context.cjs +3 -3
  384. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  385. package/dist/contexts/conversation-websocket-context.js +5 -5
  386. package/dist/extensions/canvas-extension-module-loader.d.ts +11 -0
  387. package/dist/hooks/mutation/use-manage-canvas-extensions.d.ts +12 -0
  388. package/dist/hooks/query/concurrency-limiter.cjs +2 -0
  389. package/dist/hooks/query/concurrency-limiter.cjs.map +1 -0
  390. package/dist/hooks/query/concurrency-limiter.d.ts +22 -0
  391. package/dist/hooks/query/concurrency-limiter.js +29 -0
  392. package/dist/hooks/query/concurrency-limiter.js.map +1 -0
  393. package/dist/hooks/query/query-keys.cjs.map +1 -1
  394. package/dist/hooks/query/query-keys.d.ts +4 -0
  395. package/dist/hooks/query/query-keys.js.map +1 -1
  396. package/dist/hooks/query/use-active-conversation.cjs +1 -1
  397. package/dist/hooks/query/use-active-conversation.js +4 -4
  398. package/dist/hooks/query/use-automations.cjs.map +1 -1
  399. package/dist/hooks/query/use-automations.js.map +1 -1
  400. package/dist/hooks/query/use-backends-health.cjs +1 -1
  401. package/dist/hooks/query/use-backends-health.cjs.map +1 -1
  402. package/dist/hooks/query/use-backends-health.d.ts +1 -1
  403. package/dist/hooks/query/use-backends-health.js +50 -64
  404. package/dist/hooks/query/use-backends-health.js.map +1 -1
  405. package/dist/hooks/query/use-canvas-extensions.cjs +1 -0
  406. package/dist/hooks/query/use-canvas-extensions.d.ts +5 -0
  407. package/dist/hooks/query/use-canvas-extensions.js +3 -0
  408. package/dist/hooks/query/use-commit-changes.cjs +1 -1
  409. package/dist/hooks/query/use-commit-changes.js +4 -4
  410. package/dist/hooks/query/use-latest-automation-runs.cjs +1 -1
  411. package/dist/hooks/query/use-latest-automation-runs.js +1 -0
  412. package/dist/hooks/query/use-paginated-conversations.cjs +1 -1
  413. package/dist/hooks/query/use-paginated-conversations.cjs.map +1 -1
  414. package/dist/hooks/query/use-paginated-conversations.js +19 -16
  415. package/dist/hooks/query/use-paginated-conversations.js.map +1 -1
  416. package/dist/hooks/query/use-search-providers.cjs +1 -1
  417. package/dist/hooks/query/use-search-providers.cjs.map +1 -1
  418. package/dist/hooks/query/use-search-providers.js +17 -10
  419. package/dist/hooks/query/use-search-providers.js.map +1 -1
  420. package/dist/hooks/query/use-unified-get-git-changes.cjs +1 -1
  421. package/dist/hooks/query/use-unified-get-git-changes.js +4 -4
  422. package/dist/hooks/query/use-unified-git-commits.cjs +1 -1
  423. package/dist/hooks/query/use-unified-git-commits.js +4 -4
  424. package/dist/hooks/query/use-unified-git-diff.cjs +1 -1
  425. package/dist/hooks/query/use-unified-git-diff.js +4 -4
  426. package/dist/hooks/query/use-unified-vscode-url.cjs +1 -1
  427. package/dist/hooks/query/use-unified-vscode-url.cjs.map +1 -1
  428. package/dist/hooks/query/use-unified-vscode-url.d.ts +1 -0
  429. package/dist/hooks/query/use-unified-vscode-url.js +40 -26
  430. package/dist/hooks/query/use-unified-vscode-url.js.map +1 -1
  431. package/dist/hooks/query/use-workspace-file-content.cjs +1 -1
  432. package/dist/hooks/query/use-workspace-file-content.js +5 -5
  433. package/dist/hooks/query/use-workspace-files.cjs +1 -1
  434. package/dist/hooks/query/use-workspace-files.js +6 -6
  435. package/dist/hooks/use-acp-credential-form.d.ts +6 -0
  436. package/dist/hooks/use-conversation-overview-git-diff-stats.cjs +1 -1
  437. package/dist/hooks/use-conversation-overview-git-diff-stats.js +4 -4
  438. package/dist/hooks/use-pinned-home-route.cjs +2 -0
  439. package/dist/hooks/use-pinned-home-route.cjs.map +1 -0
  440. package/dist/hooks/use-pinned-home-route.d.ts +33 -0
  441. package/dist/hooks/use-pinned-home-route.js +34 -0
  442. package/dist/hooks/use-pinned-home-route.js.map +1 -0
  443. package/dist/hooks/use-skill-enablement.cjs +2 -0
  444. package/dist/hooks/use-skill-enablement.cjs.map +1 -0
  445. package/dist/hooks/use-skill-enablement.d.ts +14 -0
  446. package/dist/hooks/use-skill-enablement.js +80 -0
  447. package/dist/hooks/use-skill-enablement.js.map +1 -0
  448. package/dist/i18n/declaration.cjs +1 -1
  449. package/dist/i18n/declaration.cjs.map +1 -1
  450. package/dist/i18n/declaration.d.ts +29 -13
  451. package/dist/i18n/declaration.js +1 -1
  452. package/dist/i18n/declaration.js.map +1 -1
  453. package/dist/i18n/translation.cjs +3 -3
  454. package/dist/i18n/translation.cjs.map +1 -1
  455. package/dist/i18n/translation.js +538 -266
  456. package/dist/i18n/translation.js.map +1 -1
  457. package/dist/index.cjs +1 -1
  458. package/dist/index.js +15 -14
  459. package/dist/lib/index.cjs +1 -1
  460. package/dist/lib/index.d.ts +1 -0
  461. package/dist/lib/index.js +1 -0
  462. package/dist/locales/ar/openhands.json +32 -16
  463. package/dist/locales/ca/openhands.json +32 -16
  464. package/dist/locales/de/openhands.json +32 -16
  465. package/dist/locales/en/openhands.json +32 -16
  466. package/dist/locales/es/openhands.json +32 -16
  467. package/dist/locales/fr/openhands.json +32 -16
  468. package/dist/locales/it/openhands.json +32 -16
  469. package/dist/locales/ja/openhands.json +32 -16
  470. package/dist/locales/ko-KR/openhands.json +32 -16
  471. package/dist/locales/no/openhands.json +32 -16
  472. package/dist/locales/pt/openhands.json +32 -16
  473. package/dist/locales/tr/openhands.json +32 -16
  474. package/dist/locales/uk/openhands.json +32 -16
  475. package/dist/locales/zh-CN/openhands.json +32 -16
  476. package/dist/locales/zh-TW/openhands.json +32 -16
  477. package/dist/manifests/automation-interface.cjs +1 -1
  478. package/dist/manifests/automation-interface.cjs.map +1 -1
  479. package/dist/manifests/automation-interface.d.ts +6 -0
  480. package/dist/manifests/automation-interface.js +11 -8
  481. package/dist/manifests/automation-interface.js.map +1 -1
  482. package/dist/node_modules/@openhands/extensions/automations/bundle-index.cjs +45 -4
  483. package/dist/node_modules/@openhands/extensions/automations/bundle-index.cjs.map +1 -1
  484. package/dist/node_modules/@openhands/extensions/automations/bundle-index.js +1 -1
  485. package/dist/node_modules/@openhands/extensions/automations/bundle-index.js.map +1 -1
  486. package/dist/node_modules/@openhands/extensions/automations/catalog/github-agents-md-maintainer/manifest.cjs +1 -1
  487. package/dist/node_modules/@openhands/extensions/automations/catalog/github-agents-md-maintainer/manifest.cjs.map +1 -1
  488. package/dist/node_modules/@openhands/extensions/automations/catalog/github-agents-md-maintainer/manifest.js +5 -0
  489. package/dist/node_modules/@openhands/extensions/automations/catalog/github-agents-md-maintainer/manifest.js.map +1 -1
  490. package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.cjs +1 -1
  491. package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.cjs.map +1 -1
  492. package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.js +5 -0
  493. package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.js.map +1 -1
  494. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs +1 -1
  495. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs.map +1 -1
  496. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js +5 -0
  497. package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js.map +1 -1
  498. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs +1 -1
  499. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs.map +1 -1
  500. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js +5 -0
  501. package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js.map +1 -1
  502. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-bitbucket-pr/manifest.cjs +9 -0
  503. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-bitbucket-pr/manifest.cjs.map +1 -0
  504. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-bitbucket-pr/manifest.js +21 -0
  505. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-bitbucket-pr/manifest.js.map +1 -0
  506. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-gitlab-mr/manifest.cjs +9 -0
  507. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-gitlab-mr/manifest.cjs.map +1 -0
  508. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-gitlab-mr/manifest.js +21 -0
  509. package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-gitlab-mr/manifest.js.map +1 -0
  510. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-issue-to-bitbucket-pr/manifest.cjs +9 -0
  511. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-issue-to-bitbucket-pr/manifest.cjs.map +1 -0
  512. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-issue-to-bitbucket-pr/manifest.js +21 -0
  513. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-issue-to-bitbucket-pr/manifest.js.map +1 -0
  514. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-issue-to-github-pr/manifest.cjs +9 -0
  515. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-issue-to-github-pr/manifest.cjs.map +1 -0
  516. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-issue-to-github-pr/manifest.js +21 -0
  517. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-issue-to-github-pr/manifest.js.map +1 -0
  518. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-issue-to-gitlab-mr/manifest.cjs +9 -0
  519. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-issue-to-gitlab-mr/manifest.cjs.map +1 -0
  520. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-issue-to-gitlab-mr/manifest.js +21 -0
  521. package/dist/node_modules/@openhands/extensions/automations/catalog/linear-issue-to-gitlab-mr/manifest.js.map +1 -0
  522. package/dist/node_modules/@openhands/extensions/automations/catalog/news-digest/manifest.cjs +1 -1
  523. package/dist/node_modules/@openhands/extensions/automations/catalog/news-digest/manifest.cjs.map +1 -1
  524. package/dist/node_modules/@openhands/extensions/automations/catalog/news-digest/manifest.js +5 -0
  525. package/dist/node_modules/@openhands/extensions/automations/catalog/news-digest/manifest.js.map +1 -1
  526. package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.cjs +30 -0
  527. package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.cjs.map +1 -0
  528. package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.js +65 -0
  529. package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.js.map +1 -0
  530. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs +1 -1
  531. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs.map +1 -1
  532. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js +21 -9
  533. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js.map +1 -1
  534. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs +1 -1
  535. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs.map +1 -1
  536. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js +2 -2
  537. package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js.map +1 -1
  538. package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.cjs +2 -0
  539. package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.cjs.map +1 -0
  540. package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.js +40 -0
  541. package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.js.map +1 -0
  542. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.cjs +1 -1
  543. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.cjs.map +1 -1
  544. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.js +1 -1
  545. package/dist/node_modules/@openhands/extensions/integrations/catalog/notion.js.map +1 -1
  546. package/dist/node_modules/@openhands/extensions/integrations/catalog-index.cjs +1 -1
  547. package/dist/node_modules/@openhands/extensions/integrations/catalog-index.cjs.map +1 -1
  548. package/dist/node_modules/@openhands/extensions/integrations/catalog-index.js +74 -72
  549. package/dist/node_modules/@openhands/extensions/integrations/catalog-index.js.map +1 -1
  550. package/dist/node_modules/@openhands/extensions/skills/index.cjs +42 -3
  551. package/dist/node_modules/@openhands/extensions/skills/index.cjs.map +1 -1
  552. package/dist/node_modules/@openhands/extensions/skills/index.js +22 -3
  553. package/dist/node_modules/@openhands/extensions/skills/index.js.map +1 -1
  554. package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-conversation.cjs +1 -1
  555. package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-conversation.js +1 -1
  556. package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-state.cjs +1 -1
  557. package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-state.cjs.map +1 -1
  558. package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-state.js +8 -7
  559. package/dist/node_modules/@openhands/typescript-client/dist/conversation/remote-state.js.map +1 -1
  560. package/dist/node_modules/@openhands/typescript-client/dist/index.cjs +1 -1
  561. package/dist/node_modules/@openhands/typescript-client/dist/index.js +2 -2
  562. package/dist/node_modules/lucide-react/dist/esm/icons/blocks.cjs +2 -0
  563. package/dist/node_modules/lucide-react/dist/esm/icons/blocks.cjs.map +1 -0
  564. package/dist/node_modules/lucide-react/dist/esm/icons/blocks.js +16 -0
  565. package/dist/node_modules/lucide-react/dist/esm/icons/blocks.js.map +1 -0
  566. package/dist/node_modules/lucide-react/dist/esm/icons/panels-top-left.cjs +2 -0
  567. package/dist/node_modules/lucide-react/dist/esm/icons/panels-top-left.cjs.map +1 -0
  568. package/dist/node_modules/lucide-react/dist/esm/icons/panels-top-left.js +23 -0
  569. package/dist/node_modules/lucide-react/dist/esm/icons/panels-top-left.js.map +1 -0
  570. package/dist/package.cjs +1 -1
  571. package/dist/package.cjs.map +1 -1
  572. package/dist/package.js +3 -3
  573. package/dist/package.js.map +1 -1
  574. package/dist/routes/agent-settings.d.ts +10 -0
  575. package/dist/routes/app-settings.cjs +1 -1
  576. package/dist/routes/app-settings.cjs.map +1 -1
  577. package/dist/routes/app-settings.js +7 -7
  578. package/dist/routes/files-tab.cjs +1 -1
  579. package/dist/routes/files-tab.cjs.map +1 -1
  580. package/dist/routes/files-tab.js +14 -14
  581. package/dist/routes/files-tab.js.map +1 -1
  582. package/dist/routes/llm-settings.cjs +1 -1
  583. package/dist/routes/llm-settings.cjs.map +1 -1
  584. package/dist/routes/llm-settings.js +122 -114
  585. package/dist/routes/llm-settings.js.map +1 -1
  586. package/dist/services/canvas-ui.cjs +1 -1
  587. package/dist/services/canvas-ui.cjs.map +1 -1
  588. package/dist/services/canvas-ui.d.ts +5 -0
  589. package/dist/services/canvas-ui.js +24 -10
  590. package/dist/services/canvas-ui.js.map +1 -1
  591. package/dist/services/settings.cjs +1 -1
  592. package/dist/services/settings.cjs.map +1 -1
  593. package/dist/services/settings.js +3 -2
  594. package/dist/services/settings.js.map +1 -1
  595. package/dist/types/automation.cjs.map +1 -1
  596. package/dist/types/automation.d.ts +20 -0
  597. package/dist/types/automation.js.map +1 -1
  598. package/dist/types/canvas-extension.cjs +2 -0
  599. package/dist/types/canvas-extension.cjs.map +1 -0
  600. package/dist/types/canvas-extension.d.ts +77 -0
  601. package/dist/types/canvas-extension.js +6 -0
  602. package/dist/types/canvas-extension.js.map +1 -0
  603. package/dist/types/settings.d.ts +7 -0
  604. package/dist/ui/help-link.cjs +1 -1
  605. package/dist/ui/help-link.cjs.map +1 -1
  606. package/dist/ui/help-link.d.ts +6 -1
  607. package/dist/ui/help-link.js +32 -18
  608. package/dist/ui/help-link.js.map +1 -1
  609. package/dist/utils/acp-auth-display.d.ts +35 -0
  610. package/dist/utils/cache-utils.cjs +1 -1
  611. package/dist/utils/cache-utils.js +5 -5
  612. package/dist/utils/format-model-name.cjs +1 -1
  613. package/dist/utils/format-model-name.cjs.map +1 -1
  614. package/dist/utils/format-model-name.d.ts +7 -3
  615. package/dist/utils/format-model-name.js +6 -11
  616. package/dist/utils/format-model-name.js.map +1 -1
  617. package/dist/utils/format-relative-time.cjs +1 -1
  618. package/dist/utils/format-relative-time.cjs.map +1 -1
  619. package/dist/utils/format-relative-time.d.ts +7 -0
  620. package/dist/utils/format-relative-time.js +7 -2
  621. package/dist/utils/format-relative-time.js.map +1 -1
  622. package/dist/utils/path-utils.cjs +1 -1
  623. package/dist/utils/path-utils.cjs.map +1 -1
  624. package/dist/utils/path-utils.d.ts +15 -3
  625. package/dist/utils/path-utils.js +29 -3
  626. package/dist/utils/path-utils.js.map +1 -1
  627. package/dist/utils/skill-enablement.cjs +2 -0
  628. package/dist/utils/skill-enablement.cjs.map +1 -0
  629. package/dist/utils/skill-enablement.d.ts +51 -0
  630. package/dist/utils/skill-enablement.js +31 -0
  631. package/dist/utils/skill-enablement.js.map +1 -0
  632. package/dist/utils/vscode-origin.cjs +2 -0
  633. package/dist/utils/vscode-origin.cjs.map +1 -0
  634. package/dist/utils/vscode-origin.d.ts +55 -0
  635. package/dist/utils/vscode-origin.js +27 -0
  636. package/dist/utils/vscode-origin.js.map +1 -0
  637. package/dist/utils/workspace-mode.d.ts +4 -0
  638. package/package.json +3 -3
  639. package/scripts/check-sdk-version-sync.mjs +6 -6
  640. package/scripts/check-translation-completeness.cjs +1 -0
  641. package/scripts/dev-extra-backend.mjs +28 -9
  642. package/scripts/dev-safe.mjs +81 -8
  643. package/scripts/dev-static.mjs +35 -37
  644. package/scripts/dev-with-automation.mjs +82 -1
  645. package/scripts/ingress.mjs +27 -1
  646. package/scripts/static-server.mjs +74 -1
  647. package/tools/canvas_ui_tool.py +19 -0
  648. package/build/assets/active-backend-context-DKFSMbn3.js +0 -2
  649. package/build/assets/agent-server-conversation-service.api-DozDKIW_.js +0 -86
  650. package/build/assets/agent-settings-351vXWc9.js +0 -2
  651. package/build/assets/agent-settings-Ce7BDZ6I.js +0 -1
  652. package/build/assets/alert-banner-Kyy1YWZU.js +0 -1
  653. package/build/assets/api-key-entry-screen-INIxqAMs.js +0 -1
  654. package/build/assets/automation-detail-DXDhUwPq.js +0 -3
  655. package/build/assets/automation-setup-route-FRr05f_g.js +0 -1
  656. package/build/assets/automations-list-CERuQWE6.js +0 -1
  657. package/build/assets/backend-form-modal-DK78-jn1.js +0 -1
  658. package/build/assets/browser-11etCQ04.js +0 -7
  659. package/build/assets/check-Cf2YoT90.js +0 -1
  660. package/build/assets/chevron-down-C3OQ-ehx.js +0 -1
  661. package/build/assets/chevron-right-CN1uUiJ1.js +0 -1
  662. package/build/assets/circle-check-g5yeGMd-.js +0 -1
  663. package/build/assets/command-menu-BZQ8S3Ke.js +0 -1
  664. package/build/assets/conversation-CchMzpGl.js +0 -1
  665. package/build/assets/conversation-Dpzftz57.js +0 -93
  666. package/build/assets/conversation-panel-CchMzpGl.js +0 -1
  667. package/build/assets/conversation-state-store-a9d2fxRc.js +0 -1
  668. package/build/assets/empty-state-CvaVahVr.js +0 -1
  669. package/build/assets/extensions-hub-CFduxBnk.js +0 -1
  670. package/build/assets/extensions-navigation-BeC224yX.js +0 -1
  671. package/build/assets/files-tab-CL3J9b3p.js +0 -1
  672. package/build/assets/format-model-name-BNPKVsIq.js +0 -1
  673. package/build/assets/get-git-path-DlAJa_i6.js +0 -1
  674. package/build/assets/git-repo-dropdown-DGMEhz7d.js +0 -1
  675. package/build/assets/home-BCGlNJCA.js +0 -1
  676. package/build/assets/home-DB1pRqTC.js +0 -1
  677. package/build/assets/home-automation-run-tooltip-CooFQRIG.js +0 -1
  678. package/build/assets/home-store-Dl1dPE58.js +0 -1
  679. package/build/assets/index-home-DB1pRqTC.js +0 -1
  680. package/build/assets/info-uYSVzX86.js +0 -1
  681. package/build/assets/install-server-modal-BbJdhzet.js +0 -1
  682. package/build/assets/kebab-menu-item-content-BYokkRHi.js +0 -1
  683. package/build/assets/list-filter-OFkpRrmi.js +0 -1
  684. package/build/assets/llm-not-configured-banner-BqqYnJ1t.js +0 -27
  685. package/build/assets/llm-settings-CnDbbmVW.js +0 -1
  686. package/build/assets/llm-settings-S8Yjg__1.js +0 -1
  687. package/build/assets/llm-subscription-service-BpPfzW4x.js +0 -1
  688. package/build/assets/loader-circle-nvrwthvj.js +0 -1
  689. package/build/assets/manage-backends-modal-BCUPswyl.js +0 -1
  690. package/build/assets/manifest-58597dde.js +0 -1
  691. package/build/assets/markdown-renderer-Cb2sBWtV.js +0 -8
  692. package/build/assets/messages-BTN5thLe.js +0 -40
  693. package/build/assets/onboarding-Cx_kaiD1.js +0 -1
  694. package/build/assets/onboarding-modal-vMwn7ihv.js +0 -1
  695. package/build/assets/plugins-management-service-BjYeF0b0.js +0 -1
  696. package/build/assets/plus-CEKne-Yp.js +0 -1
  697. package/build/assets/profiles-service.api-QB-T_u-g.js +0 -1
  698. package/build/assets/providers-FfSZ5TXP.js +0 -1
  699. package/build/assets/proxy-tcFL2yTQ.js +0 -1
  700. package/build/assets/recommended-automations-launcher-Bw8uC4V6.js +0 -1
  701. package/build/assets/root-BLeQfBEq.css +0 -1
  702. package/build/assets/root-ZKKYPR1Z.js +0 -2
  703. package/build/assets/root-layout-luJoE9IG.js +0 -2
  704. package/build/assets/schema-field-Csw5fhtN.js +0 -1
  705. package/build/assets/secrets-service-BTor9uAU.js +0 -1
  706. package/build/assets/settings-DcNPxz0v.js +0 -1
  707. package/build/assets/settings-service.api-B2agVfjL.js +0 -1
  708. package/build/assets/shared-conversation-B55pCyBG.js +0 -1
  709. package/build/assets/sidebar-nav-link-CPzhyHQg.js +0 -1
  710. package/build/assets/sidebar-store-DtpU7zaI.js +0 -1
  711. package/build/assets/skill-filter-CWZ5kjcg.js +0 -2
  712. package/build/assets/skill-scope-CV1dkAbW.js +0 -1
  713. package/build/assets/skills-plugins-DGHULTq6.js +0 -1
  714. package/build/assets/skills-settings-CM1lFv3e.js +0 -1
  715. package/build/assets/usage-tab-BcfWV6db.js +0 -1
  716. package/build/assets/use-acp-credential-form-BsSW5NHG.js +0 -1
  717. package/build/assets/use-agent-profiles-DWBPC0Si.js +0 -1
  718. package/build/assets/use-config-Bft35DOK.js +0 -1
  719. package/build/assets/use-create-secret-BSxJMxHp.js +0 -1
  720. package/build/assets/use-is-authed-CFGkY3-Z.js +0 -1
  721. package/build/assets/use-llm-configured-BI6obxsc.js +0 -1
  722. package/build/assets/use-llm-profiles-djGAhTWL.js +0 -1
  723. package/build/assets/use-manifest-capabilities-3z0-1G59.js +0 -1
  724. package/build/assets/use-onboarding-completion-BXpyUSsJ.js +0 -1
  725. package/build/assets/use-plugins-marketplace-DI4_pK56.js +0 -1
  726. package/build/assets/use-save-agent-profile-DdBSTdpN.js +0 -1
  727. package/build/assets/use-tracking-D5t9otIF.js +0 -3
  728. package/build/assets/utils-DaCIEEQP.js +0 -1
  729. package/build/assets/vendor~index-home~home~conversation-panel~conversation~alert-banner-B3qC_oj8.js +0 -1
  730. package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~mcp~automations-list~aut~ibfbmr9f-B2OLKL7N.js +0 -1
  731. package/dist/components/features/tips/random-tip.d.ts +0 -2
  732. package/dist/utils/tips.d.ts +0 -7
  733. package/dist/utils/workspace-relative-path.cjs +0 -2
  734. package/dist/utils/workspace-relative-path.cjs.map +0 -1
  735. package/dist/utils/workspace-relative-path.d.ts +0 -10
  736. package/dist/utils/workspace-relative-path.js +0 -22
  737. package/dist/utils/workspace-relative-path.js.map +0 -1
  738. /package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ew3u153i-rfV8mQ9m.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ew9ih1s8-rfV8mQ9m.js} +0 -0
  739. /package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ox0jfsa0-cHFhpUBq.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~i58xkef6-cHFhpUBq.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"llm-settings.js","names":[],"sources":["../../src/routes/llm-settings.tsx"],"sourcesContent":["import React from \"react\";\nimport { Info } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModelSelector } from \"#/components/shared/modals/settings/model-selector\";\nimport { useAgentSettingsSchema } from \"#/hooks/query/use-agent-settings-schema\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { SettingsInput } from \"#/components/features/settings/settings-input\";\nimport { SettingsDropdownInput } from \"#/components/features/settings/settings-dropdown-input\";\nimport { OpenAISubscriptionAuthCard } from \"#/components/features/settings/llm-settings/openai-subscription-auth-card\";\nimport { HelpLink } from \"#/ui/help-link\";\nimport { KeyStatusIcon } from \"#/components/features/settings/key-status-icon\";\nimport {\n SdkSectionHeaderProps,\n SdkSectionPage,\n SdkSectionSaveControl,\n} from \"#/components/features/settings/sdk-settings/sdk-section-page\";\nimport { LlmSettingsLocalView } from \"#/components/features/settings/llm-profiles\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { Settings, SettingsSchema, SettingsScope } from \"#/types/settings\";\nimport { extractModelAndProvider } from \"#/utils/extract-model-and-provider\";\nimport {\n inferInitialView,\n type SettingsFormValues,\n type SettingsView,\n} from \"#/utils/sdk-settings-schema\";\nimport { DEFAULT_SETTINGS } from \"#/services/settings\";\nimport {\n LLM_AUTH_TYPE_API_KEY,\n LLM_AUTH_TYPE_KEY,\n LLM_AUTH_TYPE_SUBSCRIPTION,\n LLM_SUBSCRIPTION_VENDOR_KEY,\n OPENAI_SUBSCRIPTION_VENDOR,\n resolveLlmAuthType,\n} from \"#/constants/llm-subscription\";\nimport { useOpenAISubscriptionModels } from \"#/hooks/query/use-llm-subscription-models\";\nimport { useProviderConnections } from \"#/hooks/query/use-provider-connections\";\nimport {\n FREE_OPENHANDS_MODEL_NOTE,\n isFreeOpenHandsModel,\n} from \"#/utils/format-model-name\";\n\n/** Form-values key for the shared provider connection a profile links to. */\nexport const LLM_PROVIDER_CONNECTION_KEY = \"llm.provider_connection_id\";\n\n/** Dropdown sentinel for \"no provider connection\" (an inline key is used). */\nconst NO_PROVIDER_CONNECTION = \"__none__\";\n\nconst LLM_EXCLUDED_KEYS = new Set([\n \"llm.model\",\n \"llm.api_key\",\n \"llm.base_url\",\n LLM_PROVIDER_CONNECTION_KEY,\n LLM_AUTH_TYPE_KEY,\n LLM_SUBSCRIPTION_VENDOR_KEY,\n]);\n\nconst buildModelId = (provider: string | null, model: string | null) => {\n if (!provider || !model) return null;\n return `${provider}/${model}`;\n};\n\nconst getSchemaFieldDefaultValue = (\n schema: SettingsSchema | null | undefined,\n fieldKey: string,\n) =>\n schema?.sections\n .flatMap((section) => section.fields)\n .find((field) => field.key === fieldKey)?.default ?? null;\n\nconst KNOWN_PROVIDER_DEFAULT_BASE_URLS: Partial<Record<string, Set<string>>> = {\n openai: new Set([\"https://api.openai.com\", \"https://api.openai.com/v1\"]),\n moonshot: new Set([\"https://api.kimi.com/coding/v1\"]),\n};\n\nconst normalizeBaseUrl = (baseUrl: string) => {\n try {\n const parsedUrl = new URL(baseUrl);\n const normalizedPath = parsedUrl.pathname.replace(/\\/+$/, \"\") || \"\";\n return `${parsedUrl.origin}${normalizedPath}`;\n } catch {\n return baseUrl.trim().replace(/\\/+$/, \"\");\n }\n};\n\nconst isProviderDefaultBaseUrl = (model: string, baseUrl: string) => {\n const normalizedBaseUrl = normalizeBaseUrl(baseUrl);\n const { provider } = extractModelAndProvider(model);\n\n if (provider) {\n const knownDefaults = KNOWN_PROVIDER_DEFAULT_BASE_URLS[provider];\n if (knownDefaults) {\n return knownDefaults.has(normalizedBaseUrl);\n }\n }\n\n return Object.values(KNOWN_PROVIDER_DEFAULT_BASE_URLS).some((knownDefaults) =>\n knownDefaults?.has(normalizedBaseUrl),\n );\n};\n\ninterface OpenHandsApiKeyHelpProps {\n testId: string;\n}\n\nfunction OpenHandsApiKeyHelp({ testId }: OpenHandsApiKeyHelpProps) {\n const { t } = useTranslation(\"openhands\");\n\n return (\n <HelpLink\n testId={testId}\n text={t(I18nKey.SETTINGS$OPENHANDS_API_KEY_HELP_TEXT)}\n linkText={t(I18nKey.SETTINGS$NAV_API_KEYS)}\n href=\"https://app.all-hands.dev/settings/api-keys\"\n suffix={` ${t(I18nKey.SETTINGS$OPENHANDS_API_KEY_HELP_SUFFIX)}`}\n />\n );\n}\n\nfunction OpenHandsFreeModelsNote() {\n return (\n <p\n data-testid=\"openhands-free-models-note\"\n className=\"flex items-start gap-2 text-xs text-warning\"\n >\n <Info className=\"mt-0.5 size-4 shrink-0 text-warning\" aria-hidden />\n <span>{FREE_OPENHANDS_MODEL_NOTE}</span>\n </p>\n );\n}\n\nexport function LlmSettingsScreen({\n scope = \"personal\",\n onSaveSuccess,\n initialValueOverrides,\n embedded,\n hideSaveButton,\n suppressSuccessToast,\n onSaveControlChange,\n showProviderConnection,\n}: {\n scope?: SettingsScope;\n /** Optional hook fired after a successful save (e.g. advance an onboarding step). */\n onSaveSuccess?: () => void;\n /** Forwarded to {@link SdkSectionPage}. */\n initialValueOverrides?: SettingsFormValues;\n /** Forwarded to {@link SdkSectionPage}. */\n embedded?: boolean;\n /** Forwarded to {@link SdkSectionPage}. */\n hideSaveButton?: boolean;\n /** Forwarded to {@link SdkSectionPage}. */\n suppressSuccessToast?: boolean;\n /** Forwarded to {@link SdkSectionPage}. */\n onSaveControlChange?: (control: SdkSectionSaveControl) => void;\n /**\n * When true (the local profile editor), show a \"Provider connection\" selector\n * that links this profile to a shared connection. Only rendered when at least\n * one connection exists, so the form is unchanged until the user creates one.\n */\n showProviderConnection?: boolean;\n}) {\n const { t } = useTranslation(\"openhands\");\n\n const { data: providerConnections } = useProviderConnections();\n const connectionOptions = React.useMemo(\n () => (showProviderConnection ? (providerConnections ?? []) : []),\n [showProviderConnection, providerConnections],\n );\n\n const { data: settings } = useSettings(scope);\n const { data: schema } = useAgentSettingsSchema(\n settings?.agent_settings_schema,\n );\n const persistedLlmSettings = settings?.agent_settings?.llm as\n | Record<string, unknown>\n | undefined;\n const initialAuthType = resolveLlmAuthType(\n initialValueOverrides?.[LLM_AUTH_TYPE_KEY] ??\n persistedLlmSettings?.auth_type,\n );\n const [enableSubscriptionModels, setEnableSubscriptionModels] =\n React.useState(initialAuthType === LLM_AUTH_TYPE_SUBSCRIPTION);\n const {\n data: subscriptionModels,\n isLoading: isSubscriptionModelsLoading,\n isFetching: isSubscriptionModelsFetching,\n } = useOpenAISubscriptionModels({ enabled: enableSubscriptionModels });\n const isWaitingForSubscriptionModels =\n enableSubscriptionModels &&\n !subscriptionModels &&\n (isSubscriptionModelsLoading || isSubscriptionModelsFetching);\n const lastApiKeyModelRef = React.useRef<string | null>(null);\n const lastSubscriptionModelRef = React.useRef<string | null>(null);\n\n React.useEffect(() => {\n if (initialAuthType === LLM_AUTH_TYPE_SUBSCRIPTION) {\n setEnableSubscriptionModels(true);\n }\n }, [initialAuthType]);\n\n const defaultModel = String(\n (DEFAULT_SETTINGS.agent_settings?.llm as Record<string, unknown>)?.model ??\n \"\",\n );\n\n const getInitialView = React.useCallback(\n (\n currentSettings: Settings,\n filteredSchema: SettingsSchema,\n ): SettingsView => {\n const schemaView = inferInitialView(currentSettings, filteredSchema);\n if (schemaView !== \"basic\") {\n return schemaView;\n }\n\n const currentModel = currentSettings.llm_model ?? \"\";\n const trimmedBaseUrl = currentSettings.llm_base_url?.trim() ?? \"\";\n const hasCustomBaseUrl =\n trimmedBaseUrl.length > 0 &&\n !isProviderDefaultBaseUrl(currentModel, trimmedBaseUrl);\n\n return hasCustomBaseUrl ? \"all\" : \"basic\";\n },\n [],\n );\n\n const buildHeader = React.useCallback(\n ({ values, isDisabled, view, onChange }: SdkSectionHeaderProps) => {\n const modelValue =\n typeof values[\"llm.model\"] === \"string\" ? values[\"llm.model\"] : \"\";\n const baseUrlValue =\n typeof values[\"llm.base_url\"] === \"string\"\n ? values[\"llm.base_url\"]\n : \"\";\n const showOpenHandsApiKeyHelp = modelValue.startsWith(\"openhands/\");\n const authType = resolveLlmAuthType(values[LLM_AUTH_TYPE_KEY]);\n const isSubscriptionAuth = authType === LLM_AUTH_TYPE_SUBSCRIPTION;\n const shouldDisableSubscriptionControls =\n isDisabled || (isSubscriptionAuth && isWaitingForSubscriptionModels);\n const subscriptionModelValue = subscriptionModels?.includes(modelValue)\n ? modelValue\n : (subscriptionModels?.[0] ?? \"\");\n\n const apiKeyValue =\n typeof values[\"llm.api_key\"] === \"string\" ? values[\"llm.api_key\"] : \"\";\n // For embedded profile forms (create/edit) the global\n // `llm_api_key_set` flag is misleading: a brand-new profile would show a\n // \"key set\" indicator just because some other profile has a key. Reflect\n // the form's own key state instead so create mode starts visibly unset.\n const apiKeyIsSet = embedded\n ? apiKeyValue.length > 0\n : Boolean(settings?.llm_api_key_set);\n\n // A profile linked to a provider connection reads its api_key / base_url\n // from that connection, so the inline key + base URL inputs are hidden.\n const connectionValue =\n typeof values[LLM_PROVIDER_CONNECTION_KEY] === \"string\"\n ? values[LLM_PROVIDER_CONNECTION_KEY]\n : \"\";\n const isLinkedToConnection = Boolean(connectionValue);\n // Show the selector whenever connections can be linked here. Include the\n // linked case so a profile pointing at an orphaned connection (its only\n // connection deleted, or the list still loading) still exposes a control\n // to unlink — otherwise the API key / base URL inputs stay hidden with no\n // way to recover.\n const showConnectionSelector =\n showProviderConnection &&\n !isSubscriptionAuth &&\n (isLinkedToConnection || connectionOptions.length > 0);\n // Surface an orphaned link (a selected id absent from the fetched list)\n // as its own option so the dropdown reflects it and can be cleared.\n const isOrphanedLink =\n isLinkedToConnection &&\n !connectionOptions.some((c) => c.id === connectionValue);\n\n const renderConnectionSelector = () => (\n <SettingsDropdownInput\n testId=\"llm-provider-connection-input\"\n name={LLM_PROVIDER_CONNECTION_KEY}\n label={t(I18nKey.SETTINGS$PROVIDER_CONNECTION_SELECT_LABEL)}\n items={[\n {\n key: NO_PROVIDER_CONNECTION,\n label: t(I18nKey.SETTINGS$MCP_AUTH_MODE_NONE),\n },\n ...connectionOptions.map((connection) => ({\n key: connection.id,\n label: connection.display_name,\n })),\n ...(isOrphanedLink\n ? [{ key: connectionValue, label: connectionValue }]\n : []),\n ]}\n selectedKey={connectionValue || NO_PROVIDER_CONNECTION}\n isClearable={false}\n isDisabled={isDisabled}\n onSelectionChange={(selectedKey) => {\n const next =\n typeof selectedKey === \"string\" &&\n selectedKey !== NO_PROVIDER_CONNECTION\n ? selectedKey\n : \"\";\n onChange(LLM_PROVIDER_CONNECTION_KEY, next);\n }}\n />\n );\n\n const renderApiKeyInput = (testId: string, helpTestId: string) => (\n <>\n <SettingsInput\n testId={testId}\n label={t(I18nKey.SETTINGS_FORM$API_KEY)}\n type=\"password\"\n className=\"w-full\"\n value={apiKeyValue}\n // eslint-disable-next-line i18next/no-literal-string -- masked-key sentinel, not translatable\n placeholder={apiKeyIsSet ? \"<hidden>\" : \"\"}\n onChange={(value) => onChange(\"llm.api_key\", value)}\n isDisabled={isDisabled}\n startContent={\n apiKeyIsSet ? <KeyStatusIcon isSet={apiKeyIsSet} /> : undefined\n }\n />\n\n <HelpLink\n testId={helpTestId}\n text={t(I18nKey.SETTINGS$DONT_KNOW_API_KEY)}\n linkText={t(I18nKey.SETTINGS$CLICK_FOR_INSTRUCTIONS)}\n href=\"https://docs.openhands.dev/usage/local-setup#getting-an-api-key\"\n />\n </>\n );\n\n const handleAuthTypeChange = (selectedKey: React.Key | null) => {\n const nextAuthType =\n selectedKey === LLM_AUTH_TYPE_SUBSCRIPTION\n ? LLM_AUTH_TYPE_SUBSCRIPTION\n : LLM_AUTH_TYPE_API_KEY;\n onChange(LLM_AUTH_TYPE_KEY, nextAuthType);\n\n if (nextAuthType === LLM_AUTH_TYPE_SUBSCRIPTION) {\n setEnableSubscriptionModels(true);\n if (modelValue && !subscriptionModels?.includes(modelValue)) {\n lastApiKeyModelRef.current = modelValue;\n }\n const restoredSubscriptionModel =\n lastSubscriptionModelRef.current &&\n subscriptionModels?.includes(lastSubscriptionModelRef.current)\n ? lastSubscriptionModelRef.current\n : subscriptionModels?.[0];\n onChange(LLM_SUBSCRIPTION_VENDOR_KEY, OPENAI_SUBSCRIPTION_VENDOR);\n if (\n !subscriptionModels?.includes(modelValue) &&\n restoredSubscriptionModel\n ) {\n onChange(\"llm.model\", restoredSubscriptionModel);\n }\n return;\n }\n\n if (modelValue && subscriptionModels?.includes(modelValue)) {\n lastSubscriptionModelRef.current = modelValue;\n onChange(\"llm.model\", lastApiKeyModelRef.current ?? defaultModel);\n }\n };\n\n const renderAuthTypeInput = () => (\n <SettingsDropdownInput\n testId=\"llm-auth-type-input\"\n name={LLM_AUTH_TYPE_KEY}\n label={t(I18nKey.SETTINGS$LLM_AUTH_TYPE)}\n items={[\n {\n key: LLM_AUTH_TYPE_API_KEY,\n label: t(I18nKey.SETTINGS$LLM_AUTH_TYPE_API_KEY),\n },\n {\n key: LLM_AUTH_TYPE_SUBSCRIPTION,\n label: t(I18nKey.SETTINGS$LLM_AUTH_TYPE_SUBSCRIPTION),\n },\n ]}\n selectedKey={authType}\n isClearable={false}\n required\n isDisabled={shouldDisableSubscriptionControls}\n onSelectionChange={handleAuthTypeChange}\n />\n );\n\n const renderSubscriptionSettings = () => (\n <div\n className=\"flex flex-col gap-6\"\n data-testid=\"llm-subscription-settings\"\n >\n <SettingsDropdownInput\n testId=\"llm-subscription-model-input\"\n name=\"llm.subscription_model\"\n label={t(I18nKey.SETTINGS$SUBSCRIPTION_MODEL)}\n items={(subscriptionModels ?? []).map((model) => ({\n key: model,\n label: model,\n }))}\n selectedKey={subscriptionModelValue}\n isClearable={false}\n required\n isDisabled={\n shouldDisableSubscriptionControls || !subscriptionModels?.length\n }\n onSelectionChange={(selectedKey) => {\n const nextModel =\n typeof selectedKey === \"string\"\n ? selectedKey\n : subscriptionModels?.[0];\n if (nextModel) {\n onChange(\"llm.model\", nextModel);\n }\n }}\n />\n <OpenAISubscriptionAuthCard isDisabled={isDisabled} />\n </div>\n );\n\n return (\n <div className=\"flex flex-col gap-6\">\n {view === \"basic\" ? (\n <div\n className=\"flex flex-col gap-6\"\n data-testid=\"llm-settings-form-basic\"\n >\n {renderAuthTypeInput()}\n\n {isSubscriptionAuth ? (\n renderSubscriptionSettings()\n ) : (\n <>\n <ModelSelector\n currentModel={modelValue || undefined}\n onChange={(provider, model) => {\n const nextModel = buildModelId(provider, model);\n if (nextModel) {\n onChange(\"llm.model\", nextModel);\n }\n }}\n wrapperClassName=\"!flex-col !gap-6\"\n isDisabled={isDisabled}\n />\n\n {showConnectionSelector ? renderConnectionSelector() : null}\n\n {showOpenHandsApiKeyHelp && !isLinkedToConnection ? (\n <OpenHandsApiKeyHelp testId=\"openhands-api-key-help\" />\n ) : null}\n\n {isLinkedToConnection\n ? null\n : renderApiKeyInput(\n // eslint-disable-next-line i18next/no-literal-string -- DOM id, not user-facing\n \"llm-api-key-input\",\n // eslint-disable-next-line i18next/no-literal-string -- DOM id, not user-facing\n \"llm-api-key-help-anchor\",\n )}\n </>\n )}\n </div>\n ) : (\n <div\n className=\"flex flex-col gap-6\"\n data-testid=\"llm-settings-form-advanced\"\n >\n {renderAuthTypeInput()}\n\n {isSubscriptionAuth ? (\n renderSubscriptionSettings()\n ) : (\n <>\n <SettingsInput\n testId=\"llm-custom-model-input\"\n label={t(I18nKey.SETTINGS$CUSTOM_MODEL)}\n type=\"text\"\n className=\"w-full\"\n value={modelValue}\n placeholder={defaultModel}\n onChange={(value) => onChange(\"llm.model\", value)}\n isDisabled={isDisabled}\n />\n\n {showOpenHandsApiKeyHelp && !isLinkedToConnection ? (\n <>\n {isFreeOpenHandsModel(modelValue) ? (\n <OpenHandsFreeModelsNote />\n ) : null}\n <OpenHandsApiKeyHelp testId=\"openhands-api-key-help-2\" />\n </>\n ) : null}\n\n {showConnectionSelector ? renderConnectionSelector() : null}\n\n {isLinkedToConnection ? null : (\n <SettingsInput\n testId=\"base-url-input\"\n label={t(I18nKey.SETTINGS$BASE_URL)}\n type=\"text\"\n className=\"w-full\"\n value={baseUrlValue}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"https://api.openai.com\"\n onChange={(value) => onChange(\"llm.base_url\", value)}\n isDisabled={isDisabled}\n />\n )}\n\n {isLinkedToConnection\n ? null\n : renderApiKeyInput(\n // eslint-disable-next-line i18next/no-literal-string -- DOM id, not user-facing\n \"llm-api-key-input\",\n // eslint-disable-next-line i18next/no-literal-string -- DOM id, not user-facing\n \"llm-api-key-help-anchor-advanced\",\n )}\n </>\n )}\n </div>\n )}\n </div>\n );\n },\n [\n connectionOptions,\n showProviderConnection,\n defaultModel,\n embedded,\n isWaitingForSubscriptionModels,\n settings?.llm_api_key_set,\n subscriptionModels,\n t,\n ],\n );\n\n const buildPayload = React.useCallback(\n (\n defaultPayload: Record<string, unknown>,\n context: {\n values: Record<string, string | boolean>;\n dirty: Record<string, boolean>;\n view: SettingsView;\n },\n ) => {\n // defaultPayload is the wrapped diff (e.g.\n // `{ agent_settings_diff: { llm: { model: \"gpt-4\" } } }`); we only\n // mutate the inner `llm` object below.\n const agentSettings = structuredClone(\n (defaultPayload.agent_settings_diff as Record<string, unknown>) ?? {},\n );\n const llm = (agentSettings.llm ?? {}) as Record<string, unknown>;\n const authType = resolveLlmAuthType(context.values[LLM_AUTH_TYPE_KEY]);\n\n if (authType === LLM_AUTH_TYPE_SUBSCRIPTION) {\n llm.auth_type = LLM_AUTH_TYPE_SUBSCRIPTION;\n llm.subscription_vendor = OPENAI_SUBSCRIPTION_VENDOR;\n const model =\n typeof llm.model === \"string\"\n ? llm.model\n : String(context.values[\"llm.model\"] ?? \"\");\n const fallbackSubscriptionModel = subscriptionModels?.[0];\n if (\n !subscriptionModels?.includes(model) &&\n !fallbackSubscriptionModel\n ) {\n throw new Error(\"Subscription models are not loaded yet.\");\n }\n llm.model = subscriptionModels?.includes(model)\n ? model\n : fallbackSubscriptionModel;\n delete llm.api_key;\n delete llm.base_url;\n } else {\n if (context.dirty[LLM_AUTH_TYPE_KEY]) {\n llm.auth_type = LLM_AUTH_TYPE_API_KEY;\n llm.subscription_vendor = null;\n }\n if (context.view === \"basic\" && llm.model !== undefined) {\n llm.base_url = getSchemaFieldDefaultValue(schema, \"llm.base_url\");\n }\n }\n\n agentSettings.llm = llm;\n return { agent_settings_diff: agentSettings };\n },\n [schema, subscriptionModels],\n );\n\n return (\n <SdkSectionPage\n scope={scope}\n settingsSources={[\n {\n settingsSource: \"agent_settings\",\n sectionKeys: [\"llm\"],\n excludeKeys: LLM_EXCLUDED_KEYS,\n },\n ]}\n header={buildHeader}\n buildPayload={buildPayload}\n getInitialView={getInitialView}\n forceShowAdvancedView\n allowAllView\n onSaveSuccess={onSaveSuccess}\n initialValueOverrides={initialValueOverrides}\n embedded={embedded}\n hideSaveButton={hideSaveButton}\n suppressSuccessToast={suppressSuccessToast}\n onSaveControlChange={onSaveControlChange}\n testId=\"llm-settings-screen\"\n />\n );\n}\n\n/**\n * Default export for the route renders the LLM-profile management view for both\n * backend types. Both manage the LLM through named profiles — local via the\n * agent-server (`/api/profiles`), cloud via the app-server\n * (`/api/v1/settings/profiles`) — and the view is backend-agnostic because it\n * goes through ProfilesService, which routes per active backend.\n *\n * The LlmSettingsScreen component is also exported for embedded use cases\n * (e.g., onboarding, the profile create/edit form).\n *\n * Note: This is a route file, only the router should import the default export.\n * Other consumers should use the named export `LlmSettingsScreen` for embedded\n * use cases.\n */\nexport default function LlmSettingsRoute() {\n return <LlmSettingsLocalView />;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA0CA,IAAa,IAA8B,8BAGrC,IAAyB,YAEzB,IAAoB,IAAI,IAAI;CAChC;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,GAEK,KAAgB,GAAyB,MACzC,CAAC,KAAY,CAAC,IAAc,OACzB,GAAG,EAAS,GAAG,KAGlB,KACJ,GACA,MAEA,GAAQ,SACL,SAAS,MAAY,EAAQ,MAAM,EACnC,MAAM,MAAU,EAAM,QAAQ,CAAQ,GAAG,WAAW,MAEnD,IAAyE;CAC7E,QAAQ,IAAI,IAAI,CAAC,0BAA0B,2BAA2B,CAAC;CACvE,UAAU,IAAI,IAAI,CAAC,gCAAgC,CAAC;AACtD,GAEM,KAAoB,MAAoB;CAC5C,IAAI;EACF,IAAM,IAAY,IAAI,IAAI,CAAO,GAC3B,IAAiB,EAAU,SAAS,QAAQ,QAAQ,EAAE,KAAK;EACjE,OAAO,GAAG,EAAU,SAAS;CAC/B,QAAQ;EACN,OAAO,EAAQ,KAAK,EAAE,QAAQ,QAAQ,EAAE;CAC1C;AACF,GAEM,KAA4B,GAAe,MAAoB;CACnE,IAAM,IAAoB,EAAiB,CAAO,GAC5C,EAAE,gBAAa,EAAwB,CAAK;CAElD,IAAI,GAAU;EACZ,IAAM,IAAgB,EAAiC;EACvD,IAAI,GACF,OAAO,EAAc,IAAI,CAAiB;CAE9C;CAEA,OAAO,OAAO,OAAO,CAAgC,EAAE,MAAM,MAC3D,GAAe,IAAI,CAAiB,CACtC;AACF;AAMA,SAAS,EAAoB,EAAE,aAAoC;CACjE,IAAM,EAAE,SAAM,EAAe,WAAW;CAExC,OACE,kBAAC,GAAD;EACU;EACR,MAAM,EAAE,EAAQ,oCAAoC;EACpD,UAAU,EAAE,EAAQ,qBAAqB;EACzC,MAAK;EACL,QAAQ,IAAI,EAAE,EAAQ,sCAAsC;CAC7D,CAAA;AAEL;AAEA,SAAS,IAA0B;CACjC,OACE,kBAAC,KAAD;EACE,eAAY;EACZ,WAAU;YAFZ,CAIE,kBAAC,GAAD;GAAM,WAAU;GAAsC,eAAA;EAAa,CAAA,GACnE,kBAAC,QAAD,EAAA,UAAO,EAAgC,CAAA,CACtC;;AAEP;AAEA,SAAgB,EAAkB,EAChC,WAAQ,YACR,kBACA,0BACA,aACA,mBACA,yBACA,wBACA,6BAqBC;CACD,IAAM,EAAE,SAAM,EAAe,WAAW,GAElC,EAAE,MAAM,MAAwB,EAAuB,GACvD,IAAoB,EAAM,cACvB,IAA0B,KAAuB,CAAC,IAAK,CAAC,GAC/D,CAAC,GAAwB,CAAmB,CAC9C,GAEM,EAAE,MAAM,MAAa,EAAY,CAAK,GACtC,EAAE,MAAM,MAAW,EACvB,GAAU,qBACZ,GACM,IAAuB,GAAU,gBAAgB,KAGjD,IAAkB,EACtB,IAAA,oBACE,GAAsB,SAC1B,GACM,CAAC,GAA0B,KAC/B,EAAM,SAAS,MAAoB,CAA0B,GACzD,EACJ,MAAM,GACN,WAAW,IACX,YAAY,OACV,EAA4B,EAAE,SAAS,EAAyB,CAAC,GAC/D,IACJ,KACA,CAAC,MACA,MAA+B,KAC5B,IAAqB,EAAM,OAAsB,IAAI,GACrD,IAA2B,EAAM,OAAsB,IAAI;CAEjE,EAAM,gBAAgB;EACpB,AAAI,MAAA,kBACF,EAA4B,EAAI;CAEpC,GAAG,CAAC,CAAe,CAAC;CAEpB,IAAM,IAAe,OAClB,EAAiB,gBAAgB,KAAiC,SACjE,EACJ,GAEM,KAAiB,EAAM,aAEzB,GACA,MACiB;EACjB,IAAM,IAAa,EAAiB,GAAiB,CAAc;EACnE,IAAI,MAAe,SACjB,OAAO;EAGT,IAAM,IAAe,EAAgB,aAAa,IAC5C,IAAiB,EAAgB,cAAc,KAAK,KAAK;EAK/D,OAHE,EAAe,SAAS,KACxB,CAAC,EAAyB,GAAc,CAAc,IAE9B,QAAQ;CACpC,GACA,CAAC,CACH,GAEM,KAAc,EAAM,aACvB,EAAE,WAAQ,eAAY,SAAM,kBAAsC;EACjE,IAAM,IACJ,OAAO,EAAO,gBAAiB,WAAW,EAAO,eAAe,IAC5D,IACJ,OAAO,EAAO,mBAAoB,WAC9B,EAAO,kBACP,IACA,IAA0B,EAAW,WAAW,YAAY,GAC5D,IAAW,EAAmB,EAAO,EAAkB,GACvD,IAAqB,MAAa,GAClC,IACJ,KAAe,KAAsB,GACjC,IAAyB,GAAoB,SAAS,CAAU,IAClE,IACC,IAAqB,MAAM,IAE1B,IACJ,OAAO,EAAO,kBAAmB,WAAW,EAAO,iBAAiB,IAKhE,IAAc,IAChB,EAAY,SAAS,IACrB,EAAQ,GAAU,iBAIhB,IACJ,OAAO,EAAA,iCAAwC,WAC3C,EAAO,KACP,IACA,IAAuB,EAAQ,GAM/B,IACJ,KACA,CAAC,MACA,KAAwB,EAAkB,SAAS,IAGhD,IACJ,KACA,CAAC,EAAkB,MAAM,MAAM,EAAE,OAAO,CAAe,GAEnD,UACJ,kBAAC,GAAD;GACE,QAAO;GACP,MAAM;GACN,OAAO,EAAE,EAAQ,yCAAyC;GAC1D,OAAO;IACL;KACE,KAAK;KACL,OAAO,EAAE,EAAQ,2BAA2B;IAC9C;IACA,GAAG,EAAkB,KAAK,OAAgB;KACxC,KAAK,EAAW;KAChB,OAAO,EAAW;IACpB,EAAE;IACF,GAAI,IACA,CAAC;KAAE,KAAK;KAAiB,OAAO;IAAgB,CAAC,IACjD,CAAC;GACP;GACA,aAAa,KAAmB;GAChC,aAAa;GACD;GACZ,oBAAoB,MAAgB;IAMlC,EAAS,GAJP,OAAO,KAAgB,YACvB,MAAgB,IACZ,IACA,EACoC;GAC5C;EACD,CAAA,GAGG,KAAqB,GAAgB,MACzC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;GACU;GACR,OAAO,EAAE,EAAQ,qBAAqB;GACtC,MAAK;GACL,WAAU;GACV,OAAO;GAEP,aAAa,IAAc,aAAa;GACxC,WAAW,MAAU,EAAS,eAAe,CAAK;GACtC;GACZ,cACE,IAAc,kBAAC,GAAD,EAAe,OAAO,EAAc,CAAA,IAAI,KAAA;EAEzD,CAAA,GAED,kBAAC,GAAD;GACE,QAAQ;GACR,MAAM,EAAE,EAAQ,0BAA0B;GAC1C,UAAU,EAAE,EAAQ,+BAA+B;GACnD,MAAK;EACN,CAAA,CACD,EAAA,CAAA,GAGE,KAAwB,MAAkC;GAC9D,IAAM,IACJ,MAAA,iBACI,IACA;GAGN,IAFA,EAAS,GAAmB,CAAY,GAEpC,MAAA,gBAA6C;IAE/C,AADA,EAA4B,EAAI,GAC5B,KAAc,CAAC,GAAoB,SAAS,CAAU,MACxD,EAAmB,UAAU;IAE/B,IAAM,IACJ,EAAyB,WACzB,GAAoB,SAAS,EAAyB,OAAO,IACzD,EAAyB,UACzB,IAAqB;IAE3B,AADA,EAAS,GAA6B,CAA0B,GAE9D,CAAC,GAAoB,SAAS,CAAU,KACxC,KAEA,EAAS,aAAa,CAAyB;IAEjD;GACF;GAEA,AAAI,KAAc,GAAoB,SAAS,CAAU,MACvD,EAAyB,UAAU,GACnC,EAAS,aAAa,EAAmB,WAAW,CAAY;EAEpE,GAEM,UACJ,kBAAC,GAAD;GACE,QAAO;GACP,MAAM;GACN,OAAO,EAAE,EAAQ,sBAAsB;GACvC,OAAO,CACL;IACE,KAAK;IACL,OAAO,EAAE,EAAQ,8BAA8B;GACjD,GACA;IACE,KAAK;IACL,OAAO,EAAE,EAAQ,mCAAmC;GACtD,CACF;GACA,aAAa;GACb,aAAa;GACb,UAAA;GACA,YAAY;GACZ,mBAAmB;EACpB,CAAA,GAGG,UACJ,kBAAC,OAAD;GACE,WAAU;GACV,eAAY;aAFd,CAIE,kBAAC,GAAD;IACE,QAAO;IACP,MAAK;IACL,OAAO,EAAE,EAAQ,2BAA2B;IAC5C,QAAQ,KAAsB,CAAC,GAAG,KAAK,OAAW;KAChD,KAAK;KACL,OAAO;IACT,EAAE;IACF,aAAa;IACb,aAAa;IACb,UAAA;IACA,YACE,KAAqC,CAAC,GAAoB;IAE5D,oBAAoB,MAAgB;KAClC,IAAM,IACJ,OAAO,KAAgB,WACnB,IACA,IAAqB;KAC3B,AAAI,KACF,EAAS,aAAa,CAAS;IAEnC;GACD,CAAA,GACD,kBAAC,GAAD,EAAwC,cAAa,CAAA,CAClD;;EAGP,OACE,kBAAC,OAAD;GAAK,WAAU;aACZ,MAAS,UACR,kBAAC,OAAD;IACE,WAAU;IACV,eAAY;cAFd,CAIG,EAAoB,GAEpB,IACC,EAA2B,IAE3B,kBAAA,GAAA,EAAA,UAAA;KACE,kBAAC,IAAD;MACE,cAAc,KAAc,KAAA;MAC5B,WAAW,GAAU,MAAU;OAC7B,IAAM,IAAY,EAAa,GAAU,CAAK;OAC9C,AAAI,KACF,EAAS,aAAa,CAAS;MAEnC;MACA,kBAAiB;MACL;KACb,CAAA;KAEA,IAAyB,EAAyB,IAAI;KAEtD,KAA2B,CAAC,IAC3B,kBAAC,GAAD,EAAqB,QAAO,yBAA0B,CAAA,IACpD;KAEH,IACG,OACA,EAEE,qBAEA,yBACF;IACJ,EAAA,CAAA,CAED;QAEL,kBAAC,OAAD;IACE,WAAU;IACV,eAAY;cAFd,CAIG,EAAoB,GAEpB,IACC,EAA2B,IAE3B,kBAAA,GAAA,EAAA,UAAA;KACE,kBAAC,GAAD;MACE,QAAO;MACP,OAAO,EAAE,EAAQ,qBAAqB;MACtC,MAAK;MACL,WAAU;MACV,OAAO;MACP,aAAa;MACb,WAAW,MAAU,EAAS,aAAa,CAAK;MACpC;KACb,CAAA;KAEA,KAA2B,CAAC,IAC3B,kBAAA,GAAA,EAAA,UAAA,CACG,GAAqB,CAAU,IAC9B,kBAAC,GAAD,CAA0B,CAAA,IACxB,MACJ,kBAAC,GAAD,EAAqB,QAAO,2BAA4B,CAAA,CACxD,EAAA,CAAA,IACA;KAEH,IAAyB,EAAyB,IAAI;KAEtD,IAAuB,OACtB,kBAAC,GAAD;MACE,QAAO;MACP,OAAO,EAAE,EAAQ,iBAAiB;MAClC,MAAK;MACL,WAAU;MACV,OAAO;MAEP,aAAY;MACZ,WAAW,MAAU,EAAS,gBAAgB,CAAK;MACvC;KACb,CAAA;KAGF,IACG,OACA,EAEE,qBAEA,kCACF;IACJ,EAAA,CAAA,CAED;;EAEJ,CAAA;CAET,GACA;EACE;EACA;EACA;EACA;EACA;EACA,GAAU;EACV;EACA;CACF,CACF,GAEM,KAAe,EAAM,aAEvB,GACA,MAKG;EAIH,IAAM,IAAgB,gBACnB,EAAe,uBAAmD,CAAC,CACtE,GACM,IAAO,EAAc,OAAO,CAAC;EAGnC,IAFiB,EAAmB,EAAQ,OAAA,gBAExC,MAAA,gBAAyC;GAE3C,AADA,EAAI,YAAY,GAChB,EAAI,sBAAsB;GAC1B,IAAM,IACJ,OAAO,EAAI,SAAU,WACjB,EAAI,QACJ,OAAO,EAAQ,OAAO,gBAAgB,EAAE,GACxC,IAA4B,IAAqB;GACvD,IACE,CAAC,GAAoB,SAAS,CAAK,KACnC,CAAC,GAED,MAAU,MAAM,yCAAyC;GAM3D,AAJA,EAAI,QAAQ,GAAoB,SAAS,CAAK,IAC1C,IACA,GACJ,OAAO,EAAI,SACX,OAAO,EAAI;EACb,OAKE,AAJI,EAAQ,MAAA,qBACV,EAAI,YAAY,GAChB,EAAI,sBAAsB,OAExB,EAAQ,SAAS,WAAW,EAAI,UAAU,KAAA,MAC5C,EAAI,WAAW,EAA2B,GAAQ,cAAc;EAKpE,OADA,EAAc,MAAM,GACb,EAAE,qBAAqB,EAAc;CAC9C,GACA,CAAC,GAAQ,CAAkB,CAC7B;CAEA,OACE,kBAAC,GAAD;EACS;EACP,iBAAiB,CACf;GACE,gBAAgB;GAChB,aAAa,CAAC,KAAK;GACnB,aAAa;EACf,CACF;EACA,QAAQ;EACM;EACE;EAChB,uBAAA;EACA,cAAA;EACe;EACQ;EACb;EACM;EACM;EACD;EACrB,QAAO;CACR,CAAA;AAEL"}
1
+ {"version":3,"file":"llm-settings.js","names":[],"sources":["../../src/routes/llm-settings.tsx"],"sourcesContent":["import React from \"react\";\nimport { Info } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModelSelector } from \"#/components/shared/modals/settings/model-selector\";\nimport { useAgentSettingsSchema } from \"#/hooks/query/use-agent-settings-schema\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { SettingsInput } from \"#/components/features/settings/settings-input\";\nimport { SettingsDropdownInput } from \"#/components/features/settings/settings-dropdown-input\";\nimport { OpenAISubscriptionAuthCard } from \"#/components/features/settings/llm-settings/openai-subscription-auth-card\";\nimport { HelpLink } from \"#/ui/help-link\";\nimport { KeyStatusIcon } from \"#/components/features/settings/key-status-icon\";\nimport {\n SdkSectionHeaderProps,\n SdkSectionPage,\n SdkSectionSaveControl,\n} from \"#/components/features/settings/sdk-settings/sdk-section-page\";\nimport { LlmSettingsLocalView } from \"#/components/features/settings/llm-profiles\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { Settings, SettingsSchema, SettingsScope } from \"#/types/settings\";\nimport { extractModelAndProvider } from \"#/utils/extract-model-and-provider\";\nimport {\n inferInitialView,\n type SettingsFormValues,\n type SettingsView,\n} from \"#/utils/sdk-settings-schema\";\nimport { DEFAULT_SETTINGS } from \"#/services/settings\";\nimport {\n LLM_AUTH_TYPE_API_KEY,\n LLM_AUTH_TYPE_KEY,\n LLM_AUTH_TYPE_SUBSCRIPTION,\n LLM_SUBSCRIPTION_VENDOR_KEY,\n OPENAI_SUBSCRIPTION_VENDOR,\n resolveLlmAuthType,\n} from \"#/constants/llm-subscription\";\nimport { useOpenAISubscriptionModels } from \"#/hooks/query/use-llm-subscription-models\";\nimport { useProviderConnections } from \"#/hooks/query/use-provider-connections\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport {\n FREE_OPENHANDS_MODEL_NOTE,\n isFreeOpenHandsModel,\n isOpenHandsProviderModel,\n} from \"#/utils/format-model-name\";\n\n/** Form-values key for the shared provider connection a profile links to. */\nexport const LLM_PROVIDER_CONNECTION_KEY = \"llm.provider_connection_id\";\n\n/** Dropdown sentinel for \"no provider connection\" (an inline key is used). */\nconst NO_PROVIDER_CONNECTION = \"__none__\";\n\nconst LLM_EXCLUDED_KEYS = new Set([\n \"llm.model\",\n \"llm.api_key\",\n \"llm.base_url\",\n LLM_PROVIDER_CONNECTION_KEY,\n LLM_AUTH_TYPE_KEY,\n LLM_SUBSCRIPTION_VENDOR_KEY,\n]);\n\nconst buildModelId = (provider: string | null, model: string | null) => {\n if (!provider || !model) return null;\n return `${provider}/${model}`;\n};\n\nconst getSchemaFieldDefaultValue = (\n schema: SettingsSchema | null | undefined,\n fieldKey: string,\n) =>\n schema?.sections\n .flatMap((section) => section.fields)\n .find((field) => field.key === fieldKey)?.default ?? null;\n\nconst KNOWN_PROVIDER_DEFAULT_BASE_URLS: Partial<Record<string, Set<string>>> = {\n openai: new Set([\"https://api.openai.com\", \"https://api.openai.com/v1\"]),\n moonshot: new Set([\"https://api.kimi.com/coding/v1\"]),\n};\n\nconst normalizeBaseUrl = (baseUrl: string) => {\n try {\n const parsedUrl = new URL(baseUrl);\n const normalizedPath = parsedUrl.pathname.replace(/\\/+$/, \"\") || \"\";\n return `${parsedUrl.origin}${normalizedPath}`;\n } catch {\n return baseUrl.trim().replace(/\\/+$/, \"\");\n }\n};\n\nconst isProviderDefaultBaseUrl = (model: string, baseUrl: string) => {\n const normalizedBaseUrl = normalizeBaseUrl(baseUrl);\n const { provider } = extractModelAndProvider(model);\n\n if (provider) {\n const knownDefaults = KNOWN_PROVIDER_DEFAULT_BASE_URLS[provider];\n if (knownDefaults) {\n return knownDefaults.has(normalizedBaseUrl);\n }\n }\n\n return Object.values(KNOWN_PROVIDER_DEFAULT_BASE_URLS).some((knownDefaults) =>\n knownDefaults?.has(normalizedBaseUrl),\n );\n};\n\ninterface OpenHandsApiKeyHelpProps {\n testId: string;\n}\n\nfunction OpenHandsApiKeyHelp({ testId }: OpenHandsApiKeyHelpProps) {\n const { t } = useTranslation(\"openhands\");\n\n return (\n <HelpLink\n testId={testId}\n text={t(I18nKey.SETTINGS$OPENHANDS_API_KEY_HELP_TEXT)}\n linkText={t(I18nKey.SETTINGS$OPENHANDS_API_KEY_HELP_LINK)}\n href=\"https://app.all-hands.dev/settings/api-keys\"\n suffix={` ${t(I18nKey.SETTINGS$OPENHANDS_API_KEY_HELP_SUFFIX)}`}\n suffixLinkText={t(I18nKey.SETTINGS$SEE_HERE_FOR_MORE_DETAILS)}\n suffixLinkHref=\"https://docs.openhands.dev/usage/local-setup#getting-an-api-key\"\n trailing=\".\"\n />\n );\n}\n\nfunction OpenHandsFreeModelsNote() {\n return (\n <p\n data-testid=\"openhands-free-models-note\"\n className=\"flex items-start gap-2 text-xs text-warning\"\n >\n <Info className=\"mt-0.5 size-4 shrink-0 text-warning\" aria-hidden />\n <span>{FREE_OPENHANDS_MODEL_NOTE}</span>\n </p>\n );\n}\n\nexport function LlmSettingsScreen({\n scope = \"personal\",\n onSaveSuccess,\n initialValueOverrides,\n embedded,\n hideSaveButton,\n suppressSuccessToast,\n onSaveControlChange,\n showProviderConnection,\n}: {\n scope?: SettingsScope;\n /** Optional hook fired after a successful save (e.g. advance an onboarding step). */\n onSaveSuccess?: () => void;\n /** Forwarded to {@link SdkSectionPage}. */\n initialValueOverrides?: SettingsFormValues;\n /** Forwarded to {@link SdkSectionPage}. */\n embedded?: boolean;\n /** Forwarded to {@link SdkSectionPage}. */\n hideSaveButton?: boolean;\n /** Forwarded to {@link SdkSectionPage}. */\n suppressSuccessToast?: boolean;\n /** Forwarded to {@link SdkSectionPage}. */\n onSaveControlChange?: (control: SdkSectionSaveControl) => void;\n /**\n * When true (the local profile editor), show a \"Provider connection\" selector\n * that links this profile to a shared connection. Only rendered when at least\n * one connection exists, so the form is unchanged until the user creates one.\n */\n showProviderConnection?: boolean;\n}) {\n const { t } = useTranslation(\"openhands\");\n\n const { backend } = useActiveBackend();\n const isCloud = backend.kind === \"cloud\";\n\n const { data: providerConnections } = useProviderConnections();\n const connectionOptions = React.useMemo(\n () => (showProviderConnection ? (providerConnections ?? []) : []),\n [showProviderConnection, providerConnections],\n );\n\n const { data: settings } = useSettings(scope);\n const { data: schema } = useAgentSettingsSchema(\n settings?.agent_settings_schema,\n );\n const persistedLlmSettings = settings?.agent_settings?.llm as\n | Record<string, unknown>\n | undefined;\n const initialAuthType = resolveLlmAuthType(\n initialValueOverrides?.[LLM_AUTH_TYPE_KEY] ??\n persistedLlmSettings?.auth_type,\n );\n const [enableSubscriptionModels, setEnableSubscriptionModels] =\n React.useState(initialAuthType === LLM_AUTH_TYPE_SUBSCRIPTION);\n const {\n data: subscriptionModels,\n isLoading: isSubscriptionModelsLoading,\n isFetching: isSubscriptionModelsFetching,\n } = useOpenAISubscriptionModels({ enabled: enableSubscriptionModels });\n const isWaitingForSubscriptionModels =\n enableSubscriptionModels &&\n !subscriptionModels &&\n (isSubscriptionModelsLoading || isSubscriptionModelsFetching);\n const lastApiKeyModelRef = React.useRef<string | null>(null);\n const lastSubscriptionModelRef = React.useRef<string | null>(null);\n\n React.useEffect(() => {\n if (initialAuthType === LLM_AUTH_TYPE_SUBSCRIPTION) {\n setEnableSubscriptionModels(true);\n }\n }, [initialAuthType]);\n\n const defaultModel = String(\n (DEFAULT_SETTINGS.agent_settings?.llm as Record<string, unknown>)?.model ??\n \"\",\n );\n\n const getInitialView = React.useCallback(\n (\n currentSettings: Settings,\n filteredSchema: SettingsSchema,\n ): SettingsView => {\n const schemaView = inferInitialView(currentSettings, filteredSchema);\n if (schemaView !== \"basic\") {\n return schemaView;\n }\n\n const currentModel = currentSettings.llm_model ?? \"\";\n const trimmedBaseUrl = currentSettings.llm_base_url?.trim() ?? \"\";\n const hasCustomBaseUrl =\n trimmedBaseUrl.length > 0 &&\n !isProviderDefaultBaseUrl(currentModel, trimmedBaseUrl);\n\n return hasCustomBaseUrl ? \"all\" : \"basic\";\n },\n [],\n );\n\n const buildHeader = React.useCallback(\n ({ values, isDisabled, view, onChange }: SdkSectionHeaderProps) => {\n const modelValue =\n typeof values[\"llm.model\"] === \"string\" ? values[\"llm.model\"] : \"\";\n const baseUrlValue =\n typeof values[\"llm.base_url\"] === \"string\"\n ? values[\"llm.base_url\"]\n : \"\";\n const showOpenHandsApiKeyHelp = isOpenHandsProviderModel(modelValue);\n const authType = resolveLlmAuthType(values[LLM_AUTH_TYPE_KEY]);\n const isSubscriptionAuth = authType === LLM_AUTH_TYPE_SUBSCRIPTION;\n // On cloud the OpenHands provider is backed by a server-minted LLM key,\n // so the inline API key / base URL inputs are not user-supplied. Local\n // mode still collects an api_key (the OpenHands provider can run against\n // a self-hosted endpoint there).\n const hideInlineCredentials =\n isCloud && showOpenHandsApiKeyHelp && !isSubscriptionAuth;\n const shouldDisableSubscriptionControls =\n isDisabled || (isSubscriptionAuth && isWaitingForSubscriptionModels);\n const subscriptionModelValue = subscriptionModels?.includes(modelValue)\n ? modelValue\n : (subscriptionModels?.[0] ?? \"\");\n\n const apiKeyValue =\n typeof values[\"llm.api_key\"] === \"string\" ? values[\"llm.api_key\"] : \"\";\n // For embedded profile forms (create/edit) the global\n // `llm_api_key_set` flag is misleading: a brand-new profile would show a\n // \"key set\" indicator just because some other profile has a key. Reflect\n // the form's own key state instead so create mode starts visibly unset.\n const apiKeyIsSet = embedded\n ? apiKeyValue.length > 0\n : Boolean(settings?.llm_api_key_set);\n\n // A profile linked to a provider connection reads its api_key / base_url\n // from that connection, so the inline key + base URL inputs are hidden.\n const connectionValue =\n typeof values[LLM_PROVIDER_CONNECTION_KEY] === \"string\"\n ? values[LLM_PROVIDER_CONNECTION_KEY]\n : \"\";\n const isLinkedToConnection = Boolean(connectionValue);\n // Show the selector whenever connections can be linked here. Include the\n // linked case so a profile pointing at an orphaned connection (its only\n // connection deleted, or the list still loading) still exposes a control\n // to unlink — otherwise the API key / base URL inputs stay hidden with no\n // way to recover.\n const showConnectionSelector =\n showProviderConnection &&\n !isSubscriptionAuth &&\n (isLinkedToConnection || connectionOptions.length > 0);\n // Surface an orphaned link (a selected id absent from the fetched list)\n // as its own option so the dropdown reflects it and can be cleared.\n const isOrphanedLink =\n isLinkedToConnection &&\n !connectionOptions.some((c) => c.id === connectionValue);\n\n const renderConnectionSelector = () => (\n <SettingsDropdownInput\n testId=\"llm-provider-connection-input\"\n name={LLM_PROVIDER_CONNECTION_KEY}\n label={t(I18nKey.SETTINGS$PROVIDER_CONNECTION_SELECT_LABEL)}\n items={[\n {\n key: NO_PROVIDER_CONNECTION,\n label: t(I18nKey.SETTINGS$MCP_AUTH_MODE_NONE),\n },\n ...connectionOptions.map((connection) => ({\n key: connection.id,\n label: connection.display_name,\n })),\n ...(isOrphanedLink\n ? [{ key: connectionValue, label: connectionValue }]\n : []),\n ]}\n selectedKey={connectionValue || NO_PROVIDER_CONNECTION}\n isClearable={false}\n isDisabled={isDisabled}\n onSelectionChange={(selectedKey) => {\n const next =\n typeof selectedKey === \"string\" &&\n selectedKey !== NO_PROVIDER_CONNECTION\n ? selectedKey\n : \"\";\n onChange(LLM_PROVIDER_CONNECTION_KEY, next);\n }}\n />\n );\n\n const renderApiKeyInput = (\n testId: string,\n helpTestId: string,\n openHandsHelpTestId: string,\n ) => (\n <>\n <SettingsInput\n testId={testId}\n label={t(I18nKey.SETTINGS_FORM$API_KEY)}\n type=\"password\"\n className=\"w-full\"\n value={apiKeyValue}\n // eslint-disable-next-line i18next/no-literal-string -- masked-key sentinel, not translatable\n placeholder={apiKeyIsSet ? \"<hidden>\" : \"\"}\n onChange={(value) => onChange(\"llm.api_key\", value)}\n isDisabled={isDisabled}\n startContent={\n apiKeyIsSet ? <KeyStatusIcon isSet={apiKeyIsSet} /> : undefined\n }\n />\n\n {/* The OpenHands provider's key lives in the OpenHands Cloud \"API\n Keys\" tab, so point users there instead of the generic docs page\n that covers both LLM and regular API keys. */}\n {showOpenHandsApiKeyHelp ? (\n <OpenHandsApiKeyHelp testId={openHandsHelpTestId} />\n ) : (\n <HelpLink\n testId={helpTestId}\n text={t(I18nKey.SETTINGS$DONT_KNOW_API_KEY)}\n linkText={t(I18nKey.SETTINGS$CLICK_FOR_INSTRUCTIONS)}\n href=\"https://docs.openhands.dev/usage/local-setup#getting-an-api-key\"\n />\n )}\n </>\n );\n\n const handleAuthTypeChange = (selectedKey: React.Key | null) => {\n const nextAuthType =\n selectedKey === LLM_AUTH_TYPE_SUBSCRIPTION\n ? LLM_AUTH_TYPE_SUBSCRIPTION\n : LLM_AUTH_TYPE_API_KEY;\n onChange(LLM_AUTH_TYPE_KEY, nextAuthType);\n\n if (nextAuthType === LLM_AUTH_TYPE_SUBSCRIPTION) {\n setEnableSubscriptionModels(true);\n if (modelValue && !subscriptionModels?.includes(modelValue)) {\n lastApiKeyModelRef.current = modelValue;\n }\n const restoredSubscriptionModel =\n lastSubscriptionModelRef.current &&\n subscriptionModels?.includes(lastSubscriptionModelRef.current)\n ? lastSubscriptionModelRef.current\n : subscriptionModels?.[0];\n onChange(LLM_SUBSCRIPTION_VENDOR_KEY, OPENAI_SUBSCRIPTION_VENDOR);\n if (\n !subscriptionModels?.includes(modelValue) &&\n restoredSubscriptionModel\n ) {\n onChange(\"llm.model\", restoredSubscriptionModel);\n }\n return;\n }\n\n if (modelValue && subscriptionModels?.includes(modelValue)) {\n lastSubscriptionModelRef.current = modelValue;\n onChange(\"llm.model\", lastApiKeyModelRef.current ?? defaultModel);\n }\n };\n\n const renderAuthTypeInput = () => (\n <SettingsDropdownInput\n testId=\"llm-auth-type-input\"\n name={LLM_AUTH_TYPE_KEY}\n label={t(I18nKey.SETTINGS$LLM_AUTH_TYPE)}\n items={[\n {\n key: LLM_AUTH_TYPE_API_KEY,\n label: t(I18nKey.SETTINGS$LLM_AUTH_TYPE_API_KEY),\n },\n {\n key: LLM_AUTH_TYPE_SUBSCRIPTION,\n label: t(I18nKey.SETTINGS$LLM_AUTH_TYPE_SUBSCRIPTION),\n },\n ]}\n selectedKey={authType}\n isClearable={false}\n required\n isDisabled={shouldDisableSubscriptionControls}\n onSelectionChange={handleAuthTypeChange}\n />\n );\n\n const renderSubscriptionSettings = () => (\n <div\n className=\"flex flex-col gap-6\"\n data-testid=\"llm-subscription-settings\"\n >\n <SettingsDropdownInput\n testId=\"llm-subscription-model-input\"\n name=\"llm.subscription_model\"\n label={t(I18nKey.SETTINGS$SUBSCRIPTION_MODEL)}\n items={(subscriptionModels ?? []).map((model) => ({\n key: model,\n label: model,\n }))}\n selectedKey={subscriptionModelValue}\n isClearable={false}\n required\n isDisabled={\n shouldDisableSubscriptionControls || !subscriptionModels?.length\n }\n onSelectionChange={(selectedKey) => {\n const nextModel =\n typeof selectedKey === \"string\"\n ? selectedKey\n : subscriptionModels?.[0];\n if (nextModel) {\n onChange(\"llm.model\", nextModel);\n }\n }}\n />\n <OpenAISubscriptionAuthCard isDisabled={isDisabled} />\n </div>\n );\n\n return (\n <div className=\"flex flex-col gap-6\">\n {view === \"basic\" ? (\n <div\n className=\"flex flex-col gap-6\"\n data-testid=\"llm-settings-form-basic\"\n >\n {renderAuthTypeInput()}\n\n {isSubscriptionAuth ? (\n renderSubscriptionSettings()\n ) : (\n <>\n <ModelSelector\n currentModel={modelValue || undefined}\n onChange={(provider, model) => {\n const nextModel = buildModelId(provider, model);\n if (nextModel) {\n onChange(\"llm.model\", nextModel);\n }\n }}\n wrapperClassName=\"!flex-col !gap-6\"\n isDisabled={isDisabled}\n />\n\n {showConnectionSelector ? renderConnectionSelector() : null}\n\n {isLinkedToConnection || hideInlineCredentials\n ? null\n : renderApiKeyInput(\n // eslint-disable-next-line i18next/no-literal-string -- DOM id, not user-facing\n \"llm-api-key-input\",\n // eslint-disable-next-line i18next/no-literal-string -- DOM id, not user-facing\n \"llm-api-key-help-anchor\",\n // eslint-disable-next-line i18next/no-literal-string -- DOM id, not user-facing\n \"openhands-api-key-help\",\n )}\n </>\n )}\n </div>\n ) : (\n <div\n className=\"flex flex-col gap-6\"\n data-testid=\"llm-settings-form-advanced\"\n >\n {renderAuthTypeInput()}\n\n {isSubscriptionAuth ? (\n renderSubscriptionSettings()\n ) : (\n <>\n <SettingsInput\n testId=\"llm-custom-model-input\"\n label={t(I18nKey.SETTINGS$CUSTOM_MODEL)}\n type=\"text\"\n className=\"w-full\"\n value={modelValue}\n placeholder={defaultModel}\n onChange={(value) => onChange(\"llm.model\", value)}\n isDisabled={isDisabled}\n />\n\n {showOpenHandsApiKeyHelp && !isLinkedToConnection ? (\n <>\n {isFreeOpenHandsModel(modelValue) ? (\n <OpenHandsFreeModelsNote />\n ) : null}\n </>\n ) : null}\n\n {showConnectionSelector ? renderConnectionSelector() : null}\n\n {isLinkedToConnection || hideInlineCredentials ? null : (\n <SettingsInput\n testId=\"base-url-input\"\n label={t(I18nKey.SETTINGS$BASE_URL)}\n type=\"text\"\n className=\"w-full\"\n value={baseUrlValue}\n // eslint-disable-next-line i18next/no-literal-string -- example value, not translatable\n placeholder=\"https://api.openai.com\"\n onChange={(value) => onChange(\"llm.base_url\", value)}\n isDisabled={isDisabled}\n />\n )}\n\n {isLinkedToConnection || hideInlineCredentials\n ? null\n : renderApiKeyInput(\n // eslint-disable-next-line i18next/no-literal-string -- DOM id, not user-facing\n \"llm-api-key-input\",\n // eslint-disable-next-line i18next/no-literal-string -- DOM id, not user-facing\n \"llm-api-key-help-anchor-advanced\",\n // eslint-disable-next-line i18next/no-literal-string -- DOM id, not user-facing\n \"openhands-api-key-help-2\",\n )}\n </>\n )}\n </div>\n )}\n </div>\n );\n },\n [\n connectionOptions,\n showProviderConnection,\n defaultModel,\n embedded,\n isCloud,\n isWaitingForSubscriptionModels,\n settings?.llm_api_key_set,\n subscriptionModels,\n t,\n ],\n );\n\n const buildPayload = React.useCallback(\n (\n defaultPayload: Record<string, unknown>,\n context: {\n values: Record<string, string | boolean>;\n dirty: Record<string, boolean>;\n view: SettingsView;\n },\n ) => {\n // defaultPayload is the wrapped diff (e.g.\n // `{ agent_settings_diff: { llm: { model: \"gpt-4\" } } }`); we only\n // mutate the inner `llm` object below.\n const agentSettings = structuredClone(\n (defaultPayload.agent_settings_diff as Record<string, unknown>) ?? {},\n );\n const llm = (agentSettings.llm ?? {}) as Record<string, unknown>;\n const authType = resolveLlmAuthType(context.values[LLM_AUTH_TYPE_KEY]);\n\n if (authType === LLM_AUTH_TYPE_SUBSCRIPTION) {\n llm.auth_type = LLM_AUTH_TYPE_SUBSCRIPTION;\n llm.subscription_vendor = OPENAI_SUBSCRIPTION_VENDOR;\n const model =\n typeof llm.model === \"string\"\n ? llm.model\n : String(context.values[\"llm.model\"] ?? \"\");\n const fallbackSubscriptionModel = subscriptionModels?.[0];\n if (\n !subscriptionModels?.includes(model) &&\n !fallbackSubscriptionModel\n ) {\n throw new Error(\"Subscription models are not loaded yet.\");\n }\n llm.model = subscriptionModels?.includes(model)\n ? model\n : fallbackSubscriptionModel;\n delete llm.api_key;\n delete llm.base_url;\n } else {\n if (context.dirty[LLM_AUTH_TYPE_KEY]) {\n llm.auth_type = LLM_AUTH_TYPE_API_KEY;\n llm.subscription_vendor = null;\n }\n if (context.view === \"basic\" && llm.model !== undefined) {\n llm.base_url = getSchemaFieldDefaultValue(schema, \"llm.base_url\");\n }\n // On cloud the OpenHands provider uses a server-minted LLM key, so\n // never send an inline api_key / base_url — let the backend attach its\n // own credential. (Local mode still collects an inline key.)\n if (\n isCloud &&\n isOpenHandsProviderModel(String(context.values[\"llm.model\"] ?? \"\"))\n ) {\n delete llm.api_key;\n delete llm.base_url;\n }\n }\n\n agentSettings.llm = llm;\n return { agent_settings_diff: agentSettings };\n },\n [schema, subscriptionModels, isCloud],\n );\n\n return (\n <SdkSectionPage\n scope={scope}\n settingsSources={[\n {\n settingsSource: \"agent_settings\",\n sectionKeys: [\"llm\"],\n excludeKeys: LLM_EXCLUDED_KEYS,\n },\n ]}\n header={buildHeader}\n buildPayload={buildPayload}\n getInitialView={getInitialView}\n forceShowAdvancedView\n allowAllView\n onSaveSuccess={onSaveSuccess}\n initialValueOverrides={initialValueOverrides}\n embedded={embedded}\n hideSaveButton={hideSaveButton}\n suppressSuccessToast={suppressSuccessToast}\n onSaveControlChange={onSaveControlChange}\n testId=\"llm-settings-screen\"\n />\n );\n}\n\n/**\n * Default export for the route renders the LLM-profile management view for both\n * backend types. Both manage the LLM through named profiles — local via the\n * agent-server (`/api/profiles`), cloud via the app-server\n * (`/api/v1/settings/profiles`) — and the view is backend-agnostic because it\n * goes through ProfilesService, which routes per active backend.\n *\n * The LlmSettingsScreen component is also exported for embedded use cases\n * (e.g., onboarding, the profile create/edit form).\n *\n * Note: This is a route file, only the router should import the default export.\n * Other consumers should use the named export `LlmSettingsScreen` for embedded\n * use cases.\n */\nexport default function LlmSettingsRoute() {\n return <LlmSettingsLocalView />;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- require("../_virtual/_rolldown/runtime.cjs");const e=require("../stores/conversation-store.cjs"),t=require("../stores/files-tab-store.cjs");var n=new Set([`files`,`browser`,`terminal`,`planner`,`tasklist`]);function r(t){let n=e.useConversationStore.getState();n.setSelectedTab(t),n.isRightPanelShown||(n.setHasRightPanelToggled(!0),n.setIsRightPanelShown(!0))}function i(e){return n.has(e)}function a(e,n=null){switch(e.command){case`navigate_to_file`:case`show_preview`:r(`files`),e.path&&t.useFilesTabStore.getState().setSelectedPath(e.path,n);return;case`open_tab`:e.tab===`vscode`?r(`files`):e.tab&&i(e.tab)?r(e.tab):e.tab&&console.warn(`[canvas_ui] Ignoring open_tab with unknown tab: ${e.tab}`);return}}exports.handleCanvasUIAction=a;
1
+ require("../_virtual/_rolldown/runtime.cjs");const e=require("../stores/conversation-store.cjs"),t=require("../api/conversation-service/conversation-service.api.cjs"),n=require("../stores/files-tab-store.cjs"),r=require("../utils/path-utils.cjs");var i=new Set([`files`,`browser`,`terminal`,`planner`,`tasklist`]);function a(t){let n=e.useConversationStore.getState();n.setSelectedTab(t),n.isRightPanelShown||(n.setHasRightPanelToggled(!0),n.setIsRightPanelShown(!0))}function o(e){return i.has(e)}function s(e,n){let r=t.default.getCurrentConversation();c({kind:`CanvasUIAction`,command:`navigate_to_file`,path:e},n??r?.id??null)}function c(e,i=null){switch(e.command){case`navigate_to_file`:case`show_preview`:{if(a(`files`),!e.path)return;let o=t.default.getCurrentConversation()?.workspace?.working_dir,s=r.toFilesTabPath(e.path,o);if(!s)return;n.useFilesTabStore.getState().setSelectedPath(s,i);return}case`open_tab`:e.tab===`vscode`?a(`files`):e.tab&&o(e.tab)?a(e.tab):e.tab&&console.warn(`[canvas_ui] Ignoring open_tab with unknown tab: ${e.tab}`);return}}exports.handleCanvasUIAction=c,exports.openWorkspaceFile=s;
2
2
  //# sourceMappingURL=canvas-ui.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"canvas-ui.cjs","names":[],"sources":["../../src/services/canvas-ui.ts"],"sourcesContent":["import {\n ConversationTab,\n useConversationStore,\n} from \"#/stores/conversation-store\";\nimport { useFilesTabStore } from \"#/stores/files-tab-store\";\nimport type { CanvasUIAction } from \"#/types/agent-server/core\";\n\nconst VALID_TABS: ReadonlySet<ConversationTab> = new Set<ConversationTab>([\n \"files\",\n \"browser\",\n \"terminal\",\n \"planner\",\n \"tasklist\",\n]);\n\n// Mirrors src/hooks/use-select-conversation-tab.ts so a non-React caller (the\n// WebSocket dispatch) gets the same \"reveal the right panel if collapsed\"\n// behavior as in-app tab switches.\nfunction navigateToTab(tab: ConversationTab) {\n const store = useConversationStore.getState();\n store.setSelectedTab(tab);\n if (!store.isRightPanelShown) {\n store.setHasRightPanelToggled(true);\n store.setIsRightPanelShown(true);\n }\n}\n\nfunction isValidTab(value: string): value is ConversationTab {\n return VALID_TABS.has(value as ConversationTab);\n}\n\nexport function handleCanvasUIAction(\n action: CanvasUIAction,\n conversationId: string | null = null,\n): void {\n switch (action.command) {\n case \"navigate_to_file\":\n case \"show_preview\":\n navigateToTab(\"files\");\n if (action.path) {\n useFilesTabStore\n .getState()\n .setSelectedPath(action.path, conversationId);\n }\n return;\n case \"open_tab\":\n if (action.tab === \"vscode\") {\n // The in-app VS Code tab was removed — on cloud backends VS Code\n // now opens in a new browser window via the link in the drawer tab\n // row. Route agent requests to Files so the drawer still opens.\n navigateToTab(\"files\");\n } else if (action.tab && isValidTab(action.tab)) {\n navigateToTab(action.tab);\n } else if (action.tab) {\n // Surface unknown tab names so they're diagnosable from the browser\n // console rather than failing silently. Valid tabs are listed in\n // VALID_TABS above and mirror ConversationTab.\n console.warn(\n `[canvas_ui] Ignoring open_tab with unknown tab: ${action.tab}`,\n );\n }\n return;\n }\n}\n"],"mappings":"4IAOA,IAAM,EAA2C,IAAI,IAAqB,CACxE,QACA,UACA,WACA,UACA,UACF,CAAC,EAKD,SAAS,EAAc,EAAsB,CAC3C,IAAM,EAAQ,EAAA,qBAAqB,SAAS,EAC5C,EAAM,eAAe,CAAG,EACnB,EAAM,oBACT,EAAM,wBAAwB,EAAI,EAClC,EAAM,qBAAqB,EAAI,EAEnC,CAEA,SAAS,EAAW,EAAyC,CAC3D,OAAO,EAAW,IAAI,CAAwB,CAChD,CAEA,SAAgB,EACd,EACA,EAAgC,KAC1B,CACN,OAAQ,EAAO,QAAf,CACE,IAAK,mBACL,IAAK,eACH,EAAc,OAAO,EACjB,EAAO,MACT,EAAA,iBACG,SAAS,EACT,gBAAgB,EAAO,KAAM,CAAc,EAEhD,OACF,IAAK,WACC,EAAO,MAAQ,SAIjB,EAAc,OAAO,EACZ,EAAO,KAAO,EAAW,EAAO,GAAG,EAC5C,EAAc,EAAO,GAAG,EACf,EAAO,KAIhB,QAAQ,KACN,mDAAmD,EAAO,KAC5D,EAEF,MACJ,CACF"}
1
+ {"version":3,"file":"canvas-ui.cjs","names":[],"sources":["../../src/services/canvas-ui.ts"],"sourcesContent":["import ConversationService from \"#/api/conversation-service/conversation-service.api\";\nimport {\n ConversationTab,\n useConversationStore,\n} from \"#/stores/conversation-store\";\nimport { useFilesTabStore } from \"#/stores/files-tab-store\";\nimport type { CanvasUIAction } from \"#/types/agent-server/core\";\nimport { toFilesTabPath } from \"#/utils/path-utils\";\n\nconst VALID_TABS: ReadonlySet<ConversationTab> = new Set<ConversationTab>([\n \"files\",\n \"browser\",\n \"terminal\",\n \"planner\",\n \"tasklist\",\n]);\n\n// Mirrors src/hooks/use-select-conversation-tab.ts so a non-React caller (the\n// WebSocket dispatch) gets the same \"reveal the right panel if collapsed\"\n// behavior as in-app tab switches.\nfunction navigateToTab(tab: ConversationTab) {\n const store = useConversationStore.getState();\n store.setSelectedTab(tab);\n if (!store.isRightPanelShown) {\n store.setHasRightPanelToggled(true);\n store.setIsRightPanelShown(true);\n }\n}\n\nfunction isValidTab(value: string): value is ConversationTab {\n return VALID_TABS.has(value as ConversationTab);\n}\n\n/**\n * Chat path click → same as agent `navigate_to_file`.\n * Optional `conversationId` tags the selection so FilesTab accepts it.\n */\nexport function openWorkspaceFile(\n path: string,\n conversationId?: string | null,\n): void {\n const conversation = ConversationService.getCurrentConversation();\n handleCanvasUIAction(\n {\n kind: \"CanvasUIAction\",\n command: \"navigate_to_file\",\n path,\n } as CanvasUIAction,\n conversationId ?? conversation?.id ?? null,\n );\n}\n\nexport function handleCanvasUIAction(\n action: CanvasUIAction,\n conversationId: string | null = null,\n): void {\n switch (action.command) {\n case \"navigate_to_file\":\n case \"show_preview\": {\n navigateToTab(\"files\");\n if (!action.path) return;\n\n const workingDir =\n ConversationService.getCurrentConversation()?.workspace?.working_dir;\n const path = toFilesTabPath(action.path, workingDir);\n if (!path) return;\n\n useFilesTabStore.getState().setSelectedPath(path, conversationId);\n return;\n }\n case \"open_tab\":\n if (action.tab === \"vscode\") {\n // The in-app VS Code tab was removed — on cloud backends VS Code\n // now opens in a new browser window via the link in the drawer tab\n // row. Route agent requests to Files so the drawer still opens.\n navigateToTab(\"files\");\n } else if (action.tab && isValidTab(action.tab)) {\n navigateToTab(action.tab);\n } else if (action.tab) {\n // Surface unknown tab names so they're diagnosable from the browser\n // console rather than failing silently. Valid tabs are listed in\n // VALID_TABS above and mirror ConversationTab.\n console.warn(\n `[canvas_ui] Ignoring open_tab with unknown tab: ${action.tab}`,\n );\n }\n return;\n }\n}\n"],"mappings":"uPASA,IAAM,EAA2C,IAAI,IAAqB,CACxE,QACA,UACA,WACA,UACA,UACF,CAAC,EAKD,SAAS,EAAc,EAAsB,CAC3C,IAAM,EAAQ,EAAA,qBAAqB,SAAS,EAC5C,EAAM,eAAe,CAAG,EACnB,EAAM,oBACT,EAAM,wBAAwB,EAAI,EAClC,EAAM,qBAAqB,EAAI,EAEnC,CAEA,SAAS,EAAW,EAAyC,CAC3D,OAAO,EAAW,IAAI,CAAwB,CAChD,CAMA,SAAgB,EACd,EACA,EACM,CACN,IAAM,EAAe,EAAA,QAAoB,uBAAuB,EAChE,EACE,CACE,KAAM,iBACN,QAAS,mBACT,MACF,EACA,GAAkB,GAAc,IAAM,IACxC,CACF,CAEA,SAAgB,EACd,EACA,EAAgC,KAC1B,CACN,OAAQ,EAAO,QAAf,CACE,IAAK,mBACL,IAAK,eAAgB,CAEnB,GADA,EAAc,OAAO,EACjB,CAAC,EAAO,KAAM,OAElB,IAAM,EACJ,EAAA,QAAoB,uBAAuB,GAAG,WAAW,YACrD,EAAO,EAAA,eAAe,EAAO,KAAM,CAAU,EACnD,GAAI,CAAC,EAAM,OAEX,EAAA,iBAAiB,SAAS,EAAE,gBAAgB,EAAM,CAAc,EAChE,MACF,CACA,IAAK,WACC,EAAO,MAAQ,SAIjB,EAAc,OAAO,EACZ,EAAO,KAAO,EAAW,EAAO,GAAG,EAC5C,EAAc,EAAO,GAAG,EACf,EAAO,KAIhB,QAAQ,KACN,mDAAmD,EAAO,KAC5D,EAEF,MACJ,CACF"}
@@ -1,2 +1,7 @@
1
1
  import type { CanvasUIAction } from "#/types/agent-server/core";
2
+ /**
3
+ * Chat path click → same as agent `navigate_to_file`.
4
+ * Optional `conversationId` tags the selection so FilesTab accepts it.
5
+ */
6
+ export declare function openWorkspaceFile(path: string, conversationId?: string | null): void;
2
7
  export declare function handleCanvasUIAction(action: CanvasUIAction, conversationId?: string | null): void;
@@ -1,32 +1,46 @@
1
1
  import { useConversationStore as e } from "../stores/conversation-store.js";
2
- import { useFilesTabStore as t } from "../stores/files-tab-store.js";
2
+ import t from "../api/conversation-service/conversation-service.api.js";
3
+ import { useFilesTabStore as n } from "../stores/files-tab-store.js";
4
+ import { toFilesTabPath as r } from "../utils/path-utils.js";
3
5
  //#region src/services/canvas-ui.ts
4
- var n = new Set([
6
+ var i = new Set([
5
7
  "files",
6
8
  "browser",
7
9
  "terminal",
8
10
  "planner",
9
11
  "tasklist"
10
12
  ]);
11
- function r(t) {
13
+ function a(t) {
12
14
  let n = e.getState();
13
15
  n.setSelectedTab(t), n.isRightPanelShown || (n.setHasRightPanelToggled(!0), n.setIsRightPanelShown(!0));
14
16
  }
15
- function i(e) {
16
- return n.has(e);
17
+ function o(e) {
18
+ return i.has(e);
17
19
  }
18
- function a(e, n = null) {
20
+ function s(e, n) {
21
+ let r = t.getCurrentConversation();
22
+ c({
23
+ kind: "CanvasUIAction",
24
+ command: "navigate_to_file",
25
+ path: e
26
+ }, n ?? r?.id ?? null);
27
+ }
28
+ function c(e, i = null) {
19
29
  switch (e.command) {
20
30
  case "navigate_to_file":
21
- case "show_preview":
22
- r("files"), e.path && t.getState().setSelectedPath(e.path, n);
31
+ case "show_preview": {
32
+ if (a("files"), !e.path) return;
33
+ let o = t.getCurrentConversation()?.workspace?.working_dir, s = r(e.path, o);
34
+ if (!s) return;
35
+ n.getState().setSelectedPath(s, i);
23
36
  return;
37
+ }
24
38
  case "open_tab":
25
- e.tab === "vscode" ? r("files") : e.tab && i(e.tab) ? r(e.tab) : e.tab && console.warn(`[canvas_ui] Ignoring open_tab with unknown tab: ${e.tab}`);
39
+ e.tab === "vscode" ? a("files") : e.tab && o(e.tab) ? a(e.tab) : e.tab && console.warn(`[canvas_ui] Ignoring open_tab with unknown tab: ${e.tab}`);
26
40
  return;
27
41
  }
28
42
  }
29
43
  //#endregion
30
- export { a as handleCanvasUIAction };
44
+ export { c as handleCanvasUIAction, s as openWorkspaceFile };
31
45
 
32
46
  //# sourceMappingURL=canvas-ui.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"canvas-ui.js","names":[],"sources":["../../src/services/canvas-ui.ts"],"sourcesContent":["import {\n ConversationTab,\n useConversationStore,\n} from \"#/stores/conversation-store\";\nimport { useFilesTabStore } from \"#/stores/files-tab-store\";\nimport type { CanvasUIAction } from \"#/types/agent-server/core\";\n\nconst VALID_TABS: ReadonlySet<ConversationTab> = new Set<ConversationTab>([\n \"files\",\n \"browser\",\n \"terminal\",\n \"planner\",\n \"tasklist\",\n]);\n\n// Mirrors src/hooks/use-select-conversation-tab.ts so a non-React caller (the\n// WebSocket dispatch) gets the same \"reveal the right panel if collapsed\"\n// behavior as in-app tab switches.\nfunction navigateToTab(tab: ConversationTab) {\n const store = useConversationStore.getState();\n store.setSelectedTab(tab);\n if (!store.isRightPanelShown) {\n store.setHasRightPanelToggled(true);\n store.setIsRightPanelShown(true);\n }\n}\n\nfunction isValidTab(value: string): value is ConversationTab {\n return VALID_TABS.has(value as ConversationTab);\n}\n\nexport function handleCanvasUIAction(\n action: CanvasUIAction,\n conversationId: string | null = null,\n): void {\n switch (action.command) {\n case \"navigate_to_file\":\n case \"show_preview\":\n navigateToTab(\"files\");\n if (action.path) {\n useFilesTabStore\n .getState()\n .setSelectedPath(action.path, conversationId);\n }\n return;\n case \"open_tab\":\n if (action.tab === \"vscode\") {\n // The in-app VS Code tab was removed — on cloud backends VS Code\n // now opens in a new browser window via the link in the drawer tab\n // row. Route agent requests to Files so the drawer still opens.\n navigateToTab(\"files\");\n } else if (action.tab && isValidTab(action.tab)) {\n navigateToTab(action.tab);\n } else if (action.tab) {\n // Surface unknown tab names so they're diagnosable from the browser\n // console rather than failing silently. Valid tabs are listed in\n // VALID_TABS above and mirror ConversationTab.\n console.warn(\n `[canvas_ui] Ignoring open_tab with unknown tab: ${action.tab}`,\n );\n }\n return;\n }\n}\n"],"mappings":";;;AAOA,IAAM,IAA2C,IAAI,IAAqB;CACxE;CACA;CACA;CACA;CACA;AACF,CAAC;AAKD,SAAS,EAAc,GAAsB;CAC3C,IAAM,IAAQ,EAAqB,SAAS;CAE5C,AADA,EAAM,eAAe,CAAG,GACnB,EAAM,sBACT,EAAM,wBAAwB,EAAI,GAClC,EAAM,qBAAqB,EAAI;AAEnC;AAEA,SAAS,EAAW,GAAyC;CAC3D,OAAO,EAAW,IAAI,CAAwB;AAChD;AAEA,SAAgB,EACd,GACA,IAAgC,MAC1B;CACN,QAAQ,EAAO,SAAf;EACE,KAAK;EACL,KAAK;GAEH,AADA,EAAc,OAAO,GACjB,EAAO,QACT,EACG,SAAS,EACT,gBAAgB,EAAO,MAAM,CAAc;GAEhD;EACF,KAAK;GACH,AAAI,EAAO,QAAQ,WAIjB,EAAc,OAAO,IACZ,EAAO,OAAO,EAAW,EAAO,GAAG,IAC5C,EAAc,EAAO,GAAG,IACf,EAAO,OAIhB,QAAQ,KACN,mDAAmD,EAAO,KAC5D;GAEF;CACJ;AACF"}
1
+ {"version":3,"file":"canvas-ui.js","names":[],"sources":["../../src/services/canvas-ui.ts"],"sourcesContent":["import ConversationService from \"#/api/conversation-service/conversation-service.api\";\nimport {\n ConversationTab,\n useConversationStore,\n} from \"#/stores/conversation-store\";\nimport { useFilesTabStore } from \"#/stores/files-tab-store\";\nimport type { CanvasUIAction } from \"#/types/agent-server/core\";\nimport { toFilesTabPath } from \"#/utils/path-utils\";\n\nconst VALID_TABS: ReadonlySet<ConversationTab> = new Set<ConversationTab>([\n \"files\",\n \"browser\",\n \"terminal\",\n \"planner\",\n \"tasklist\",\n]);\n\n// Mirrors src/hooks/use-select-conversation-tab.ts so a non-React caller (the\n// WebSocket dispatch) gets the same \"reveal the right panel if collapsed\"\n// behavior as in-app tab switches.\nfunction navigateToTab(tab: ConversationTab) {\n const store = useConversationStore.getState();\n store.setSelectedTab(tab);\n if (!store.isRightPanelShown) {\n store.setHasRightPanelToggled(true);\n store.setIsRightPanelShown(true);\n }\n}\n\nfunction isValidTab(value: string): value is ConversationTab {\n return VALID_TABS.has(value as ConversationTab);\n}\n\n/**\n * Chat path click → same as agent `navigate_to_file`.\n * Optional `conversationId` tags the selection so FilesTab accepts it.\n */\nexport function openWorkspaceFile(\n path: string,\n conversationId?: string | null,\n): void {\n const conversation = ConversationService.getCurrentConversation();\n handleCanvasUIAction(\n {\n kind: \"CanvasUIAction\",\n command: \"navigate_to_file\",\n path,\n } as CanvasUIAction,\n conversationId ?? conversation?.id ?? null,\n );\n}\n\nexport function handleCanvasUIAction(\n action: CanvasUIAction,\n conversationId: string | null = null,\n): void {\n switch (action.command) {\n case \"navigate_to_file\":\n case \"show_preview\": {\n navigateToTab(\"files\");\n if (!action.path) return;\n\n const workingDir =\n ConversationService.getCurrentConversation()?.workspace?.working_dir;\n const path = toFilesTabPath(action.path, workingDir);\n if (!path) return;\n\n useFilesTabStore.getState().setSelectedPath(path, conversationId);\n return;\n }\n case \"open_tab\":\n if (action.tab === \"vscode\") {\n // The in-app VS Code tab was removed — on cloud backends VS Code\n // now opens in a new browser window via the link in the drawer tab\n // row. Route agent requests to Files so the drawer still opens.\n navigateToTab(\"files\");\n } else if (action.tab && isValidTab(action.tab)) {\n navigateToTab(action.tab);\n } else if (action.tab) {\n // Surface unknown tab names so they're diagnosable from the browser\n // console rather than failing silently. Valid tabs are listed in\n // VALID_TABS above and mirror ConversationTab.\n console.warn(\n `[canvas_ui] Ignoring open_tab with unknown tab: ${action.tab}`,\n );\n }\n return;\n }\n}\n"],"mappings":";;;;;AASA,IAAM,IAA2C,IAAI,IAAqB;CACxE;CACA;CACA;CACA;CACA;AACF,CAAC;AAKD,SAAS,EAAc,GAAsB;CAC3C,IAAM,IAAQ,EAAqB,SAAS;CAE5C,AADA,EAAM,eAAe,CAAG,GACnB,EAAM,sBACT,EAAM,wBAAwB,EAAI,GAClC,EAAM,qBAAqB,EAAI;AAEnC;AAEA,SAAS,EAAW,GAAyC;CAC3D,OAAO,EAAW,IAAI,CAAwB;AAChD;AAMA,SAAgB,EACd,GACA,GACM;CACN,IAAM,IAAe,EAAoB,uBAAuB;CAChE,EACE;EACE,MAAM;EACN,SAAS;EACT;CACF,GACA,KAAkB,GAAc,MAAM,IACxC;AACF;AAEA,SAAgB,EACd,GACA,IAAgC,MAC1B;CACN,QAAQ,EAAO,SAAf;EACE,KAAK;EACL,KAAK,gBAAgB;GAEnB,IADA,EAAc,OAAO,GACjB,CAAC,EAAO,MAAM;GAElB,IAAM,IACJ,EAAoB,uBAAuB,GAAG,WAAW,aACrD,IAAO,EAAe,EAAO,MAAM,CAAU;GACnD,IAAI,CAAC,GAAM;GAEX,EAAiB,SAAS,EAAE,gBAAgB,GAAM,CAAc;GAChE;EACF;EACA,KAAK;GACH,AAAI,EAAO,QAAQ,WAIjB,EAAc,OAAO,IACZ,EAAO,OAAO,EAAW,EAAO,GAAG,IAC5C,EAAc,EAAO,GAAG,IACf,EAAO,OAIhB,QAAQ,KACN,mDAAmD,EAAO,KAC5D;GAEF;CACJ;AACF"}
@@ -1,2 +1,2 @@
1
- require("../_virtual/_rolldown/runtime.cjs");var e={llm_model:`openhands/kimi-k3`,llm_base_url:``,agent:`CodeActAgent`,language:`en`,llm_api_key:null,llm_api_key_set:!1,search_api_key_set:!1,confirmation_mode:!1,security_analyzer:`llm`,max_iterations:null,remote_runtime_resource_factor:1,provider_tokens_set:{},enable_default_condenser:!0,condenser_max_size:240,enable_sound_notifications:!1,user_consents_to_analytics:null,enable_proactive_conversation_starters:!1,enable_solvability_analysis:!1,search_api_key:``,is_new_user:!0,disabled_skills:[],mcp_config:{},max_budget_per_task:null,email:``,email_verified:!0,git_user_name:`openhands`,git_user_email:`openhands@all-hands.dev`,title_llm_profile:null,agent_settings_schema:null,agent_settings:{schema_version:6,agent_kind:`openhands`,agent:`CodeActAgent`,llm:{model:`openhands/kimi-k3`},condenser:{enabled:!0,max_size:240},verification:{critic_enabled:!1,enable_iterative_refinement:!1},enable_sub_agents:!1,mcp_config:{}},conversation_settings_schema:null,conversation_settings:{schema_version:1,confirmation_mode:!1,security_analyzer:`llm`}};exports.DEFAULT_SETTINGS=e;
1
+ require("../_virtual/_rolldown/runtime.cjs");var e={llm_model:`openai/gpt-5.6-sol`,llm_base_url:``,agent:`CodeActAgent`,language:`en`,llm_api_key:null,llm_api_key_set:!1,search_api_key_set:!1,confirmation_mode:!1,security_analyzer:`llm`,max_iterations:null,remote_runtime_resource_factor:1,provider_tokens_set:{},enable_default_condenser:!0,condenser_max_size:240,enable_sound_notifications:!1,user_consents_to_analytics:null,enable_proactive_conversation_starters:!1,enable_solvability_analysis:!1,search_api_key:``,is_new_user:!0,disabled_skills:[],mcp_config:{},max_budget_per_task:null,email:``,email_verified:!0,git_user_name:`openhands`,git_user_email:`openhands@all-hands.dev`,title_llm_profile:null,agent_settings_schema:null,agent_settings:{schema_version:6,agent_kind:`openhands`,agent:`CodeActAgent`,llm:{model:`openai/gpt-5.6-sol`},condenser:{enabled:!0,max_size:240},verification:{critic_enabled:!1,enable_iterative_refinement:!1},enable_sub_agents:!1,enable_switch_llm_tool:!0,mcp_config:{}},conversation_settings_schema:null,conversation_settings:{schema_version:1,confirmation_mode:!1,security_analyzer:`llm`}};exports.DEFAULT_SETTINGS=e;
2
2
  //# sourceMappingURL=settings.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings.cjs","names":[],"sources":["../../src/services/settings.ts"],"sourcesContent":["import { Settings } from \"#/types/settings\";\n\nexport const LATEST_SETTINGS_VERSION = 5;\n\nexport const DEFAULT_SETTINGS: Settings = {\n llm_model: \"openhands/kimi-k3\",\n llm_base_url: \"\",\n agent: \"CodeActAgent\",\n language: \"en\",\n llm_api_key: null,\n llm_api_key_set: false,\n search_api_key_set: false,\n confirmation_mode: false,\n security_analyzer: \"llm\",\n max_iterations: null,\n remote_runtime_resource_factor: 1,\n provider_tokens_set: {},\n enable_default_condenser: true,\n condenser_max_size: 240,\n enable_sound_notifications: false,\n user_consents_to_analytics: null,\n enable_proactive_conversation_starters: false,\n enable_solvability_analysis: false,\n search_api_key: \"\",\n is_new_user: true,\n disabled_skills: [],\n mcp_config: {},\n max_budget_per_task: null,\n email: \"\",\n email_verified: true,\n git_user_name: \"openhands\",\n git_user_email: \"openhands@all-hands.dev\",\n title_llm_profile: null,\n agent_settings_schema: null,\n agent_settings: {\n schema_version: 6,\n agent_kind: \"openhands\",\n agent: \"CodeActAgent\",\n llm: {\n model: \"openhands/kimi-k3\",\n },\n condenser: {\n enabled: true,\n max_size: 240,\n },\n verification: {\n critic_enabled: false,\n enable_iterative_refinement: false,\n },\n enable_sub_agents: false,\n mcp_config: {},\n },\n conversation_settings_schema: null,\n conversation_settings: {\n schema_version: 1,\n confirmation_mode: false,\n security_analyzer: \"llm\",\n },\n};\n\n/**\n * Get the default settings\n */\nexport const getDefaultSettings = (): Settings => DEFAULT_SETTINGS;\n"],"mappings":"6CAIA,IAAa,EAA6B,CACxC,UAAW,oBACX,aAAc,GACd,MAAO,eACP,SAAU,KACV,YAAa,KACb,gBAAiB,GACjB,mBAAoB,GACpB,kBAAmB,GACnB,kBAAmB,MACnB,eAAgB,KAChB,+BAAgC,EAChC,oBAAqB,CAAC,EACtB,yBAA0B,GAC1B,mBAAoB,IACpB,2BAA4B,GAC5B,2BAA4B,KAC5B,uCAAwC,GACxC,4BAA6B,GAC7B,eAAgB,GAChB,YAAa,GACb,gBAAiB,CAAC,EAClB,WAAY,CAAC,EACb,oBAAqB,KACrB,MAAO,GACP,eAAgB,GAChB,cAAe,YACf,eAAgB,0BAChB,kBAAmB,KACnB,sBAAuB,KACvB,eAAgB,CACd,eAAgB,EAChB,WAAY,YACZ,MAAO,eACP,IAAK,CACH,MAAO,mBACT,EACA,UAAW,CACT,QAAS,GACT,SAAU,GACZ,EACA,aAAc,CACZ,eAAgB,GAChB,4BAA6B,EAC/B,EACA,kBAAmB,GACnB,WAAY,CAAC,CACf,EACA,6BAA8B,KAC9B,sBAAuB,CACrB,eAAgB,EAChB,kBAAmB,GACnB,kBAAmB,KACrB,CACF"}
1
+ {"version":3,"file":"settings.cjs","names":[],"sources":["../../src/services/settings.ts"],"sourcesContent":["import { Settings } from \"#/types/settings\";\n\nexport const LATEST_SETTINGS_VERSION = 5;\n\nexport const DEFAULT_SETTINGS: Settings = {\n llm_model: \"openai/gpt-5.6-sol\",\n llm_base_url: \"\",\n agent: \"CodeActAgent\",\n language: \"en\",\n llm_api_key: null,\n llm_api_key_set: false,\n search_api_key_set: false,\n confirmation_mode: false,\n security_analyzer: \"llm\",\n max_iterations: null,\n remote_runtime_resource_factor: 1,\n provider_tokens_set: {},\n enable_default_condenser: true,\n condenser_max_size: 240,\n enable_sound_notifications: false,\n user_consents_to_analytics: null,\n enable_proactive_conversation_starters: false,\n enable_solvability_analysis: false,\n search_api_key: \"\",\n is_new_user: true,\n disabled_skills: [],\n mcp_config: {},\n max_budget_per_task: null,\n email: \"\",\n email_verified: true,\n git_user_name: \"openhands\",\n git_user_email: \"openhands@all-hands.dev\",\n title_llm_profile: null,\n agent_settings_schema: null,\n agent_settings: {\n schema_version: 6,\n agent_kind: \"openhands\",\n agent: \"CodeActAgent\",\n llm: {\n model: \"openai/gpt-5.6-sol\",\n },\n condenser: {\n enabled: true,\n max_size: 240,\n },\n verification: {\n critic_enabled: false,\n enable_iterative_refinement: false,\n },\n enable_sub_agents: false,\n enable_switch_llm_tool: true,\n mcp_config: {},\n },\n conversation_settings_schema: null,\n conversation_settings: {\n schema_version: 1,\n confirmation_mode: false,\n security_analyzer: \"llm\",\n },\n};\n\n/**\n * Get the default settings\n */\nexport const getDefaultSettings = (): Settings => DEFAULT_SETTINGS;\n"],"mappings":"6CAIA,IAAa,EAA6B,CACxC,UAAW,qBACX,aAAc,GACd,MAAO,eACP,SAAU,KACV,YAAa,KACb,gBAAiB,GACjB,mBAAoB,GACpB,kBAAmB,GACnB,kBAAmB,MACnB,eAAgB,KAChB,+BAAgC,EAChC,oBAAqB,CAAC,EACtB,yBAA0B,GAC1B,mBAAoB,IACpB,2BAA4B,GAC5B,2BAA4B,KAC5B,uCAAwC,GACxC,4BAA6B,GAC7B,eAAgB,GAChB,YAAa,GACb,gBAAiB,CAAC,EAClB,WAAY,CAAC,EACb,oBAAqB,KACrB,MAAO,GACP,eAAgB,GAChB,cAAe,YACf,eAAgB,0BAChB,kBAAmB,KACnB,sBAAuB,KACvB,eAAgB,CACd,eAAgB,EAChB,WAAY,YACZ,MAAO,eACP,IAAK,CACH,MAAO,oBACT,EACA,UAAW,CACT,QAAS,GACT,SAAU,GACZ,EACA,aAAc,CACZ,eAAgB,GAChB,4BAA6B,EAC/B,EACA,kBAAmB,GACnB,uBAAwB,GACxB,WAAY,CAAC,CACf,EACA,6BAA8B,KAC9B,sBAAuB,CACrB,eAAgB,EAChB,kBAAmB,GACnB,kBAAmB,KACrB,CACF"}
@@ -1,6 +1,6 @@
1
1
  //#region src/services/settings.ts
2
2
  var e = {
3
- llm_model: "openhands/kimi-k3",
3
+ llm_model: "openai/gpt-5.6-sol",
4
4
  llm_base_url: "",
5
5
  agent: "CodeActAgent",
6
6
  language: "en",
@@ -33,7 +33,7 @@ var e = {
33
33
  schema_version: 6,
34
34
  agent_kind: "openhands",
35
35
  agent: "CodeActAgent",
36
- llm: { model: "openhands/kimi-k3" },
36
+ llm: { model: "openai/gpt-5.6-sol" },
37
37
  condenser: {
38
38
  enabled: !0,
39
39
  max_size: 240
@@ -43,6 +43,7 @@ var e = {
43
43
  enable_iterative_refinement: !1
44
44
  },
45
45
  enable_sub_agents: !1,
46
+ enable_switch_llm_tool: !0,
46
47
  mcp_config: {}
47
48
  },
48
49
  conversation_settings_schema: null,
@@ -1 +1 @@
1
- {"version":3,"file":"settings.js","names":[],"sources":["../../src/services/settings.ts"],"sourcesContent":["import { Settings } from \"#/types/settings\";\n\nexport const LATEST_SETTINGS_VERSION = 5;\n\nexport const DEFAULT_SETTINGS: Settings = {\n llm_model: \"openhands/kimi-k3\",\n llm_base_url: \"\",\n agent: \"CodeActAgent\",\n language: \"en\",\n llm_api_key: null,\n llm_api_key_set: false,\n search_api_key_set: false,\n confirmation_mode: false,\n security_analyzer: \"llm\",\n max_iterations: null,\n remote_runtime_resource_factor: 1,\n provider_tokens_set: {},\n enable_default_condenser: true,\n condenser_max_size: 240,\n enable_sound_notifications: false,\n user_consents_to_analytics: null,\n enable_proactive_conversation_starters: false,\n enable_solvability_analysis: false,\n search_api_key: \"\",\n is_new_user: true,\n disabled_skills: [],\n mcp_config: {},\n max_budget_per_task: null,\n email: \"\",\n email_verified: true,\n git_user_name: \"openhands\",\n git_user_email: \"openhands@all-hands.dev\",\n title_llm_profile: null,\n agent_settings_schema: null,\n agent_settings: {\n schema_version: 6,\n agent_kind: \"openhands\",\n agent: \"CodeActAgent\",\n llm: {\n model: \"openhands/kimi-k3\",\n },\n condenser: {\n enabled: true,\n max_size: 240,\n },\n verification: {\n critic_enabled: false,\n enable_iterative_refinement: false,\n },\n enable_sub_agents: false,\n mcp_config: {},\n },\n conversation_settings_schema: null,\n conversation_settings: {\n schema_version: 1,\n confirmation_mode: false,\n security_analyzer: \"llm\",\n },\n};\n\n/**\n * Get the default settings\n */\nexport const getDefaultSettings = (): Settings => DEFAULT_SETTINGS;\n"],"mappings":";AAIA,IAAa,IAA6B;CACxC,WAAW;CACX,cAAc;CACd,OAAO;CACP,UAAU;CACV,aAAa;CACb,iBAAiB;CACjB,oBAAoB;CACpB,mBAAmB;CACnB,mBAAmB;CACnB,gBAAgB;CAChB,gCAAgC;CAChC,qBAAqB,CAAC;CACtB,0BAA0B;CAC1B,oBAAoB;CACpB,4BAA4B;CAC5B,4BAA4B;CAC5B,wCAAwC;CACxC,6BAA6B;CAC7B,gBAAgB;CAChB,aAAa;CACb,iBAAiB,CAAC;CAClB,YAAY,CAAC;CACb,qBAAqB;CACrB,OAAO;CACP,gBAAgB;CAChB,eAAe;CACf,gBAAgB;CAChB,mBAAmB;CACnB,uBAAuB;CACvB,gBAAgB;EACd,gBAAgB;EAChB,YAAY;EACZ,OAAO;EACP,KAAK,EACH,OAAO,oBACT;EACA,WAAW;GACT,SAAS;GACT,UAAU;EACZ;EACA,cAAc;GACZ,gBAAgB;GAChB,6BAA6B;EAC/B;EACA,mBAAmB;EACnB,YAAY,CAAC;CACf;CACA,8BAA8B;CAC9B,uBAAuB;EACrB,gBAAgB;EAChB,mBAAmB;EACnB,mBAAmB;CACrB;AACF"}
1
+ {"version":3,"file":"settings.js","names":[],"sources":["../../src/services/settings.ts"],"sourcesContent":["import { Settings } from \"#/types/settings\";\n\nexport const LATEST_SETTINGS_VERSION = 5;\n\nexport const DEFAULT_SETTINGS: Settings = {\n llm_model: \"openai/gpt-5.6-sol\",\n llm_base_url: \"\",\n agent: \"CodeActAgent\",\n language: \"en\",\n llm_api_key: null,\n llm_api_key_set: false,\n search_api_key_set: false,\n confirmation_mode: false,\n security_analyzer: \"llm\",\n max_iterations: null,\n remote_runtime_resource_factor: 1,\n provider_tokens_set: {},\n enable_default_condenser: true,\n condenser_max_size: 240,\n enable_sound_notifications: false,\n user_consents_to_analytics: null,\n enable_proactive_conversation_starters: false,\n enable_solvability_analysis: false,\n search_api_key: \"\",\n is_new_user: true,\n disabled_skills: [],\n mcp_config: {},\n max_budget_per_task: null,\n email: \"\",\n email_verified: true,\n git_user_name: \"openhands\",\n git_user_email: \"openhands@all-hands.dev\",\n title_llm_profile: null,\n agent_settings_schema: null,\n agent_settings: {\n schema_version: 6,\n agent_kind: \"openhands\",\n agent: \"CodeActAgent\",\n llm: {\n model: \"openai/gpt-5.6-sol\",\n },\n condenser: {\n enabled: true,\n max_size: 240,\n },\n verification: {\n critic_enabled: false,\n enable_iterative_refinement: false,\n },\n enable_sub_agents: false,\n enable_switch_llm_tool: true,\n mcp_config: {},\n },\n conversation_settings_schema: null,\n conversation_settings: {\n schema_version: 1,\n confirmation_mode: false,\n security_analyzer: \"llm\",\n },\n};\n\n/**\n * Get the default settings\n */\nexport const getDefaultSettings = (): Settings => DEFAULT_SETTINGS;\n"],"mappings":";AAIA,IAAa,IAA6B;CACxC,WAAW;CACX,cAAc;CACd,OAAO;CACP,UAAU;CACV,aAAa;CACb,iBAAiB;CACjB,oBAAoB;CACpB,mBAAmB;CACnB,mBAAmB;CACnB,gBAAgB;CAChB,gCAAgC;CAChC,qBAAqB,CAAC;CACtB,0BAA0B;CAC1B,oBAAoB;CACpB,4BAA4B;CAC5B,4BAA4B;CAC5B,wCAAwC;CACxC,6BAA6B;CAC7B,gBAAgB;CAChB,aAAa;CACb,iBAAiB,CAAC;CAClB,YAAY,CAAC;CACb,qBAAqB;CACrB,OAAO;CACP,gBAAgB;CAChB,eAAe;CACf,gBAAgB;CAChB,mBAAmB;CACnB,uBAAuB;CACvB,gBAAgB;EACd,gBAAgB;EAChB,YAAY;EACZ,OAAO;EACP,KAAK,EACH,OAAO,qBACT;EACA,WAAW;GACT,SAAS;GACT,UAAU;EACZ;EACA,cAAc;GACZ,gBAAgB;GAChB,6BAA6B;EAC/B;EACA,mBAAmB;EACnB,wBAAwB;EACxB,YAAY,CAAC;CACf;CACA,8BAA8B;CAC9B,uBAAuB;EACrB,gBAAgB;EAChB,mBAAmB;EACnB,mBAAmB;CACrB;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"automation.cjs","names":[],"sources":["../../src/types/automation.ts"],"sourcesContent":["export interface AutomationTrigger {\n /**\n * Trigger kind. Known values are the schedule aliases \"cron\" / \"schedule\"\n * (time-based) and \"event\" (webhook/event-driven). Kept as `string` rather\n * than a closed union on purpose: the backend emits more than one\n * scheduled-trigger alias and may introduce new kinds, so UI code branches\n * on `type === \"event\"` and treats every other value as a schedule.\n */\n type: string;\n /** Cron expression (schedule triggers only). */\n schedule?: string;\n /** Human-readable schedule description (schedule triggers only). */\n schedule_human?: string;\n /** IANA timezone name (schedule triggers only). */\n timezone?: string;\n /** Event source, e.g. \"github\" (event triggers only). */\n source?: string;\n /** Event key pattern(s) to match, e.g. \"pull_request.opened\" or [\"push\", \"release.*\"]. */\n on?: string | string[];\n /** JMESPath filter expression evaluated against the raw webhook payload. */\n filter?: string;\n}\n\nexport interface Automation {\n id: string;\n name: string;\n trigger: AutomationTrigger;\n enabled: boolean;\n repository?: string;\n /** LLM/model profile name used for automation runs. */\n model?: string | null;\n /**\n * Maximum run time in seconds. `null`/omitted uses the server default\n * (600s, 10 min); the deployment reports the maximum it accepts.\n */\n timeout?: number | null;\n\n created_at: string;\n updated_at: string;\n prompt: string | null;\n branch?: string;\n plugins?: string[];\n notification?: string;\n timezone?: string;\n last_triggered_at?: string | null;\n}\n\nexport type AutomationSpec = Omit<\n Automation,\n \"id\" | \"created_at\" | \"updated_at\" | \"last_triggered_at\"\n>;\n\n/** The envelope constants come from the interface manifest's import/export spec. */\nexport interface AutomationExportFile {\n version: number;\n kind: string;\n spec: AutomationSpec;\n}\n\nexport interface AutomationsResponse {\n automations: Automation[];\n total: number;\n}\n\n/** Mirrors `RunStatus` in the automation service's OpenAPI schema. */\nexport enum AutomationRunStatus {\n PENDING = \"PENDING\",\n RUNNING = \"RUNNING\",\n COMPLETED = \"COMPLETED\",\n FAILED = \"FAILED\",\n CANCELLED = \"CANCELLED\",\n SKIPPED = \"SKIPPED\",\n}\n\nexport interface AutomationRun {\n id: string;\n status: AutomationRunStatus;\n conversation_id: string | null;\n /**\n * ID of the bash command that ran the automation inside the agent-server\n * sandbox. Used to fetch run logs from\n * `/api/bash/bash_events/{bash_command_id}` and the matching\n * `BashOutput` events. Null when the run failed before a command was\n * dispatched (e.g. sandbox provisioning errors).\n */\n bash_command_id: string | null;\n error_detail: string | null;\n /**\n * Accumulated LLM cost of the run in USD, reported by the SDK in the\n * completion callback. `null` means unknown — the run predates cost\n * tracking, or ended without a callback (cancelled, watchdog timeout).\n * Absent entirely when the automation service is older than the release\n * that added the field, hence optional.\n */\n cost?: number | null;\n started_at: string;\n completed_at: string | null;\n}\n\nexport interface AutomationRunsResponse {\n runs: AutomationRun[];\n total: number;\n}\n\nexport type ActivityLogExportFormat = \"json\" | \"csv\";\n\n/** Client-built Activity Log export row (from list runs + automation detail). */\nexport interface AutomationRunExportRow {\n run_id: string;\n automation_id: string;\n automation_name: string;\n trigger: AutomationTrigger | Record<string, unknown>;\n start_time: string | null;\n end_time: string | null;\n duration_seconds: number | null;\n status: AutomationRunStatus;\n conversation_id: string | null;\n conversation_url: string | null;\n error: string | null;\n /**\n * Accumulated LLM cost in USD, or null when unknown. Unlike\n * `AutomationRun[\"cost\"]` this is always present: the row normalizes a\n * missing field to null so every exported record has the same shape.\n */\n cost: number | null;\n}\n"],"mappings":"6CAiEA,IAAY,EAAL,SAAA,EAAA,OACL,GAAA,QAAA,UACA,EAAA,QAAA,UACA,EAAA,UAAA,YACA,EAAA,OAAA,SACA,EAAA,UAAA,YACA,EAAA,QAAA,WACF,EAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"automation.cjs","names":[],"sources":["../../src/types/automation.ts"],"sourcesContent":["export interface AutomationTrigger {\n /**\n * Trigger kind. Known values are the schedule aliases \"cron\" / \"schedule\"\n * (time-based) and \"event\" (webhook/event-driven). Kept as `string` rather\n * than a closed union on purpose: the backend emits more than one\n * scheduled-trigger alias and may introduce new kinds, so UI code branches\n * on `type === \"event\"` and treats every other value as a schedule.\n */\n type: string;\n /** Cron expression (schedule triggers only). */\n schedule?: string;\n /** Human-readable schedule description (schedule triggers only). */\n schedule_human?: string;\n /** IANA timezone name (schedule triggers only). */\n timezone?: string;\n /** Event source, e.g. \"github\" (event triggers only). */\n source?: string;\n /** Event key pattern(s) to match, e.g. \"pull_request.opened\" or [\"push\", \"release.*\"]. */\n on?: string | string[];\n /** JMESPath filter expression evaluated against the raw webhook payload. */\n filter?: string;\n}\n\nexport interface Automation {\n id: string;\n name: string;\n trigger: AutomationTrigger;\n enabled: boolean;\n repository?: string;\n /** LLM/model profile name used for automation runs. */\n model?: string | null;\n /**\n * Maximum run time in seconds. `null`/omitted uses the server default\n * (600s, 10 min); the deployment reports the maximum it accepts.\n */\n timeout?: number | null;\n\n created_at: string;\n updated_at: string;\n prompt: string | null;\n branch?: string;\n plugins?: string[];\n notification?: string;\n timezone?: string;\n last_triggered_at?: string | null;\n}\n\nexport type AutomationSpec = Omit<\n Automation,\n \"id\" | \"created_at\" | \"updated_at\" | \"last_triggered_at\"\n>;\n\n/** The envelope constants come from the interface manifest's import/export spec. */\nexport interface AutomationExportFile {\n version: number;\n kind: string;\n spec: AutomationSpec;\n}\n\nexport interface AutomationsResponse {\n automations: Automation[];\n total: number;\n}\n\n/** Mirrors `RunStatus` in the automation service's OpenAPI schema. */\nexport enum AutomationRunStatus {\n PENDING = \"PENDING\",\n RUNNING = \"RUNNING\",\n COMPLETED = \"COMPLETED\",\n FAILED = \"FAILED\",\n CANCELLED = \"CANCELLED\",\n SKIPPED = \"SKIPPED\",\n}\n\nexport interface AutomationRun {\n id: string;\n status: AutomationRunStatus;\n conversation_id: string | null;\n /**\n * ID of the bash command that ran the automation inside the agent-server\n * sandbox. Used to fetch run logs from\n * `/api/bash/bash_events/{bash_command_id}` and the matching\n * `BashOutput` events. Null when the run failed before a command was\n * dispatched (e.g. sandbox provisioning errors).\n */\n bash_command_id: string | null;\n error_detail: string | null;\n /**\n * Accumulated LLM cost of the run in USD, reported by the SDK in the\n * completion callback. `null` means unknown — the run predates cost\n * tracking, or ended without a callback (cancelled, watchdog timeout).\n * Absent entirely when the automation service is older than the release\n * that added the field, hence optional.\n */\n cost?: number | null;\n /**\n * Machine-readable code for the run's current or last-known phase (e.g.\n * \"sandbox_provisioning\"). `null` means nothing has reported one; absent\n * entirely against an automation service that predates phase reporting.\n * Code and label are one value, always written together.\n */\n phase_code?: string | null;\n /**\n * Author-supplied description of the phase (at most 200 characters, no\n * control or separator characters, emoji and non-Latin text allowed).\n * Data, not translatable interface copy.\n */\n phase_label?: string | null;\n /** UTC datetime the phase was last written. Same nullability as `phase_code`. */\n phase_updated_at?: string | null;\n started_at: string;\n completed_at: string | null;\n}\n\nexport interface AutomationRunsResponse {\n runs: AutomationRun[];\n total: number;\n}\n\nexport type ActivityLogExportFormat = \"json\" | \"csv\";\n\n/** Client-built Activity Log export row (from list runs + automation detail). */\nexport interface AutomationRunExportRow {\n run_id: string;\n automation_id: string;\n automation_name: string;\n trigger: AutomationTrigger | Record<string, unknown>;\n start_time: string | null;\n end_time: string | null;\n duration_seconds: number | null;\n status: AutomationRunStatus;\n conversation_id: string | null;\n conversation_url: string | null;\n error: string | null;\n /**\n * Accumulated LLM cost in USD, or null when unknown. Unlike\n * `AutomationRun[\"cost\"]` this is always present: the row normalizes a\n * missing field to null so every exported record has the same shape.\n */\n cost: number | null;\n /**\n * The raw `phase_code`, like `status`, falling back to `phase_label` for a\n * phase reported without a code. Null only when the run has no phase.\n */\n phase: string | null;\n}\n"],"mappings":"6CAiEA,IAAY,EAAL,SAAA,EAAA,OACL,GAAA,QAAA,UACA,EAAA,QAAA,UACA,EAAA,UAAA,YACA,EAAA,OAAA,SACA,EAAA,UAAA,YACA,EAAA,QAAA,WACF,EAAA,CAAA,CAAA"}
@@ -83,6 +83,21 @@ export interface AutomationRun {
83
83
  * that added the field, hence optional.
84
84
  */
85
85
  cost?: number | null;
86
+ /**
87
+ * Machine-readable code for the run's current or last-known phase (e.g.
88
+ * "sandbox_provisioning"). `null` means nothing has reported one; absent
89
+ * entirely against an automation service that predates phase reporting.
90
+ * Code and label are one value, always written together.
91
+ */
92
+ phase_code?: string | null;
93
+ /**
94
+ * Author-supplied description of the phase (at most 200 characters, no
95
+ * control or separator characters, emoji and non-Latin text allowed).
96
+ * Data, not translatable interface copy.
97
+ */
98
+ phase_label?: string | null;
99
+ /** UTC datetime the phase was last written. Same nullability as `phase_code`. */
100
+ phase_updated_at?: string | null;
86
101
  started_at: string;
87
102
  completed_at: string | null;
88
103
  }
@@ -110,4 +125,9 @@ export interface AutomationRunExportRow {
110
125
  * missing field to null so every exported record has the same shape.
111
126
  */
112
127
  cost: number | null;
128
+ /**
129
+ * The raw `phase_code`, like `status`, falling back to `phase_label` for a
130
+ * phase reported without a code. Null only when the run has no phase.
131
+ */
132
+ phase: string | null;
113
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"automation.js","names":[],"sources":["../../src/types/automation.ts"],"sourcesContent":["export interface AutomationTrigger {\n /**\n * Trigger kind. Known values are the schedule aliases \"cron\" / \"schedule\"\n * (time-based) and \"event\" (webhook/event-driven). Kept as `string` rather\n * than a closed union on purpose: the backend emits more than one\n * scheduled-trigger alias and may introduce new kinds, so UI code branches\n * on `type === \"event\"` and treats every other value as a schedule.\n */\n type: string;\n /** Cron expression (schedule triggers only). */\n schedule?: string;\n /** Human-readable schedule description (schedule triggers only). */\n schedule_human?: string;\n /** IANA timezone name (schedule triggers only). */\n timezone?: string;\n /** Event source, e.g. \"github\" (event triggers only). */\n source?: string;\n /** Event key pattern(s) to match, e.g. \"pull_request.opened\" or [\"push\", \"release.*\"]. */\n on?: string | string[];\n /** JMESPath filter expression evaluated against the raw webhook payload. */\n filter?: string;\n}\n\nexport interface Automation {\n id: string;\n name: string;\n trigger: AutomationTrigger;\n enabled: boolean;\n repository?: string;\n /** LLM/model profile name used for automation runs. */\n model?: string | null;\n /**\n * Maximum run time in seconds. `null`/omitted uses the server default\n * (600s, 10 min); the deployment reports the maximum it accepts.\n */\n timeout?: number | null;\n\n created_at: string;\n updated_at: string;\n prompt: string | null;\n branch?: string;\n plugins?: string[];\n notification?: string;\n timezone?: string;\n last_triggered_at?: string | null;\n}\n\nexport type AutomationSpec = Omit<\n Automation,\n \"id\" | \"created_at\" | \"updated_at\" | \"last_triggered_at\"\n>;\n\n/** The envelope constants come from the interface manifest's import/export spec. */\nexport interface AutomationExportFile {\n version: number;\n kind: string;\n spec: AutomationSpec;\n}\n\nexport interface AutomationsResponse {\n automations: Automation[];\n total: number;\n}\n\n/** Mirrors `RunStatus` in the automation service's OpenAPI schema. */\nexport enum AutomationRunStatus {\n PENDING = \"PENDING\",\n RUNNING = \"RUNNING\",\n COMPLETED = \"COMPLETED\",\n FAILED = \"FAILED\",\n CANCELLED = \"CANCELLED\",\n SKIPPED = \"SKIPPED\",\n}\n\nexport interface AutomationRun {\n id: string;\n status: AutomationRunStatus;\n conversation_id: string | null;\n /**\n * ID of the bash command that ran the automation inside the agent-server\n * sandbox. Used to fetch run logs from\n * `/api/bash/bash_events/{bash_command_id}` and the matching\n * `BashOutput` events. Null when the run failed before a command was\n * dispatched (e.g. sandbox provisioning errors).\n */\n bash_command_id: string | null;\n error_detail: string | null;\n /**\n * Accumulated LLM cost of the run in USD, reported by the SDK in the\n * completion callback. `null` means unknown — the run predates cost\n * tracking, or ended without a callback (cancelled, watchdog timeout).\n * Absent entirely when the automation service is older than the release\n * that added the field, hence optional.\n */\n cost?: number | null;\n started_at: string;\n completed_at: string | null;\n}\n\nexport interface AutomationRunsResponse {\n runs: AutomationRun[];\n total: number;\n}\n\nexport type ActivityLogExportFormat = \"json\" | \"csv\";\n\n/** Client-built Activity Log export row (from list runs + automation detail). */\nexport interface AutomationRunExportRow {\n run_id: string;\n automation_id: string;\n automation_name: string;\n trigger: AutomationTrigger | Record<string, unknown>;\n start_time: string | null;\n end_time: string | null;\n duration_seconds: number | null;\n status: AutomationRunStatus;\n conversation_id: string | null;\n conversation_url: string | null;\n error: string | null;\n /**\n * Accumulated LLM cost in USD, or null when unknown. Unlike\n * `AutomationRun[\"cost\"]` this is always present: the row normalizes a\n * missing field to null so every exported record has the same shape.\n */\n cost: number | null;\n}\n"],"mappings":";AAiEA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,UAAA,WACA,EAAA,UAAA,WACA,EAAA,YAAA,aACA,EAAA,SAAA,UACA,EAAA,YAAA,aACA,EAAA,UAAA;AACF,EAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"automation.js","names":[],"sources":["../../src/types/automation.ts"],"sourcesContent":["export interface AutomationTrigger {\n /**\n * Trigger kind. Known values are the schedule aliases \"cron\" / \"schedule\"\n * (time-based) and \"event\" (webhook/event-driven). Kept as `string` rather\n * than a closed union on purpose: the backend emits more than one\n * scheduled-trigger alias and may introduce new kinds, so UI code branches\n * on `type === \"event\"` and treats every other value as a schedule.\n */\n type: string;\n /** Cron expression (schedule triggers only). */\n schedule?: string;\n /** Human-readable schedule description (schedule triggers only). */\n schedule_human?: string;\n /** IANA timezone name (schedule triggers only). */\n timezone?: string;\n /** Event source, e.g. \"github\" (event triggers only). */\n source?: string;\n /** Event key pattern(s) to match, e.g. \"pull_request.opened\" or [\"push\", \"release.*\"]. */\n on?: string | string[];\n /** JMESPath filter expression evaluated against the raw webhook payload. */\n filter?: string;\n}\n\nexport interface Automation {\n id: string;\n name: string;\n trigger: AutomationTrigger;\n enabled: boolean;\n repository?: string;\n /** LLM/model profile name used for automation runs. */\n model?: string | null;\n /**\n * Maximum run time in seconds. `null`/omitted uses the server default\n * (600s, 10 min); the deployment reports the maximum it accepts.\n */\n timeout?: number | null;\n\n created_at: string;\n updated_at: string;\n prompt: string | null;\n branch?: string;\n plugins?: string[];\n notification?: string;\n timezone?: string;\n last_triggered_at?: string | null;\n}\n\nexport type AutomationSpec = Omit<\n Automation,\n \"id\" | \"created_at\" | \"updated_at\" | \"last_triggered_at\"\n>;\n\n/** The envelope constants come from the interface manifest's import/export spec. */\nexport interface AutomationExportFile {\n version: number;\n kind: string;\n spec: AutomationSpec;\n}\n\nexport interface AutomationsResponse {\n automations: Automation[];\n total: number;\n}\n\n/** Mirrors `RunStatus` in the automation service's OpenAPI schema. */\nexport enum AutomationRunStatus {\n PENDING = \"PENDING\",\n RUNNING = \"RUNNING\",\n COMPLETED = \"COMPLETED\",\n FAILED = \"FAILED\",\n CANCELLED = \"CANCELLED\",\n SKIPPED = \"SKIPPED\",\n}\n\nexport interface AutomationRun {\n id: string;\n status: AutomationRunStatus;\n conversation_id: string | null;\n /**\n * ID of the bash command that ran the automation inside the agent-server\n * sandbox. Used to fetch run logs from\n * `/api/bash/bash_events/{bash_command_id}` and the matching\n * `BashOutput` events. Null when the run failed before a command was\n * dispatched (e.g. sandbox provisioning errors).\n */\n bash_command_id: string | null;\n error_detail: string | null;\n /**\n * Accumulated LLM cost of the run in USD, reported by the SDK in the\n * completion callback. `null` means unknown — the run predates cost\n * tracking, or ended without a callback (cancelled, watchdog timeout).\n * Absent entirely when the automation service is older than the release\n * that added the field, hence optional.\n */\n cost?: number | null;\n /**\n * Machine-readable code for the run's current or last-known phase (e.g.\n * \"sandbox_provisioning\"). `null` means nothing has reported one; absent\n * entirely against an automation service that predates phase reporting.\n * Code and label are one value, always written together.\n */\n phase_code?: string | null;\n /**\n * Author-supplied description of the phase (at most 200 characters, no\n * control or separator characters, emoji and non-Latin text allowed).\n * Data, not translatable interface copy.\n */\n phase_label?: string | null;\n /** UTC datetime the phase was last written. Same nullability as `phase_code`. */\n phase_updated_at?: string | null;\n started_at: string;\n completed_at: string | null;\n}\n\nexport interface AutomationRunsResponse {\n runs: AutomationRun[];\n total: number;\n}\n\nexport type ActivityLogExportFormat = \"json\" | \"csv\";\n\n/** Client-built Activity Log export row (from list runs + automation detail). */\nexport interface AutomationRunExportRow {\n run_id: string;\n automation_id: string;\n automation_name: string;\n trigger: AutomationTrigger | Record<string, unknown>;\n start_time: string | null;\n end_time: string | null;\n duration_seconds: number | null;\n status: AutomationRunStatus;\n conversation_id: string | null;\n conversation_url: string | null;\n error: string | null;\n /**\n * Accumulated LLM cost in USD, or null when unknown. Unlike\n * `AutomationRun[\"cost\"]` this is always present: the row normalizes a\n * missing field to null so every exported record has the same shape.\n */\n cost: number | null;\n /**\n * The raw `phase_code`, like `status`, falling back to `phase_label` for a\n * phase reported without a code. Null only when the run has no phase.\n */\n phase: string | null;\n}\n"],"mappings":";AAiEA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,UAAA,WACA,EAAA,UAAA,WACA,EAAA,YAAA,aACA,EAAA,SAAA,UACA,EAAA,YAAA,aACA,EAAA,UAAA;AACF,EAAA,CAAA,CAAA"}
@@ -0,0 +1,2 @@
1
+ require("../_virtual/_rolldown/runtime.cjs");var e=1,t=`1`;exports.CANVAS_EXTENSION_HOST_API_VERSION=t,exports.CANVAS_EXTENSION_MANIFEST_SCHEMA_VERSION=e;
2
+ //# sourceMappingURL=canvas-extension.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvas-extension.cjs","names":[],"sources":["../../src/types/canvas-extension.ts"],"sourcesContent":["export const CANVAS_EXTENSION_MANIFEST_SCHEMA_VERSION = 1 as const;\nexport const CANVAS_EXTENSION_HOST_API_VERSION = \"1\" as const;\n\nexport interface CanvasExtensionPageContribution {\n id: string;\n title: string;\n path: string;\n nav_label?: string | null;\n description?: string | null;\n}\n\nexport interface CanvasExtensionContributions {\n pages?: CanvasExtensionPageContribution[] | null;\n}\n\n/** Parsed contents of `canvas-extension.json`. */\nexport interface CanvasExtensionManifest {\n schema_version: typeof CANVAS_EXTENSION_MANIFEST_SCHEMA_VERSION;\n name: string;\n display_name?: string | null;\n version: string;\n description?: string | null;\n entrypoint: string;\n contributes?: CanvasExtensionContributions | null;\n}\n\nexport interface InstalledCanvasExtensionInfo {\n name: string;\n version: string;\n description?: string | null;\n enabled: boolean;\n source: string;\n requested_ref?: string | null;\n resolved_ref?: string | null;\n repo_path?: string | null;\n installed_at: string;\n install_path: string;\n /** Absent until the backend exposes page contributions (OSS-10048). */\n manifest?: CanvasExtensionManifest | null;\n}\n\nexport interface InstallCanvasExtensionRequest {\n source: string;\n ref?: string | null;\n repo_path?: string | null;\n force?: boolean;\n}\n\nexport type CanvasExtensionDispose = () => void;\n\nexport interface CanvasExtensionPageMountContext {\n container: HTMLElement;\n /** Remainder of the route below the page contribution's declared path. */\n path: string;\n navigate: (path: string) => void;\n}\n\nexport type CanvasExtensionPageMount = (\n context: CanvasExtensionPageMountContext,\n) => void | CanvasExtensionDispose | Promise<void | CanvasExtensionDispose>;\n\nexport interface CanvasExtensionAgentServerRequest {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n path: string;\n body?: unknown;\n headers?: Record<string, string>;\n}\n\nexport interface CanvasExtensionHost {\n readonly apiVersion: typeof CANVAS_EXTENSION_HOST_API_VERSION;\n readonly extension: Readonly<{\n name: string;\n version: string;\n resolvedRef: string | null;\n }>;\n readonly backend: Readonly<{\n id: string;\n kind: \"local\" | \"cloud\";\n orgId: string | null;\n }>;\n registerPage: (\n contributionId: string,\n mount: CanvasExtensionPageMount,\n ) => CanvasExtensionDispose;\n navigate: (path: string) => void;\n agentServer: {\n request: <T = unknown>(\n request: CanvasExtensionAgentServerRequest,\n ) => Promise<T>;\n };\n}\n\nexport interface CanvasExtensionModule {\n activate: (\n host: CanvasExtensionHost,\n ) => void | CanvasExtensionDispose | Promise<void | CanvasExtensionDispose>;\n}\n"],"mappings":"6CAAA,IAAa,EAA2C,EAC3C,EAAoC"}
@@ -0,0 +1,77 @@
1
+ export declare const CANVAS_EXTENSION_MANIFEST_SCHEMA_VERSION: 1;
2
+ export declare const CANVAS_EXTENSION_HOST_API_VERSION: "1";
3
+ export interface CanvasExtensionPageContribution {
4
+ id: string;
5
+ title: string;
6
+ path: string;
7
+ nav_label?: string | null;
8
+ description?: string | null;
9
+ }
10
+ export interface CanvasExtensionContributions {
11
+ pages?: CanvasExtensionPageContribution[] | null;
12
+ }
13
+ /** Parsed contents of `canvas-extension.json`. */
14
+ export interface CanvasExtensionManifest {
15
+ schema_version: typeof CANVAS_EXTENSION_MANIFEST_SCHEMA_VERSION;
16
+ name: string;
17
+ display_name?: string | null;
18
+ version: string;
19
+ description?: string | null;
20
+ entrypoint: string;
21
+ contributes?: CanvasExtensionContributions | null;
22
+ }
23
+ export interface InstalledCanvasExtensionInfo {
24
+ name: string;
25
+ version: string;
26
+ description?: string | null;
27
+ enabled: boolean;
28
+ source: string;
29
+ requested_ref?: string | null;
30
+ resolved_ref?: string | null;
31
+ repo_path?: string | null;
32
+ installed_at: string;
33
+ install_path: string;
34
+ /** Absent until the backend exposes page contributions (OSS-10048). */
35
+ manifest?: CanvasExtensionManifest | null;
36
+ }
37
+ export interface InstallCanvasExtensionRequest {
38
+ source: string;
39
+ ref?: string | null;
40
+ repo_path?: string | null;
41
+ force?: boolean;
42
+ }
43
+ export type CanvasExtensionDispose = () => void;
44
+ export interface CanvasExtensionPageMountContext {
45
+ container: HTMLElement;
46
+ /** Remainder of the route below the page contribution's declared path. */
47
+ path: string;
48
+ navigate: (path: string) => void;
49
+ }
50
+ export type CanvasExtensionPageMount = (context: CanvasExtensionPageMountContext) => void | CanvasExtensionDispose | Promise<void | CanvasExtensionDispose>;
51
+ export interface CanvasExtensionAgentServerRequest {
52
+ method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
53
+ path: string;
54
+ body?: unknown;
55
+ headers?: Record<string, string>;
56
+ }
57
+ export interface CanvasExtensionHost {
58
+ readonly apiVersion: typeof CANVAS_EXTENSION_HOST_API_VERSION;
59
+ readonly extension: Readonly<{
60
+ name: string;
61
+ version: string;
62
+ resolvedRef: string | null;
63
+ }>;
64
+ readonly backend: Readonly<{
65
+ id: string;
66
+ kind: "local" | "cloud";
67
+ orgId: string | null;
68
+ }>;
69
+ registerPage: (contributionId: string, mount: CanvasExtensionPageMount) => CanvasExtensionDispose;
70
+ navigate: (path: string) => void;
71
+ agentServer: {
72
+ request: <T = unknown>(request: CanvasExtensionAgentServerRequest) => Promise<T>;
73
+ };
74
+ }
75
+ export interface CanvasExtensionModule {
76
+ activate: (host: CanvasExtensionHost) => void | CanvasExtensionDispose | Promise<void | CanvasExtensionDispose>;
77
+ }
@@ -0,0 +1,6 @@
1
+ //#region src/types/canvas-extension.ts
2
+ var e = 1, t = "1";
3
+ //#endregion
4
+ export { t as CANVAS_EXTENSION_HOST_API_VERSION, e as CANVAS_EXTENSION_MANIFEST_SCHEMA_VERSION };
5
+
6
+ //# sourceMappingURL=canvas-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvas-extension.js","names":[],"sources":["../../src/types/canvas-extension.ts"],"sourcesContent":["export const CANVAS_EXTENSION_MANIFEST_SCHEMA_VERSION = 1 as const;\nexport const CANVAS_EXTENSION_HOST_API_VERSION = \"1\" as const;\n\nexport interface CanvasExtensionPageContribution {\n id: string;\n title: string;\n path: string;\n nav_label?: string | null;\n description?: string | null;\n}\n\nexport interface CanvasExtensionContributions {\n pages?: CanvasExtensionPageContribution[] | null;\n}\n\n/** Parsed contents of `canvas-extension.json`. */\nexport interface CanvasExtensionManifest {\n schema_version: typeof CANVAS_EXTENSION_MANIFEST_SCHEMA_VERSION;\n name: string;\n display_name?: string | null;\n version: string;\n description?: string | null;\n entrypoint: string;\n contributes?: CanvasExtensionContributions | null;\n}\n\nexport interface InstalledCanvasExtensionInfo {\n name: string;\n version: string;\n description?: string | null;\n enabled: boolean;\n source: string;\n requested_ref?: string | null;\n resolved_ref?: string | null;\n repo_path?: string | null;\n installed_at: string;\n install_path: string;\n /** Absent until the backend exposes page contributions (OSS-10048). */\n manifest?: CanvasExtensionManifest | null;\n}\n\nexport interface InstallCanvasExtensionRequest {\n source: string;\n ref?: string | null;\n repo_path?: string | null;\n force?: boolean;\n}\n\nexport type CanvasExtensionDispose = () => void;\n\nexport interface CanvasExtensionPageMountContext {\n container: HTMLElement;\n /** Remainder of the route below the page contribution's declared path. */\n path: string;\n navigate: (path: string) => void;\n}\n\nexport type CanvasExtensionPageMount = (\n context: CanvasExtensionPageMountContext,\n) => void | CanvasExtensionDispose | Promise<void | CanvasExtensionDispose>;\n\nexport interface CanvasExtensionAgentServerRequest {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n path: string;\n body?: unknown;\n headers?: Record<string, string>;\n}\n\nexport interface CanvasExtensionHost {\n readonly apiVersion: typeof CANVAS_EXTENSION_HOST_API_VERSION;\n readonly extension: Readonly<{\n name: string;\n version: string;\n resolvedRef: string | null;\n }>;\n readonly backend: Readonly<{\n id: string;\n kind: \"local\" | \"cloud\";\n orgId: string | null;\n }>;\n registerPage: (\n contributionId: string,\n mount: CanvasExtensionPageMount,\n ) => CanvasExtensionDispose;\n navigate: (path: string) => void;\n agentServer: {\n request: <T = unknown>(\n request: CanvasExtensionAgentServerRequest,\n ) => Promise<T>;\n };\n}\n\nexport interface CanvasExtensionModule {\n activate: (\n host: CanvasExtensionHost,\n ) => void | CanvasExtensionDispose | Promise<void | CanvasExtensionDispose>;\n}\n"],"mappings":";AAAA,IAAa,IAA2C,GAC3C,IAAoC"}
@@ -113,7 +113,14 @@ export type Settings = {
113
113
  search_api_key?: string;
114
114
  is_new_user?: boolean;
115
115
  mcp_config?: MCPConfig;
116
+ /** Deny-list over user- and project-authored skills. */
116
117
  disabled_skills?: string[];
118
+ /**
119
+ * Allow-list over the bundled `@openhands/extensions` catalog. `undefined`
120
+ * means "never migrated", the only signal `migrateSkillEnablement` has, so
121
+ * it is deliberately absent from `DEFAULT_SETTINGS`.
122
+ */
123
+ enabled_skills?: string[];
117
124
  max_budget_per_task: number | null;
118
125
  email?: string;
119
126
  email_verified?: boolean;
@@ -1,2 +1,2 @@
1
- require("../_virtual/_rolldown/runtime.cjs");const e=require("../utils/utils.cjs"),t=require("../node_modules/class-variance-authority/dist/index.cjs");let n=require("react/jsx-runtime");var r=t.cva(``,{variants:{size:{default:`text-xs`,settings:`text-sm text-[var(--oh-muted)] font-normal leading-5.5`},linkColor:{default:``,white:`text-white`}},defaultVariants:{size:`default`,linkColor:`default`}});function i({testId:t,text:i,linkText:a,href:o,suffix:s,size:c,linkColor:l,className:u,linkTextClassName:d,suffixClassName:f}){return(0,n.jsxs)(`p`,{"data-testid":t,className:e.cn(r({size:c}),u),children:[i,` `,(0,n.jsx)(`a`,{href:o,rel:`noreferrer noopener`,target:`_blank`,className:e.cn(`underline underline-offset-2`,r({size:c,linkColor:l}),d),children:a}),s&&(0,n.jsx)(`span`,{className:f,children:s})]})}exports.HelpLink=i;
1
+ require("../_virtual/_rolldown/runtime.cjs");const e=require("../utils/utils.cjs"),t=require("../node_modules/class-variance-authority/dist/index.cjs");let n=require("react/jsx-runtime");var r=t.cva(``,{variants:{size:{default:`text-xs`,settings:`text-sm text-[var(--oh-muted)] font-normal leading-5.5`},linkColor:{default:``,white:`text-white`}},defaultVariants:{size:`default`,linkColor:`default`}});function i({testId:t,text:i,linkText:a,href:o,suffix:s,suffixLinkText:c,suffixLinkHref:l,trailing:u,size:d,linkColor:f,className:p,linkTextClassName:m,suffixClassName:h}){return(0,n.jsxs)(`p`,{"data-testid":t,className:e.cn(r({size:d}),p),children:[i,` `,(0,n.jsx)(`a`,{href:o,rel:`noreferrer noopener`,target:`_blank`,className:e.cn(`underline underline-offset-2`,r({size:d,linkColor:f}),m),children:a}),s&&(0,n.jsx)(`span`,{className:h,children:s}),c&&l?(0,n.jsxs)(n.Fragment,{children:[` `,(0,n.jsx)(`a`,{href:l,rel:`noreferrer noopener`,target:`_blank`,className:e.cn(`underline underline-offset-2`,r({size:d,linkColor:f}),m),children:c}),u]}):null]})}exports.HelpLink=i;
2
2
  //# sourceMappingURL=help-link.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"help-link.cjs","names":[],"sources":["../../src/ui/help-link.tsx"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"#/utils/utils\";\n\nconst helpLinkVariants = cva(\"\", {\n variants: {\n size: {\n default: \"text-xs\",\n settings: \"text-sm text-[var(--oh-muted)] font-normal leading-5.5\",\n },\n linkColor: {\n default: \"\",\n white: \"text-white\",\n },\n },\n defaultVariants: {\n size: \"default\",\n linkColor: \"default\",\n },\n});\n\ninterface HelpLinkProps extends VariantProps<typeof helpLinkVariants> {\n testId: string;\n text: string;\n linkText: string;\n href: string;\n suffix?: string;\n className?: string;\n linkTextClassName?: string;\n suffixClassName?: string;\n}\n\nexport function HelpLink({\n testId,\n text,\n linkText,\n href,\n suffix,\n size,\n linkColor,\n className,\n linkTextClassName,\n suffixClassName,\n}: HelpLinkProps) {\n return (\n <p\n data-testid={testId}\n className={cn(helpLinkVariants({ size }), className)}\n >\n {text}{\" \"}\n <a\n href={href}\n rel=\"noreferrer noopener\"\n target=\"_blank\"\n className={cn(\n \"underline underline-offset-2\",\n helpLinkVariants({ size, linkColor }),\n linkTextClassName,\n )}\n >\n {linkText}\n </a>\n {suffix && <span className={suffixClassName}>{suffix}</span>}\n </p>\n );\n}\n"],"mappings":"2LAGA,IAAM,EAAmB,EAAA,IAAI,GAAI,CAC/B,SAAU,CACR,KAAM,CACJ,QAAS,UACT,SAAU,wDACZ,EACA,UAAW,CACT,QAAS,GACT,MAAO,YACT,CACF,EACA,gBAAiB,CACf,KAAM,UACN,UAAW,SACb,CACF,CAAC,EAaD,SAAgB,EAAS,CACvB,SACA,OACA,WACA,OACA,SACA,OACA,YACA,YACA,oBACA,mBACgB,CAChB,OACE,EAAA,EAAA,MAAC,IAAD,CACE,cAAa,EACb,UAAW,EAAA,GAAG,EAAiB,CAAE,MAAK,CAAC,EAAG,CAAS,WAFrD,CAIG,EAAM,KACP,EAAA,EAAA,KAAC,IAAD,CACQ,OACN,IAAI,sBACJ,OAAO,SACP,UAAW,EAAA,GACT,+BACA,EAAiB,CAAE,OAAM,WAAU,CAAC,EACpC,CACF,WAEC,CACA,CAAA,EACF,IAAU,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,WAAkB,CAAa,CAAA,CAC1D,GAEP"}
1
+ {"version":3,"file":"help-link.cjs","names":[],"sources":["../../src/ui/help-link.tsx"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"#/utils/utils\";\n\nconst helpLinkVariants = cva(\"\", {\n variants: {\n size: {\n default: \"text-xs\",\n settings: \"text-sm text-[var(--oh-muted)] font-normal leading-5.5\",\n },\n linkColor: {\n default: \"\",\n white: \"text-white\",\n },\n },\n defaultVariants: {\n size: \"default\",\n linkColor: \"default\",\n },\n});\n\ninterface HelpLinkProps extends VariantProps<typeof helpLinkVariants> {\n testId: string;\n text: string;\n linkText: string;\n href: string;\n suffix?: string;\n /** Optional second link rendered after the suffix. */\n suffixLinkText?: string;\n suffixLinkHref?: string;\n /** Trailing text rendered after the second link (e.g. a period). */\n trailing?: string;\n className?: string;\n linkTextClassName?: string;\n suffixClassName?: string;\n}\n\nexport function HelpLink({\n testId,\n text,\n linkText,\n href,\n suffix,\n suffixLinkText,\n suffixLinkHref,\n trailing,\n size,\n linkColor,\n className,\n linkTextClassName,\n suffixClassName,\n}: HelpLinkProps) {\n return (\n <p\n data-testid={testId}\n className={cn(helpLinkVariants({ size }), className)}\n >\n {text}{\" \"}\n <a\n href={href}\n rel=\"noreferrer noopener\"\n target=\"_blank\"\n className={cn(\n \"underline underline-offset-2\",\n helpLinkVariants({ size, linkColor }),\n linkTextClassName,\n )}\n >\n {linkText}\n </a>\n {suffix && <span className={suffixClassName}>{suffix}</span>}\n {suffixLinkText && suffixLinkHref ? (\n <>\n {\" \"}\n <a\n href={suffixLinkHref}\n rel=\"noreferrer noopener\"\n target=\"_blank\"\n className={cn(\n \"underline underline-offset-2\",\n helpLinkVariants({ size, linkColor }),\n linkTextClassName,\n )}\n >\n {suffixLinkText}\n </a>\n {trailing}\n </>\n ) : null}\n </p>\n );\n}\n"],"mappings":"2LAGA,IAAM,EAAmB,EAAA,IAAI,GAAI,CAC/B,SAAU,CACR,KAAM,CACJ,QAAS,UACT,SAAU,wDACZ,EACA,UAAW,CACT,QAAS,GACT,MAAO,YACT,CACF,EACA,gBAAiB,CACf,KAAM,UACN,UAAW,SACb,CACF,CAAC,EAkBD,SAAgB,EAAS,CACvB,SACA,OACA,WACA,OACA,SACA,iBACA,iBACA,WACA,OACA,YACA,YACA,oBACA,mBACgB,CAChB,OACE,EAAA,EAAA,MAAC,IAAD,CACE,cAAa,EACb,UAAW,EAAA,GAAG,EAAiB,CAAE,MAAK,CAAC,EAAG,CAAS,WAFrD,CAIG,EAAM,KACP,EAAA,EAAA,KAAC,IAAD,CACQ,OACN,IAAI,sBACJ,OAAO,SACP,UAAW,EAAA,GACT,+BACA,EAAiB,CAAE,OAAM,WAAU,CAAC,EACpC,CACF,WAEC,CACA,CAAA,EACF,IAAU,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,WAAkB,CAAa,CAAA,EAC1D,GAAkB,GACjB,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,CACG,KACD,EAAA,EAAA,KAAC,IAAD,CACE,KAAM,EACN,IAAI,sBACJ,OAAO,SACP,UAAW,EAAA,GACT,+BACA,EAAiB,CAAE,OAAM,WAAU,CAAC,EACpC,CACF,WAEC,CACA,CAAA,EACF,CACD,CAAA,CAAA,EACA,IACH,GAEP"}
@@ -9,9 +9,14 @@ interface HelpLinkProps extends VariantProps<typeof helpLinkVariants> {
9
9
  linkText: string;
10
10
  href: string;
11
11
  suffix?: string;
12
+ /** Optional second link rendered after the suffix. */
13
+ suffixLinkText?: string;
14
+ suffixLinkHref?: string;
15
+ /** Trailing text rendered after the second link (e.g. a period). */
16
+ trailing?: string;
12
17
  className?: string;
13
18
  linkTextClassName?: string;
14
19
  suffixClassName?: string;
15
20
  }
16
- export declare function HelpLink({ testId, text, linkText, href, suffix, size, linkColor, className, linkTextClassName, suffixClassName, }: HelpLinkProps): import("react").JSX.Element;
21
+ export declare function HelpLink({ testId, text, linkText, href, suffix, suffixLinkText, suffixLinkHref, trailing, size, linkColor, className, linkTextClassName, suffixClassName, }: HelpLinkProps): import("react").JSX.Element;
17
22
  export {};