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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (460) hide show
  1. package/README.md +2 -2
  2. package/README.windows.md +2 -2
  3. package/build/assets/{QueryClientProvider-w1cZWY41.js → QueryClientProvider-7oLZ1RtQ.js} +1 -1
  4. package/build/assets/{Trans-BJeYqz2A.js → Trans-rF21Jwln.js} +1 -1
  5. package/build/assets/acp-providers-C55k29rf.js +1 -0
  6. package/build/assets/active-backend-context-CQTk4wD8.js +1 -0
  7. package/build/assets/add-backend-modal-BdYxoUdL.js +1 -0
  8. package/build/assets/agent-server-client-options-Dvgeb3x4.js +1 -0
  9. package/build/assets/agent-server-compatibility-BANjmMTo.js +1 -0
  10. package/build/assets/agent-server-conversation-service.api-js3oYcdU.js +5 -0
  11. package/build/assets/{agent-settings-BXBaybB_.js → agent-settings-BNrffu3I.js} +1 -1
  12. package/build/assets/{alert-banner-NeUl1-PQ.js → alert-banner-BzU93oDh.js} +1 -1
  13. package/build/assets/{analytics-consent-form-modal-DxkThW4K.js → analytics-consent-form-modal-Ce-_Skcd.js} +1 -1
  14. package/build/assets/api-key-entry-screen-CGyS-Cna.js +1 -0
  15. package/build/assets/{app-settings-C-U6jONZ.js → app-settings-DmOs4oik.js} +1 -1
  16. package/build/assets/automation-detail-DLbCVJCw.js +1 -0
  17. package/build/assets/{automations-list-BLJzAd-p.js → automations-list-Ces5shz5.js} +1 -1
  18. package/build/assets/{back-nav-button-DgkK0Ka6.js → back-nav-button-BDM9vr_o.js} +1 -1
  19. package/build/assets/backend-form-modal-BUy-PzZN.js +1 -0
  20. package/build/assets/{backend-synced-settings-badge-BktJcGgH.js → backend-synced-settings-badge-1A63yxGs.js} +1 -1
  21. package/build/assets/{base-modal-DZCNv0A4.js → base-modal-Ba5WcNb6.js} +1 -1
  22. package/build/assets/{brand-button-LBFNic99.js → brand-button-BoiPxAGm.js} +1 -1
  23. package/build/assets/browser-B8bp1IqT.js +5 -0
  24. package/build/assets/browser-store-C5uQbbIi.js +1 -0
  25. package/build/assets/{browser-tab-be3QvXg9.js → browser-tab-CiBRWB4X.js} +1 -1
  26. package/build/assets/chat-send-button-qKFZuB9E.js +1 -0
  27. package/build/assets/check-BDAbW7je.js +1 -0
  28. package/build/assets/{checkmark-Rmpruj7q.js → checkmark-SEZPnU2I.js} +1 -1
  29. package/build/assets/{chevron-down-KhWYEjeW.js → chevron-down-DUxWwzTm.js} +1 -1
  30. package/build/assets/{chevron-left-small-6nyFCWVQ.js → chevron-left-small-x9_-ucHG.js} +1 -1
  31. package/build/assets/{circle-plus-check-toggle-DquBwJ_6.js → circle-plus-check-toggle-CboDp7XB.js} +1 -1
  32. package/build/assets/{close-D_o3d8QM.js → close-CbOsKMRg.js} +1 -1
  33. package/build/assets/{code-tag-DhsjDB-v.js → code-tag-C0vR_IQH.js} +1 -1
  34. package/build/assets/{color-themes-0biOprdo.js → color-themes-B9n7pBQl.js} +1 -1
  35. package/build/assets/{combobox-caret-CO7eozIY.js → combobox-caret-DwMmhrrA.js} +1 -1
  36. package/build/assets/{command-store-UzKGSUC2.js → command-store-BUWgE-vZ.js} +1 -1
  37. package/build/assets/{condenser-settings-BulzYEuW.js → condenser-settings-FCBjvqSo.js} +1 -1
  38. package/build/assets/{confirmation-modal-CMAtd9R0.js → confirmation-modal-BPgWqWRI.js} +1 -1
  39. package/build/assets/{context-menu-list-item-D0swnhFt.js → context-menu-list-item-CHWCx1Mc.js} +1 -1
  40. package/build/assets/conversation-CT8AvxEH.js +1 -0
  41. package/build/assets/conversation-panel-DqDDs4WZ.js +1 -0
  42. package/build/assets/conversation-service.api-y_eB_43m.js +1 -0
  43. package/build/assets/conversation-state-store-DpgQaK_O.js +1 -0
  44. package/build/assets/conversation-store-CiYGBud3.js +6 -0
  45. package/build/assets/{conversation-tab-empty-state-DYjKsg_c.js → conversation-tab-empty-state-Ba5hbJhn.js} +1 -1
  46. package/build/assets/conversation-vNuLKgz6.js +19 -0
  47. package/build/assets/conversation-websocket-context-Bb4XBXoc.js +3 -0
  48. package/build/assets/{copy-BM0RpLez.js → copy-CAxUvM-U.js} +1 -1
  49. package/build/assets/{custom-toast-handlers-BohXx7uh.js → custom-toast-handlers-fgD4IYsu.js} +1 -1
  50. package/build/assets/{declaration-DaUdB2Wg.js → declaration-IA661TBv.js} +1 -1
  51. package/build/assets/{device-verify-DiEJqpJb.js → device-verify-BOQz2LJQ.js} +1 -1
  52. package/build/assets/{dist-xtCm0O6P.js → dist-B-SKiGDl.js} +1 -1
  53. package/build/assets/dist-CeJSjcAI.js +1 -0
  54. package/build/assets/{dropdown-classes-Vqz86I0R.js → dropdown-classes-lT1LUsbO.js} +1 -1
  55. package/build/assets/edit-automation-modal-C-oC5tis.js +1 -0
  56. package/build/assets/ellipsis-button-CiLx8dqc.js +1 -0
  57. package/build/assets/{entry.client-BvKgdCQ9.js → entry.client-Db3BpFL_.js} +2 -2
  58. package/build/assets/{enum-filter-dropdown-DdFgk0EM.js → enum-filter-dropdown-DFwoVtOw.js} +1 -1
  59. package/build/assets/{environment-switch-overlay-CuBuZOaa.js → environment-switch-overlay-Cow6h62p.js} +1 -1
  60. package/build/assets/{extensions-hub-Dayqvv0n.js → extensions-hub-BxZbAtjP.js} +1 -1
  61. package/build/assets/extensions-navigation-BIb-vAa2.js +1 -0
  62. package/build/assets/{file-DwHCkWZT.js → file-BJCSojij.js} +1 -1
  63. package/build/assets/files-tab-DpulQlIo.js +1 -0
  64. package/build/assets/files-tab-store-CZAEwv3x.js +1 -0
  65. package/build/assets/{folder-2h1hR1Qb.js → folder-wShAU0y7.js} +1 -1
  66. package/build/assets/git-control-bar-branch-button-D1uam-nI.js +27 -0
  67. package/build/assets/{globe-qFjFNG6J.js → globe-CQ_5xwpo.js} +1 -1
  68. package/build/assets/home-sJAFzI6v.js +1 -0
  69. package/build/assets/{i18n-zDndR1Ne.js → i18n-CyvU1o95.js} +1 -1
  70. package/build/assets/install-server-modal-BjEzlLF5.js +1 -0
  71. package/build/assets/{launch-I00QV8YT.js → launch-DgtB1JTX.js} +1 -1
  72. package/build/assets/{lesson-plan-C18uB_56.js → lesson-plan-B607buca.js} +1 -1
  73. package/build/assets/{link-external-DtcdPFbw.js → link-external-DCsHkAj4.js} +1 -1
  74. package/build/assets/llm-client-BnqeDPua.js +1 -0
  75. package/build/assets/llm-settings-B8kPJ0Of.js +1 -0
  76. package/build/assets/llm-settings-CjUpPsvA.js +1 -0
  77. package/build/assets/{loading-spinner-DNwR4--Z.js → loading-spinner-CFuA0UNt.js} +1 -1
  78. package/build/assets/manage-backends-modal-CTA-2x4F.js +1 -0
  79. package/build/assets/manifest-d3e8504d.js +1 -0
  80. package/build/assets/{markdown-renderer-D6B-u2nM.js → markdown-renderer-oOUs3tw5.js} +1 -1
  81. package/build/assets/mcp-client-xEdbDxOL.js +1 -0
  82. package/build/assets/mcp-kJYdM8aJ.js +9 -0
  83. package/build/assets/messages-BFJXB6MW.js +36 -0
  84. package/build/assets/{modal-backdrop-BDqI1zBV.js → modal-backdrop-B1si6TUd.js} +1 -1
  85. package/build/assets/{modal-body-CCLCqX1J.js → modal-body-2Po2nl1e.js} +1 -1
  86. package/build/assets/{modal-classes-DwTdT3IK.js → modal-classes-9XTtWCtF.js} +1 -1
  87. package/build/assets/{modal-close-button-gQgKqUf-.js → modal-close-button-DY-rVmld.js} +1 -1
  88. package/build/assets/model-selector-z_QOzaRV.js +1 -0
  89. package/build/assets/{navigation-context-aNGUUtdq.js → navigation-context-CszaA-CJ.js} +1 -1
  90. package/build/assets/{navigation-link-CYkF2y3K.js → navigation-link-DXg4oo29.js} +1 -1
  91. package/build/assets/onboarding-CZ_7nd-M.js +1 -0
  92. package/build/assets/{openhands-logo-CHmtDV-t.js → openhands-logo-B-IDE1ER.js} +1 -1
  93. package/build/assets/{option-service.api-CGNANEcT.js → option-service.api-DHOGfYKh.js} +1 -1
  94. package/build/assets/organization-service.api-D79cdERN.js +1 -0
  95. package/build/assets/path-utils-0KWEiRs9.js +1 -0
  96. package/build/assets/{pencil-Dr0b2jL1.js → pencil-COslZGUC.js} +1 -1
  97. package/build/assets/{plan-components--aLlpASH.js → plan-components-DsiDjcDi.js} +1 -1
  98. package/build/assets/{planner-tab-B-5EeCEm.js → planner-tab-CNmJiZ22.js} +1 -1
  99. package/build/assets/plus-D8aJZRkD.js +1 -0
  100. package/build/assets/profiles-client-CesbAK-7.js +1 -0
  101. package/build/assets/{providers-DknP6O2g.js → providers-Bpq3xFRA.js} +1 -1
  102. package/build/assets/proxy-wIasY2Po.js +1 -0
  103. package/build/assets/{query-client-config-CWWGQWvw.js → query-client-config-CITeuHD7.js} +1 -1
  104. package/build/assets/{recommended-automations-launcher-BIul0osB.js → recommended-automations-launcher-B1kfmFTQ.js} +8 -10
  105. package/build/assets/root-CIZ7Rv1X.js +2 -0
  106. package/build/assets/root-layout-B5ijp9At.js +2 -0
  107. package/build/assets/{sdk-section-page-VmtJWH3A.js → sdk-section-page-DTyvCc52.js} +1 -1
  108. package/build/assets/{sdk-settings-schema-DFievvEK.js → sdk-settings-schema-B0KrqqPX.js} +1 -1
  109. package/build/assets/{search-BeVRXvX7.js → search-BqXT2Ied.js} +1 -1
  110. package/build/assets/secrets-service-rJqZtDmI.js +1 -0
  111. package/build/assets/{secrets-settings-BLMvCkKm.js → secrets-settings-BQNSDLKS.js} +1 -1
  112. package/build/assets/server-client-Cz8PyIbN.js +1 -0
  113. package/build/assets/settings-BUlJrO_h.js +1 -0
  114. package/build/assets/settings-client-BUlG0Gzq.js +1 -0
  115. package/build/assets/{settings-dropdown-input-DA_pzHWE.js → settings-dropdown-input-BUk4m23x.js} +1 -1
  116. package/build/assets/{settings-gear-aNebYlCy.js → settings-gear-DFmoMp-6.js} +1 -1
  117. package/build/assets/{settings-index-CycvkOoq.js → settings-index-DE91Eahc.js} +1 -1
  118. package/build/assets/{settings-input-8y5p4kze.js → settings-input-DsoZj8Dm.js} +1 -1
  119. package/build/assets/{settings-list-classes-Qk7zl0Wu.js → settings-list-classes-D8VAVZmi.js} +1 -1
  120. package/build/assets/{settings-modal-DdntdOGP.js → settings-modal-CCaPYVqW.js} +1 -1
  121. package/build/assets/{settings-section-header-context-B77tsYlx.js → settings-section-header-context-D61smD-W.js} +1 -1
  122. package/build/assets/settings-service.api-4u2RKC8k.js +1 -0
  123. package/build/assets/{settings-switch-ba4DuiNO.js → settings-switch-BQiAS9ga.js} +1 -1
  124. package/build/assets/{settings-utils-BxzHqLmZ.js → settings-utils-chxTa1vn.js} +1 -1
  125. package/build/assets/shared-conversation-sBPLAawM.js +1 -0
  126. package/build/assets/{sidebar-mobile-menu-toggle-C0mmabKj.js → sidebar-mobile-menu-toggle-BDXWzhyB.js} +1 -1
  127. package/build/assets/{sidebar-nav-link-BsYdDFfb.js → sidebar-nav-link-Bhlzlhp8.js} +1 -1
  128. package/build/assets/{skill-card-pill-row-BhUlGcYB.js → skill-card-pill-row-Bg5joQf6.js} +1 -1
  129. package/build/assets/{skills-TYjOUQ2d.js → skills-BDOWVle-.js} +1 -1
  130. package/build/assets/skills-client-Cr9F5306.js +1 -0
  131. package/build/assets/{skills-plugins-D0pdqgKa.js → skills-plugins-fihjo1KZ.js} +1 -1
  132. package/build/assets/{skills-settings-VqKTkmVl.js → skills-settings-NQnuMwZP.js} +1 -1
  133. package/build/assets/{styled-tooltip-TCp7svY3.js → styled-tooltip-GXy1qxsO.js} +1 -1
  134. package/build/assets/suspense-C9MBE_9N.js +1 -0
  135. package/build/assets/{switch-skeleton-cKrdaYGj.js → switch-skeleton-QpdcdxRP.js} +1 -1
  136. package/build/assets/{task-list-tab-BiizRsY3.js → task-list-tab-Hl9BuVfq.js} +1 -1
  137. package/build/assets/telemetry-j9SLrtY7.js +2 -0
  138. package/build/assets/{terminal-BSYITdM0.js → terminal-BUww3Ssl.js} +1 -1
  139. package/build/assets/{terminal-CpgZx6go.js → terminal-DRwe8--D.js} +1 -1
  140. package/build/assets/{toggle-switch-CUgOZqZu.js → toggle-switch-DDr-DnEc.js} +1 -1
  141. package/build/assets/{trash-2-CbVljPko.js → trash-2-DAKXV2Wm.js} +1 -1
  142. package/build/assets/{typography-Bvw0IxaN.js → typography-Cx7uw7z3.js} +1 -1
  143. package/build/assets/{u-check-circle-u9QiS4Fr.js → u-check-circle-CftRwky1.js} +1 -1
  144. package/build/assets/{u-check-circle-half-DjpjzWu3.js → u-check-circle-half-sGVk0BtL.js} +1 -1
  145. package/build/assets/{u-circuit-DlBlOwx9.js → u-circuit-Cg9tH5qb.js} +1 -1
  146. package/build/assets/{u-edit-BIYzjs3v.js → u-edit-foF02hwH.js} +1 -1
  147. package/build/assets/{use-active-conversation-q1wT8LI5.js → use-active-conversation-DJGoI9Mc.js} +1 -1
  148. package/build/assets/use-agent-settings-schema-DtusObuC.js +1 -0
  149. package/build/assets/{use-agent-state-CCHlVqvY.js → use-agent-state-BXgWhFh6.js} +1 -1
  150. package/build/assets/{use-cloud-current-user-id-BAKf91Zx.js → use-cloud-current-user-id-e1Pk7NxQ.js} +1 -1
  151. package/build/assets/use-config-DSzkljTq.js +1 -0
  152. package/build/assets/use-create-conversation-CzvaVA5A.js +1 -0
  153. package/build/assets/use-event-store-DSpvASbC.js +1 -0
  154. package/build/assets/use-get-secrets-DiLgP147.js +1 -0
  155. package/build/assets/use-handle-plan-click-CUZwmKIk.js +1 -0
  156. package/build/assets/use-is-authed-fNsj-Adj.js +1 -0
  157. package/build/assets/{use-launch-skill-in-chat-3ydwpi_M.js → use-launch-skill-in-chat-ClRJlIx7.js} +1 -1
  158. package/build/assets/use-llm-profiles-CyNVoVqm.js +1 -0
  159. package/build/assets/use-runtime-is-ready-CWkGQFsb.js +1 -0
  160. package/build/assets/{use-save-settings-rE9aA29R.js → use-save-settings-CP23emUY.js} +1 -1
  161. package/build/assets/use-settings-0qFqC-r6.js +1 -0
  162. package/build/assets/{use-settings-nav-items-C7MOWj09.js → use-settings-nav-items-C6YxUn4h.js} +1 -1
  163. package/build/assets/use-skills-BWHATXK-.js +1 -0
  164. package/build/assets/{use-task-list-YMkSzdDv.js → use-task-list-JPudBRv3.js} +1 -1
  165. package/build/assets/{use-tracking-DQYdZpxi.js → use-tracking-CjLZgh8X.js} +1 -1
  166. package/build/assets/use-unified-vscode-url-DSn2tT08.js +1 -0
  167. package/build/assets/use-user-conversation-CQ5IwnZk.js +1 -0
  168. package/build/assets/{useMutation-DDo48A8t.js → useMutation-7hG0GuPx.js} +1 -1
  169. package/build/assets/useQuery-JDs8UaWj.js +1 -0
  170. package/build/assets/{useTranslation-CEcjrme-.js → useTranslation-CbJtty1g.js} +1 -1
  171. package/build/assets/{utils-CdgBzLA7.js → utils-CVcuFUYj.js} +1 -1
  172. package/build/assets/{vendor~browser-DWk6fNtJ.js → vendor~browser-Dwwc84Zf.js} +1 -1
  173. package/build/assets/{vendor~browser-tab-NZdVoI2Z.js → vendor~browser-tab-Bhohe29F.js} +1 -1
  174. package/build/assets/{vendor~conversation-panel~conversation-gp03cWZW.js → vendor~conversation-panel~conversation-DYHL7QoY.js} +1 -1
  175. package/build/assets/{vendor~conversation-panel~conversation~index-BZ5C6Xpz.js → vendor~conversation-panel~conversation~index-Be58Romv.js} +1 -1
  176. package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~oli4dvxu-BodGsxSf.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~oli4dvxu-CBEOG8NF.js} +1 -1
  177. package/build/assets/{vendor~files-tab-Buz36Y-q.js → vendor~files-tab-B447_Zns.js} +1 -1
  178. package/build/assets/{vendor~home~conversation-panel~conversation-DG0H5SkJ.js → vendor~home~conversation-panel~conversation-DZ-F7J6T.js} +1 -1
  179. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CXivI4Ym.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-B4oeCCli.js} +1 -1
  180. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-9Il_wz8U.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CQQAW8hY.js} +1 -1
  181. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-1pTajrpX.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DFsI4CLy.js} +1 -1
  182. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Ceeqkj0k.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DcvlNgbn.js} +1 -1
  183. package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-B7I1ZxCx.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-ojk_J4bB.js} +1 -1
  184. package/build/assets/{vendor~launch-DXL78kBf.js → vendor~launch-BdXJCmwc.js} +1 -1
  185. package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-CfAc3nMS.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-DToubnIU.js} +1 -1
  186. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation-DkwcKRtv.js → vendor~root-layout~home~conversation-panel~conversation-Cg0nXqVs.js} +1 -1
  187. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-DSqEbr0N.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~bok0tgtf-Dr8Ly0at.js} +1 -1
  188. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-BC9XTECT.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~bok0tgtf-DveauQfg.js} +1 -1
  189. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-D0XUSHNN.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~jpfhx3ls-zdl_Rltz.js} +2 -2
  190. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~settings~settings-index~agen~jxrvuot9-BaCzvZac.js +48 -0
  191. package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-CcFtthyg.js → vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-BwbkftxT.js} +1 -1
  192. package/build/assets/{vendor~root-layout~home~mcp~automations-list-cNHi83v_.js → vendor~root-layout~home~mcp~automations-list-CtdIEhjQ.js} +1 -1
  193. package/build/assets/{vendor~root-layout~home~mcp~automations-list-BnIlGhjl.js → vendor~root-layout~home~mcp~automations-list-DGOI7kQz.js} +1 -1
  194. package/build/assets/{vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-BGWUbqUq.js → vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-CbuXadI-.js} +1 -1
  195. package/build/assets/{vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-BuCSnjsW.js → vendor~root-layout~home~mcp~llm-settings~agent-settings~condenser-settings~verification-set~o7tv66sg-iPAfRWNQ.js} +2 -2
  196. package/build/assets/{verification-settings-CIqtxWat.js → verification-settings-Cm02KmeI.js} +1 -1
  197. package/build/assets/{vscode-tab-DEt72yJX.js → vscode-tab-AF70Yke0.js} +1 -1
  198. package/build/assets/{waiting-for-runtime-message-DSjJfeoj.js → waiting-for-runtime-message-Bg27u9JB.js} +1 -1
  199. package/build/assets/x-8AbJWTbX.js +1 -0
  200. package/build/assets/{x-mark-DsJ9tDD0.js → x-mark-Cn-YJVbN.js} +1 -1
  201. package/build/index.html +4 -4
  202. package/build/locales/ar/openhands.json +2 -1
  203. package/build/locales/ca/openhands.json +2 -1
  204. package/build/locales/de/openhands.json +2 -1
  205. package/build/locales/en/openhands.json +2 -1
  206. package/build/locales/es/openhands.json +2 -1
  207. package/build/locales/fr/openhands.json +2 -1
  208. package/build/locales/it/openhands.json +2 -1
  209. package/build/locales/ja/openhands.json +2 -1
  210. package/build/locales/ko-KR/openhands.json +2 -1
  211. package/build/locales/no/openhands.json +2 -1
  212. package/build/locales/pt/openhands.json +2 -1
  213. package/build/locales/tr/openhands.json +2 -1
  214. package/build/locales/uk/openhands.json +2 -1
  215. package/build/locales/zh-CN/openhands.json +2 -1
  216. package/build/locales/zh-TW/openhands.json +2 -1
  217. package/config/defaults.json +1 -1
  218. package/dist/api/agent-server-adapter.cjs +3 -3
  219. package/dist/api/agent-server-adapter.cjs.map +1 -1
  220. package/dist/api/agent-server-adapter.js +94 -86
  221. package/dist/api/agent-server-adapter.js.map +1 -1
  222. package/dist/api/app-preferences-store.cjs.map +1 -1
  223. package/dist/api/app-preferences-store.d.ts +6 -2
  224. package/dist/api/app-preferences-store.js.map +1 -1
  225. package/dist/api/cloud/proxy.cjs +1 -1
  226. package/dist/api/cloud/proxy.cjs.map +1 -1
  227. package/dist/api/cloud/proxy.d.ts +18 -6
  228. package/dist/api/cloud/proxy.js +1 -1
  229. package/dist/api/cloud/proxy.js.map +1 -1
  230. package/dist/api/conversation-metadata-store.cjs.map +1 -1
  231. package/dist/api/conversation-metadata-store.d.ts +8 -0
  232. package/dist/api/conversation-metadata-store.js.map +1 -1
  233. package/dist/api/conversation-service/agent-server-conversation-service.types.d.ts +9 -0
  234. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs +1 -1
  235. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs.map +1 -1
  236. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js +9 -9
  237. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js.map +1 -1
  238. package/dist/components/conversation-events/chat/event-message.cjs +1 -1
  239. package/dist/components/conversation-events/chat/event-message.cjs.map +1 -1
  240. package/dist/components/conversation-events/chat/event-message.js +80 -71
  241. package/dist/components/conversation-events/chat/event-message.js.map +1 -1
  242. package/dist/components/features/automations/recommended-automations-launcher.d.ts +7 -1
  243. package/dist/components/features/chat/switch-profile-button.cjs +1 -1
  244. package/dist/components/features/chat/switch-profile-button.cjs.map +1 -1
  245. package/dist/components/features/chat/switch-profile-button.js +5 -5
  246. package/dist/components/features/chat/switch-profile-button.js.map +1 -1
  247. package/dist/components/features/conversation-panel/skills-modal.cjs +1 -1
  248. package/dist/components/features/conversation-panel/skills-modal.cjs.map +1 -1
  249. package/dist/components/features/conversation-panel/skills-modal.js +34 -37
  250. package/dist/components/features/conversation-panel/skills-modal.js.map +1 -1
  251. package/dist/components/features/home/workspace-selection-form.d.ts +1 -0
  252. package/dist/components/features/onboarding/steps/setup-llm-step.d.ts +8 -0
  253. package/dist/components/features/settings/llm-profiles/profile-actions-menu.cjs +1 -1
  254. package/dist/components/features/settings/llm-profiles/profile-actions-menu.js +1 -0
  255. package/dist/components/features/sidebar/sidebar.cjs +1 -1
  256. package/dist/components/features/sidebar/sidebar.js +6 -6
  257. package/dist/components/features/skills/extensions-navigation.cjs +1 -1
  258. package/dist/components/features/skills/extensions-navigation.cjs.map +1 -1
  259. package/dist/components/features/skills/extensions-navigation.d.ts +1 -9
  260. package/dist/components/features/skills/extensions-navigation.js +31 -50
  261. package/dist/components/features/skills/extensions-navigation.js.map +1 -1
  262. package/dist/constants/acp-providers.cjs +1 -1
  263. package/dist/constants/acp-providers.js +1 -1
  264. package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
  265. package/dist/hooks/mutation/use-create-conversation.cjs.map +1 -1
  266. package/dist/hooks/mutation/use-create-conversation.js +26 -14
  267. package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
  268. package/dist/hooks/mutation/use-switch-llm-profile-and-log.cjs +1 -1
  269. package/dist/hooks/mutation/use-switch-llm-profile-and-log.cjs.map +1 -1
  270. package/dist/hooks/mutation/use-switch-llm-profile-and-log.js +26 -15
  271. package/dist/hooks/mutation/use-switch-llm-profile-and-log.js.map +1 -1
  272. package/dist/i18n/declaration.cjs +1 -1
  273. package/dist/i18n/declaration.cjs.map +1 -1
  274. package/dist/i18n/declaration.d.ts +1 -0
  275. package/dist/i18n/declaration.js +1 -1
  276. package/dist/i18n/declaration.js.map +1 -1
  277. package/dist/i18n/translation.cjs +1 -1
  278. package/dist/i18n/translation.cjs.map +1 -1
  279. package/dist/i18n/translation.js +32 -15
  280. package/dist/i18n/translation.js.map +1 -1
  281. package/dist/index.cjs +1 -1
  282. package/dist/index.js +10 -10
  283. package/dist/lib/index.cjs +1 -1
  284. package/dist/lib/index.js +1 -1
  285. package/dist/locales/ar/openhands.json +2 -1
  286. package/dist/locales/ca/openhands.json +2 -1
  287. package/dist/locales/de/openhands.json +2 -1
  288. package/dist/locales/en/openhands.json +2 -1
  289. package/dist/locales/es/openhands.json +2 -1
  290. package/dist/locales/fr/openhands.json +2 -1
  291. package/dist/locales/it/openhands.json +2 -1
  292. package/dist/locales/ja/openhands.json +2 -1
  293. package/dist/locales/ko-KR/openhands.json +2 -1
  294. package/dist/locales/no/openhands.json +2 -1
  295. package/dist/locales/pt/openhands.json +2 -1
  296. package/dist/locales/tr/openhands.json +2 -1
  297. package/dist/locales/uk/openhands.json +2 -1
  298. package/dist/locales/zh-CN/openhands.json +2 -1
  299. package/dist/locales/zh-TW/openhands.json +2 -1
  300. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.cjs +1 -1
  301. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.cjs.map +1 -1
  302. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.js +10 -1
  303. package/dist/node_modules/@openhands/typescript-client/dist/models/acp.js.map +1 -1
  304. package/dist/package.cjs +1 -1
  305. package/dist/package.cjs.map +1 -1
  306. package/dist/package.js +2 -2
  307. package/dist/package.js.map +1 -1
  308. package/dist/routes/llm-settings.cjs +1 -1
  309. package/dist/routes/llm-settings.cjs.map +1 -1
  310. package/dist/routes/llm-settings.js +21 -21
  311. package/dist/routes/llm-settings.js.map +1 -1
  312. package/dist/routes/mcp.cjs +1 -1
  313. package/dist/routes/mcp.cjs.map +1 -1
  314. package/dist/routes/mcp.d.ts +0 -1
  315. package/dist/routes/mcp.js +0 -1
  316. package/dist/routes/mcp.js.map +1 -1
  317. package/dist/types/agent-server/core/events/index.d.ts +1 -0
  318. package/dist/types/agent-server/core/events/streaming-delta-event.d.ts +7 -0
  319. package/dist/types/agent-server/core/openhands-event.d.ts +2 -2
  320. package/dist/types/agent-server/type-guards.cjs +1 -1
  321. package/dist/types/agent-server/type-guards.cjs.map +1 -1
  322. package/dist/types/agent-server/type-guards.d.ts +2 -0
  323. package/dist/types/agent-server/type-guards.js +3 -3
  324. package/dist/types/agent-server/type-guards.js.map +1 -1
  325. package/dist/utils/handle-event-for-ui.cjs +1 -1
  326. package/dist/utils/handle-event-for-ui.cjs.map +1 -1
  327. package/dist/utils/handle-event-for-ui.js +69 -13
  328. package/dist/utils/handle-event-for-ui.js.map +1 -1
  329. package/dist/utils/mcp-config.cjs +1 -1
  330. package/dist/utils/mcp-config.cjs.map +1 -1
  331. package/dist/utils/mcp-config.js +27 -19
  332. package/dist/utils/mcp-config.js.map +1 -1
  333. package/dist/utils/mcp-marketplace-utils.cjs +1 -1
  334. package/dist/utils/mcp-marketplace-utils.cjs.map +1 -1
  335. package/dist/utils/mcp-marketplace-utils.js +38 -18
  336. package/dist/utils/mcp-marketplace-utils.js.map +1 -1
  337. package/dist/utils/normalize-display-model.cjs +1 -1
  338. package/dist/utils/normalize-display-model.cjs.map +1 -1
  339. package/dist/utils/normalize-display-model.js +8 -7
  340. package/dist/utils/normalize-display-model.js.map +1 -1
  341. package/dist/utils/openhands-llm.cjs +1 -1
  342. package/dist/utils/openhands-llm.cjs.map +1 -1
  343. package/dist/utils/openhands-llm.d.ts +13 -0
  344. package/dist/utils/openhands-llm.js +9 -3
  345. package/dist/utils/openhands-llm.js.map +1 -1
  346. package/package.json +2 -2
  347. package/scripts/check-sdk-version-sync.mjs +6 -6
  348. package/scripts/dev-safe.mjs +71 -120
  349. package/scripts/dev-with-automation.mjs +58 -4
  350. package/scripts/runtime-services-info.mjs +199 -0
  351. package/scripts/static-server.mjs +42 -4
  352. package/build/assets/acp-providers-DJr8DlNG.js +0 -1
  353. package/build/assets/acp-route-guard-A__sWgbc.js +0 -1
  354. package/build/assets/active-backend-context-I2w666XY.js +0 -1
  355. package/build/assets/add-backend-modal-BDBDBXsJ.js +0 -1
  356. package/build/assets/agent-server-client-options-9agOSarV.js +0 -1
  357. package/build/assets/agent-server-compatibility-B7QStIcH.js +0 -1
  358. package/build/assets/agent-server-conversation-service.api-Cagoqq1V.js +0 -5
  359. package/build/assets/api-key-entry-screen-ByXA4hXH.js +0 -1
  360. package/build/assets/automation-detail-Dbmgt974.js +0 -1
  361. package/build/assets/backend-form-modal-CeB983Sj.js +0 -1
  362. package/build/assets/browser-D08Sp3ZY.js +0 -5
  363. package/build/assets/browser-store-JRrcGdlk.js +0 -1
  364. package/build/assets/chat-send-button-5qz0zj6R.js +0 -1
  365. package/build/assets/check-CZhEL6rP.js +0 -1
  366. package/build/assets/conversation-BrjF2-Ky.js +0 -1
  367. package/build/assets/conversation-HgR_TTPE.js +0 -19
  368. package/build/assets/conversation-panel-BlRcO5AC.js +0 -1
  369. package/build/assets/conversation-service.api-B_Pdmwsa.js +0 -1
  370. package/build/assets/conversation-state-store-D-w0uurj.js +0 -1
  371. package/build/assets/conversation-store-CC-isCnP.js +0 -1
  372. package/build/assets/conversation-websocket-context-G95yfL81.js +0 -3
  373. package/build/assets/dist-Bl-1K5Tv.js +0 -1
  374. package/build/assets/edit-automation-modal-CNZgSSiH.js +0 -1
  375. package/build/assets/extensions-navigation-yFLAU06N.js +0 -1
  376. package/build/assets/files-tab-CMredyYX.js +0 -1
  377. package/build/assets/files-tab-store-DLU28g8C.js +0 -1
  378. package/build/assets/git-control-bar-branch-button-D8blTNXh.js +0 -27
  379. package/build/assets/home-CWw845Rz.js +0 -1
  380. package/build/assets/install-server-modal-D8Q0xZcN.js +0 -1
  381. package/build/assets/llm-client-BqyLKgUN.js +0 -1
  382. package/build/assets/llm-settings-CAnFYAEG.js +0 -1
  383. package/build/assets/llm-settings-DotqpmCF.js +0 -1
  384. package/build/assets/manage-backends-modal-Ceo_SOcf.js +0 -1
  385. package/build/assets/manifest-61ec2d68.js +0 -1
  386. package/build/assets/mcp-EvrLVTla.js +0 -9
  387. package/build/assets/messages-Bz9TWjlh.js +0 -36
  388. package/build/assets/middleware-CfatjPYZ.js +0 -6
  389. package/build/assets/model-selector-CZOi4V7r.js +0 -1
  390. package/build/assets/onboarding-CPCKYvFh.js +0 -1
  391. package/build/assets/organization-service.api-Dn74hBTH.js +0 -1
  392. package/build/assets/path-utils-BjxzIGLp.js +0 -1
  393. package/build/assets/plus-DT-M0FA1.js +0 -1
  394. package/build/assets/profiles-client-BrqNmaDV.js +0 -1
  395. package/build/assets/proxy-sRh0WKI7.js +0 -1
  396. package/build/assets/root-CklXEh3W.js +0 -2
  397. package/build/assets/root-layout-BCA_X8XL.js +0 -2
  398. package/build/assets/secrets-service-DVtlLWY8.js +0 -1
  399. package/build/assets/server-client-DYv_GHPl.js +0 -1
  400. package/build/assets/settings-CXvJUx_j.js +0 -1
  401. package/build/assets/settings-service.api-DxIEtvx6.js +0 -1
  402. package/build/assets/shared-conversation-x41nZQi7.js +0 -1
  403. package/build/assets/sidebar-store-DnQAJAE5.js +0 -1
  404. package/build/assets/telemetry-fQFd-8V3.js +0 -2
  405. package/build/assets/use-agent-settings-schema-Yxf7KGyG.js +0 -1
  406. package/build/assets/use-config-DwfigQ_Y.js +0 -1
  407. package/build/assets/use-create-conversation-BEzddjXn.js +0 -1
  408. package/build/assets/use-event-store-Cxqc45Sw.js +0 -1
  409. package/build/assets/use-get-secrets-BlO1BfUo.js +0 -1
  410. package/build/assets/use-handle-plan-click-Bfl0zIBr.js +0 -1
  411. package/build/assets/use-is-authed-hHndEep7.js +0 -1
  412. package/build/assets/use-llm-profiles-E-jjZMZw.js +0 -1
  413. package/build/assets/use-runtime-is-ready-DBWzvAmc.js +0 -1
  414. package/build/assets/use-settings-BPTbE7lg.js +0 -1
  415. package/build/assets/use-skills-QhoaIYGF.js +0 -1
  416. package/build/assets/use-unified-vscode-url-DFtNIC1Q.js +0 -1
  417. package/build/assets/use-user-conversation-BRAseenw.js +0 -1
  418. package/build/assets/vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-D8soyAAx.js +0 -48
  419. package/build/assets/vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~jaomi49z-Cw89stA6.js +0 -1
  420. package/build/assets/x-JOBEVLW0.js +0 -1
  421. package/dist/components/features/conversation-panel/skills-runtime-waiting-state.cjs +0 -2
  422. package/dist/components/features/conversation-panel/skills-runtime-waiting-state.cjs.map +0 -1
  423. package/dist/components/features/conversation-panel/skills-runtime-waiting-state.d.ts +0 -1
  424. package/dist/components/features/conversation-panel/skills-runtime-waiting-state.js +0 -21
  425. package/dist/components/features/conversation-panel/skills-runtime-waiting-state.js.map +0 -1
  426. package/dist/utils/acp-route-guard.cjs +0 -1
  427. package/dist/utils/acp-route-guard.d.ts +0 -26
  428. package/dist/utils/acp-route-guard.js +0 -4
  429. /package/build/assets/{agent-server-ui-style-scope-BwIZYdC1.js → agent-server-ui-style-scope-Bhc5vpWO.js} +0 -0
  430. /package/build/assets/{automation-DJ_3GeXD.js → automation-BzmydDjr.js} +0 -0
  431. /package/build/assets/{common-DqjLSBOt.js → common-Cfviy7yT.js} +0 -0
  432. /package/build/assets/{context-CEQZwATj.js → context-BBqptpXX.js} +0 -0
  433. /package/build/assets/{conversation-local-storage-YmOVXxxW.js → conversation-local-storage-D5Tre_GA.js} +0 -0
  434. /package/build/assets/{createLucideIcon-Ddu8jDOQ.js → createLucideIcon-C9OEnwvX.js} +0 -0
  435. /package/build/assets/{environment-switch-store-CiurvTtK.js → environment-switch-store-BpKxp6Xq.js} +0 -0
  436. /package/build/assets/{git-status-mapper-DnL9OC8_.js → git-status-mapper-C3rfzUex.js} +0 -0
  437. /package/build/assets/{handle-capture-consent-3XrjZ8wi.js → handle-capture-consent-DDnXMC9Y.js} +0 -0
  438. /package/build/assets/{health-store-B5f0S2FY.js → health-store-d-d2ssv4.js} +0 -0
  439. /package/build/assets/{iconBase-BVhFI-0E.js → iconBase-1A_WRQ4E.js} +0 -0
  440. /package/build/assets/{map-provider-C3Z5Dx2J.js → map-provider-XSFHmdDs.js} +0 -0
  441. /package/build/assets/{objectWithoutPropertiesLoose-DSQKyRhw.js → objectWithoutPropertiesLoose-B-IA9dU9.js} +0 -0
  442. /package/build/assets/{query-keys-tAsQcc_9.js → query-keys-CQaji0wJ.js} +0 -0
  443. /package/build/assets/{react-Dy05vyj5.js → react-CuAHzoGi.js} +0 -0
  444. /package/build/assets/{retrieve-axios-error-message-BY-yIkIq.js → retrieve-axios-error-message-DbnSBc_1.js} +0 -0
  445. /package/build/assets/{sdk-settings-field-metadata-C6KMD-jZ.js → sdk-settings-field-metadata-CETNItbo.js} +0 -0
  446. /package/build/assets/{settings-DGY6n4J2.js → settings-BgL2HUsU.js} +0 -0
  447. /package/build/assets/{settings-like-page-layout-classes-DNg2vKSM.js → settings-like-page-layout-classes-DENKlZpD.js} +0 -0
  448. /package/build/assets/{use-breakpoint-DpxHDmuH.js → use-breakpoint-Dt2knceC.js} +0 -0
  449. /package/build/assets/{use-click-outside-element-DhxCUyWl.js → use-click-outside-element-Bu2A3s59.js} +0 -0
  450. /package/build/assets/{v4-khGvL7i2.js → v4-BygpdDmc.js} +0 -0
  451. /package/build/assets/{vendor~browser-BDNLFng6.js → vendor~browser-BYEwwJqV.js} +0 -0
  452. /package/build/assets/{vendor~conversation-panel~conversation~alert-banner-D_hRW_zc.js → vendor~conversation-panel~conversation~alert-banner-BnHToS5O.js} +0 -0
  453. /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~j8sdb9mk-OFpe9fX_.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~j8sdb9mk-oCzr0-9g.js} +0 -0
  454. /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~lpdshwee-BPuuVEqr.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~skills-set~lpdshwee-CTmh4bwd.js} +0 -0
  455. /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~skills-settings~m~o9nrx3fm-D44TR8hL.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~skills-settings~m~o9nrx3fm-87v-LliW.js} +0 -0
  456. /package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Dr3Ow7Ms.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-D8cqyq4k.js} +0 -0
  457. /package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~i4kjfqhl-B1TKKuuH.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~mcp~~ntycl9e1-DspdqGPW.js} +0 -0
  458. /package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~e9ykmtgh-Fa-nXZ4M.js → vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~e9ykmtgh-DMH1jSwL.js} +0 -0
  459. /package/build/assets/{vendor~terminal-0ObOedYm.js → vendor~terminal-aeP3PnKf.js} +0 -0
  460. /package/build/assets/{vscode-url-helper-BMq8JBhB.js → vscode-url-helper-DOCkV_-G.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"event-message.js","names":[],"sources":["../../../../src/components/conversation-events/chat/event-message.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n OpenHandsEvent,\n MessageEvent,\n ActionEvent,\n} from \"#/types/agent-server/core\";\nimport {\n FinishAction,\n ThinkAction,\n} from \"#/types/agent-server/core/base/action\";\nimport {\n isActionEvent,\n isObservationEvent,\n isAgentErrorEvent,\n isUserMessageEvent,\n isPlanningFileEditorObservationEvent,\n isHookExecutionEvent,\n isACPToolCallEvent,\n} from \"#/types/agent-server/type-guards\";\nimport { useConfig } from \"#/hooks/query/use-config\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\nimport { AgentState } from \"#/types/agent-state\";\nimport { PlanPreview } from \"../../features/chat/plan-preview\";\nimport { ErrorEventMessage } from \"./event-message-components/error-event-message\";\nimport { UserAssistantEventMessage } from \"./event-message-components/user-assistant-event-message\";\nimport { FinishEventMessage } from \"./event-message-components/finish-event-message\";\nimport { GenericEventMessageWrapper } from \"./event-message-components/generic-event-message-wrapper\";\nimport { ThoughtEventMessage } from \"./event-message-components/thought-event-message\";\nimport { CollapsibleThinking } from \"./event-message-components/collapsible-thinking\";\nimport { HookExecutionEventMessage } from \"./event-message-components/hook-execution-event-message\";\nimport { createSkillReadyEvent } from \"./event-content-helpers/create-skill-ready-event\";\nimport { shouldShowPlanPreview } from \"./hooks/use-plan-preview-events\";\nimport { getReasoningContent } from \"./event-thought-helpers\";\n\ninterface EventMessageProps {\n event: OpenHandsEvent & { isFromPlanningAgent?: boolean };\n messages: OpenHandsEvent[];\n isLastMessage: boolean;\n isInLast10Actions: boolean;\n /** Set of event IDs that should render PlanPreview (one per user message phase) */\n planPreviewEventIds?: Set<string>;\n /**\n * When true, do not render the inline `ThoughtEventMessage` for action /\n * observation events. The caller is expected to render the thought\n * separately (e.g. via a hoisted \"thought\" rendered item) so the message\n * pane and the in-group rendering don't double up on the same content.\n * Has no effect on `ThinkAction`, whose thought IS its action body.\n */\n suppressThought?: boolean;\n}\n\n/**\n * Extracts activated skills from a MessageEvent, supporting both\n * activated_skills and activated_microagents field names.\n */\nconst getActivatedSkills = (event: MessageEvent): string[] =>\n (event as unknown as { activated_skills?: string[] }).activated_skills ||\n event.activated_microagents ||\n [];\n\n/**\n * Checks if extended content contains valid text content.\n */\nconst hasValidExtendedContent = (\n extendedContent: MessageEvent[\"extended_content\"],\n): boolean => {\n if (!extendedContent || extendedContent.length === 0) {\n return false;\n }\n\n return extendedContent.some(\n (content) => content.type === \"text\" && content.text.trim().length > 0,\n );\n};\n\n/**\n * Determines if a Skill Ready event should be displayed for the given message event.\n */\nconst shouldShowSkillReadyEvent = (messageEvent: MessageEvent): boolean => {\n const activatedSkills = getActivatedSkills(messageEvent);\n const hasActivatedSkills = activatedSkills.length > 0;\n const hasExtendedContent = hasValidExtendedContent(\n messageEvent.extended_content,\n );\n\n return hasActivatedSkills && hasExtendedContent;\n};\n\ninterface CommonProps {\n isLastMessage: boolean;\n isInLast10Actions: boolean;\n config: unknown;\n isFromPlanningAgent: boolean;\n}\n\n/**\n * Renders a user message with its corresponding Skill Ready event.\n */\nconst renderUserMessageWithSkillReady = (\n messageEvent: MessageEvent,\n commonProps: CommonProps,\n isLastMessage: boolean,\n): React.ReactElement => {\n try {\n const skillReadyEvent = createSkillReadyEvent(messageEvent);\n return (\n <>\n <UserAssistantEventMessage\n event={messageEvent}\n isLastMessage={false}\n isFromPlanningAgent={commonProps.isFromPlanningAgent}\n />\n <GenericEventMessageWrapper\n event={skillReadyEvent}\n isLastMessage={isLastMessage}\n />\n </>\n );\n } catch (error) {\n // If skill ready event creation fails, just render the user message\n return (\n <UserAssistantEventMessage\n event={messageEvent}\n isLastMessage={isLastMessage}\n isFromPlanningAgent={commonProps.isFromPlanningAgent}\n />\n );\n }\n};\n\nexport function EventMessage({\n event,\n messages,\n isLastMessage,\n isInLast10Actions,\n planPreviewEventIds,\n suppressThought = false,\n}: EventMessageProps) {\n const { data: config } = useConfig();\n const { planContent } = useConversationStore();\n const { curAgentState } = useAgentState();\n\n // Disable Build button while agent is running (streaming)\n const isAgentRunning =\n curAgentState === AgentState.RUNNING ||\n curAgentState === AgentState.LOADING;\n\n // Read isFromPlanningAgent directly from the event object\n const isFromPlanningAgent = event.isFromPlanningAgent || false;\n\n // Common props for components that need them\n const commonProps = {\n isLastMessage,\n isInLast10Actions,\n config,\n isFromPlanningAgent,\n };\n\n // Agent error events\n if (isAgentErrorEvent(event)) {\n return <ErrorEventMessage event={event} {...commonProps} />;\n }\n\n // Hook execution events\n if (isHookExecutionEvent(event)) {\n return <HookExecutionEventMessage event={event} />;\n }\n\n // ACP sub-agent tool call events (Claude Code, Codex, Gemini CLI, …)\n // render through the same generic wrapper used for observation events so\n // the card shape, success indicator and markdown rendering all match.\n if (isACPToolCallEvent(event)) {\n return (\n <GenericEventMessageWrapper event={event} isLastMessage={isLastMessage} />\n );\n }\n\n // Finish actions\n if (isActionEvent(event) && event.action.kind === \"FinishAction\") {\n return (\n <FinishEventMessage\n event={event as ActionEvent<FinishAction>}\n {...commonProps}\n />\n );\n }\n\n // ThinkAction - render the thought inside a collapsible section so it\n // doesn't dominate the chat, especially when the thinking language\n // (usually English) differs from the conversation language.\n if (isActionEvent(event) && event.action.kind === \"ThinkAction\") {\n const thinkAction = event as ActionEvent<ThinkAction>;\n return <CollapsibleThinking content={thinkAction.action.thought} />;\n }\n\n // Action events - render thought + action (will be replaced by thought + observation)\n if (isActionEvent(event)) {\n const reasoningContent = getReasoningContent(event);\n return (\n <>\n {reasoningContent && <CollapsibleThinking content={reasoningContent} />}\n {!suppressThought && (\n <ThoughtEventMessage\n event={event}\n isFromPlanningAgent={isFromPlanningAgent}\n />\n )}\n <GenericEventMessageWrapper\n event={event}\n isLastMessage={isLastMessage}\n />\n </>\n );\n }\n\n // Observation events - find the corresponding action and render thought + observation\n if (isObservationEvent(event)) {\n // Handle PlanningFileEditorObservation specially\n if (isPlanningFileEditorObservationEvent(event)) {\n // Only show PlanPreview if this event is marked as the one to display\n // (last PlanningFileEditorObservation in its phase)\n if (\n planPreviewEventIds &&\n shouldShowPlanPreview(event.id, planPreviewEventIds)\n ) {\n // Show shine effect only if this is the last message AND agent is running\n const isStreaming =\n isLastMessage && curAgentState === AgentState.RUNNING;\n return (\n <PlanPreview\n planContent={planContent}\n isStreaming={isStreaming}\n isBuildDisabled={isAgentRunning}\n />\n );\n }\n // Not the designated preview event for this phase - render nothing\n // This prevents duplicate previews within the same phase\n return null;\n }\n\n // Find the action that this observation is responding to\n const correspondingAction = messages.find(\n (msg) => isActionEvent(msg) && msg.id === event.action_id,\n );\n\n // Skip ThoughtEventMessage for ThinkAction (thought IS the action)\n const shouldShowThought =\n !suppressThought &&\n correspondingAction &&\n isActionEvent(correspondingAction) &&\n correspondingAction.action.kind !== \"ThinkAction\";\n\n const reasoningContent =\n correspondingAction && isActionEvent(correspondingAction)\n ? getReasoningContent(correspondingAction)\n : \"\";\n\n return (\n <>\n {reasoningContent && <CollapsibleThinking content={reasoningContent} />}\n {shouldShowThought && (\n <ThoughtEventMessage\n event={correspondingAction}\n isFromPlanningAgent={isFromPlanningAgent}\n />\n )}\n <GenericEventMessageWrapper\n event={event}\n isLastMessage={isLastMessage}\n correspondingAction={\n correspondingAction && isActionEvent(correspondingAction)\n ? correspondingAction\n : undefined\n }\n />\n </>\n );\n }\n\n // Message events (user and assistant messages)\n if (!isActionEvent(event) && !isObservationEvent(event)) {\n const messageEvent = event as MessageEvent;\n\n // Check if this is a user message that should display a Skill Ready event\n if (isUserMessageEvent(event) && shouldShowSkillReadyEvent(messageEvent)) {\n return renderUserMessageWithSkillReady(\n messageEvent,\n commonProps,\n isLastMessage,\n );\n }\n\n // Render normal message event (user or assistant)\n return (\n <UserAssistantEventMessage\n event={messageEvent}\n {...commonProps}\n isLastMessage={isLastMessage}\n />\n );\n }\n\n // Generic fallback for all other events\n return (\n <GenericEventMessageWrapper event={event} isLastMessage={isLastMessage} />\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAwDA,IAAM,KAAsB,MACzB,EAAqD,oBACtD,EAAM,yBACN,EAAE,EAKE,KACJ,MAEI,CAAC,KAAmB,EAAgB,WAAW,IAC1C,KAGF,EAAgB,MACpB,MAAY,EAAQ,SAAS,UAAU,EAAQ,KAAK,MAAM,CAAC,SAAS,EACtE,EAMG,KAA6B,MAAwC;CAEzE,IAAM,IADkB,EAAmB,EAChB,CAAgB,SAAS,GAC9C,IAAqB,EACzB,EAAa,iBACd;AAED,QAAO,KAAsB;GAazB,KACJ,GACA,GACA,MACuB;AACvB,KAAI;EACF,IAAM,IAAkB,EAAsB,EAAa;AAC3D,SACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;GACE,OAAO;GACP,eAAe;GACf,qBAAqB,EAAY;GACjC,CAAA,EACF,kBAAC,GAAD;GACE,OAAO;GACQ;GACf,CAAA,CACD,EAAA,CAAA;SAES;AAEd,SACE,kBAAC,GAAD;GACE,OAAO;GACQ;GACf,qBAAqB,EAAY;GACjC,CAAA;;;AAKR,SAAgB,EAAa,EAC3B,UACA,aACA,kBACA,sBACA,wBACA,qBAAkB,MACE;CACpB,IAAM,EAAE,MAAM,MAAW,GAAW,EAC9B,EAAE,mBAAgB,GAAsB,EACxC,EAAE,qBAAkB,GAAe,EAGnC,IACJ,MAAkB,EAAW,WAC7B,MAAkB,EAAW,SAGzB,IAAsB,EAAM,uBAAuB,IAGnD,IAAc;EAClB;EACA;EACA;EACA;EACD;AAGD,KAAI,EAAkB,EAAM,CAC1B,QAAO,kBAAC,GAAD;EAA0B;EAAO,GAAI;EAAe,CAAA;AAI7D,KAAI,EAAqB,EAAM,CAC7B,QAAO,kBAAC,GAAD,EAAkC,UAAS,CAAA;AAMpD,KAAI,EAAmB,EAAM,CAC3B,QACE,kBAAC,GAAD;EAAmC;EAAsB;EAAiB,CAAA;AAK9E,KAAI,EAAc,EAAM,IAAI,EAAM,OAAO,SAAS,eAChD,QACE,kBAAC,GAAD;EACS;EACP,GAAI;EACJ,CAAA;AAON,KAAI,EAAc,EAAM,IAAI,EAAM,OAAO,SAAS,cAEhD,QAAO,kBAAC,GAAD,EAAqB,SAAS,EAAY,OAAO,SAAW,CAAA;AAIrE,KAAI,EAAc,EAAM,EAAE;EACxB,IAAM,IAAmB,EAAoB,EAAM;AACnD,SACE,kBAAA,GAAA,EAAA,UAAA;GACG,KAAoB,kBAAC,GAAD,EAAqB,SAAS,GAAoB,CAAA;GACtE,CAAC,KACA,kBAAC,GAAD;IACS;IACc;IACrB,CAAA;GAEJ,kBAAC,GAAD;IACS;IACQ;IACf,CAAA;GACD,EAAA,CAAA;;AAKP,KAAI,EAAmB,EAAM,EAAE;AAE7B,MAAI,EAAqC,EAAM,CAoB7C,QAhBE,KACA,EAAsB,EAAM,IAAI,EAAoB,GAMlD,kBAAC,GAAD;GACe;GACA,aAJf,KAAiB,MAAkB,EAAW;GAK5C,iBAAiB;GACjB,CAAA,GAKC;EAIT,IAAM,IAAsB,EAAS,MAClC,MAAQ,EAAc,EAAI,IAAI,EAAI,OAAO,EAAM,UACjD,EAGK,IACJ,CAAC,KACD,KACA,EAAc,EAAoB,IAClC,EAAoB,OAAO,SAAS,eAEhC,IACJ,KAAuB,EAAc,EAAoB,GACrD,EAAoB,EAAoB,GACxC;AAEN,SACE,kBAAA,GAAA,EAAA,UAAA;GACG,KAAoB,kBAAC,GAAD,EAAqB,SAAS,GAAoB,CAAA;GACtE,KACC,kBAAC,GAAD;IACE,OAAO;IACc;IACrB,CAAA;GAEJ,kBAAC,GAAD;IACS;IACQ;IACf,qBACE,KAAuB,EAAc,EAAoB,GACrD,IACA,KAAA;IAEN,CAAA;GACD,EAAA,CAAA;;AAKP,KAAI,CAAC,EAAc,EAAM,IAAI,CAAC,EAAmB,EAAM,EAAE;EACvD,IAAM,IAAe;AAYrB,SATI,EAAmB,EAAM,IAAI,EAA0B,EAAa,GAC/D,EACL,GACA,GACA,EACD,GAKD,kBAAC,GAAD;GACE,OAAO;GACP,GAAI;GACW;GACf,CAAA;;AAKN,QACE,kBAAC,GAAD;EAAmC;EAAsB;EAAiB,CAAA"}
1
+ {"version":3,"file":"event-message.js","names":[],"sources":["../../../../src/components/conversation-events/chat/event-message.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n OpenHandsEvent,\n MessageEvent,\n ActionEvent,\n} from \"#/types/agent-server/core\";\nimport {\n FinishAction,\n ThinkAction,\n} from \"#/types/agent-server/core/base/action\";\nimport {\n isActionEvent,\n isObservationEvent,\n isAgentErrorEvent,\n isUserMessageEvent,\n isPlanningFileEditorObservationEvent,\n isHookExecutionEvent,\n isACPToolCallEvent,\n isStreamingDeltaEvent,\n} from \"#/types/agent-server/type-guards\";\nimport { useConfig } from \"#/hooks/query/use-config\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\nimport { AgentState } from \"#/types/agent-state\";\nimport { ChatMessage } from \"#/components/features/chat/chat-message\";\nimport { PlanPreview } from \"../../features/chat/plan-preview\";\nimport { ErrorEventMessage } from \"./event-message-components/error-event-message\";\nimport { UserAssistantEventMessage } from \"./event-message-components/user-assistant-event-message\";\nimport { FinishEventMessage } from \"./event-message-components/finish-event-message\";\nimport { GenericEventMessageWrapper } from \"./event-message-components/generic-event-message-wrapper\";\nimport { ThoughtEventMessage } from \"./event-message-components/thought-event-message\";\nimport { CollapsibleThinking } from \"./event-message-components/collapsible-thinking\";\nimport { HookExecutionEventMessage } from \"./event-message-components/hook-execution-event-message\";\nimport { createSkillReadyEvent } from \"./event-content-helpers/create-skill-ready-event\";\nimport { shouldShowPlanPreview } from \"./hooks/use-plan-preview-events\";\nimport { getReasoningContent } from \"./event-thought-helpers\";\n\ninterface EventMessageProps {\n event: OpenHandsEvent & { isFromPlanningAgent?: boolean };\n messages: OpenHandsEvent[];\n isLastMessage: boolean;\n isInLast10Actions: boolean;\n /** Set of event IDs that should render PlanPreview (one per user message phase) */\n planPreviewEventIds?: Set<string>;\n /**\n * When true, do not render the inline `ThoughtEventMessage` for action /\n * observation events. The caller is expected to render the thought\n * separately (e.g. via a hoisted \"thought\" rendered item) so the message\n * pane and the in-group rendering don't double up on the same content.\n * Has no effect on `ThinkAction`, whose thought IS its action body.\n */\n suppressThought?: boolean;\n}\n\n/**\n * Extracts activated skills from a MessageEvent, supporting both\n * activated_skills and activated_microagents field names.\n */\nconst getActivatedSkills = (event: MessageEvent): string[] =>\n (event as unknown as { activated_skills?: string[] }).activated_skills ||\n event.activated_microagents ||\n [];\n\n/**\n * Checks if extended content contains valid text content.\n */\nconst hasValidExtendedContent = (\n extendedContent: MessageEvent[\"extended_content\"],\n): boolean => {\n if (!extendedContent || extendedContent.length === 0) {\n return false;\n }\n\n return extendedContent.some(\n (content) => content.type === \"text\" && content.text.trim().length > 0,\n );\n};\n\n/**\n * Determines if a Skill Ready event should be displayed for the given message event.\n */\nconst shouldShowSkillReadyEvent = (messageEvent: MessageEvent): boolean => {\n const activatedSkills = getActivatedSkills(messageEvent);\n const hasActivatedSkills = activatedSkills.length > 0;\n const hasExtendedContent = hasValidExtendedContent(\n messageEvent.extended_content,\n );\n\n return hasActivatedSkills && hasExtendedContent;\n};\n\ninterface CommonProps {\n isLastMessage: boolean;\n isInLast10Actions: boolean;\n config: unknown;\n isFromPlanningAgent: boolean;\n}\n\n/**\n * Renders a user message with its corresponding Skill Ready event.\n */\nconst renderUserMessageWithSkillReady = (\n messageEvent: MessageEvent,\n commonProps: CommonProps,\n isLastMessage: boolean,\n): React.ReactElement => {\n try {\n const skillReadyEvent = createSkillReadyEvent(messageEvent);\n return (\n <>\n <UserAssistantEventMessage\n event={messageEvent}\n isLastMessage={false}\n isFromPlanningAgent={commonProps.isFromPlanningAgent}\n />\n <GenericEventMessageWrapper\n event={skillReadyEvent}\n isLastMessage={isLastMessage}\n />\n </>\n );\n } catch (error) {\n // If skill ready event creation fails, just render the user message\n return (\n <UserAssistantEventMessage\n event={messageEvent}\n isLastMessage={isLastMessage}\n isFromPlanningAgent={commonProps.isFromPlanningAgent}\n />\n );\n }\n};\n\nexport function EventMessage({\n event,\n messages,\n isLastMessage,\n isInLast10Actions,\n planPreviewEventIds,\n suppressThought = false,\n}: EventMessageProps) {\n const { data: config } = useConfig();\n const { planContent } = useConversationStore();\n const { curAgentState } = useAgentState();\n\n // Disable Build button while agent is running (streaming)\n const isAgentRunning =\n curAgentState === AgentState.RUNNING ||\n curAgentState === AgentState.LOADING;\n\n // Read isFromPlanningAgent directly from the event object\n const isFromPlanningAgent = event.isFromPlanningAgent || false;\n\n // Common props for components that need them\n const commonProps = {\n isLastMessage,\n isInLast10Actions,\n config,\n isFromPlanningAgent,\n };\n\n // Agent error events\n if (isAgentErrorEvent(event)) {\n return <ErrorEventMessage event={event} {...commonProps} />;\n }\n\n // Hook execution events\n if (isHookExecutionEvent(event)) {\n return <HookExecutionEventMessage event={event} />;\n }\n\n // ACP sub-agent tool call events (Claude Code, Codex, Gemini CLI, …)\n // render through the same generic wrapper used for observation events so\n // the card shape, success indicator and markdown rendering all match.\n if (isACPToolCallEvent(event)) {\n return (\n <GenericEventMessageWrapper event={event} isLastMessage={isLastMessage} />\n );\n }\n\n if (isStreamingDeltaEvent(event)) {\n const content = event.content ?? \"\";\n const reasoningContent = event.reasoning_content ?? \"\";\n return (\n <>\n {reasoningContent && <CollapsibleThinking content={reasoningContent} />}\n {content && (\n <ChatMessage\n type=\"agent\"\n message={content}\n isFromPlanningAgent={isFromPlanningAgent}\n />\n )}\n </>\n );\n }\n\n // Finish actions\n if (isActionEvent(event) && event.action.kind === \"FinishAction\") {\n return (\n <FinishEventMessage\n event={event as ActionEvent<FinishAction>}\n {...commonProps}\n />\n );\n }\n\n // ThinkAction - render the thought inside a collapsible section so it\n // doesn't dominate the chat, especially when the thinking language\n // (usually English) differs from the conversation language.\n if (isActionEvent(event) && event.action.kind === \"ThinkAction\") {\n const thinkAction = event as ActionEvent<ThinkAction>;\n return <CollapsibleThinking content={thinkAction.action.thought} />;\n }\n\n // Action events - render thought + action (will be replaced by thought + observation)\n if (isActionEvent(event)) {\n const reasoningContent = getReasoningContent(event);\n return (\n <>\n {reasoningContent && <CollapsibleThinking content={reasoningContent} />}\n {!suppressThought && (\n <ThoughtEventMessage\n event={event}\n isFromPlanningAgent={isFromPlanningAgent}\n />\n )}\n <GenericEventMessageWrapper\n event={event}\n isLastMessage={isLastMessage}\n />\n </>\n );\n }\n\n // Observation events - find the corresponding action and render thought + observation\n if (isObservationEvent(event)) {\n // Handle PlanningFileEditorObservation specially\n if (isPlanningFileEditorObservationEvent(event)) {\n // Only show PlanPreview if this event is marked as the one to display\n // (last PlanningFileEditorObservation in its phase)\n if (\n planPreviewEventIds &&\n shouldShowPlanPreview(event.id, planPreviewEventIds)\n ) {\n // Show shine effect only if this is the last message AND agent is running\n const isStreaming =\n isLastMessage && curAgentState === AgentState.RUNNING;\n return (\n <PlanPreview\n planContent={planContent}\n isStreaming={isStreaming}\n isBuildDisabled={isAgentRunning}\n />\n );\n }\n // Not the designated preview event for this phase - render nothing\n // This prevents duplicate previews within the same phase\n return null;\n }\n\n // Find the action that this observation is responding to\n const correspondingAction = messages.find(\n (msg) => isActionEvent(msg) && msg.id === event.action_id,\n );\n\n // Skip ThoughtEventMessage for ThinkAction (thought IS the action)\n const shouldShowThought =\n !suppressThought &&\n correspondingAction &&\n isActionEvent(correspondingAction) &&\n correspondingAction.action.kind !== \"ThinkAction\";\n\n const reasoningContent =\n correspondingAction && isActionEvent(correspondingAction)\n ? getReasoningContent(correspondingAction)\n : \"\";\n\n return (\n <>\n {reasoningContent && <CollapsibleThinking content={reasoningContent} />}\n {shouldShowThought && (\n <ThoughtEventMessage\n event={correspondingAction}\n isFromPlanningAgent={isFromPlanningAgent}\n />\n )}\n <GenericEventMessageWrapper\n event={event}\n isLastMessage={isLastMessage}\n correspondingAction={\n correspondingAction && isActionEvent(correspondingAction)\n ? correspondingAction\n : undefined\n }\n />\n </>\n );\n }\n\n // Message events (user and assistant messages)\n if (!isActionEvent(event) && !isObservationEvent(event)) {\n const messageEvent = event as MessageEvent;\n\n // Check if this is a user message that should display a Skill Ready event\n if (isUserMessageEvent(event) && shouldShowSkillReadyEvent(messageEvent)) {\n return renderUserMessageWithSkillReady(\n messageEvent,\n commonProps,\n isLastMessage,\n );\n }\n\n // Render normal message event (user or assistant)\n return (\n <UserAssistantEventMessage\n event={messageEvent}\n {...commonProps}\n isLastMessage={isLastMessage}\n />\n );\n }\n\n // Generic fallback for all other events\n return (\n <GenericEventMessageWrapper event={event} isLastMessage={isLastMessage} />\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA0DA,IAAM,KAAsB,MACzB,EAAqD,oBACtD,EAAM,yBACN,EAAE,EAKE,KACJ,MAEI,CAAC,KAAmB,EAAgB,WAAW,IAC1C,KAGF,EAAgB,MACpB,MAAY,EAAQ,SAAS,UAAU,EAAQ,KAAK,MAAM,CAAC,SAAS,EACtE,EAMG,KAA6B,MAAwC;CAEzE,IAAM,IADkB,EAAmB,EAChB,CAAgB,SAAS,GAC9C,IAAqB,EACzB,EAAa,iBACd;AAED,QAAO,KAAsB;GAazB,KACJ,GACA,GACA,MACuB;AACvB,KAAI;EACF,IAAM,IAAkB,EAAsB,EAAa;AAC3D,SACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;GACE,OAAO;GACP,eAAe;GACf,qBAAqB,EAAY;GACjC,CAAA,EACF,kBAAC,GAAD;GACE,OAAO;GACQ;GACf,CAAA,CACD,EAAA,CAAA;SAES;AAEd,SACE,kBAAC,GAAD;GACE,OAAO;GACQ;GACf,qBAAqB,EAAY;GACjC,CAAA;;;AAKR,SAAgB,EAAa,EAC3B,UACA,aACA,kBACA,sBACA,wBACA,qBAAkB,MACE;CACpB,IAAM,EAAE,MAAM,MAAW,GAAW,EAC9B,EAAE,mBAAgB,GAAsB,EACxC,EAAE,qBAAkB,GAAe,EAGnC,IACJ,MAAkB,EAAW,WAC7B,MAAkB,EAAW,SAGzB,IAAsB,EAAM,uBAAuB,IAGnD,IAAc;EAClB;EACA;EACA;EACA;EACD;AAGD,KAAI,EAAkB,EAAM,CAC1B,QAAO,kBAAC,GAAD;EAA0B;EAAO,GAAI;EAAe,CAAA;AAI7D,KAAI,EAAqB,EAAM,CAC7B,QAAO,kBAAC,GAAD,EAAkC,UAAS,CAAA;AAMpD,KAAI,EAAmB,EAAM,CAC3B,QACE,kBAAC,GAAD;EAAmC;EAAsB;EAAiB,CAAA;AAI9E,KAAI,EAAsB,EAAM,EAAE;EAChC,IAAM,IAAU,EAAM,WAAW,IAC3B,IAAmB,EAAM,qBAAqB;AACpD,SACE,kBAAA,GAAA,EAAA,UAAA,CACG,KAAoB,kBAAC,GAAD,EAAqB,SAAS,GAAoB,CAAA,EACtE,KACC,kBAAC,GAAD;GACE,MAAK;GACL,SAAS;GACY;GACrB,CAAA,CAEH,EAAA,CAAA;;AAKP,KAAI,EAAc,EAAM,IAAI,EAAM,OAAO,SAAS,eAChD,QACE,kBAAC,GAAD;EACS;EACP,GAAI;EACJ,CAAA;AAON,KAAI,EAAc,EAAM,IAAI,EAAM,OAAO,SAAS,cAEhD,QAAO,kBAAC,GAAD,EAAqB,SAAS,EAAY,OAAO,SAAW,CAAA;AAIrE,KAAI,EAAc,EAAM,EAAE;EACxB,IAAM,IAAmB,EAAoB,EAAM;AACnD,SACE,kBAAA,GAAA,EAAA,UAAA;GACG,KAAoB,kBAAC,GAAD,EAAqB,SAAS,GAAoB,CAAA;GACtE,CAAC,KACA,kBAAC,GAAD;IACS;IACc;IACrB,CAAA;GAEJ,kBAAC,GAAD;IACS;IACQ;IACf,CAAA;GACD,EAAA,CAAA;;AAKP,KAAI,EAAmB,EAAM,EAAE;AAE7B,MAAI,EAAqC,EAAM,CAoB7C,QAhBE,KACA,EAAsB,EAAM,IAAI,EAAoB,GAMlD,kBAAC,GAAD;GACe;GACA,aAJf,KAAiB,MAAkB,EAAW;GAK5C,iBAAiB;GACjB,CAAA,GAKC;EAIT,IAAM,IAAsB,EAAS,MAClC,MAAQ,EAAc,EAAI,IAAI,EAAI,OAAO,EAAM,UACjD,EAGK,IACJ,CAAC,KACD,KACA,EAAc,EAAoB,IAClC,EAAoB,OAAO,SAAS,eAEhC,IACJ,KAAuB,EAAc,EAAoB,GACrD,EAAoB,EAAoB,GACxC;AAEN,SACE,kBAAA,GAAA,EAAA,UAAA;GACG,KAAoB,kBAAC,GAAD,EAAqB,SAAS,GAAoB,CAAA;GACtE,KACC,kBAAC,GAAD;IACE,OAAO;IACc;IACrB,CAAA;GAEJ,kBAAC,GAAD;IACS;IACQ;IACf,qBACE,KAAuB,EAAc,EAAoB,GACrD,IACA,KAAA;IAEN,CAAA;GACD,EAAA,CAAA;;AAKP,KAAI,CAAC,EAAc,EAAM,IAAI,CAAC,EAAmB,EAAM,EAAE;EACvD,IAAM,IAAe;AAYrB,SATI,EAAmB,EAAM,IAAI,EAA0B,EAAa,GAC/D,EACL,GACA,GACA,EACD,GAKD,kBAAC,GAAD;GACE,OAAO;GACP,GAAI;GACW;GACf,CAAA;;AAKN,QACE,kBAAC,GAAD;EAAmC;EAAsB;EAAiB,CAAA"}
@@ -4,6 +4,12 @@ interface RecommendedAutomationsLauncherProps {
4
4
  /** When true, only the automation card grid scrolls inside its section. */
5
5
  scrollableGrid?: boolean;
6
6
  }
7
- export declare function buildAutomationPrompt(basePrompt: string, backendKind: "local" | "cloud", backendHost?: string): string;
7
+ /**
8
+ * The catalog prompt (or slash command) is passed through as-is.
9
+ * API routing (host, auth) is discovered by the agent at runtime from
10
+ * `<RUNTIME_SERVICES>` in the system prompt — the skills themselves
11
+ * contain the instructions for reading that block.
12
+ */
13
+ export declare function buildAutomationPrompt(basePrompt: string): string;
8
14
  export declare function RecommendedAutomationsLauncher({ query, onLaunched, scrollableGrid, }: RecommendedAutomationsLauncherProps): import("react/jsx-runtime").JSX.Element | null;
9
15
  export {};
@@ -1,2 +1,2 @@
1
- const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../utils/utils.cjs`),i=require(`../../../hooks/use-conversation-id.cjs`),a=require(`../../../stores/model-store.cjs`),o=require(`../../../hooks/query/use-active-conversation.cjs`),s=require(`../../../utils/form-control-classes.cjs`),c=require(`../../../hooks/query/use-settings.cjs`),l=require(`../../../hooks/query/use-llm-profiles.cjs`),u=require(`../../../ui/combobox-caret.cjs`),d=require(`../../../hooks/mutation/use-switch-llm-profile-and-log.cjs`),f=require(`./switch-profile-context-menu.cjs`);let p=require(`react`);p=e.__toESM(p,1);let m=require(`react/jsx-runtime`);function h(){let{t:e}=t.useTranslation(`openhands`),[h,g]=p.default.useState(!1),{conversationId:_}=i.useOptionalConversationId(),{data:v}=l.useLlmProfiles(),{data:y}=o.useActiveConversation(),{data:b}=c.useSettings(),{switchAndLog:x,isPending:S}=d.useSwitchLlmProfileAndLog(),C=a.useModelStore(e=>_?e.activeProfileByConversation[_]:void 0),w=v?.profiles??[],T=y?.llm_model??null,E=y?.agent_kind===`acp`||!y&&b?.agent_settings?.agent_kind===`acp`,D=C??(T?w.find(e=>e.model===T)?.name??null:v?.active_profile??null),O=w.find(e=>e.name===D)?.model??T??null;return w.length===0||E?null:(0,m.jsxs)(`div`,{className:`relative`,children:[(0,m.jsxs)(`button`,{type:`button`,onClick:e=>{e.preventDefault(),e.stopPropagation(),g(e=>!e)},disabled:S,"data-testid":`switch-profile-button`,title:O??void 0,"aria-haspopup":`menu`,"aria-expanded":h,className:r.cn(s.chatInputPillButtonClassName,`max-w-[200px]`,`disabled:opacity-50 disabled:cursor-not-allowed`),children:[(0,m.jsx)(`span`,{className:`truncate`,children:D??e(n.I18nKey.LLM$SELECT_MODEL_PLACEHOLDER)}),(0,m.jsx)(u.ComboboxCaretInline,{isOpen:h})]}),h&&(0,m.jsx)(f.SwitchProfileContextMenu,{profiles:w,activeProfileName:D,onSelect:e=>{e!==D&&x(_,e)},onClose:()=>g(!1)})]})}exports.SwitchProfileButton=h;
1
+ const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../utils/utils.cjs`),i=require(`../../../hooks/use-conversation-id.cjs`),a=require(`../../../stores/model-store.cjs`),o=require(`../../../hooks/query/use-active-conversation.cjs`),s=require(`../../../utils/form-control-classes.cjs`),c=require(`../../../hooks/query/use-settings.cjs`),l=require(`../../../hooks/query/use-llm-profiles.cjs`),u=require(`../../../ui/combobox-caret.cjs`),d=require(`../../../hooks/mutation/use-switch-llm-profile-and-log.cjs`),f=require(`./switch-profile-context-menu.cjs`);let p=require(`react`);p=e.__toESM(p,1);let m=require(`react/jsx-runtime`);function h(){let{t:e}=t.useTranslation(`openhands`),[h,g]=p.default.useState(!1),{conversationId:_}=i.useOptionalConversationId(),{data:v}=l.useLlmProfiles(),{data:y}=o.useActiveConversation(),{data:b}=c.useSettings(),{switchAndLog:x,isPending:S}=d.useSwitchLlmProfileAndLog(),C=a.useModelStore(e=>_?e.activeProfileByConversation[_]:void 0),w=v?.profiles??[],T=y?.llm_model??null,E=y?.agent_kind===`acp`||!y&&b?.agent_settings?.agent_kind===`acp`,D=y?.active_profile??null,O=D&&w.some(e=>e.name===D)?D:null,k=C??O??(T?w.find(e=>e.model===T)?.name??null:v?.active_profile??null),A=w.find(e=>e.name===k)?.model??T??null;return w.length===0||E?null:(0,m.jsxs)(`div`,{className:`relative`,children:[(0,m.jsxs)(`button`,{type:`button`,onClick:e=>{e.preventDefault(),e.stopPropagation(),g(e=>!e)},disabled:S,"data-testid":`switch-profile-button`,title:A??void 0,"aria-haspopup":`menu`,"aria-expanded":h,className:r.cn(s.chatInputPillButtonClassName,`max-w-[200px]`,`disabled:opacity-50 disabled:cursor-not-allowed`),children:[(0,m.jsx)(`span`,{className:`truncate`,children:k??e(n.I18nKey.LLM$SELECT_MODEL_PLACEHOLDER)}),(0,m.jsx)(u.ComboboxCaretInline,{isOpen:h})]}),h&&(0,m.jsx)(f.SwitchProfileContextMenu,{profiles:w,activeProfileName:k,onSelect:e=>{e!==k&&x(_,e)},onClose:()=>g(!1)})]})}exports.SwitchProfileButton=h;
2
2
  //# sourceMappingURL=switch-profile-button.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"switch-profile-button.cjs","names":[],"sources":["../../../../src/components/features/chat/switch-profile-button.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\nimport { useSwitchLlmProfileAndLog } from \"#/hooks/mutation/use-switch-llm-profile-and-log\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\nimport { SwitchProfileContextMenu } from \"./switch-profile-context-menu\";\n\nexport function SwitchProfileButton() {\n const { t } = useTranslation(\"openhands\");\n const [contextMenuOpen, setContextMenuOpen] = React.useState(false);\n // Null on the home page; `useSwitchLlmProfileAndLog` is fine with that\n // because /api/profiles/<name>/activate is a global endpoint.\n const { conversationId } = useOptionalConversationId();\n const { data } = useLlmProfiles();\n const { data: conversation } = useActiveConversation();\n const { data: settings } = useSettings();\n const { switchAndLog, isPending } = useSwitchLlmProfileAndLog();\n // Optimistic value written by recordSwitch on a successful switch — gives\n // instant in-conversation feedback before the conversation refetch lands\n // with the new `llm_model`.\n const optimisticActiveProfile = useModelStore((s) =>\n conversationId ? s.activeProfileByConversation[conversationId] : undefined,\n );\n\n const profiles = data?.profiles ?? [];\n const conversationModel = conversation?.llm_model ?? null;\n // ACPAgent conversations route prompts to a CLI subprocess whose model is\n // controlled by ``acp_model`` (set in Settings → Agent), not by the LLM\n // profile picker. Surfacing the switcher here would let the user \"change\n // the model\" while the running subprocess silently keeps its own — a\n // confusing no-op. Hide the button even when ``llm_model`` carries an ACP\n // display model for chips/headers.\n //\n // On the home screen ``conversation`` is undefined; fall back to\n // ``settings.agent_settings.agent_kind`` so the picker also hides when\n // ACP is the *default* the next-created conversation would inherit.\n // Otherwise an ACP user lands on a home page with an LLM-switch\n // control that contradicts the ACP nav gating everywhere else.\n const isAcpActive =\n conversation?.agent_kind === \"acp\" ||\n (!conversation && settings?.agent_settings?.agent_kind === \"acp\");\n\n // Resolution priority for the active profile name:\n // 1. Optimistic (just-clicked) — instant feedback before the refetch.\n // 2. Profile whose model matches the running llm_model — cold loads.\n // 3. User-level active_profile — home page / before the conversation has\n // sent any messages.\n const activeProfileName =\n optimisticActiveProfile ??\n (conversationModel\n ? (profiles.find((p) => p.model === conversationModel)?.name ?? null)\n : (data?.active_profile ?? null));\n const activeProfileModel =\n profiles.find((p) => p.name === activeProfileName)?.model ??\n conversationModel ??\n null;\n\n if (profiles.length === 0 || isAcpActive) {\n return null;\n }\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n setContextMenuOpen((open) => !open);\n };\n\n const handleSelect = (profileName: string) => {\n if (profileName === activeProfileName) return;\n switchAndLog(conversationId, profileName);\n };\n\n return (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isPending}\n data-testid=\"switch-profile-button\"\n title={activeProfileModel ?? undefined}\n aria-haspopup=\"menu\"\n aria-expanded={contextMenuOpen}\n className={cn(\n chatInputPillButtonClassName,\n \"max-w-[200px]\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n )}\n >\n <span className=\"truncate\">\n {activeProfileName ?? t(I18nKey.LLM$SELECT_MODEL_PLACEHOLDER)}\n </span>\n <ComboboxCaretInline isOpen={contextMenuOpen} />\n </button>\n {contextMenuOpen && (\n <SwitchProfileContextMenu\n profiles={profiles}\n activeProfileName={activeProfileName}\n onSelect={handleSelect}\n onClose={() => setContextMenuOpen(false)}\n />\n )}\n </div>\n );\n}\n"],"mappings":"owBAcA,SAAgB,GAAsB,CACpC,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,CAAC,EAAiB,GAAsB,EAAA,QAAM,SAAS,GAAM,CAG7D,CAAE,kBAAmB,EAAA,2BAA2B,CAChD,CAAE,QAAS,EAAA,gBAAgB,CAC3B,CAAE,KAAM,GAAiB,EAAA,uBAAuB,CAChD,CAAE,KAAM,GAAa,EAAA,aAAa,CAClC,CAAE,eAAc,aAAc,EAAA,2BAA2B,CAIzD,EAA0B,EAAA,cAAe,GAC7C,EAAiB,EAAE,4BAA4B,GAAkB,IAAA,GAClE,CAEK,EAAW,GAAM,UAAY,EAAE,CAC/B,EAAoB,GAAc,WAAa,KAa/C,EACJ,GAAc,aAAe,OAC5B,CAAC,GAAgB,GAAU,gBAAgB,aAAe,MAOvD,EACJ,IACC,EACI,EAAS,KAAM,GAAM,EAAE,QAAU,EAAkB,EAAE,MAAQ,KAC7D,GAAM,gBAAkB,MACzB,EACJ,EAAS,KAAM,GAAM,EAAE,OAAS,EAAkB,EAAE,OACpD,GACA,KAiBF,OAfI,EAAS,SAAW,GAAK,EACpB,MAeP,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oBAAf,EACE,EAAA,EAAA,MAAC,SAAD,CACE,KAAK,SACL,QAfe,GAA+C,CAClE,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,CACvB,EAAoB,GAAS,CAAC,EAAK,EAa/B,SAAU,EACV,cAAY,wBACZ,MAAO,GAAsB,IAAA,GAC7B,gBAAc,OACd,gBAAe,EACf,UAAW,EAAA,GACT,EAAA,6BACA,gBACA,kDACD,UAZH,EAcE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oBACb,GAAqB,EAAE,EAAA,QAAQ,6BAA6B,CACxD,CAAA,EACP,EAAA,EAAA,KAAC,EAAA,oBAAD,CAAqB,OAAQ,EAAmB,CAAA,CACzC,GACR,IACC,EAAA,EAAA,KAAC,EAAA,yBAAD,CACY,WACS,oBACnB,SA9Bc,GAAwB,CACxC,IAAgB,GACpB,EAAa,EAAgB,EAAY,EA6BnC,YAAe,EAAmB,GAAM,CACxC,CAAA,CAEA"}
1
+ {"version":3,"file":"switch-profile-button.cjs","names":[],"sources":["../../../../src/components/features/chat/switch-profile-button.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\nimport { useSwitchLlmProfileAndLog } from \"#/hooks/mutation/use-switch-llm-profile-and-log\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\nimport { SwitchProfileContextMenu } from \"./switch-profile-context-menu\";\n\nexport function SwitchProfileButton() {\n const { t } = useTranslation(\"openhands\");\n const [contextMenuOpen, setContextMenuOpen] = React.useState(false);\n // Null on the home page; `useSwitchLlmProfileAndLog` is fine with that\n // because /api/profiles/<name>/activate is a global endpoint.\n const { conversationId } = useOptionalConversationId();\n const { data } = useLlmProfiles();\n const { data: conversation } = useActiveConversation();\n const { data: settings } = useSettings();\n const { switchAndLog, isPending } = useSwitchLlmProfileAndLog();\n // Optimistic value written by recordSwitch on a successful switch — gives\n // instant in-conversation feedback before the conversation refetch lands\n // with the new `llm_model`.\n const optimisticActiveProfile = useModelStore((s) =>\n conversationId ? s.activeProfileByConversation[conversationId] : undefined,\n );\n\n const profiles = data?.profiles ?? [];\n const conversationModel = conversation?.llm_model ?? null;\n // ACPAgent conversations route prompts to a CLI subprocess whose model is\n // controlled by ``acp_model`` (set in Settings → Agent), not by the LLM\n // profile picker. Surfacing the switcher here would let the user \"change\n // the model\" while the running subprocess silently keeps its own — a\n // confusing no-op. Hide the button even when ``llm_model`` carries an ACP\n // display model for chips/headers.\n //\n // On the home screen ``conversation`` is undefined; fall back to\n // ``settings.agent_settings.agent_kind`` so the picker also hides when\n // ACP is the *default* the next-created conversation would inherit.\n // Otherwise an ACP user lands on a home page with an LLM-switch\n // control that contradicts the ACP nav gating everywhere else.\n const isAcpActive =\n conversation?.agent_kind === \"acp\" ||\n (!conversation && settings?.agent_settings?.agent_kind === \"acp\");\n\n // Resolution priority for the active profile name:\n // 1. Optimistic (just-clicked) — instant feedback before the refetch.\n // 2. Profile stamped on the conversation at creation / last switch —\n // exact identity, survives reload, and is unambiguous when several\n // profiles share one underlying model (#1082). Validated against the\n // live list so a since-deleted/renamed profile falls through.\n // 3. Profile whose model matches the running llm_model — legacy fallback.\n // 4. User-level active_profile — home page / before the conversation has\n // sent any messages.\n const stampedProfile = conversation?.active_profile ?? null;\n const conversationProfile =\n stampedProfile && profiles.some((p) => p.name === stampedProfile)\n ? stampedProfile\n : null;\n const activeProfileName =\n optimisticActiveProfile ??\n conversationProfile ??\n (conversationModel\n ? (profiles.find((p) => p.model === conversationModel)?.name ?? null)\n : (data?.active_profile ?? null));\n const activeProfileModel =\n profiles.find((p) => p.name === activeProfileName)?.model ??\n conversationModel ??\n null;\n\n if (profiles.length === 0 || isAcpActive) {\n return null;\n }\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n setContextMenuOpen((open) => !open);\n };\n\n const handleSelect = (profileName: string) => {\n if (profileName === activeProfileName) return;\n switchAndLog(conversationId, profileName);\n };\n\n return (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isPending}\n data-testid=\"switch-profile-button\"\n title={activeProfileModel ?? undefined}\n aria-haspopup=\"menu\"\n aria-expanded={contextMenuOpen}\n className={cn(\n chatInputPillButtonClassName,\n \"max-w-[200px]\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n )}\n >\n <span className=\"truncate\">\n {activeProfileName ?? t(I18nKey.LLM$SELECT_MODEL_PLACEHOLDER)}\n </span>\n <ComboboxCaretInline isOpen={contextMenuOpen} />\n </button>\n {contextMenuOpen && (\n <SwitchProfileContextMenu\n profiles={profiles}\n activeProfileName={activeProfileName}\n onSelect={handleSelect}\n onClose={() => setContextMenuOpen(false)}\n />\n )}\n </div>\n );\n}\n"],"mappings":"owBAcA,SAAgB,GAAsB,CACpC,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,CAAC,EAAiB,GAAsB,EAAA,QAAM,SAAS,GAAM,CAG7D,CAAE,kBAAmB,EAAA,2BAA2B,CAChD,CAAE,QAAS,EAAA,gBAAgB,CAC3B,CAAE,KAAM,GAAiB,EAAA,uBAAuB,CAChD,CAAE,KAAM,GAAa,EAAA,aAAa,CAClC,CAAE,eAAc,aAAc,EAAA,2BAA2B,CAIzD,EAA0B,EAAA,cAAe,GAC7C,EAAiB,EAAE,4BAA4B,GAAkB,IAAA,GAClE,CAEK,EAAW,GAAM,UAAY,EAAE,CAC/B,EAAoB,GAAc,WAAa,KAa/C,EACJ,GAAc,aAAe,OAC5B,CAAC,GAAgB,GAAU,gBAAgB,aAAe,MAWvD,EAAiB,GAAc,gBAAkB,KACjD,EACJ,GAAkB,EAAS,KAAM,GAAM,EAAE,OAAS,EAAe,CAC7D,EACA,KACA,EACJ,GACA,IACC,EACI,EAAS,KAAM,GAAM,EAAE,QAAU,EAAkB,EAAE,MAAQ,KAC7D,GAAM,gBAAkB,MACzB,EACJ,EAAS,KAAM,GAAM,EAAE,OAAS,EAAkB,EAAE,OACpD,GACA,KAiBF,OAfI,EAAS,SAAW,GAAK,EACpB,MAeP,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oBAAf,EACE,EAAA,EAAA,MAAC,SAAD,CACE,KAAK,SACL,QAfe,GAA+C,CAClE,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,CACvB,EAAoB,GAAS,CAAC,EAAK,EAa/B,SAAU,EACV,cAAY,wBACZ,MAAO,GAAsB,IAAA,GAC7B,gBAAc,OACd,gBAAe,EACf,UAAW,EAAA,GACT,EAAA,6BACA,gBACA,kDACD,UAZH,EAcE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oBACb,GAAqB,EAAE,EAAA,QAAQ,6BAA6B,CACxD,CAAA,EACP,EAAA,EAAA,KAAC,EAAA,oBAAD,CAAqB,OAAQ,EAAmB,CAAA,CACzC,GACR,IACC,EAAA,EAAA,KAAC,EAAA,yBAAD,CACY,WACS,oBACnB,SA9Bc,GAAwB,CACxC,IAAgB,GACpB,EAAa,EAAgB,EAAY,EA6BnC,YAAe,EAAmB,GAAM,CACxC,CAAA,CAEA"}
@@ -14,7 +14,7 @@ import f from "react";
14
14
  import { jsx as p, jsxs as m } from "react/jsx-runtime";
15
15
  //#region src/components/features/chat/switch-profile-button.tsx
16
16
  function h() {
17
- let { t: h } = e("openhands"), [g, _] = f.useState(!1), { conversationId: v } = r(), { data: y } = c(), { data: b } = a(), { data: x } = s(), { switchAndLog: S, isPending: C } = u(), w = i((e) => v ? e.activeProfileByConversation[v] : void 0), T = y?.profiles ?? [], E = b?.llm_model ?? null, D = b?.agent_kind === "acp" || !b && x?.agent_settings?.agent_kind === "acp", O = w ?? (E ? T.find((e) => e.model === E)?.name ?? null : y?.active_profile ?? null), k = T.find((e) => e.name === O)?.model ?? E ?? null;
17
+ let { t: h } = e("openhands"), [g, _] = f.useState(!1), { conversationId: v } = r(), { data: y } = c(), { data: b } = a(), { data: x } = s(), { switchAndLog: S, isPending: C } = u(), w = i((e) => v ? e.activeProfileByConversation[v] : void 0), T = y?.profiles ?? [], E = b?.llm_model ?? null, D = b?.agent_kind === "acp" || !b && x?.agent_settings?.agent_kind === "acp", O = b?.active_profile ?? null, k = O && T.some((e) => e.name === O) ? O : null, A = w ?? k ?? (E ? T.find((e) => e.model === E)?.name ?? null : y?.active_profile ?? null), j = T.find((e) => e.name === A)?.model ?? E ?? null;
18
18
  return T.length === 0 || D ? null : /* @__PURE__ */ m("div", {
19
19
  className: "relative",
20
20
  children: [/* @__PURE__ */ m("button", {
@@ -24,19 +24,19 @@ function h() {
24
24
  },
25
25
  disabled: C,
26
26
  "data-testid": "switch-profile-button",
27
- title: k ?? void 0,
27
+ title: j ?? void 0,
28
28
  "aria-haspopup": "menu",
29
29
  "aria-expanded": g,
30
30
  className: n(o, "max-w-[200px]", "disabled:opacity-50 disabled:cursor-not-allowed"),
31
31
  children: [/* @__PURE__ */ p("span", {
32
32
  className: "truncate",
33
- children: O ?? h(t.LLM$SELECT_MODEL_PLACEHOLDER)
33
+ children: A ?? h(t.LLM$SELECT_MODEL_PLACEHOLDER)
34
34
  }), /* @__PURE__ */ p(l, { isOpen: g })]
35
35
  }), g && /* @__PURE__ */ p(d, {
36
36
  profiles: T,
37
- activeProfileName: O,
37
+ activeProfileName: A,
38
38
  onSelect: (e) => {
39
- e !== O && S(v, e);
39
+ e !== A && S(v, e);
40
40
  },
41
41
  onClose: () => _(!1)
42
42
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"switch-profile-button.js","names":[],"sources":["../../../../src/components/features/chat/switch-profile-button.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\nimport { useSwitchLlmProfileAndLog } from \"#/hooks/mutation/use-switch-llm-profile-and-log\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\nimport { SwitchProfileContextMenu } from \"./switch-profile-context-menu\";\n\nexport function SwitchProfileButton() {\n const { t } = useTranslation(\"openhands\");\n const [contextMenuOpen, setContextMenuOpen] = React.useState(false);\n // Null on the home page; `useSwitchLlmProfileAndLog` is fine with that\n // because /api/profiles/<name>/activate is a global endpoint.\n const { conversationId } = useOptionalConversationId();\n const { data } = useLlmProfiles();\n const { data: conversation } = useActiveConversation();\n const { data: settings } = useSettings();\n const { switchAndLog, isPending } = useSwitchLlmProfileAndLog();\n // Optimistic value written by recordSwitch on a successful switch — gives\n // instant in-conversation feedback before the conversation refetch lands\n // with the new `llm_model`.\n const optimisticActiveProfile = useModelStore((s) =>\n conversationId ? s.activeProfileByConversation[conversationId] : undefined,\n );\n\n const profiles = data?.profiles ?? [];\n const conversationModel = conversation?.llm_model ?? null;\n // ACPAgent conversations route prompts to a CLI subprocess whose model is\n // controlled by ``acp_model`` (set in Settings → Agent), not by the LLM\n // profile picker. Surfacing the switcher here would let the user \"change\n // the model\" while the running subprocess silently keeps its own — a\n // confusing no-op. Hide the button even when ``llm_model`` carries an ACP\n // display model for chips/headers.\n //\n // On the home screen ``conversation`` is undefined; fall back to\n // ``settings.agent_settings.agent_kind`` so the picker also hides when\n // ACP is the *default* the next-created conversation would inherit.\n // Otherwise an ACP user lands on a home page with an LLM-switch\n // control that contradicts the ACP nav gating everywhere else.\n const isAcpActive =\n conversation?.agent_kind === \"acp\" ||\n (!conversation && settings?.agent_settings?.agent_kind === \"acp\");\n\n // Resolution priority for the active profile name:\n // 1. Optimistic (just-clicked) — instant feedback before the refetch.\n // 2. Profile whose model matches the running llm_model — cold loads.\n // 3. User-level active_profile — home page / before the conversation has\n // sent any messages.\n const activeProfileName =\n optimisticActiveProfile ??\n (conversationModel\n ? (profiles.find((p) => p.model === conversationModel)?.name ?? null)\n : (data?.active_profile ?? null));\n const activeProfileModel =\n profiles.find((p) => p.name === activeProfileName)?.model ??\n conversationModel ??\n null;\n\n if (profiles.length === 0 || isAcpActive) {\n return null;\n }\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n setContextMenuOpen((open) => !open);\n };\n\n const handleSelect = (profileName: string) => {\n if (profileName === activeProfileName) return;\n switchAndLog(conversationId, profileName);\n };\n\n return (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isPending}\n data-testid=\"switch-profile-button\"\n title={activeProfileModel ?? undefined}\n aria-haspopup=\"menu\"\n aria-expanded={contextMenuOpen}\n className={cn(\n chatInputPillButtonClassName,\n \"max-w-[200px]\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n )}\n >\n <span className=\"truncate\">\n {activeProfileName ?? t(I18nKey.LLM$SELECT_MODEL_PLACEHOLDER)}\n </span>\n <ComboboxCaretInline isOpen={contextMenuOpen} />\n </button>\n {contextMenuOpen && (\n <SwitchProfileContextMenu\n profiles={profiles}\n activeProfileName={activeProfileName}\n onSelect={handleSelect}\n onClose={() => setContextMenuOpen(false)}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAcA,SAAgB,IAAsB;CACpC,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,CAAC,GAAiB,KAAsB,EAAM,SAAS,GAAM,EAG7D,EAAE,sBAAmB,GAA2B,EAChD,EAAE,YAAS,GAAgB,EAC3B,EAAE,MAAM,MAAiB,GAAuB,EAChD,EAAE,MAAM,MAAa,GAAa,EAClC,EAAE,iBAAc,iBAAc,GAA2B,EAIzD,IAA0B,GAAe,MAC7C,IAAiB,EAAE,4BAA4B,KAAkB,KAAA,EAClE,EAEK,IAAW,GAAM,YAAY,EAAE,EAC/B,IAAoB,GAAc,aAAa,MAa/C,IACJ,GAAc,eAAe,SAC5B,CAAC,KAAgB,GAAU,gBAAgB,eAAe,OAOvD,IACJ,MACC,IACI,EAAS,MAAM,MAAM,EAAE,UAAU,EAAkB,EAAE,QAAQ,OAC7D,GAAM,kBAAkB,OACzB,IACJ,EAAS,MAAM,MAAM,EAAE,SAAS,EAAkB,EAAE,SACpD,KACA;AAiBF,QAfI,EAAS,WAAW,KAAK,IACpB,OAeP,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,UAAD;GACE,MAAK;GACL,UAfe,MAA+C;AAGlE,IAFA,EAAM,gBAAgB,EACtB,EAAM,iBAAiB,EACvB,GAAoB,MAAS,CAAC,EAAK;;GAa/B,UAAU;GACV,eAAY;GACZ,OAAO,KAAsB,KAAA;GAC7B,iBAAc;GACd,iBAAe;GACf,WAAW,EACT,GACA,iBACA,kDACD;aAZH,CAcE,kBAAC,QAAD;IAAM,WAAU;cACb,KAAqB,EAAE,EAAQ,6BAA6B;IACxD,CAAA,EACP,kBAAC,GAAD,EAAqB,QAAQ,GAAmB,CAAA,CACzC;MACR,KACC,kBAAC,GAAD;GACY;GACS;GACnB,WA9Bc,MAAwB;AACxC,UAAgB,KACpB,EAAa,GAAgB,EAAY;;GA6BnC,eAAe,EAAmB,GAAM;GACxC,CAAA,CAEA"}
1
+ {"version":3,"file":"switch-profile-button.js","names":[],"sources":["../../../../src/components/features/chat/switch-profile-button.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ComboboxCaretInline } from \"#/ui/combobox-caret\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\nimport { useSwitchLlmProfileAndLog } from \"#/hooks/mutation/use-switch-llm-profile-and-log\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { useModelStore } from \"#/stores/model-store\";\nimport { cn } from \"#/utils/utils\";\nimport { chatInputPillButtonClassName } from \"#/utils/form-control-classes\";\nimport { SwitchProfileContextMenu } from \"./switch-profile-context-menu\";\n\nexport function SwitchProfileButton() {\n const { t } = useTranslation(\"openhands\");\n const [contextMenuOpen, setContextMenuOpen] = React.useState(false);\n // Null on the home page; `useSwitchLlmProfileAndLog` is fine with that\n // because /api/profiles/<name>/activate is a global endpoint.\n const { conversationId } = useOptionalConversationId();\n const { data } = useLlmProfiles();\n const { data: conversation } = useActiveConversation();\n const { data: settings } = useSettings();\n const { switchAndLog, isPending } = useSwitchLlmProfileAndLog();\n // Optimistic value written by recordSwitch on a successful switch — gives\n // instant in-conversation feedback before the conversation refetch lands\n // with the new `llm_model`.\n const optimisticActiveProfile = useModelStore((s) =>\n conversationId ? s.activeProfileByConversation[conversationId] : undefined,\n );\n\n const profiles = data?.profiles ?? [];\n const conversationModel = conversation?.llm_model ?? null;\n // ACPAgent conversations route prompts to a CLI subprocess whose model is\n // controlled by ``acp_model`` (set in Settings → Agent), not by the LLM\n // profile picker. Surfacing the switcher here would let the user \"change\n // the model\" while the running subprocess silently keeps its own — a\n // confusing no-op. Hide the button even when ``llm_model`` carries an ACP\n // display model for chips/headers.\n //\n // On the home screen ``conversation`` is undefined; fall back to\n // ``settings.agent_settings.agent_kind`` so the picker also hides when\n // ACP is the *default* the next-created conversation would inherit.\n // Otherwise an ACP user lands on a home page with an LLM-switch\n // control that contradicts the ACP nav gating everywhere else.\n const isAcpActive =\n conversation?.agent_kind === \"acp\" ||\n (!conversation && settings?.agent_settings?.agent_kind === \"acp\");\n\n // Resolution priority for the active profile name:\n // 1. Optimistic (just-clicked) — instant feedback before the refetch.\n // 2. Profile stamped on the conversation at creation / last switch —\n // exact identity, survives reload, and is unambiguous when several\n // profiles share one underlying model (#1082). Validated against the\n // live list so a since-deleted/renamed profile falls through.\n // 3. Profile whose model matches the running llm_model — legacy fallback.\n // 4. User-level active_profile — home page / before the conversation has\n // sent any messages.\n const stampedProfile = conversation?.active_profile ?? null;\n const conversationProfile =\n stampedProfile && profiles.some((p) => p.name === stampedProfile)\n ? stampedProfile\n : null;\n const activeProfileName =\n optimisticActiveProfile ??\n conversationProfile ??\n (conversationModel\n ? (profiles.find((p) => p.model === conversationModel)?.name ?? null)\n : (data?.active_profile ?? null));\n const activeProfileModel =\n profiles.find((p) => p.name === activeProfileName)?.model ??\n conversationModel ??\n null;\n\n if (profiles.length === 0 || isAcpActive) {\n return null;\n }\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n setContextMenuOpen((open) => !open);\n };\n\n const handleSelect = (profileName: string) => {\n if (profileName === activeProfileName) return;\n switchAndLog(conversationId, profileName);\n };\n\n return (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isPending}\n data-testid=\"switch-profile-button\"\n title={activeProfileModel ?? undefined}\n aria-haspopup=\"menu\"\n aria-expanded={contextMenuOpen}\n className={cn(\n chatInputPillButtonClassName,\n \"max-w-[200px]\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n )}\n >\n <span className=\"truncate\">\n {activeProfileName ?? t(I18nKey.LLM$SELECT_MODEL_PLACEHOLDER)}\n </span>\n <ComboboxCaretInline isOpen={contextMenuOpen} />\n </button>\n {contextMenuOpen && (\n <SwitchProfileContextMenu\n profiles={profiles}\n activeProfileName={activeProfileName}\n onSelect={handleSelect}\n onClose={() => setContextMenuOpen(false)}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAcA,SAAgB,IAAsB;CACpC,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,CAAC,GAAiB,KAAsB,EAAM,SAAS,GAAM,EAG7D,EAAE,sBAAmB,GAA2B,EAChD,EAAE,YAAS,GAAgB,EAC3B,EAAE,MAAM,MAAiB,GAAuB,EAChD,EAAE,MAAM,MAAa,GAAa,EAClC,EAAE,iBAAc,iBAAc,GAA2B,EAIzD,IAA0B,GAAe,MAC7C,IAAiB,EAAE,4BAA4B,KAAkB,KAAA,EAClE,EAEK,IAAW,GAAM,YAAY,EAAE,EAC/B,IAAoB,GAAc,aAAa,MAa/C,IACJ,GAAc,eAAe,SAC5B,CAAC,KAAgB,GAAU,gBAAgB,eAAe,OAWvD,IAAiB,GAAc,kBAAkB,MACjD,IACJ,KAAkB,EAAS,MAAM,MAAM,EAAE,SAAS,EAAe,GAC7D,IACA,MACA,IACJ,KACA,MACC,IACI,EAAS,MAAM,MAAM,EAAE,UAAU,EAAkB,EAAE,QAAQ,OAC7D,GAAM,kBAAkB,OACzB,IACJ,EAAS,MAAM,MAAM,EAAE,SAAS,EAAkB,EAAE,SACpD,KACA;AAiBF,QAfI,EAAS,WAAW,KAAK,IACpB,OAeP,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,UAAD;GACE,MAAK;GACL,UAfe,MAA+C;AAGlE,IAFA,EAAM,gBAAgB,EACtB,EAAM,iBAAiB,EACvB,GAAoB,MAAS,CAAC,EAAK;;GAa/B,UAAU;GACV,eAAY;GACZ,OAAO,KAAsB,KAAA;GAC7B,iBAAc;GACd,iBAAe;GACf,WAAW,EACT,GACA,iBACA,kDACD;aAZH,CAcE,kBAAC,QAAD;IAAM,WAAU;cACb,KAAqB,EAAE,EAAQ,6BAA6B;IACxD,CAAA,EACP,kBAAC,GAAD,EAAqB,QAAQ,GAAmB,CAAA,CACzC;MACR,KACC,kBAAC,GAAD;GACY;GACS;GACnB,WA9Bc,MAAwB;AACxC,UAAgB,KACpB,EAAa,GAAgB,EAAY;;GA6BnC,eAAe,EAAmB,GAAM;GACxC,CAAA,CAEA"}
@@ -1,2 +1,2 @@
1
- require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../../../types/agent-state.cjs`),r=require(`../../../api/agent-server-config.cjs`),i=require(`../../../hooks/use-agent-state.cjs`),a=require(`../../../hooks/query/use-conversation-skills.cjs`),o=require(`../../shared/modals/modal-backdrop.cjs`),s=require(`../../shared/modals/modal-body.cjs`),c=require(`../../../utils/skill-scope.cjs`),l=require(`./skills-modal-header.cjs`),u=require(`./skills-modal-section.cjs`),d=require(`./skills-runtime-waiting-state.cjs`),f=require(`./skills-loading-state.cjs`),p=require(`./skills-empty-state.cjs`),m=require(`./skill-item.cjs`);let h=require(`react`),g=require(`react/jsx-runtime`);var _={project:t.I18nKey.SKILLS_MODAL$SECTION_PROJECT,personal:t.I18nKey.SKILLS_MODAL$SECTION_USER,public:t.I18nKey.SKILLS_MODAL$SECTION_PUBLIC};function v({onClose:t}){let{t:v}=e.useTranslation(`openhands`),{curAgentState:y}=i.useAgentState(),b=r.getAgentServerWorkingDir(),[x,S]=(0,h.useState)({}),{data:C,isLoading:w,isError:T,refetch:E,isRefetching:D}=a.useConversationSkills(),O=(0,h.useMemo)(()=>C?c.groupSkillsByScope(C,b):null,[C,b]),k=e=>{S(t=>({...t,[e]:!t[e]}))},A=![n.AgentState.LOADING,n.AgentState.INIT].includes(y);return(0,g.jsx)(o.ModalBackdrop,{onClose:t,children:(0,g.jsxs)(s.ModalBody,{width:`lg`,className:`relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]`,testID:`skills-modal`,children:[(0,g.jsx)(l.SkillsModalHeader,{isLoading:w,isRefetching:D,onRefresh:E,onClose:t}),(0,g.jsx)(`div`,{className:`w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always`,children:A?w?(0,g.jsx)(f.SkillsLoadingState,{}):T||!C||C.length===0?(0,g.jsx)(p.SkillsEmptyState,{isError:T}):O&&(0,g.jsx)(`div`,{className:`divide-y divide-[var(--oh-border)]`,children:c.SKILL_SCOPE_ORDER.map(e=>{let t=O[e];return t.length===0?null:(0,g.jsx)(u.SkillsModalSection,{title:v(_[e]),count:t.length,children:t.map(t=>(0,g.jsx)(m.SkillItem,{skill:t,isExpanded:x[t.name]||!1,onToggle:k},`${e}-${t.name}`))},e)})}):(0,g.jsx)(d.SkillsRuntimeWaitingState,{})})]})})}exports.SkillsModal=v;
1
+ require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../../../api/agent-server-config.cjs`),r=require(`../../../hooks/query/use-conversation-skills.cjs`),i=require(`../../shared/modals/modal-backdrop.cjs`),a=require(`../../shared/modals/modal-body.cjs`),o=require(`../../../utils/skill-scope.cjs`),s=require(`./skills-modal-header.cjs`),c=require(`./skills-modal-section.cjs`),l=require(`./skills-loading-state.cjs`),u=require(`./skills-empty-state.cjs`),d=require(`./skill-item.cjs`);let f=require(`react`),p=require(`react/jsx-runtime`);var m={project:t.I18nKey.SKILLS_MODAL$SECTION_PROJECT,personal:t.I18nKey.SKILLS_MODAL$SECTION_USER,public:t.I18nKey.SKILLS_MODAL$SECTION_PUBLIC};function h({onClose:t}){let{t:h}=e.useTranslation(`openhands`),g=n.getAgentServerWorkingDir(),[_,v]=(0,f.useState)({}),{data:y,isLoading:b,isError:x,refetch:S,isRefetching:C}=r.useConversationSkills(),w=(0,f.useMemo)(()=>y?o.groupSkillsByScope(y,g):null,[y,g]),T=e=>{v(t=>({...t,[e]:!t[e]}))};return(0,p.jsx)(i.ModalBackdrop,{onClose:t,children:(0,p.jsxs)(a.ModalBody,{width:`lg`,className:`relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]`,testID:`skills-modal`,children:[(0,p.jsx)(s.SkillsModalHeader,{isLoading:b,isRefetching:C,onRefresh:S,onClose:t}),(0,p.jsx)(`div`,{className:`w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always`,children:b?(0,p.jsx)(l.SkillsLoadingState,{}):x||!y||y.length===0?(0,p.jsx)(u.SkillsEmptyState,{isError:x}):w&&(0,p.jsx)(`div`,{className:`divide-y divide-[var(--oh-border)]`,children:o.SKILL_SCOPE_ORDER.map(e=>{let t=w[e];return t.length===0?null:(0,p.jsx)(c.SkillsModalSection,{title:h(m[e]),count:t.length,children:t.map(t=>(0,p.jsx)(d.SkillItem,{skill:t,isExpanded:_[t.name]||!1,onToggle:T},`${e}-${t.name}`))},e)})})})]})})}exports.SkillsModal=h;
2
2
  //# sourceMappingURL=skills-modal.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"skills-modal.cjs","names":[],"sources":["../../../../src/components/features/conversation-panel/skills-modal.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getAgentServerWorkingDir } from \"#/api/agent-server-config\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport { AgentState } from \"#/types/agent-state\";\nimport {\n groupSkillsByScope,\n SKILL_SCOPE_ORDER,\n type SkillScope,\n} from \"#/utils/skill-scope\";\nimport { SkillsModalHeader } from \"./skills-modal-header\";\nimport { SkillsModalSection } from \"./skills-modal-section\";\nimport { SkillsRuntimeWaitingState } from \"./skills-runtime-waiting-state\";\nimport { SkillsLoadingState } from \"./skills-loading-state\";\nimport { SkillsEmptyState } from \"./skills-empty-state\";\nimport { SkillItem } from \"./skill-item\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\n\ninterface SkillsModalProps {\n onClose: () => void;\n}\n\nconst SECTION_TITLE_KEY: Record<SkillScope, I18nKey> = {\n project: I18nKey.SKILLS_MODAL$SECTION_PROJECT,\n personal: I18nKey.SKILLS_MODAL$SECTION_USER,\n public: I18nKey.SKILLS_MODAL$SECTION_PUBLIC,\n};\n\nexport function SkillsModal({ onClose }: SkillsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const { curAgentState } = useAgentState();\n const projectDir = getAgentServerWorkingDir();\n const [expandedAgents, setExpandedAgents] = useState<Record<string, boolean>>(\n {},\n );\n // Scope the catalog to this conversation's attached workspace so the listed\n // skills match the project skills actually loaded into the conversation.\n const {\n data: skills,\n isLoading,\n isError,\n refetch,\n isRefetching,\n } = useConversationSkills();\n\n const groupedSkills = useMemo(\n () => (skills ? groupSkillsByScope(skills, projectDir) : null),\n [skills, projectDir],\n );\n\n const toggleAgent = (agentName: string) => {\n setExpandedAgents((prev) => ({\n ...prev,\n [agentName]: !prev[agentName],\n }));\n };\n\n const isAgentReady = ![AgentState.LOADING, AgentState.INIT].includes(\n curAgentState,\n );\n\n return (\n <ModalBackdrop onClose={onClose}>\n <ModalBody\n width=\"lg\"\n className=\"relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]\"\n testID=\"skills-modal\"\n >\n <SkillsModalHeader\n isLoading={isLoading}\n isRefetching={isRefetching}\n onRefresh={refetch}\n onClose={onClose}\n />\n\n <div className=\"w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\">\n {!isAgentReady ? (\n <SkillsRuntimeWaitingState />\n ) : isLoading ? (\n <SkillsLoadingState />\n ) : isError || !skills || skills.length === 0 ? (\n <SkillsEmptyState isError={isError} />\n ) : (\n groupedSkills && (\n <div className=\"divide-y divide-[var(--oh-border)]\">\n {SKILL_SCOPE_ORDER.map((scope) => {\n const scopedSkills = groupedSkills[scope];\n if (scopedSkills.length === 0) {\n return null;\n }\n\n return (\n <SkillsModalSection\n key={scope}\n title={t(SECTION_TITLE_KEY[scope])}\n count={scopedSkills.length}\n >\n {scopedSkills.map((skill) => {\n const isExpanded = expandedAgents[skill.name] || false;\n\n return (\n <SkillItem\n key={`${scope}-${skill.name}`}\n skill={skill}\n isExpanded={isExpanded}\n onToggle={toggleAgent}\n />\n );\n })}\n </SkillsModalSection>\n );\n })}\n </div>\n )\n )}\n </div>\n </ModalBody>\n </ModalBackdrop>\n );\n}\n"],"mappings":"6yBAyBA,IAAM,EAAiD,CACrD,QAAS,EAAA,QAAQ,6BACjB,SAAU,EAAA,QAAQ,0BAClB,OAAQ,EAAA,QAAQ,4BACjB,CAED,SAAgB,EAAY,CAAE,WAA6B,CACzD,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,CAAE,iBAAkB,EAAA,eAAe,CACnC,EAAa,EAAA,0BAA0B,CACvC,CAAC,EAAgB,IAAA,EAAA,EAAA,UACrB,EAAE,CACH,CAGK,CACJ,KAAM,EACN,YACA,UACA,UACA,gBACE,EAAA,uBAAuB,CAErB,GAAA,EAAA,EAAA,aACG,EAAS,EAAA,mBAAmB,EAAQ,EAAW,CAAG,KACzD,CAAC,EAAQ,EAAW,CACrB,CAEK,EAAe,GAAsB,CACzC,EAAmB,IAAU,CAC3B,GAAG,GACF,GAAY,CAAC,EAAK,GACpB,EAAE,EAGC,EAAe,CAAC,CAAC,EAAA,WAAW,QAAS,EAAA,WAAW,KAAK,CAAC,SAC1D,EACD,CAED,OACE,EAAA,EAAA,KAAC,EAAA,cAAD,CAAwB,oBACtB,EAAA,EAAA,MAAC,EAAA,UAAD,CACE,MAAM,KACN,UAAU,mFACV,OAAO,wBAHT,EAKE,EAAA,EAAA,KAAC,EAAA,kBAAD,CACa,YACG,eACd,UAAW,EACF,UACT,CAAA,EAEF,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+HACX,EAEE,GACF,EAAA,EAAA,KAAC,EAAA,mBAAD,EAAsB,CAAA,CACpB,GAAW,CAAC,GAAU,EAAO,SAAW,GAC1C,EAAA,EAAA,KAAC,EAAA,iBAAD,CAA2B,UAAW,CAAA,CAEtC,IACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,8CACZ,EAAA,kBAAkB,IAAK,GAAU,CAChC,IAAM,EAAe,EAAc,GAKnC,OAJI,EAAa,SAAW,EACnB,MAIP,EAAA,EAAA,KAAC,EAAA,mBAAD,CAEE,MAAO,EAAE,EAAkB,GAAO,CAClC,MAAO,EAAa,gBAEnB,EAAa,IAAK,IAIf,EAAA,EAAA,KAAC,EAAA,UAAD,CAES,QACK,WANG,EAAe,EAAM,OAAS,GAO7C,SAAU,EACV,CAJK,GAAG,EAAM,GAAG,EAAM,OAIvB,CAEJ,CACiB,CAhBd,EAgBc,EAEvB,CACE,CAAA,EAnCR,EAAA,EAAA,KAAC,EAAA,0BAAD,EAA6B,CAAA,CAsC3B,CAAA,CACI,GACE,CAAA"}
1
+ {"version":3,"file":"skills-modal.cjs","names":[],"sources":["../../../../src/components/features/conversation-panel/skills-modal.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getAgentServerWorkingDir } from \"#/api/agent-server-config\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport {\n groupSkillsByScope,\n SKILL_SCOPE_ORDER,\n type SkillScope,\n} from \"#/utils/skill-scope\";\nimport { SkillsModalHeader } from \"./skills-modal-header\";\nimport { SkillsModalSection } from \"./skills-modal-section\";\nimport { SkillsLoadingState } from \"./skills-loading-state\";\nimport { SkillsEmptyState } from \"./skills-empty-state\";\nimport { SkillItem } from \"./skill-item\";\n\ninterface SkillsModalProps {\n onClose: () => void;\n}\n\nconst SECTION_TITLE_KEY: Record<SkillScope, I18nKey> = {\n project: I18nKey.SKILLS_MODAL$SECTION_PROJECT,\n personal: I18nKey.SKILLS_MODAL$SECTION_USER,\n public: I18nKey.SKILLS_MODAL$SECTION_PUBLIC,\n};\n\nexport function SkillsModal({ onClose }: SkillsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const projectDir = getAgentServerWorkingDir();\n const [expandedAgents, setExpandedAgents] = useState<Record<string, boolean>>(\n {},\n );\n // Scope the catalog to this conversation's attached workspace so the listed\n // skills match the project skills actually loaded into the conversation.\n const {\n data: skills,\n isLoading,\n isError,\n refetch,\n isRefetching,\n } = useConversationSkills();\n\n const groupedSkills = useMemo(\n () => (skills ? groupSkillsByScope(skills, projectDir) : null),\n [skills, projectDir],\n );\n\n const toggleAgent = (agentName: string) => {\n setExpandedAgents((prev) => ({\n ...prev,\n [agentName]: !prev[agentName],\n }));\n };\n\n return (\n <ModalBackdrop onClose={onClose}>\n <ModalBody\n width=\"lg\"\n className=\"relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]\"\n testID=\"skills-modal\"\n >\n <SkillsModalHeader\n isLoading={isLoading}\n isRefetching={isRefetching}\n onRefresh={refetch}\n onClose={onClose}\n />\n\n <div className=\"w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\">\n {isLoading ? (\n <SkillsLoadingState />\n ) : isError || !skills || skills.length === 0 ? (\n <SkillsEmptyState isError={isError} />\n ) : (\n groupedSkills && (\n <div className=\"divide-y divide-[var(--oh-border)]\">\n {SKILL_SCOPE_ORDER.map((scope) => {\n const scopedSkills = groupedSkills[scope];\n if (scopedSkills.length === 0) {\n return null;\n }\n\n return (\n <SkillsModalSection\n key={scope}\n title={t(SECTION_TITLE_KEY[scope])}\n count={scopedSkills.length}\n >\n {scopedSkills.map((skill) => {\n const isExpanded = expandedAgents[skill.name] || false;\n\n return (\n <SkillItem\n key={`${scope}-${skill.name}`}\n skill={skill}\n isExpanded={isExpanded}\n onToggle={toggleAgent}\n />\n );\n })}\n </SkillsModalSection>\n );\n })}\n </div>\n )\n )}\n </div>\n </ModalBody>\n </ModalBackdrop>\n );\n}\n"],"mappings":"iqBAsBA,IAAM,EAAiD,CACrD,QAAS,EAAA,QAAQ,6BACjB,SAAU,EAAA,QAAQ,0BAClB,OAAQ,EAAA,QAAQ,4BACjB,CAED,SAAgB,EAAY,CAAE,WAA6B,CACzD,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,EAAa,EAAA,0BAA0B,CACvC,CAAC,EAAgB,IAAA,EAAA,EAAA,UACrB,EAAE,CACH,CAGK,CACJ,KAAM,EACN,YACA,UACA,UACA,gBACE,EAAA,uBAAuB,CAErB,GAAA,EAAA,EAAA,aACG,EAAS,EAAA,mBAAmB,EAAQ,EAAW,CAAG,KACzD,CAAC,EAAQ,EAAW,CACrB,CAEK,EAAe,GAAsB,CACzC,EAAmB,IAAU,CAC3B,GAAG,GACF,GAAY,CAAC,EAAK,GACpB,EAAE,EAGL,OACE,EAAA,EAAA,KAAC,EAAA,cAAD,CAAwB,oBACtB,EAAA,EAAA,MAAC,EAAA,UAAD,CACE,MAAM,KACN,UAAU,mFACV,OAAO,wBAHT,EAKE,EAAA,EAAA,KAAC,EAAA,kBAAD,CACa,YACG,eACd,UAAW,EACF,UACT,CAAA,EAEF,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+HACZ,GACC,EAAA,EAAA,KAAC,EAAA,mBAAD,EAAsB,CAAA,CACpB,GAAW,CAAC,GAAU,EAAO,SAAW,GAC1C,EAAA,EAAA,KAAC,EAAA,iBAAD,CAA2B,UAAW,CAAA,CAEtC,IACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,8CACZ,EAAA,kBAAkB,IAAK,GAAU,CAChC,IAAM,EAAe,EAAc,GAKnC,OAJI,EAAa,SAAW,EACnB,MAIP,EAAA,EAAA,KAAC,EAAA,mBAAD,CAEE,MAAO,EAAE,EAAkB,GAAO,CAClC,MAAO,EAAa,gBAEnB,EAAa,IAAK,IAIf,EAAA,EAAA,KAAC,EAAA,UAAD,CAES,QACK,WANG,EAAe,EAAM,OAAS,GAO7C,SAAU,EACV,CAJK,GAAG,EAAM,GAAG,EAAM,OAIvB,CAEJ,CACiB,CAhBd,EAgBc,EAEvB,CACE,CAAA,CAGN,CAAA,CACI,GACE,CAAA"}
@@ -1,66 +1,63 @@
1
1
  import { useTranslation as e } from "../../../node_modules/react-i18next/dist/es/useTranslation.js";
2
2
  import { I18nKey as t } from "../../../i18n/declaration.js";
3
- import { AgentState as n } from "../../../types/agent-state.js";
4
- import { getAgentServerWorkingDir as r } from "../../../api/agent-server-config.js";
5
- import { useAgentState as i } from "../../../hooks/use-agent-state.js";
6
- import { useConversationSkills as a } from "../../../hooks/query/use-conversation-skills.js";
7
- import { ModalBackdrop as o } from "../../shared/modals/modal-backdrop.js";
8
- import { ModalBody as s } from "../../shared/modals/modal-body.js";
9
- import { SKILL_SCOPE_ORDER as c, groupSkillsByScope as l } from "../../../utils/skill-scope.js";
10
- import { SkillsModalHeader as u } from "./skills-modal-header.js";
11
- import { SkillsModalSection as d } from "./skills-modal-section.js";
12
- import { SkillsRuntimeWaitingState as f } from "./skills-runtime-waiting-state.js";
13
- import { SkillsLoadingState as p } from "./skills-loading-state.js";
14
- import { SkillsEmptyState as m } from "./skills-empty-state.js";
15
- import { SkillItem as h } from "./skill-item.js";
16
- import { useMemo as g, useState as _ } from "react";
17
- import { jsx as v, jsxs as y } from "react/jsx-runtime";
3
+ import { getAgentServerWorkingDir as n } from "../../../api/agent-server-config.js";
4
+ import { useConversationSkills as r } from "../../../hooks/query/use-conversation-skills.js";
5
+ import { ModalBackdrop as i } from "../../shared/modals/modal-backdrop.js";
6
+ import { ModalBody as a } from "../../shared/modals/modal-body.js";
7
+ import { SKILL_SCOPE_ORDER as o, groupSkillsByScope as s } from "../../../utils/skill-scope.js";
8
+ import { SkillsModalHeader as c } from "./skills-modal-header.js";
9
+ import { SkillsModalSection as l } from "./skills-modal-section.js";
10
+ import { SkillsLoadingState as u } from "./skills-loading-state.js";
11
+ import { SkillsEmptyState as d } from "./skills-empty-state.js";
12
+ import { SkillItem as f } from "./skill-item.js";
13
+ import { useMemo as p, useState as m } from "react";
14
+ import { jsx as h, jsxs as g } from "react/jsx-runtime";
18
15
  //#region src/components/features/conversation-panel/skills-modal.tsx
19
- var b = {
16
+ var _ = {
20
17
  project: t.SKILLS_MODAL$SECTION_PROJECT,
21
18
  personal: t.SKILLS_MODAL$SECTION_USER,
22
19
  public: t.SKILLS_MODAL$SECTION_PUBLIC
23
20
  };
24
- function x({ onClose: t }) {
25
- let { t: x } = e("openhands"), { curAgentState: S } = i(), C = r(), [w, T] = _({}), { data: E, isLoading: D, isError: O, refetch: k, isRefetching: A } = a(), j = g(() => E ? l(E, C) : null, [E, C]), M = (e) => {
26
- T((t) => ({
21
+ function v({ onClose: t }) {
22
+ let { t: v } = e("openhands"), y = n(), [b, x] = m({}), { data: S, isLoading: C, isError: w, refetch: T, isRefetching: E } = r(), D = p(() => S ? s(S, y) : null, [S, y]), O = (e) => {
23
+ x((t) => ({
27
24
  ...t,
28
25
  [e]: !t[e]
29
26
  }));
30
- }, N = ![n.LOADING, n.INIT].includes(S);
31
- return /* @__PURE__ */ v(o, {
27
+ };
28
+ return /* @__PURE__ */ h(i, {
32
29
  onClose: t,
33
- children: /* @__PURE__ */ y(s, {
30
+ children: /* @__PURE__ */ g(a, {
34
31
  width: "lg",
35
32
  className: "relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]",
36
33
  testID: "skills-modal",
37
- children: [/* @__PURE__ */ v(u, {
38
- isLoading: D,
39
- isRefetching: A,
40
- onRefresh: k,
34
+ children: [/* @__PURE__ */ h(c, {
35
+ isLoading: C,
36
+ isRefetching: E,
37
+ onRefresh: T,
41
38
  onClose: t
42
- }), /* @__PURE__ */ v("div", {
39
+ }), /* @__PURE__ */ h("div", {
43
40
  className: "w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always",
44
- children: N ? D ? /* @__PURE__ */ v(p, {}) : O || !E || E.length === 0 ? /* @__PURE__ */ v(m, { isError: O }) : j && /* @__PURE__ */ v("div", {
41
+ children: C ? /* @__PURE__ */ h(u, {}) : w || !S || S.length === 0 ? /* @__PURE__ */ h(d, { isError: w }) : D && /* @__PURE__ */ h("div", {
45
42
  className: "divide-y divide-[var(--oh-border)]",
46
- children: c.map((e) => {
47
- let t = j[e];
48
- return t.length === 0 ? null : /* @__PURE__ */ v(d, {
49
- title: x(b[e]),
43
+ children: o.map((e) => {
44
+ let t = D[e];
45
+ return t.length === 0 ? null : /* @__PURE__ */ h(l, {
46
+ title: v(_[e]),
50
47
  count: t.length,
51
- children: t.map((t) => /* @__PURE__ */ v(h, {
48
+ children: t.map((t) => /* @__PURE__ */ h(f, {
52
49
  skill: t,
53
- isExpanded: w[t.name] || !1,
54
- onToggle: M
50
+ isExpanded: b[t.name] || !1,
51
+ onToggle: O
55
52
  }, `${e}-${t.name}`))
56
53
  }, e);
57
54
  })
58
- }) : /* @__PURE__ */ v(f, {})
55
+ })
59
56
  })]
60
57
  })
61
58
  });
62
59
  }
63
60
  //#endregion
64
- export { x as SkillsModal };
61
+ export { v as SkillsModal };
65
62
 
66
63
  //# sourceMappingURL=skills-modal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"skills-modal.js","names":[],"sources":["../../../../src/components/features/conversation-panel/skills-modal.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getAgentServerWorkingDir } from \"#/api/agent-server-config\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport { AgentState } from \"#/types/agent-state\";\nimport {\n groupSkillsByScope,\n SKILL_SCOPE_ORDER,\n type SkillScope,\n} from \"#/utils/skill-scope\";\nimport { SkillsModalHeader } from \"./skills-modal-header\";\nimport { SkillsModalSection } from \"./skills-modal-section\";\nimport { SkillsRuntimeWaitingState } from \"./skills-runtime-waiting-state\";\nimport { SkillsLoadingState } from \"./skills-loading-state\";\nimport { SkillsEmptyState } from \"./skills-empty-state\";\nimport { SkillItem } from \"./skill-item\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\n\ninterface SkillsModalProps {\n onClose: () => void;\n}\n\nconst SECTION_TITLE_KEY: Record<SkillScope, I18nKey> = {\n project: I18nKey.SKILLS_MODAL$SECTION_PROJECT,\n personal: I18nKey.SKILLS_MODAL$SECTION_USER,\n public: I18nKey.SKILLS_MODAL$SECTION_PUBLIC,\n};\n\nexport function SkillsModal({ onClose }: SkillsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const { curAgentState } = useAgentState();\n const projectDir = getAgentServerWorkingDir();\n const [expandedAgents, setExpandedAgents] = useState<Record<string, boolean>>(\n {},\n );\n // Scope the catalog to this conversation's attached workspace so the listed\n // skills match the project skills actually loaded into the conversation.\n const {\n data: skills,\n isLoading,\n isError,\n refetch,\n isRefetching,\n } = useConversationSkills();\n\n const groupedSkills = useMemo(\n () => (skills ? groupSkillsByScope(skills, projectDir) : null),\n [skills, projectDir],\n );\n\n const toggleAgent = (agentName: string) => {\n setExpandedAgents((prev) => ({\n ...prev,\n [agentName]: !prev[agentName],\n }));\n };\n\n const isAgentReady = ![AgentState.LOADING, AgentState.INIT].includes(\n curAgentState,\n );\n\n return (\n <ModalBackdrop onClose={onClose}>\n <ModalBody\n width=\"lg\"\n className=\"relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]\"\n testID=\"skills-modal\"\n >\n <SkillsModalHeader\n isLoading={isLoading}\n isRefetching={isRefetching}\n onRefresh={refetch}\n onClose={onClose}\n />\n\n <div className=\"w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\">\n {!isAgentReady ? (\n <SkillsRuntimeWaitingState />\n ) : isLoading ? (\n <SkillsLoadingState />\n ) : isError || !skills || skills.length === 0 ? (\n <SkillsEmptyState isError={isError} />\n ) : (\n groupedSkills && (\n <div className=\"divide-y divide-[var(--oh-border)]\">\n {SKILL_SCOPE_ORDER.map((scope) => {\n const scopedSkills = groupedSkills[scope];\n if (scopedSkills.length === 0) {\n return null;\n }\n\n return (\n <SkillsModalSection\n key={scope}\n title={t(SECTION_TITLE_KEY[scope])}\n count={scopedSkills.length}\n >\n {scopedSkills.map((skill) => {\n const isExpanded = expandedAgents[skill.name] || false;\n\n return (\n <SkillItem\n key={`${scope}-${skill.name}`}\n skill={skill}\n isExpanded={isExpanded}\n onToggle={toggleAgent}\n />\n );\n })}\n </SkillsModalSection>\n );\n })}\n </div>\n )\n )}\n </div>\n </ModalBody>\n </ModalBackdrop>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAyBA,IAAM,IAAiD;CACrD,SAAS,EAAQ;CACjB,UAAU,EAAQ;CAClB,QAAQ,EAAQ;CACjB;AAED,SAAgB,EAAY,EAAE,cAA6B;CACzD,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,EAAE,qBAAkB,GAAe,EACnC,IAAa,GAA0B,EACvC,CAAC,GAAgB,KAAqB,EAC1C,EAAE,CACH,EAGK,EACJ,MAAM,GACN,cACA,YACA,YACA,oBACE,GAAuB,EAErB,IAAgB,QACb,IAAS,EAAmB,GAAQ,EAAW,GAAG,MACzD,CAAC,GAAQ,EAAW,CACrB,EAEK,KAAe,MAAsB;AACzC,KAAmB,OAAU;GAC3B,GAAG;IACF,IAAY,CAAC,EAAK;GACpB,EAAE;IAGC,IAAe,CAAC,CAAC,EAAW,SAAS,EAAW,KAAK,CAAC,SAC1D,EACD;AAED,QACE,kBAAC,GAAD;EAAwB;YACtB,kBAAC,GAAD;GACE,OAAM;GACN,WAAU;GACV,QAAO;aAHT,CAKE,kBAAC,GAAD;IACa;IACG;IACd,WAAW;IACF;IACT,CAAA,EAEF,kBAAC,OAAD;IAAK,WAAU;cACX,IAEE,IACF,kBAAC,GAAD,EAAsB,CAAA,GACpB,KAAW,CAAC,KAAU,EAAO,WAAW,IAC1C,kBAAC,GAAD,EAA2B,YAAW,CAAA,GAEtC,KACE,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAkB,KAAK,MAAU;MAChC,IAAM,IAAe,EAAc;AAKnC,aAJI,EAAa,WAAW,IACnB,OAIP,kBAAC,GAAD;OAEE,OAAO,EAAE,EAAkB,GAAO;OAClC,OAAO,EAAa;iBAEnB,EAAa,KAAK,MAIf,kBAAC,GAAD;QAES;QACK,YANG,EAAe,EAAM,SAAS;QAO7C,UAAU;QACV,EAJK,GAAG,EAAM,GAAG,EAAM,OAIvB,CAEJ;OACiB,EAhBd,EAgBc;OAEvB;KACE,CAAA,GAnCR,kBAAC,GAAD,EAA6B,CAAA;IAsC3B,CAAA,CACI;;EACE,CAAA"}
1
+ {"version":3,"file":"skills-modal.js","names":[],"sources":["../../../../src/components/features/conversation-panel/skills-modal.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ModalBackdrop } from \"#/components/shared/modals/modal-backdrop\";\nimport { ModalBody } from \"#/components/shared/modals/modal-body\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { getAgentServerWorkingDir } from \"#/api/agent-server-config\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport {\n groupSkillsByScope,\n SKILL_SCOPE_ORDER,\n type SkillScope,\n} from \"#/utils/skill-scope\";\nimport { SkillsModalHeader } from \"./skills-modal-header\";\nimport { SkillsModalSection } from \"./skills-modal-section\";\nimport { SkillsLoadingState } from \"./skills-loading-state\";\nimport { SkillsEmptyState } from \"./skills-empty-state\";\nimport { SkillItem } from \"./skill-item\";\n\ninterface SkillsModalProps {\n onClose: () => void;\n}\n\nconst SECTION_TITLE_KEY: Record<SkillScope, I18nKey> = {\n project: I18nKey.SKILLS_MODAL$SECTION_PROJECT,\n personal: I18nKey.SKILLS_MODAL$SECTION_USER,\n public: I18nKey.SKILLS_MODAL$SECTION_PUBLIC,\n};\n\nexport function SkillsModal({ onClose }: SkillsModalProps) {\n const { t } = useTranslation(\"openhands\");\n const projectDir = getAgentServerWorkingDir();\n const [expandedAgents, setExpandedAgents] = useState<Record<string, boolean>>(\n {},\n );\n // Scope the catalog to this conversation's attached workspace so the listed\n // skills match the project skills actually loaded into the conversation.\n const {\n data: skills,\n isLoading,\n isError,\n refetch,\n isRefetching,\n } = useConversationSkills();\n\n const groupedSkills = useMemo(\n () => (skills ? groupSkillsByScope(skills, projectDir) : null),\n [skills, projectDir],\n );\n\n const toggleAgent = (agentName: string) => {\n setExpandedAgents((prev) => ({\n ...prev,\n [agentName]: !prev[agentName],\n }));\n };\n\n return (\n <ModalBackdrop onClose={onClose}>\n <ModalBody\n width=\"lg\"\n className=\"relative max-h-[80vh] flex flex-col items-start border border-[var(--oh-border)]\"\n testID=\"skills-modal\"\n >\n <SkillsModalHeader\n isLoading={isLoading}\n isRefetching={isRefetching}\n onRefresh={refetch}\n onClose={onClose}\n />\n\n <div className=\"w-full h-[60vh] overflow-auto rounded-md border border-[var(--oh-border)] bg-surface-raised custom-scrollbar-always\">\n {isLoading ? (\n <SkillsLoadingState />\n ) : isError || !skills || skills.length === 0 ? (\n <SkillsEmptyState isError={isError} />\n ) : (\n groupedSkills && (\n <div className=\"divide-y divide-[var(--oh-border)]\">\n {SKILL_SCOPE_ORDER.map((scope) => {\n const scopedSkills = groupedSkills[scope];\n if (scopedSkills.length === 0) {\n return null;\n }\n\n return (\n <SkillsModalSection\n key={scope}\n title={t(SECTION_TITLE_KEY[scope])}\n count={scopedSkills.length}\n >\n {scopedSkills.map((skill) => {\n const isExpanded = expandedAgents[skill.name] || false;\n\n return (\n <SkillItem\n key={`${scope}-${skill.name}`}\n skill={skill}\n isExpanded={isExpanded}\n onToggle={toggleAgent}\n />\n );\n })}\n </SkillsModalSection>\n );\n })}\n </div>\n )\n )}\n </div>\n </ModalBody>\n </ModalBackdrop>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAsBA,IAAM,IAAiD;CACrD,SAAS,EAAQ;CACjB,UAAU,EAAQ;CAClB,QAAQ,EAAQ;CACjB;AAED,SAAgB,EAAY,EAAE,cAA6B;CACzD,IAAM,EAAE,SAAM,EAAe,YAAY,EACnC,IAAa,GAA0B,EACvC,CAAC,GAAgB,KAAqB,EAC1C,EAAE,CACH,EAGK,EACJ,MAAM,GACN,cACA,YACA,YACA,oBACE,GAAuB,EAErB,IAAgB,QACb,IAAS,EAAmB,GAAQ,EAAW,GAAG,MACzD,CAAC,GAAQ,EAAW,CACrB,EAEK,KAAe,MAAsB;AACzC,KAAmB,OAAU;GAC3B,GAAG;IACF,IAAY,CAAC,EAAK;GACpB,EAAE;;AAGL,QACE,kBAAC,GAAD;EAAwB;YACtB,kBAAC,GAAD;GACE,OAAM;GACN,WAAU;GACV,QAAO;aAHT,CAKE,kBAAC,GAAD;IACa;IACG;IACd,WAAW;IACF;IACT,CAAA,EAEF,kBAAC,OAAD;IAAK,WAAU;cACZ,IACC,kBAAC,GAAD,EAAsB,CAAA,GACpB,KAAW,CAAC,KAAU,EAAO,WAAW,IAC1C,kBAAC,GAAD,EAA2B,YAAW,CAAA,GAEtC,KACE,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAkB,KAAK,MAAU;MAChC,IAAM,IAAe,EAAc;AAKnC,aAJI,EAAa,WAAW,IACnB,OAIP,kBAAC,GAAD;OAEE,OAAO,EAAE,EAAkB,GAAO;OAClC,OAAO,EAAa;iBAEnB,EAAa,KAAK,MAIf,kBAAC,GAAD;QAES;QACK,YANG,EAAe,EAAM,SAAS;QAO7C,UAAU;QACV,EAJK,GAAG,EAAM,GAAG,EAAM,OAIvB,CAEJ;OACiB,EAhBd,EAgBc;OAEvB;KACE,CAAA;IAGN,CAAA,CACI;;EACE,CAAA"}
@@ -10,5 +10,6 @@ interface WorkspaceSelectionFormProps {
10
10
  */
11
11
  onConfirm?: (workspace: LocalWorkspace) => void;
12
12
  }
13
+ export declare const HOME_SELECTED_WORKSPACE_PATH_KEY = "oh:home-selected-workspace-path";
13
14
  export declare function WorkspaceSelectionForm({ isLoadingSettings, onConfirm, }: WorkspaceSelectionFormProps): import("react/jsx-runtime").JSX.Element;
14
15
  export {};
@@ -2,6 +2,14 @@ interface SetupLlmStepProps {
2
2
  onBack: () => void;
3
3
  onNext: () => void;
4
4
  }
5
+ /**
6
+ * Pre-fills the LLM form with the OpenAI GPT-5.5 model. The SDK's
7
+ * bare default model is `gpt-5.5`; Canvas stores provider-qualified
8
+ * LiteLLM model ids, so the onboarding override uses this OpenAI-prefixed
9
+ * model id. Keeping this as an explicit override marks the model dirty so
10
+ * the Next button persists the suggested default immediately.
11
+ */
12
+ export declare const ONBOARDING_DEFAULT_LLM_MODEL = "openai/gpt-5.5";
5
13
  /**
6
14
  * Step 2: embed the LLM settings form. The screen runs in `embedded`
7
15
  * mode (so it doesn't render its own sticky Save bar) and with
@@ -1 +1 @@
1
- const e=require(`../../../../_virtual/_rolldown/runtime.cjs`);require(`../../../../utils/utils.cjs`),require(`../../../../utils/dropdown-classes.cjs`),require(`../../../../icons/u-check-circle.cjs`),require(`../../../../icons/u-edit.cjs`),require(`../../../../icons/u-delete.cjs`),require(`../../conversation/conversation-name-context-menu-icon-text.cjs`),require(`react`),require(`react/jsx-runtime`);let t=require(`react-dom`);t=e.__toESM(t,1);
1
+ const e=require(`../../../../_virtual/_rolldown/runtime.cjs`);require(`../../../../utils/utils.cjs`),require(`../../../shared/buttons/styled-tooltip.cjs`),require(`../../../../utils/dropdown-classes.cjs`),require(`../../../../icons/u-check-circle.cjs`),require(`../../../../icons/u-edit.cjs`),require(`../../../../icons/u-delete.cjs`),require(`../../conversation/conversation-name-context-menu-icon-text.cjs`),require(`react`),require(`react/jsx-runtime`);let t=require(`react-dom`);t=e.__toESM(t,1);
@@ -1,4 +1,5 @@
1
1
  import "../../../../utils/utils.js";
2
+ import "../../../shared/buttons/styled-tooltip.js";
2
3
  import "../../../../utils/dropdown-classes.js";
3
4
  import "../../../../icons/u-check-circle.js";
4
5
  import "../../../../icons/u-edit.js";
@@ -1,2 +1,2 @@
1
- const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../utils/utils.cjs`),i=require(`../../../context/navigation-context.cjs`),a=require(`../../../contexts/active-backend-context.cjs`),o=require(`../../../utils/custom-toast-handlers.cjs`),s=require(`../../../hooks/query/use-settings.cjs`),c=require(`../../../hooks/use-click-outside-element.cjs`),l=require(`../../../hooks/query/use-config.cjs`),ee=require(`./sidebar-mobile-nav-context.cjs`),u=require(`../../../stores/sidebar-store.cjs`),d=require(`../../../hooks/query/use-backends-health.cjs`),f=require(`./sidebar-rail-body.cjs`);let p=require(`react`);p=e.__toESM(p,1);let m=require(`react/jsx-runtime`);var h=p.default.lazy(()=>Promise.resolve().then(()=>require(`../../shared/modals/settings/settings-modal.cjs`)).then(e=>({default:e.SettingsModal}))),g=p.default.lazy(()=>Promise.resolve().then(()=>require(`../backends/add-backend-modal.cjs`)).then(e=>({default:e.AddBackendModal}))),_=p.default.lazy(()=>Promise.resolve().then(()=>require(`../backends/manage-backends-modal.cjs`)).then(e=>({default:e.ManageBackendsModal}))),v=250;function y(){let{t:e}=t.useTranslation(`openhands`),{currentPath:y}=i.useNavigation(),{data:b}=l.useConfig(),{data:x,error:S,isError:C,isFetching:w}=s.useSettings(),{backends:T,active:E}=a.useActiveBackendContext(),D=d.useBackendsHealth(T)[E.backend.id],O=u.useSidebarStore(e=>e.collapsed),k=u.useSidebarStore(e=>e.setCollapsed),[A,j]=p.default.useState(!1),[M,N]=p.default.useState(!1),P=p.default.useRef(null),[F,I]=p.default.useState(!1),[L,R]=p.default.useState(!1),[z,B]=p.default.useState(!1),V=p.default.useRef(!1),[,H]=p.default.useReducer(e=>e+1,0),{isOpen:U,close:W}=ee.useSidebarMobileNav(),[G,K]=p.default.useState(!1),[q,J]=p.default.useState(!1),Y=c.useClickOutsideElement(()=>N(!1)),X=s.getErrorStatus(S);p.default.useEffect(()=>{W()},[y,W]),p.default.useEffect(()=>{if(U){K(!0);let e=requestAnimationFrame(()=>{J(!0)});return()=>cancelAnimationFrame(e)}J(!1);let e=window.setTimeout(()=>{K(!1)},v);return()=>window.clearTimeout(e)},[U]),p.default.useEffect(()=>{if(!U)return;let e=e=>{e.key===`Escape`&&W()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[U,W]),p.default.useEffect(()=>{y===`/settings`?j(!1):!w&&C&&X!==404?o.displayErrorToast(`Something went wrong while fetching settings. Please reload the page.`):X===404&&!b?.feature_flags?.hide_llm_settings&&j(!0)},[y,w,C,X,b?.feature_flags?.hide_llm_settings]);let Z=x?.email_verified===!1,Q=e(O?n.I18nKey.SIDEBAR$EXPAND:n.I18nKey.SIDEBAR$COLLAPSE),te=p.default.useCallback(e=>{if(!O)return;let t=e.target;t instanceof HTMLElement&&(t.closest(`a,button,input,textarea,select,[role='button'],[role='link']`)||k(!1))},[O,k]),$={linkDisabled:Z,collapseToggleLabel:Q,onCollapse:p.default.useCallback(()=>{B(!1),V.current=!0,H(),k(!0),window.setTimeout(()=>{V.current=!1,H()},250)},[k]),onExpand:()=>k(!1),showCollapsedExpandButton:O&&z&&!V.current,isExtensionsActive:y===`/customize`||y.startsWith(`/skills`)||y===`/plugins`||y===`/mcp`,currentPath:y,activeBackendHealth:D,collapsedBackendPopoverOpen:M,setCollapsedBackendPopoverOpen:N,collapsedBackendPopoverRef:Y,collapsedBackendCloseTimer:P,onOpenAddBackend:()=>I(!0),onOpenManageBackends:()=>R(!0)};return(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`aside`,{"aria-label":e(n.I18nKey.SIDEBAR$NAVIGATION_LABEL),"data-collapsed":O?`true`:`false`,onClick:te,onMouseEnter:()=>{O&&B(!0)},onMouseLeave:()=>{B(!1)},className:r.cn(`max-md:hidden flex bg-base flex-col min-h-0 transition-[width,min-width] duration-200`,`md:border-r md:border-[var(--oh-border)] md:h-full`,O?`md:w-[60px] md:min-w-[60px] md:px-2.5`:`md:w-[300px] md:min-w-[300px] pb-2 md:pl-2.5 md:pr-0`,y===`/`&&`md:pb-3`),children:(0,m.jsx)(f.SidebarRailBody,{collapsed:O,showCollapseToggle:!0,...$})}),G?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`div`,{className:r.cn(`fixed inset-0 z-40 bg-black/50 md:hidden`,`transition-opacity ease-in-out motion-reduce:transition-none`,q?`opacity-100`:`pointer-events-none opacity-0`),style:{transitionDuration:`${v}ms`},onClick:W,"aria-hidden":!q}),(0,m.jsx)(`aside`,{"aria-label":e(n.I18nKey.SIDEBAR$NAVIGATION_LABEL),"data-testid":`sidebar-mobile-drawer`,"aria-hidden":!q,className:r.cn(`fixed inset-y-0 left-0 z-50 flex min-h-0 w-[min(300px,85vw)] flex-col bg-base`,`border-r border-[var(--oh-border)] pb-2 pl-2.5 pr-0 md:hidden`,`transition-transform ease-in-out motion-reduce:transition-none`,q?`translate-x-0`:`-translate-x-full`),style:{transitionDuration:`${v}ms`},children:(0,m.jsx)(f.SidebarRailBody,{collapsed:!1,showCollapseToggle:!1,showMobileCloseButton:!0,onCloseMobile:W,...$})})]}):null,A&&(0,m.jsx)(p.default.Suspense,{fallback:null,children:(0,m.jsx)(h,{settings:x,onClose:()=>j(!1)})}),F&&(0,m.jsx)(p.default.Suspense,{fallback:null,children:(0,m.jsx)(g,{onClose:()=>I(!1)})}),L&&(0,m.jsx)(p.default.Suspense,{fallback:null,children:(0,m.jsx)(_,{onClose:()=>R(!1)})})]})}exports.Sidebar=y;
1
+ const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../../../i18n/declaration.cjs`),r=require(`../../../utils/utils.cjs`),i=require(`../../../context/navigation-context.cjs`),a=require(`../../../contexts/active-backend-context.cjs`),o=require(`../../../utils/custom-toast-handlers.cjs`),s=require(`../../../hooks/query/use-settings.cjs`),c=require(`../../../hooks/use-click-outside-element.cjs`),l=require(`../../../hooks/query/use-config.cjs`),ee=require(`./sidebar-mobile-nav-context.cjs`),u=require(`../../../hooks/query/use-backends-health.cjs`),d=require(`./sidebar-rail-body.cjs`),f=require(`../../../stores/sidebar-store.cjs`);let p=require(`react`);p=e.__toESM(p,1);let m=require(`react/jsx-runtime`);var h=p.default.lazy(()=>Promise.resolve().then(()=>require(`../../shared/modals/settings/settings-modal.cjs`)).then(e=>({default:e.SettingsModal}))),g=p.default.lazy(()=>Promise.resolve().then(()=>require(`../backends/add-backend-modal.cjs`)).then(e=>({default:e.AddBackendModal}))),_=p.default.lazy(()=>Promise.resolve().then(()=>require(`../backends/manage-backends-modal.cjs`)).then(e=>({default:e.ManageBackendsModal}))),v=250;function y(){let{t:e}=t.useTranslation(`openhands`),{currentPath:y}=i.useNavigation(),{data:b}=l.useConfig(),{data:x,error:S,isError:C,isFetching:w}=s.useSettings(),{backends:T,active:E}=a.useActiveBackendContext(),D=u.useBackendsHealth(T)[E.backend.id],O=f.useSidebarStore(e=>e.collapsed),k=f.useSidebarStore(e=>e.setCollapsed),[A,j]=p.default.useState(!1),[M,N]=p.default.useState(!1),P=p.default.useRef(null),[F,I]=p.default.useState(!1),[L,R]=p.default.useState(!1),[z,B]=p.default.useState(!1),V=p.default.useRef(!1),[,H]=p.default.useReducer(e=>e+1,0),{isOpen:U,close:W}=ee.useSidebarMobileNav(),[G,K]=p.default.useState(!1),[q,J]=p.default.useState(!1),Y=c.useClickOutsideElement(()=>N(!1)),X=s.getErrorStatus(S);p.default.useEffect(()=>{W()},[y,W]),p.default.useEffect(()=>{if(U){K(!0);let e=requestAnimationFrame(()=>{J(!0)});return()=>cancelAnimationFrame(e)}J(!1);let e=window.setTimeout(()=>{K(!1)},v);return()=>window.clearTimeout(e)},[U]),p.default.useEffect(()=>{if(!U)return;let e=e=>{e.key===`Escape`&&W()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[U,W]),p.default.useEffect(()=>{y===`/settings`?j(!1):!w&&C&&X!==404?o.displayErrorToast(`Something went wrong while fetching settings. Please reload the page.`):X===404&&!b?.feature_flags?.hide_llm_settings&&j(!0)},[y,w,C,X,b?.feature_flags?.hide_llm_settings]);let Z=x?.email_verified===!1,Q=e(O?n.I18nKey.SIDEBAR$EXPAND:n.I18nKey.SIDEBAR$COLLAPSE),te=p.default.useCallback(e=>{if(!O)return;let t=e.target;t instanceof HTMLElement&&(t.closest(`a,button,input,textarea,select,[role='button'],[role='link']`)||k(!1))},[O,k]),$={linkDisabled:Z,collapseToggleLabel:Q,onCollapse:p.default.useCallback(()=>{B(!1),V.current=!0,H(),k(!0),window.setTimeout(()=>{V.current=!1,H()},250)},[k]),onExpand:()=>k(!1),showCollapsedExpandButton:O&&z&&!V.current,isExtensionsActive:y===`/customize`||y.startsWith(`/skills`)||y===`/plugins`||y===`/mcp`,currentPath:y,activeBackendHealth:D,collapsedBackendPopoverOpen:M,setCollapsedBackendPopoverOpen:N,collapsedBackendPopoverRef:Y,collapsedBackendCloseTimer:P,onOpenAddBackend:()=>I(!0),onOpenManageBackends:()=>R(!0)};return(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`aside`,{"aria-label":e(n.I18nKey.SIDEBAR$NAVIGATION_LABEL),"data-collapsed":O?`true`:`false`,onClick:te,onMouseEnter:()=>{O&&B(!0)},onMouseLeave:()=>{B(!1)},className:r.cn(`max-md:hidden flex bg-base flex-col min-h-0 transition-[width,min-width] duration-200`,`md:border-r md:border-[var(--oh-border)] md:h-full`,O?`md:w-[60px] md:min-w-[60px] md:px-2.5`:`md:w-[300px] md:min-w-[300px] pb-2 md:pl-2.5 md:pr-0`,y===`/`&&`md:pb-3`),children:(0,m.jsx)(d.SidebarRailBody,{collapsed:O,showCollapseToggle:!0,...$})}),G?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`div`,{className:r.cn(`fixed inset-0 z-40 bg-black/50 md:hidden`,`transition-opacity ease-in-out motion-reduce:transition-none`,q?`opacity-100`:`pointer-events-none opacity-0`),style:{transitionDuration:`${v}ms`},onClick:W,"aria-hidden":!q}),(0,m.jsx)(`aside`,{"aria-label":e(n.I18nKey.SIDEBAR$NAVIGATION_LABEL),"data-testid":`sidebar-mobile-drawer`,"aria-hidden":!q,className:r.cn(`fixed inset-y-0 left-0 z-50 flex min-h-0 w-[min(300px,85vw)] flex-col bg-base`,`border-r border-[var(--oh-border)] pb-2 pl-2.5 pr-0 md:hidden`,`transition-transform ease-in-out motion-reduce:transition-none`,q?`translate-x-0`:`-translate-x-full`),style:{transitionDuration:`${v}ms`},children:(0,m.jsx)(d.SidebarRailBody,{collapsed:!1,showCollapseToggle:!1,showMobileCloseButton:!0,onCloseMobile:W,...$})})]}):null,A&&(0,m.jsx)(p.default.Suspense,{fallback:null,children:(0,m.jsx)(h,{settings:x,onClose:()=>j(!1)})}),F&&(0,m.jsx)(p.default.Suspense,{fallback:null,children:(0,m.jsx)(g,{onClose:()=>I(!1)})}),L&&(0,m.jsx)(p.default.Suspense,{fallback:null,children:(0,m.jsx)(_,{onClose:()=>R(!1)})})]})}exports.Sidebar=y;
2
2
  //# sourceMappingURL=sidebar.cjs.map
@@ -8,15 +8,15 @@ import { getErrorStatus as o, useSettings as s } from "../../../hooks/query/use-
8
8
  import { useClickOutsideElement as c } from "../../../hooks/use-click-outside-element.js";
9
9
  import { useConfig as ee } from "../../../hooks/query/use-config.js";
10
10
  import { useSidebarMobileNav as te } from "./sidebar-mobile-nav-context.js";
11
- import { useSidebarStore as l } from "../../../stores/sidebar-store.js";
12
- import { useBackendsHealth as u } from "../../../hooks/query/use-backends-health.js";
13
- import { SidebarRailBody as d } from "./sidebar-rail-body.js";
11
+ import { useBackendsHealth as l } from "../../../hooks/query/use-backends-health.js";
12
+ import { SidebarRailBody as u } from "./sidebar-rail-body.js";
13
+ import { useSidebarStore as d } from "../../../stores/sidebar-store.js";
14
14
  import f from "react";
15
15
  import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
16
16
  //#region src/components/features/sidebar/sidebar.tsx
17
17
  var g = f.lazy(() => import("../../shared/modals/settings/settings-modal.js").then((e) => ({ default: e.SettingsModal }))), _ = f.lazy(() => import("../backends/add-backend-modal.js").then((e) => ({ default: e.AddBackendModal }))), v = f.lazy(() => import("../backends/manage-backends-modal.js").then((e) => ({ default: e.ManageBackendsModal }))), y = 250;
18
18
  function b() {
19
- let { t: b } = e("openhands"), { currentPath: x } = r(), { data: S } = ee(), { data: C, error: w, isError: T, isFetching: E } = s(), { backends: D, active: O } = i(), k = u(D)[O.backend.id], A = l((e) => e.collapsed), j = l((e) => e.setCollapsed), [M, N] = f.useState(!1), [P, F] = f.useState(!1), I = f.useRef(null), [L, R] = f.useState(!1), [z, B] = f.useState(!1), [V, H] = f.useState(!1), U = f.useRef(!1), [, W] = f.useReducer((e) => e + 1, 0), { isOpen: G, close: K } = te(), [q, J] = f.useState(!1), [Y, X] = f.useState(!1), Z = c(() => F(!1)), Q = o(w);
19
+ let { t: b } = e("openhands"), { currentPath: x } = r(), { data: S } = ee(), { data: C, error: w, isError: T, isFetching: E } = s(), { backends: D, active: O } = i(), k = l(D)[O.backend.id], A = d((e) => e.collapsed), j = d((e) => e.setCollapsed), [M, N] = f.useState(!1), [P, F] = f.useState(!1), I = f.useRef(null), [L, R] = f.useState(!1), [z, B] = f.useState(!1), [V, H] = f.useState(!1), U = f.useRef(!1), [, W] = f.useReducer((e) => e + 1, 0), { isOpen: G, close: K } = te(), [q, J] = f.useState(!1), [Y, X] = f.useState(!1), Z = c(() => F(!1)), Q = o(w);
20
20
  f.useEffect(() => {
21
21
  K();
22
22
  }, [x, K]), f.useEffect(() => {
@@ -83,7 +83,7 @@ function b() {
83
83
  H(!1);
84
84
  },
85
85
  className: n("max-md:hidden flex bg-base flex-col min-h-0 transition-[width,min-width] duration-200", "md:border-r md:border-[var(--oh-border)] md:h-full", A ? "md:w-[60px] md:min-w-[60px] md:px-2.5" : "md:w-[300px] md:min-w-[300px] pb-2 md:pl-2.5 md:pr-0", x === "/" && "md:pb-3"),
86
- children: /* @__PURE__ */ m(d, {
86
+ children: /* @__PURE__ */ m(u, {
87
87
  collapsed: A,
88
88
  showCollapseToggle: !0,
89
89
  ...$
@@ -100,7 +100,7 @@ function b() {
100
100
  "aria-hidden": !Y,
101
101
  className: n("fixed inset-y-0 left-0 z-50 flex min-h-0 w-[min(300px,85vw)] flex-col bg-base", "border-r border-[var(--oh-border)] pb-2 pl-2.5 pr-0 md:hidden", "transition-transform ease-in-out motion-reduce:transition-none", Y ? "translate-x-0" : "-translate-x-full"),
102
102
  style: { transitionDuration: `${y}ms` },
103
- children: /* @__PURE__ */ m(d, {
103
+ children: /* @__PURE__ */ m(u, {
104
104
  collapsed: !1,
105
105
  showCollapseToggle: !1,
106
106
  showMobileCloseButton: !0,
@@ -1,2 +1,2 @@
1
- require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../../../utils/utils.cjs`),r=require(`../../../constants/acp-providers.cjs`),i=require(`../../../hooks/query/use-settings.cjs`),a=require(`../../shared/buttons/styled-tooltip.cjs`),o=require(`../../shared/navigation-link.cjs`),s=require(`../../../icons/skills.cjs`),c=require(`../../../hooks/use-breakpoint.cjs`),l=require(`../sidebar/sidebar-layout.cjs`),u=require(`../settings/backend-synced-settings-badge.cjs`),d=require(`../../../icons/server-process.cjs`),f=require(`../../../stores/sidebar-store.cjs`);let p=require(`react/jsx-runtime`);var m=[{to:`/skills`,label:`Skills`,icon:(0,p.jsx)(s.default,{width:16,height:16,"aria-hidden":`true`}),end:!0},{to:`/mcp`,label:`MCP Servers`,icon:(0,p.jsx)(d.default,{width:16,height:16}),end:!0,disabledByAcp:!0},{to:`/plugins`,label:`Plugins`,icon:(0,p.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,width:16,height:16,"aria-hidden":`true`,children:[(0,p.jsx)(`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`}),(0,p.jsx)(`path`,{d:`m3.3 7 8.7 5 8.7-5`}),(0,p.jsx)(`path`,{d:`M12 22V12`})]}),end:!0,comingSoon:!0}];function h(){let{t:s}=e.useTranslation(`openhands`),{data:d}=i.useSettings(),h=f.useSidebarStore(e=>e.collapsed),g=c.useBreakpoint(1023),_=c.useBreakpoint(767),v=!h&&g&&!_,y=d?.agent_settings?.agent_kind===`acp`,b=typeof d?.agent_settings?.acp_server==`string`?d.agent_settings.acp_server:void 0,x=y?r.ACP_PROVIDERS.find(({key:e})=>e===b)?.display_name??`ACP Agent`:void 0;return v?null:(0,p.jsxs)(`aside`,{"data-testid":`extensions-navbar-desktop`,className:`hidden md:flex md:w-[260px] md:shrink-0 md:flex-col md:gap-2 md:sticky md:top-8 md:self-start`,children:[(0,p.jsx)(`span`,{className:`px-2 text-sm font-normal text-white`,children:s(t.I18nKey.NAV$CUSTOMIZE)}),(0,p.jsx)(`div`,{className:`flex flex-col gap-0.5 pt-0.5`,children:m.map(e=>{let r=!!(y&&e.disabledByAcp),i=(0,p.jsx)(`span`,{className:`shrink-0 flex items-center justify-center`,children:e.icon}),c=(0,p.jsx)(`span`,{className:`truncate`,children:e.label}),u=e.comingSoon&&(0,p.jsx)(`span`,{className:`ml-auto shrink-0 rounded-full border border-white/20 bg-white/5 px-1.5 py-0.5 text-[10px] font-medium text-[var(--oh-text-dim)]`,children:s(t.I18nKey.NAV$COMING_SOON)});return r?(0,p.jsx)(a.StyledTooltip,{content:s(t.I18nKey.SETTINGS$AGENT_DISABLED_TOOLTIP,{agentName:x}),placement:`right`,children:(0,p.jsxs)(`span`,{"aria-disabled":`true`,"data-testid":`sidebar-extensions-${e.to}`,className:n.cn(l.sidebarNavRowClassName(),`truncate text-[var(--oh-muted)] opacity-50 cursor-not-allowed`),children:[i,c,u]})},e.to):(0,p.jsxs)(o.NavigationLink,{to:e.to,end:e.end,"data-testid":`sidebar-extensions-${e.to}`,className:({isActive:e})=>n.cn(l.sidebarNavRowClassName(),`truncate`,e?l.SIDEBAR_ROW_INTERACTIVE_CLASS.active:l.SIDEBAR_ROW_INTERACTIVE_CLASS.idle),children:[i,c,u]},e.to)})}),(0,p.jsx)(`div`,{className:`px-2 pt-3`,children:(0,p.jsx)(u.BackendSyncedSettingsBadge,{})})]})}exports.ExtensionsNavigation=h;
1
+ require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../node_modules/react-i18next/dist/es/useTranslation.cjs`),t=require(`../../../i18n/declaration.cjs`),n=require(`../../../utils/utils.cjs`),r=require(`../../shared/navigation-link.cjs`),i=require(`../../../icons/skills.cjs`),a=require(`../sidebar/sidebar-layout.cjs`),o=require(`../settings/backend-synced-settings-badge.cjs`),s=require(`../../../icons/server-process.cjs`);let c=require(`react/jsx-runtime`);var l=[{to:`/skills`,label:`Skills`,icon:(0,c.jsx)(i.default,{width:16,height:16,"aria-hidden":`true`}),end:!0},{to:`/mcp`,label:`MCP Servers`,icon:(0,c.jsx)(s.default,{width:16,height:16}),end:!0},{to:`/plugins`,label:`Plugins`,icon:(0,c.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,width:16,height:16,"aria-hidden":`true`,children:[(0,c.jsx)(`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`}),(0,c.jsx)(`path`,{d:`m3.3 7 8.7 5 8.7-5`}),(0,c.jsx)(`path`,{d:`M12 22V12`})]}),end:!0,comingSoon:!0}];function u(){let{t:i}=e.useTranslation(`openhands`);return(0,c.jsxs)(`aside`,{"data-testid":`extensions-navbar-desktop`,className:`hidden md:flex md:w-[260px] md:shrink-0 md:flex-col md:gap-2 md:sticky md:top-8 md:self-start`,children:[(0,c.jsx)(`span`,{className:`px-2 text-sm font-normal text-white`,children:i(t.I18nKey.NAV$CUSTOMIZE)}),(0,c.jsx)(`div`,{className:`flex flex-col gap-0.5 pt-0.5`,children:l.map(e=>{let o=(0,c.jsx)(`span`,{className:`shrink-0 flex items-center justify-center`,children:e.icon}),s=(0,c.jsx)(`span`,{className:`truncate`,children:e.label}),l=e.comingSoon&&(0,c.jsx)(`span`,{className:`ml-auto shrink-0 rounded-full border border-white/20 bg-white/5 px-1.5 py-0.5 text-[10px] font-medium text-[var(--oh-text-dim)]`,children:i(t.I18nKey.NAV$COMING_SOON)});return(0,c.jsxs)(r.NavigationLink,{to:e.to,end:e.end,"data-testid":`sidebar-extensions-${e.to}`,className:({isActive:e})=>n.cn(a.sidebarNavRowClassName(),`truncate`,e?a.SIDEBAR_ROW_INTERACTIVE_CLASS.active:a.SIDEBAR_ROW_INTERACTIVE_CLASS.idle),children:[o,s,l]},e.to)})}),(0,c.jsx)(`div`,{className:`px-2 pt-3`,children:(0,c.jsx)(o.BackendSyncedSettingsBadge,{})})]})}exports.ExtensionsNavigation=u;
2
2
  //# sourceMappingURL=extensions-navigation.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extensions-navigation.cjs","names":[],"sources":["../../../../src/components/features/skills/extensions-navigation.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { StyledTooltip } from \"#/components/shared/buttons/styled-tooltip\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { ACP_PROVIDERS } from \"#/constants/acp-providers\";\nimport { cn } from \"#/utils/utils\";\nimport SkillsIcon from \"#/icons/skills.svg?react\";\nimport ServerProcessIcon from \"#/icons/server-process.svg?react\";\nimport { BackendSyncedSettingsBadge } from \"#/components/features/settings/backend-synced-settings-badge\";\nimport {\n SIDEBAR_ROW_INTERACTIVE_CLASS,\n sidebarNavRowClassName,\n} from \"#/components/features/sidebar/sidebar-layout\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { useSidebarStore } from \"#/stores/sidebar-store\";\nimport { useBreakpoint } from \"#/hooks/use-breakpoint\";\n\ninterface ExtensionNavItem {\n to: string;\n label: string;\n icon: React.ReactElement;\n end?: boolean;\n comingSoon?: boolean;\n /**\n * When true, this item greys out (and the /route's ``clientLoader``\n * bounces to ``/settings/agent``) while an ACP agent is active.\n * The ACP sub-agent manages its own MCP servers; the SDK rejects\n * ``mcp_config`` on ``ACPAgent`` init outright, so the OpenHands-\n * side editor would silently no-op against the running subprocess.\n */\n disabledByAcp?: boolean;\n}\n\nexport const EXTENSIONS_NAV_ITEMS: ExtensionNavItem[] = [\n {\n to: \"/skills\",\n label: \"Skills\",\n icon: <SkillsIcon width={16} height={16} aria-hidden=\"true\" />,\n end: true,\n },\n {\n to: \"/mcp\",\n label: \"MCP Servers\",\n icon: <ServerProcessIcon width={16} height={16} />,\n end: true,\n disabledByAcp: true,\n },\n {\n to: \"/plugins\",\n label: \"Plugins\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n width={16}\n height={16}\n aria-hidden=\"true\"\n >\n <path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\" />\n <path d=\"m3.3 7 8.7 5 8.7-5\" />\n <path d=\"M12 22V12\" />\n </svg>\n ),\n end: true,\n comingSoon: true,\n },\n];\n\nexport function ExtensionsNavigation() {\n const { t } = useTranslation(\"openhands\");\n const { data: settings } = useSettings();\n const sidebarCollapsed = useSidebarStore((state) => state.collapsed);\n // At iPad portrait widths (md to <lg) an expanded primary Sidebar (300px)\n // plus this nav (260px) leaves the main content unreadable. Hide ourselves\n // until the user collapses the Sidebar or the viewport reaches `lg`.\n const belowLg = useBreakpoint(1023);\n const belowMd = useBreakpoint(767);\n const hideForExpandedSidebar = !sidebarCollapsed && belowLg && !belowMd;\n const isAcpAgent = settings?.agent_settings?.agent_kind === \"acp\";\n const acpServerKey =\n typeof settings?.agent_settings?.acp_server === \"string\"\n ? settings.agent_settings.acp_server\n : undefined;\n const acpServerName = isAcpAgent\n ? (ACP_PROVIDERS.find(({ key }) => key === acpServerKey)?.display_name ??\n \"ACP Agent\")\n : undefined;\n\n if (hideForExpandedSidebar) return null;\n\n return (\n <aside\n data-testid=\"extensions-navbar-desktop\"\n className=\"hidden md:flex md:w-[260px] md:shrink-0 md:flex-col md:gap-2 md:sticky md:top-8 md:self-start\"\n >\n <span className=\"px-2 text-sm font-normal text-white\">\n {t(I18nKey.NAV$CUSTOMIZE)}\n </span>\n <div className=\"flex flex-col gap-0.5 pt-0.5\">\n {EXTENSIONS_NAV_ITEMS.map((item) => {\n const disabled = !!(isAcpAgent && item.disabledByAcp);\n const baseRow = (\n <span className=\"shrink-0 flex items-center justify-center\">\n {item.icon}\n </span>\n );\n const label = <span className=\"truncate\">{item.label}</span>;\n const comingSoonBadge = item.comingSoon && (\n <span className=\"ml-auto shrink-0 rounded-full border border-white/20 bg-white/5 px-1.5 py-0.5 text-[10px] font-medium text-[var(--oh-text-dim)]\">\n {t(I18nKey.NAV$COMING_SOON)}\n </span>\n );\n\n if (disabled) {\n // Render a non-clickable surrogate so the URL and a11y tree\n // both communicate \"you can't go here right now,\" then wrap\n // in StyledTooltip for the why. Mirrors the SettingsNavLink\n // disabled rendering — same flag (``disabledByAcp``), same\n // explanatory tooltip (\"Disabled while {agentName} is the\n // active agent\"), same greyed styles.\n return (\n <StyledTooltip\n key={item.to}\n content={t(I18nKey.SETTINGS$AGENT_DISABLED_TOOLTIP, {\n agentName: acpServerName,\n })}\n placement=\"right\"\n >\n <span\n aria-disabled=\"true\"\n data-testid={`sidebar-extensions-${item.to}`}\n className={cn(\n sidebarNavRowClassName(),\n \"truncate text-[var(--oh-muted)] opacity-50 cursor-not-allowed\",\n )}\n >\n {baseRow}\n {label}\n {comingSoonBadge}\n </span>\n </StyledTooltip>\n );\n }\n\n return (\n <NavigationLink\n key={item.to}\n to={item.to}\n end={item.end}\n data-testid={`sidebar-extensions-${item.to}`}\n className={({ isActive }) =>\n cn(\n sidebarNavRowClassName(),\n \"truncate\",\n isActive\n ? SIDEBAR_ROW_INTERACTIVE_CLASS.active\n : SIDEBAR_ROW_INTERACTIVE_CLASS.idle,\n )\n }\n >\n {baseRow}\n {label}\n {comingSoonBadge}\n </NavigationLink>\n );\n })}\n </div>\n <div className=\"px-2 pt-3\">\n <BackendSyncedSettingsBadge />\n </div>\n </aside>\n );\n}\n"],"mappings":"2tBAiCA,IAAa,EAA2C,CACtD,CACE,GAAI,UACJ,MAAO,SACP,MAAM,EAAA,EAAA,KAAC,EAAA,QAAD,CAAY,MAAO,GAAI,OAAQ,GAAI,cAAY,OAAS,CAAA,CAC9D,IAAK,GACN,CACD,CACE,GAAI,OACJ,MAAO,cACP,MAAM,EAAA,EAAA,KAAC,EAAA,QAAD,CAAmB,MAAO,GAAI,OAAQ,GAAM,CAAA,CAClD,IAAK,GACL,cAAe,GAChB,CACD,CACE,GAAI,WACJ,MAAO,UACP,MACE,EAAA,EAAA,MAAC,MAAD,CACE,MAAM,6BACN,QAAQ,YACR,KAAK,OACL,OAAO,eACP,YAAY,IACZ,cAAc,QACd,eAAe,QACf,MAAO,GACP,OAAQ,GACR,cAAY,gBAVd,EAYE,EAAA,EAAA,KAAC,OAAD,CAAM,EAAE,yHAA2H,CAAA,EACnI,EAAA,EAAA,KAAC,OAAD,CAAM,EAAE,qBAAuB,CAAA,EAC/B,EAAA,EAAA,KAAC,OAAD,CAAM,EAAE,YAAc,CAAA,CAClB,GAER,IAAK,GACL,WAAY,GACb,CACF,CAED,SAAgB,GAAuB,CACrC,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,CAAE,KAAM,GAAa,EAAA,aAAa,CAClC,EAAmB,EAAA,gBAAiB,GAAU,EAAM,UAAU,CAI9D,EAAU,EAAA,cAAc,KAAK,CAC7B,EAAU,EAAA,cAAc,IAAI,CAC5B,EAAyB,CAAC,GAAoB,GAAW,CAAC,EAC1D,EAAa,GAAU,gBAAgB,aAAe,MACtD,EACJ,OAAO,GAAU,gBAAgB,YAAe,SAC5C,EAAS,eAAe,WACxB,IAAA,GACA,EAAgB,EACjB,EAAA,cAAc,MAAM,CAAE,SAAU,IAAQ,EAAa,EAAE,cACxD,YACA,IAAA,GAIJ,OAFI,EAA+B,MAGjC,EAAA,EAAA,MAAC,QAAD,CACE,cAAY,4BACZ,UAAU,yGAFZ,EAIE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,+CACb,EAAE,EAAA,QAAQ,cAAc,CACpB,CAAA,EACP,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,wCACZ,EAAqB,IAAK,GAAS,CAClC,IAAM,EAAW,CAAC,EAAE,GAAc,EAAK,eACjC,GACJ,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qDACb,EAAK,KACD,CAAA,CAEH,GAAQ,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oBAAY,EAAK,MAAa,CAAA,CACtD,EAAkB,EAAK,aAC3B,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,2IACb,EAAE,EAAA,QAAQ,gBAAgB,CACtB,CAAA,CAkCT,OA/BI,GAQA,EAAA,EAAA,KAAC,EAAA,cAAD,CAEE,QAAS,EAAE,EAAA,QAAQ,gCAAiC,CAClD,UAAW,EACZ,CAAC,CACF,UAAU,kBAEV,EAAA,EAAA,MAAC,OAAD,CACE,gBAAc,OACd,cAAa,sBAAsB,EAAK,KACxC,UAAW,EAAA,GACT,EAAA,wBAAwB,CACxB,gEACD,UANH,CAQG,EACA,EACA,EACI,GACO,CAlBT,EAAK,GAkBI,EAKlB,EAAA,EAAA,MAAC,EAAA,eAAD,CAEE,GAAI,EAAK,GACT,IAAK,EAAK,IACV,cAAa,sBAAsB,EAAK,KACxC,WAAY,CAAE,cACZ,EAAA,GACE,EAAA,wBAAwB,CACxB,WACA,EACI,EAAA,8BAA8B,OAC9B,EAAA,8BAA8B,KACnC,UAZL,CAeG,EACA,EACA,EACc,EAjBV,EAAK,GAiBK,EAEnB,CACE,CAAA,EACN,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,sBACb,EAAA,EAAA,KAAC,EAAA,2BAAD,EAA8B,CAAA,CAC1B,CAAA,CACA"}
1
+ {"version":3,"file":"extensions-navigation.cjs","names":[],"sources":["../../../../src/components/features/skills/extensions-navigation.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport { cn } from \"#/utils/utils\";\nimport SkillsIcon from \"#/icons/skills.svg?react\";\nimport ServerProcessIcon from \"#/icons/server-process.svg?react\";\nimport { BackendSyncedSettingsBadge } from \"#/components/features/settings/backend-synced-settings-badge\";\nimport {\n SIDEBAR_ROW_INTERACTIVE_CLASS,\n sidebarNavRowClassName,\n} from \"#/components/features/sidebar/sidebar-layout\";\nimport { I18nKey } from \"#/i18n/declaration\";\n\ninterface ExtensionNavItem {\n to: string;\n label: string;\n icon: React.ReactElement;\n end?: boolean;\n comingSoon?: boolean;\n}\n\nexport const EXTENSIONS_NAV_ITEMS: ExtensionNavItem[] = [\n {\n to: \"/skills\",\n label: \"Skills\",\n icon: <SkillsIcon width={16} height={16} aria-hidden=\"true\" />,\n end: true,\n },\n {\n to: \"/mcp\",\n label: \"MCP Servers\",\n icon: <ServerProcessIcon width={16} height={16} />,\n end: true,\n },\n {\n to: \"/plugins\",\n label: \"Plugins\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n width={16}\n height={16}\n aria-hidden=\"true\"\n >\n <path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\" />\n <path d=\"m3.3 7 8.7 5 8.7-5\" />\n <path d=\"M12 22V12\" />\n </svg>\n ),\n end: true,\n comingSoon: true,\n },\n];\n\nexport function ExtensionsNavigation() {\n const { t } = useTranslation(\"openhands\");\n\n return (\n <aside\n data-testid=\"extensions-navbar-desktop\"\n className=\"hidden md:flex md:w-[260px] md:shrink-0 md:flex-col md:gap-2 md:sticky md:top-8 md:self-start\"\n >\n <span className=\"px-2 text-sm font-normal text-white\">\n {t(I18nKey.NAV$CUSTOMIZE)}\n </span>\n <div className=\"flex flex-col gap-0.5 pt-0.5\">\n {EXTENSIONS_NAV_ITEMS.map((item) => {\n const baseRow = (\n <span className=\"shrink-0 flex items-center justify-center\">\n {item.icon}\n </span>\n );\n const label = <span className=\"truncate\">{item.label}</span>;\n const comingSoonBadge = item.comingSoon && (\n <span className=\"ml-auto shrink-0 rounded-full border border-white/20 bg-white/5 px-1.5 py-0.5 text-[10px] font-medium text-[var(--oh-text-dim)]\">\n {t(I18nKey.NAV$COMING_SOON)}\n </span>\n );\n\n return (\n <NavigationLink\n key={item.to}\n to={item.to}\n end={item.end}\n data-testid={`sidebar-extensions-${item.to}`}\n className={({ isActive }) =>\n cn(\n sidebarNavRowClassName(),\n \"truncate\",\n isActive\n ? SIDEBAR_ROW_INTERACTIVE_CLASS.active\n : SIDEBAR_ROW_INTERACTIVE_CLASS.idle,\n )\n }\n >\n {baseRow}\n {label}\n {comingSoonBadge}\n </NavigationLink>\n );\n })}\n </div>\n <div className=\"px-2 pt-3\">\n <BackendSyncedSettingsBadge />\n </div>\n </aside>\n );\n}\n"],"mappings":"meAoBA,IAAa,EAA2C,CACtD,CACE,GAAI,UACJ,MAAO,SACP,MAAM,EAAA,EAAA,KAAC,EAAA,QAAD,CAAY,MAAO,GAAI,OAAQ,GAAI,cAAY,OAAS,CAAA,CAC9D,IAAK,GACN,CACD,CACE,GAAI,OACJ,MAAO,cACP,MAAM,EAAA,EAAA,KAAC,EAAA,QAAD,CAAmB,MAAO,GAAI,OAAQ,GAAM,CAAA,CAClD,IAAK,GACN,CACD,CACE,GAAI,WACJ,MAAO,UACP,MACE,EAAA,EAAA,MAAC,MAAD,CACE,MAAM,6BACN,QAAQ,YACR,KAAK,OACL,OAAO,eACP,YAAY,IACZ,cAAc,QACd,eAAe,QACf,MAAO,GACP,OAAQ,GACR,cAAY,gBAVd,EAYE,EAAA,EAAA,KAAC,OAAD,CAAM,EAAE,yHAA2H,CAAA,EACnI,EAAA,EAAA,KAAC,OAAD,CAAM,EAAE,qBAAuB,CAAA,EAC/B,EAAA,EAAA,KAAC,OAAD,CAAM,EAAE,YAAc,CAAA,CAClB,GAER,IAAK,GACL,WAAY,GACb,CACF,CAED,SAAgB,GAAuB,CACrC,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CAEzC,OACE,EAAA,EAAA,MAAC,QAAD,CACE,cAAY,4BACZ,UAAU,yGAFZ,EAIE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,+CACb,EAAE,EAAA,QAAQ,cAAc,CACpB,CAAA,EACP,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,wCACZ,EAAqB,IAAK,GAAS,CAClC,IAAM,GACJ,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qDACb,EAAK,KACD,CAAA,CAEH,GAAQ,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oBAAY,EAAK,MAAa,CAAA,CACtD,EAAkB,EAAK,aAC3B,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,2IACb,EAAE,EAAA,QAAQ,gBAAgB,CACtB,CAAA,CAGT,OACE,EAAA,EAAA,MAAC,EAAA,eAAD,CAEE,GAAI,EAAK,GACT,IAAK,EAAK,IACV,cAAa,sBAAsB,EAAK,KACxC,WAAY,CAAE,cACZ,EAAA,GACE,EAAA,wBAAwB,CACxB,WACA,EACI,EAAA,8BAA8B,OAC9B,EAAA,8BAA8B,KACnC,UAZL,CAeG,EACA,EACA,EACc,EAjBV,EAAK,GAiBK,EAEnB,CACE,CAAA,EACN,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,sBACb,EAAA,EAAA,KAAC,EAAA,2BAAD,EAA8B,CAAA,CAC1B,CAAA,CACA"}
@@ -4,15 +4,7 @@ interface ExtensionNavItem {
4
4
  icon: React.ReactElement;
5
5
  end?: boolean;
6
6
  comingSoon?: boolean;
7
- /**
8
- * When true, this item greys out (and the /route's ``clientLoader``
9
- * bounces to ``/settings/agent``) while an ACP agent is active.
10
- * The ACP sub-agent manages its own MCP servers; the SDK rejects
11
- * ``mcp_config`` on ``ACPAgent`` init outright, so the OpenHands-
12
- * side editor would silently no-op against the running subprocess.
13
- */
14
- disabledByAcp?: boolean;
15
7
  }
16
8
  export declare const EXTENSIONS_NAV_ITEMS: ExtensionNavItem[];
17
- export declare function ExtensionsNavigation(): import("react/jsx-runtime").JSX.Element | null;
9
+ export declare function ExtensionsNavigation(): import("react/jsx-runtime").JSX.Element;
18
10
  export {};