@openhands/agent-canvas 1.10.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (500) hide show
  1. package/README.md +1 -1
  2. package/README.windows.md +2 -2
  3. package/build/assets/{acp-providers-DLe_gVDY.js → acp-providers-BkL3HWa3.js} +1 -1
  4. package/build/assets/{active-backend-context-B0wI7OzM.js → active-backend-context-BBvP-bI2.js} +1 -1
  5. package/build/assets/{agent-context-settings-CaQtdNA-.js → agent-context-settings-Bno1nwPL.js} +1 -1
  6. package/build/assets/{agent-profiles-settings-CvuErjp6.js → agent-profiles-settings-DqoS7RL3.js} +1 -1
  7. package/build/assets/agent-server-conversation-service.api-0RztSdJJ.js +86 -0
  8. package/build/assets/agent-settings-BJHryp65.js +1 -0
  9. package/build/assets/{agent-settings-UE-U4Xii.js → agent-settings-h8hQz-IU.js} +1 -1
  10. package/build/assets/{alert-banner-BMaOtTCG.js → alert-banner-lrK-2_0Y.js} +1 -1
  11. package/build/assets/{api-key-entry-screen-Cy66vT4D.js → api-key-entry-screen-Qsb83VX1.js} +1 -1
  12. package/build/assets/{app-settings-9ok42bV6.js → app-settings-r1RUbgGi.js} +1 -1
  13. package/build/assets/{automation-detail-fuITm6i3.js → automation-detail-7LkL91j9.js} +3 -3
  14. package/build/assets/{automation-export-CRq40mux.js → automation-export-U2QNyNy6.js} +1 -1
  15. package/build/assets/{automation-setup-route-EXDazOHW.js → automation-setup-route-Bel9_Lue.js} +1 -1
  16. package/build/assets/{automation-templates-BArZsaxP.js → automation-templates-CRLDssaI.js} +1 -1
  17. package/build/assets/{automations-list-CG4HKOTn.js → automations-list-B2iV3ZKW.js} +1 -1
  18. package/build/assets/{back-nav-button-BZB6H7xz.js → back-nav-button-B3pYwmUJ.js} +1 -1
  19. package/build/assets/backend-form-modal-OroTqnAv.js +1 -0
  20. package/build/assets/{backend-synced-settings-badge-B_NXJ3u1.js → backend-synced-settings-badge-DB4717Iu.js} +1 -1
  21. package/build/assets/{badge-C64c-7PO.js → badge-yR53enbU.js} +1 -1
  22. package/build/assets/{base-modal-C0RQPug5.js → base-modal-3NmIOKDm.js} +1 -1
  23. package/build/assets/{brand-button-DJmFCyMK.js → brand-button-CJcwjnfb.js} +1 -1
  24. package/build/assets/{browser-D3gd2n83.js → browser--eoQOo4M.js} +1 -1
  25. package/build/assets/{browser-tab-BicAWuJ1.js → browser-tab-A94o33Vn.js} +1 -1
  26. package/build/assets/{chat-send-button-CCrH1E8u.js → chat-send-button-B8n6-DQA.js} +1 -1
  27. package/build/assets/{circle-plus-check-toggle-CB_sNERY.js → circle-plus-check-toggle-BVzv5EkZ.js} +1 -1
  28. package/build/assets/{cloud-funnel-analytics-XynamQGU.js → cloud-funnel-analytics-CBQdPZl_.js} +1 -1
  29. package/build/assets/{combobox-caret-Bwiifgjs.js → combobox-caret-BlmRwiM8.js} +1 -1
  30. package/build/assets/command-menu-PsRXVBz2.js +1 -0
  31. package/build/assets/{condenser-settings-cNGy75gq.js → condenser-settings-w7L3EFvm.js} +1 -1
  32. package/build/assets/{confirmation-modal-BATFmFyP.js → confirmation-modal-DAH0XtOp.js} +1 -1
  33. package/build/assets/{context-menu-list-item-DhJCcBA0.js → context-menu-list-item-BQhmFVEK.js} +1 -1
  34. package/build/assets/{conversation-Csdxh9Xt.js → conversation-BUzBZAc-.js} +4 -4
  35. package/build/assets/conversation-panel-pzAKsSDb.js +1 -0
  36. package/build/assets/conversation-pzAKsSDb.js +1 -0
  37. package/build/assets/{conversation-state-store-C2QzhPaK.js → conversation-state-store-Bs8gA263.js} +1 -1
  38. package/build/assets/{conversation-tab-empty-state-D3fb5xIA.js → conversation-tab-empty-state-C9sfDOlt.js} +1 -1
  39. package/build/assets/{copy-to-clipboard-button-c4MQwKGj.js → copy-to-clipboard-button-DatoElj8.js} +1 -1
  40. package/build/assets/{device-verify-oFpQoLgm.js → device-verify-BIjXeW9N.js} +1 -1
  41. package/build/assets/{dropdown-classes-f91ARMV1.js → dropdown-classes-zFW7qPSK.js} +1 -1
  42. package/build/assets/{entry.client-BCzY2Bf3.js → entry.client-DzbDyLkV.js} +2 -2
  43. package/build/assets/{enum-filter-dropdown-HG3q3rkV.js → enum-filter-dropdown-CctILg5t.js} +1 -1
  44. package/build/assets/{environment-switch-overlay-CquZXolz.js → environment-switch-overlay-Cvmo6clk.js} +1 -1
  45. package/build/assets/{extensions-hub-BeweE0PW.js → extensions-hub-DOmHPGTA.js} +1 -1
  46. package/build/assets/{extensions-navigation-Dd58NlUF.js → extensions-navigation-6zU5M1pa.js} +1 -1
  47. package/build/assets/{files-tab-CLLG55-q.js → files-tab-BzofBmF4.js} +1 -1
  48. package/build/assets/{form-control-classes-pHtZUI6K.js → form-control-classes-DLN3Qgub.js} +1 -1
  49. package/build/assets/{format-relative-time-6-3uvOXe.js → format-relative-time-DGPQlPx0.js} +1 -1
  50. package/build/assets/{git-provider-icon-wg7ShB98.js → git-provider-icon-BLMlwy02.js} +1 -1
  51. package/build/assets/{git-repo-dropdown-CWnaUyxL.js → git-repo-dropdown-B7RvO70z.js} +1 -1
  52. package/build/assets/git-repo-dropdown-B_PTq4ol.js +1 -0
  53. package/build/assets/{highlighted-source-view-DBtI3por.js → highlighted-source-view-CgJfD5VT.js} +1 -1
  54. package/build/assets/{home-BpZQkDWM.js → home-DEZaZqYv.js} +1 -1
  55. package/build/assets/home-r89Vj2td.js +1 -0
  56. package/build/assets/{home-store-DM4qw1lF.js → home-store-D7CjMN_-.js} +1 -1
  57. package/build/assets/index-home-r89Vj2td.js +1 -0
  58. package/build/assets/install-server-modal-BTwK5lbi.js +1 -0
  59. package/build/assets/{kebab-menu-item-content-By16Tm_0.js → kebab-menu-item-content-C4CkeiJO.js} +1 -1
  60. package/build/assets/{launch-C9uijypN.js → launch-DVlx4v9o.js} +1 -1
  61. package/build/assets/{llm-not-configured-banner-DrBrhfN0.js → llm-not-configured-banner-CwKu8C6g.js} +2 -2
  62. package/build/assets/llm-settings-BJotLQND.js +1 -0
  63. package/build/assets/llm-settings-CDM-5H2A.js +1 -0
  64. package/build/assets/{llm-subscription-service-DwjJ8-_X.js → llm-subscription-service-7eVfDIE1.js} +1 -1
  65. package/build/assets/{loading-spinner-6Yj-YyoS.js → loading-spinner-CN3riY7k.js} +1 -1
  66. package/build/assets/{manage-backends-modal-DrwErS0N.js → manage-backends-modal-HNWKLYhq.js} +1 -1
  67. package/build/assets/manifest-2a36a8f8.js +1 -0
  68. package/build/assets/{manifest-subpage-layout-CtqVwIvJ.js → manifest-subpage-layout-D-m-h8_t.js} +1 -1
  69. package/build/assets/map-provider-7Bp2aih5.js +1 -0
  70. package/build/assets/markdown-renderer-BiiiIznl.js +8 -0
  71. package/build/assets/mcp-gLgPP7AS.js +9 -0
  72. package/build/assets/{mcp-marketplace-utils-BMnYz0Gc.js → mcp-marketplace-utils-Dr_HG_ol.js} +1 -1
  73. package/build/assets/messages-D1cbVhRK.js +40 -0
  74. package/build/assets/{modal-body-BHGCSAtj.js → modal-body-duRaxj_K.js} +1 -1
  75. package/build/assets/{modal-classes-DSTLuxkA.js → modal-classes-CLEXO6dj.js} +1 -1
  76. package/build/assets/{modal-close-button-dheWZ2ys.js → modal-close-button-D0aT02hs.js} +1 -1
  77. package/build/assets/npm-DRzJF5Zn.js +1 -0
  78. package/build/assets/{onboarding-5CZvRBbh.js → onboarding-DSr8hOpk.js} +1 -1
  79. package/build/assets/{onboarding-modal-CD2ehuxt.js → onboarding-modal-C6Euf7N4.js} +1 -1
  80. package/build/assets/{organization-service.api-Dsuoep0g.js → organization-service.api-C4GYWwj9.js} +1 -1
  81. package/build/assets/{planner-tab-DeO7Thb0.js → planner-tab-CZcguxTK.js} +1 -1
  82. package/build/assets/{plugins-management-service-C9f75R6X.js → plugins-management-service-BmDzOQsd.js} +1 -1
  83. package/build/assets/{profiles-service.api-Dl20_2IM.js → profiles-service.api-CoLTwjc1.js} +1 -1
  84. package/build/assets/{providers-CeuhK46N.js → providers-tBzTpz1w.js} +1 -1
  85. package/build/assets/{proxy-CIGI9zQC.js → proxy-DCI9S-LA.js} +1 -1
  86. package/build/assets/recommended-automations-launcher-BbJAJVED.js +1 -0
  87. package/build/assets/root-BfM_kC_d.css +1 -0
  88. package/build/assets/root-gstBEjty.js +2 -0
  89. package/build/assets/root-layout-BIAFLP9p.js +2 -0
  90. package/build/assets/{schema-field-z2vSLuLo.js → schema-field-zhsVDllR.js} +1 -1
  91. package/build/assets/{sdk-section-page-BnCXAytf.js → sdk-section-page-CS4GWn0y.js} +1 -1
  92. package/build/assets/{secrets-service-DGUNlwQd.js → secrets-service-DjgGduXk.js} +1 -1
  93. package/build/assets/{secrets-settings-DUmML_dK.js → secrets-settings-f-qahfbi.js} +1 -1
  94. package/build/assets/{segmented-toggle-eSofF7gn.js → segmented-toggle-SmvsR3jW.js} +1 -1
  95. package/build/assets/settings-DQd0xLEw.js +1 -0
  96. package/build/assets/{settings-dropdown-input-Cx4g7Xfl.js → settings-dropdown-input-TWIeiG02.js} +1 -1
  97. package/build/assets/{settings-index-BECdgecg.js → settings-index-BVwy9JEp.js} +1 -1
  98. package/build/assets/{settings-input-BQY115xH.js → settings-input-D61Vzp9e.js} +1 -1
  99. package/build/assets/{settings-list-classes-C9cLrrcc.js → settings-list-classes-sE0ASr1s.js} +1 -1
  100. package/build/assets/{settings-modal-ChBJNTdd.js → settings-modal-D6D5ngET.js} +1 -1
  101. package/build/assets/{settings-service.api-Dz9cZyvx.js → settings-service.api-DZp7E7A9.js} +1 -1
  102. package/build/assets/{settings-switch-BIodMVz9.js → settings-switch-Drt-rF5s.js} +1 -1
  103. package/build/assets/{settings-utils-BL_Z9uIe.js → settings-utils-gw2ppAvw.js} +1 -1
  104. package/build/assets/{shared-conversation-CSF0aTuE.js → shared-conversation-DIxZjElr.js} +1 -1
  105. package/build/assets/{wrench-DRitTfwe.js → shield-check-D2cpEpv3.js} +1 -1
  106. package/build/assets/{sidebar-layout-DEycoFd_.js → sidebar-layout-Dxg6zc2K.js} +1 -1
  107. package/build/assets/{sidebar-mobile-menu-toggle-DeRvTupV.js → sidebar-mobile-menu-toggle-OoZBHxaT.js} +1 -1
  108. package/build/assets/{sidebar-nav-link-BjpQ-NVc.js → sidebar-nav-link-CxLoG-dG.js} +1 -1
  109. package/build/assets/sidebar-store-BJeYY-E9.js +1 -0
  110. package/build/assets/{skill-card-pill-row-BH6fPGba.js → skill-card-pill-row-B_BYBONu.js} +1 -1
  111. package/build/assets/{skill-icon-badge-D4uznfjU.js → skill-icon-badge-CN41Hy9l.js} +1 -1
  112. package/build/assets/{skill-scope-DH_AUUUP.js → skill-scope-B1Per5XI.js} +1 -1
  113. package/build/assets/{skills-plugins-vfvOk34h.js → skills-plugins-B3AO6sMz.js} +1 -1
  114. package/build/assets/skills-settings-DmmgJ6CT.js +2 -0
  115. package/build/assets/{styled-tooltip-CQ9JEFiO.js → styled-tooltip-C5C07RQC.js} +1 -1
  116. package/build/assets/{task-list-tab-DeF_uXdw.js → task-list-tab-C19Q_JNf.js} +1 -1
  117. package/build/assets/{terminal-DRc4rup7.js → terminal-CbuMRYal.js} +1 -1
  118. package/build/assets/{toggle-switch--8n8NeV_.js → toggle-switch-CIioisto.js} +1 -1
  119. package/build/assets/{typography-BSbUhJPn.js → typography-D9tiHct7.js} +1 -1
  120. package/build/assets/{use-acp-credential-form-BGKFi1VL.js → use-acp-credential-form-DJmmJKMo.js} +1 -1
  121. package/build/assets/{use-activate-agent-profile-2nvALjC-.js → use-activate-agent-profile-CeFfYwu_.js} +1 -1
  122. package/build/assets/{use-agent-profiles-BlQA67MW.js → use-agent-profiles-BHLkLbRR.js} +1 -1
  123. package/build/assets/{use-can-manage-org-profiles-Clw5Dh1s.js → use-can-manage-org-profiles-Bu4y8gSx.js} +1 -1
  124. package/build/assets/{use-cloud-current-user-id-B8AQSQFM.js → use-cloud-current-user-id-QD9x3ySO.js} +1 -1
  125. package/build/assets/{use-config-C3zGuUQI.js → use-config-CPwqciXN.js} +1 -1
  126. package/build/assets/{use-create-conversation-FaP0kUpg.js → use-create-conversation-DWaSVUOB.js} +1 -1
  127. package/build/assets/{use-create-secret-CgQ3pXd6.js → use-create-secret-BsOfOLvg.js} +1 -1
  128. package/build/assets/{use-llm-profiles-C-tDO6UB.js → use-llm-profiles-CU8ah1pz.js} +1 -1
  129. package/build/assets/{use-manifest-capabilities-DLP5wCxp.js → use-manifest-capabilities-DBYPjyV6.js} +1 -1
  130. package/build/assets/{use-onboarding-completion-BiCdXvlU.js → use-onboarding-completion-CtNJxkXG.js} +1 -1
  131. package/build/assets/{use-plugins-marketplace-DRFNLBlr.js → use-plugins-marketplace-ZEA-gyM9.js} +1 -1
  132. package/build/assets/{use-save-agent-profile-CaGVAudI.js → use-save-agent-profile-DgI_Uz9a.js} +1 -1
  133. package/build/assets/{use-save-settings-C9B8Y-h3.js → use-save-settings-pSjRhD_m.js} +1 -1
  134. package/build/assets/{use-settings-3RcgdUuZ.js → use-settings-BHWsOcIG.js} +1 -1
  135. package/build/assets/use-settings-nav-items-CQgkxUbV.js +16 -0
  136. package/build/assets/{use-tracking-CTtkLAmx.js → use-tracking-CGCsBWhg.js} +1 -1
  137. package/build/assets/{use-user-conversation-Bei82QsZ.js → use-user-conversation-DRfEU8x0.js} +1 -1
  138. package/build/assets/utils-DPQfkd-7.js +1 -0
  139. package/build/assets/{verification-settings-nD61Ijph.js → verification-settings-BItwt998.js} +1 -1
  140. package/build/assets/wrench-B1_H-tL1.js +1 -0
  141. package/build/index.html +4 -4
  142. package/build/locales/ar/openhands.json +39 -2
  143. package/build/locales/ca/openhands.json +39 -2
  144. package/build/locales/de/openhands.json +39 -2
  145. package/build/locales/en/openhands.json +39 -2
  146. package/build/locales/es/openhands.json +39 -2
  147. package/build/locales/fr/openhands.json +39 -2
  148. package/build/locales/it/openhands.json +39 -2
  149. package/build/locales/ja/openhands.json +39 -2
  150. package/build/locales/ko-KR/openhands.json +39 -2
  151. package/build/locales/no/openhands.json +39 -2
  152. package/build/locales/pt/openhands.json +39 -2
  153. package/build/locales/tr/openhands.json +39 -2
  154. package/build/locales/uk/openhands.json +39 -2
  155. package/build/locales/zh-CN/openhands.json +39 -2
  156. package/build/locales/zh-TW/openhands.json +39 -2
  157. package/config/defaults.json +1 -1
  158. package/dist/api/agent-server-adapter.cjs +3 -3
  159. package/dist/api/agent-server-adapter.cjs.map +1 -1
  160. package/dist/api/agent-server-adapter.d.ts +32 -5
  161. package/dist/api/agent-server-adapter.js +120 -91
  162. package/dist/api/agent-server-adapter.js.map +1 -1
  163. package/dist/api/cloud/conversation-service.api.cjs +1 -1
  164. package/dist/api/cloud/conversation-service.api.cjs.map +1 -1
  165. package/dist/api/cloud/conversation-service.api.d.ts +19 -2
  166. package/dist/api/cloud/conversation-service.api.js +51 -47
  167. package/dist/api/cloud/conversation-service.api.js.map +1 -1
  168. package/dist/api/conversation-file-upload.api.cjs +1 -1
  169. package/dist/api/conversation-file-upload.api.js +10 -10
  170. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
  171. package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
  172. package/dist/api/conversation-service/agent-server-conversation-service.api.js +55 -61
  173. package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
  174. package/dist/api/event-service/event-service.api.cjs +1 -1
  175. package/dist/api/event-service/event-service.api.js +12 -12
  176. package/dist/api/launch-child-conversation-client-tool.cjs +47 -0
  177. package/dist/api/launch-child-conversation-client-tool.cjs.map +1 -0
  178. package/dist/api/launch-child-conversation-client-tool.d.ts +3 -0
  179. package/dist/api/launch-child-conversation-client-tool.js +93 -0
  180. package/dist/api/launch-child-conversation-client-tool.js.map +1 -0
  181. package/dist/api/open-hands.types.d.ts +1 -1
  182. package/dist/api/workspace-upload-path.cjs +1 -1
  183. package/dist/api/workspace-upload-path.js +8 -8
  184. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs +1 -1
  185. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs.map +1 -1
  186. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js +24 -18
  187. package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js.map +1 -1
  188. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
  189. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
  190. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +5 -0
  191. package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
  192. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs +2 -2
  193. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs.map +1 -1
  194. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js +11 -7
  195. package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js.map +1 -1
  196. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs +1 -2
  197. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs.map +1 -1
  198. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.d.ts +2 -8
  199. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js +48 -51
  200. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js.map +1 -1
  201. package/dist/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.cjs +2 -0
  202. package/dist/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.cjs.map +1 -0
  203. package/dist/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.d.ts +12 -0
  204. package/dist/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.js +6 -0
  205. package/dist/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.js.map +1 -0
  206. package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.cjs +1 -1
  207. package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.cjs.map +1 -1
  208. package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.d.ts +16 -1
  209. package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.js +95 -78
  210. package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.js.map +1 -1
  211. package/dist/components/features/conversation-panel/conversation-card/conversation-repo-link.cjs +1 -1
  212. package/dist/components/features/conversation-panel/conversation-card/conversation-repo-link.cjs.map +1 -1
  213. package/dist/components/features/conversation-panel/conversation-card/conversation-repo-link.js +40 -38
  214. package/dist/components/features/conversation-panel/conversation-card/conversation-repo-link.js.map +1 -1
  215. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.cjs +2 -0
  216. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.cjs.map +1 -0
  217. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.d.ts +14 -0
  218. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.js +167 -0
  219. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.js.map +1 -0
  220. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.cjs +2 -0
  221. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.cjs.map +1 -0
  222. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.d.ts +63 -0
  223. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.js +66 -0
  224. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.js.map +1 -0
  225. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-icons.cjs +2 -0
  226. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-icons.cjs.map +1 -0
  227. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-icons.d.ts +15 -0
  228. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-icons.js +117 -0
  229. package/dist/components/features/conversation-panel/conversation-card/conversation-tag-icons.js.map +1 -0
  230. package/dist/components/features/conversation-panel/conversation-card/no-repository.cjs +1 -1
  231. package/dist/components/features/conversation-panel/conversation-card/no-repository.cjs.map +1 -1
  232. package/dist/components/features/conversation-panel/conversation-card/no-repository.js +30 -19
  233. package/dist/components/features/conversation-panel/conversation-card/no-repository.js.map +1 -1
  234. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs +1 -1
  235. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs.map +1 -1
  236. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.d.ts +7 -2
  237. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js +146 -104
  238. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js.map +1 -1
  239. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs +1 -1
  240. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs.map +1 -1
  241. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.d.ts +20 -0
  242. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js +53 -27
  243. package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js.map +1 -1
  244. package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
  245. package/dist/components/features/conversation-panel/conversation-panel.cjs.map +1 -1
  246. package/dist/components/features/conversation-panel/conversation-panel.js +226 -213
  247. package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
  248. package/dist/components/features/settings/agent-canvas-update-card.cjs +1 -1
  249. package/dist/components/features/settings/agent-canvas-update-card.cjs.map +1 -1
  250. package/dist/components/features/settings/agent-canvas-update-card.d.ts +10 -5
  251. package/dist/components/features/settings/agent-canvas-update-card.js +223 -149
  252. package/dist/components/features/settings/agent-canvas-update-card.js.map +1 -1
  253. package/dist/components/features/settings/agent-canvas-version-modal.cjs +2 -0
  254. package/dist/components/features/settings/agent-canvas-version-modal.cjs.map +1 -0
  255. package/dist/components/features/settings/agent-canvas-version-modal.d.ts +11 -0
  256. package/dist/components/features/settings/agent-canvas-version-modal.js +166 -0
  257. package/dist/components/features/settings/agent-canvas-version-modal.js.map +1 -0
  258. package/dist/components/features/settings/agent-canvas-version-tile.cjs +2 -0
  259. package/dist/components/features/settings/agent-canvas-version-tile.cjs.map +1 -0
  260. package/dist/components/features/settings/agent-canvas-version-tile.d.ts +13 -0
  261. package/dist/components/features/settings/agent-canvas-version-tile.js +60 -0
  262. package/dist/components/features/settings/agent-canvas-version-tile.js.map +1 -0
  263. package/dist/components/features/settings/settings-desktop-sidebar.cjs +1 -1
  264. package/dist/components/features/settings/settings-desktop-sidebar.cjs.map +1 -1
  265. package/dist/components/features/settings/settings-desktop-sidebar.js +1 -1
  266. package/dist/components/features/settings/settings-desktop-sidebar.js.map +1 -1
  267. package/dist/components/features/settings/settings-mobile-drawer.cjs +1 -1
  268. package/dist/components/features/settings/settings-mobile-drawer.cjs.map +1 -1
  269. package/dist/components/features/settings/settings-mobile-drawer.js +1 -1
  270. package/dist/components/features/settings/settings-mobile-drawer.js.map +1 -1
  271. package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
  272. package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
  273. package/dist/components/features/sidebar/sidebar-rail-body.js +109 -108
  274. package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
  275. package/dist/components/features/skills/extensions-navigation.cjs +1 -1
  276. package/dist/components/features/skills/extensions-navigation.cjs.map +1 -1
  277. package/dist/components/features/skills/extensions-navigation.js +9 -9
  278. package/dist/components/features/skills/extensions-navigation.js.map +1 -1
  279. package/dist/config/defaults.cjs +1 -1
  280. package/dist/config/defaults.cjs.map +1 -1
  281. package/dist/config/defaults.js +1 -1
  282. package/dist/config/defaults.js.map +1 -1
  283. package/dist/constants/child-conversation.cjs +2 -0
  284. package/dist/constants/child-conversation.cjs.map +1 -0
  285. package/dist/constants/child-conversation.d.ts +29 -0
  286. package/dist/constants/child-conversation.js +6 -0
  287. package/dist/constants/child-conversation.js.map +1 -0
  288. package/dist/contexts/conversation-websocket-context.cjs +3 -3
  289. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  290. package/dist/contexts/conversation-websocket-context.js +189 -188
  291. package/dist/contexts/conversation-websocket-context.js.map +1 -1
  292. package/dist/hooks/chat/use-model-interceptor.cjs +1 -1
  293. package/dist/hooks/chat/use-model-interceptor.js +6 -6
  294. package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
  295. package/dist/hooks/mutation/use-create-conversation.js +6 -6
  296. package/dist/i18n/declaration.cjs +1 -1
  297. package/dist/i18n/declaration.cjs.map +1 -1
  298. package/dist/i18n/declaration.d.ts +38 -1
  299. package/dist/i18n/declaration.js +1 -1
  300. package/dist/i18n/declaration.js.map +1 -1
  301. package/dist/i18n/translation.cjs +2 -2
  302. package/dist/i18n/translation.cjs.map +1 -1
  303. package/dist/i18n/translation.js +644 -15
  304. package/dist/i18n/translation.js.map +1 -1
  305. package/dist/icons/docker.cjs +2 -0
  306. package/dist/icons/docker.cjs.map +1 -0
  307. package/dist/icons/docker.js +19 -0
  308. package/dist/icons/docker.js.map +1 -0
  309. package/dist/icons/npm.cjs +2 -0
  310. package/dist/icons/npm.cjs.map +1 -0
  311. package/dist/icons/npm.js +19 -0
  312. package/dist/icons/npm.js.map +1 -0
  313. package/dist/locales/ar/openhands.json +39 -2
  314. package/dist/locales/ca/openhands.json +39 -2
  315. package/dist/locales/de/openhands.json +39 -2
  316. package/dist/locales/en/openhands.json +39 -2
  317. package/dist/locales/es/openhands.json +39 -2
  318. package/dist/locales/fr/openhands.json +39 -2
  319. package/dist/locales/it/openhands.json +39 -2
  320. package/dist/locales/ja/openhands.json +39 -2
  321. package/dist/locales/ko-KR/openhands.json +39 -2
  322. package/dist/locales/no/openhands.json +39 -2
  323. package/dist/locales/pt/openhands.json +39 -2
  324. package/dist/locales/tr/openhands.json +39 -2
  325. package/dist/locales/uk/openhands.json +39 -2
  326. package/dist/locales/zh-CN/openhands.json +39 -2
  327. package/dist/locales/zh-TW/openhands.json +39 -2
  328. package/dist/node_modules/@openhands/typescript-client/dist/index.cjs +1 -1
  329. package/dist/node_modules/@openhands/typescript-client/dist/index.js +1 -1
  330. package/dist/node_modules/lucide-react/dist/esm/icons/briefcase.cjs +2 -0
  331. package/dist/node_modules/lucide-react/dist/esm/icons/briefcase.cjs.map +1 -0
  332. package/dist/node_modules/lucide-react/dist/esm/icons/briefcase.js +16 -0
  333. package/dist/node_modules/lucide-react/dist/esm/icons/briefcase.js.map +1 -0
  334. package/dist/node_modules/lucide-react/dist/esm/icons/building-2.cjs +2 -0
  335. package/dist/node_modules/lucide-react/dist/esm/icons/building-2.cjs.map +1 -0
  336. package/dist/node_modules/lucide-react/dist/esm/icons/building-2.js +27 -0
  337. package/dist/node_modules/lucide-react/dist/esm/icons/building-2.js.map +1 -0
  338. package/dist/node_modules/lucide-react/dist/esm/icons/circle-arrow-up.cjs +2 -0
  339. package/dist/node_modules/lucide-react/dist/esm/icons/circle-arrow-up.cjs.map +1 -0
  340. package/dist/node_modules/lucide-react/dist/esm/icons/circle-arrow-up.js +21 -0
  341. package/dist/node_modules/lucide-react/dist/esm/icons/circle-arrow-up.js.map +1 -0
  342. package/dist/node_modules/lucide-react/dist/esm/icons/circle-user-round.cjs +2 -0
  343. package/dist/node_modules/lucide-react/dist/esm/icons/circle-user-round.cjs.map +1 -0
  344. package/dist/node_modules/lucide-react/dist/esm/icons/circle-user-round.js +23 -0
  345. package/dist/node_modules/lucide-react/dist/esm/icons/circle-user-round.js.map +1 -0
  346. package/dist/node_modules/lucide-react/dist/esm/icons/cloud-cog.cjs +2 -0
  347. package/dist/node_modules/lucide-react/dist/esm/icons/cloud-cog.cjs.map +1 -0
  348. package/dist/node_modules/lucide-react/dist/esm/icons/cloud-cog.js +43 -0
  349. package/dist/node_modules/lucide-react/dist/esm/icons/cloud-cog.js.map +1 -0
  350. package/dist/node_modules/lucide-react/dist/esm/icons/earth.cjs +2 -0
  351. package/dist/node_modules/lucide-react/dist/esm/icons/earth.cjs.map +1 -0
  352. package/dist/node_modules/lucide-react/dist/esm/icons/earth.js +25 -0
  353. package/dist/node_modules/lucide-react/dist/esm/icons/earth.js.map +1 -0
  354. package/dist/node_modules/lucide-react/dist/esm/icons/flag.cjs +2 -0
  355. package/dist/node_modules/lucide-react/dist/esm/icons/flag.cjs.map +1 -0
  356. package/dist/node_modules/lucide-react/dist/esm/icons/flag.js +9 -0
  357. package/dist/node_modules/lucide-react/dist/esm/icons/flag.js.map +1 -0
  358. package/dist/node_modules/lucide-react/dist/esm/icons/folder-git-2.cjs +2 -0
  359. package/dist/node_modules/lucide-react/dist/esm/icons/folder-git-2.cjs.map +1 -0
  360. package/dist/node_modules/lucide-react/dist/esm/icons/folder-git-2.js +27 -0
  361. package/dist/node_modules/lucide-react/dist/esm/icons/folder-git-2.js.map +1 -0
  362. package/dist/node_modules/lucide-react/dist/esm/icons/folder-key.cjs +2 -0
  363. package/dist/node_modules/lucide-react/dist/esm/icons/folder-key.cjs.map +1 -0
  364. package/dist/node_modules/lucide-react/dist/esm/icons/folder-key.js +25 -0
  365. package/dist/node_modules/lucide-react/dist/esm/icons/folder-key.js.map +1 -0
  366. package/dist/node_modules/lucide-react/dist/esm/icons/git-pull-request.cjs +2 -0
  367. package/dist/node_modules/lucide-react/dist/esm/icons/git-pull-request.cjs.map +1 -0
  368. package/dist/node_modules/lucide-react/dist/esm/icons/git-pull-request.js +30 -0
  369. package/dist/node_modules/lucide-react/dist/esm/icons/git-pull-request.js.map +1 -0
  370. package/dist/node_modules/lucide-react/dist/esm/icons/hash.cjs +2 -0
  371. package/dist/node_modules/lucide-react/dist/esm/icons/hash.cjs.map +1 -0
  372. package/dist/node_modules/lucide-react/dist/esm/icons/hash.js +35 -0
  373. package/dist/node_modules/lucide-react/dist/esm/icons/hash.js.map +1 -0
  374. package/dist/node_modules/lucide-react/dist/esm/icons/house.cjs +2 -0
  375. package/dist/node_modules/lucide-react/dist/esm/icons/house.cjs.map +1 -0
  376. package/dist/node_modules/lucide-react/dist/esm/icons/house.js +12 -0
  377. package/dist/node_modules/lucide-react/dist/esm/icons/house.js.map +1 -0
  378. package/dist/node_modules/lucide-react/dist/esm/icons/id-card.cjs +2 -0
  379. package/dist/node_modules/lucide-react/dist/esm/icons/id-card.cjs.map +1 -0
  380. package/dist/node_modules/lucide-react/dist/esm/icons/id-card.js +33 -0
  381. package/dist/node_modules/lucide-react/dist/esm/icons/id-card.js.map +1 -0
  382. package/dist/node_modules/lucide-react/dist/esm/icons/key-round.cjs +2 -0
  383. package/dist/node_modules/lucide-react/dist/esm/icons/key-round.cjs.map +1 -0
  384. package/dist/node_modules/lucide-react/dist/esm/icons/key-round.js +15 -0
  385. package/dist/node_modules/lucide-react/dist/esm/icons/key-round.js.map +1 -0
  386. package/dist/node_modules/lucide-react/dist/esm/icons/layers.cjs +2 -0
  387. package/dist/node_modules/lucide-react/dist/esm/icons/layers.cjs.map +1 -0
  388. package/dist/node_modules/lucide-react/dist/esm/icons/layers.js +19 -0
  389. package/dist/node_modules/lucide-react/dist/esm/icons/layers.js.map +1 -0
  390. package/dist/node_modules/lucide-react/dist/esm/icons/link-2.cjs +2 -0
  391. package/dist/node_modules/lucide-react/dist/esm/icons/link-2.cjs.map +1 -0
  392. package/dist/node_modules/lucide-react/dist/esm/icons/link-2.js +22 -0
  393. package/dist/node_modules/lucide-react/dist/esm/icons/link-2.js.map +1 -0
  394. package/dist/node_modules/lucide-react/dist/esm/icons/mails.cjs +2 -0
  395. package/dist/node_modules/lucide-react/dist/esm/icons/mails.cjs.map +1 -0
  396. package/dist/node_modules/lucide-react/dist/esm/icons/mails.js +23 -0
  397. package/dist/node_modules/lucide-react/dist/esm/icons/mails.js.map +1 -0
  398. package/dist/node_modules/lucide-react/dist/esm/icons/messages-square.cjs +2 -0
  399. package/dist/node_modules/lucide-react/dist/esm/icons/messages-square.cjs.map +1 -0
  400. package/dist/node_modules/lucide-react/dist/esm/icons/messages-square.js +12 -0
  401. package/dist/node_modules/lucide-react/dist/esm/icons/messages-square.js.map +1 -0
  402. package/dist/node_modules/lucide-react/dist/esm/icons/plug.cjs +2 -0
  403. package/dist/node_modules/lucide-react/dist/esm/icons/plug.cjs.map +1 -0
  404. package/dist/node_modules/lucide-react/dist/esm/icons/plug.js +23 -0
  405. package/dist/node_modules/lucide-react/dist/esm/icons/plug.js.map +1 -0
  406. package/dist/node_modules/lucide-react/dist/esm/icons/square-kanban.cjs +2 -0
  407. package/dist/node_modules/lucide-react/dist/esm/icons/square-kanban.cjs.map +1 -0
  408. package/dist/node_modules/lucide-react/dist/esm/icons/square-kanban.js +27 -0
  409. package/dist/node_modules/lucide-react/dist/esm/icons/square-kanban.js.map +1 -0
  410. package/dist/node_modules/lucide-react/dist/esm/icons/ticket.cjs +2 -0
  411. package/dist/node_modules/lucide-react/dist/esm/icons/ticket.cjs.map +1 -0
  412. package/dist/node_modules/lucide-react/dist/esm/icons/ticket.js +23 -0
  413. package/dist/node_modules/lucide-react/dist/esm/icons/ticket.js.map +1 -0
  414. package/dist/node_modules/lucide-react/dist/esm/icons/users-round.cjs +2 -0
  415. package/dist/node_modules/lucide-react/dist/esm/icons/users-round.cjs.map +1 -0
  416. package/dist/node_modules/lucide-react/dist/esm/icons/users-round.js +21 -0
  417. package/dist/node_modules/lucide-react/dist/esm/icons/users-round.js.map +1 -0
  418. package/dist/node_modules/lucide-react/dist/esm/icons/waypoints.cjs +2 -0
  419. package/dist/node_modules/lucide-react/dist/esm/icons/waypoints.cjs.map +1 -0
  420. package/dist/node_modules/lucide-react/dist/esm/icons/waypoints.js +43 -0
  421. package/dist/node_modules/lucide-react/dist/esm/icons/waypoints.js.map +1 -0
  422. package/dist/node_modules/lucide-react/dist/esm/icons/webhook.cjs +2 -0
  423. package/dist/node_modules/lucide-react/dist/esm/icons/webhook.cjs.map +1 -0
  424. package/dist/node_modules/lucide-react/dist/esm/icons/webhook.js +19 -0
  425. package/dist/node_modules/lucide-react/dist/esm/icons/webhook.js.map +1 -0
  426. package/dist/node_modules/lucide-react/dist/esm/icons/workflow.cjs +2 -0
  427. package/dist/node_modules/lucide-react/dist/esm/icons/workflow.cjs.map +1 -0
  428. package/dist/node_modules/lucide-react/dist/esm/icons/workflow.js +27 -0
  429. package/dist/node_modules/lucide-react/dist/esm/icons/workflow.js.map +1 -0
  430. package/dist/node_modules/lucide-react/dist/esm/icons/wrench.cjs +2 -0
  431. package/dist/node_modules/lucide-react/dist/esm/icons/wrench.cjs.map +1 -0
  432. package/dist/node_modules/lucide-react/dist/esm/icons/wrench.js +9 -0
  433. package/dist/node_modules/lucide-react/dist/esm/icons/wrench.js.map +1 -0
  434. package/dist/node_modules/lucide-react/dist/esm/icons/zap.cjs +2 -0
  435. package/dist/node_modules/lucide-react/dist/esm/icons/zap.cjs.map +1 -0
  436. package/dist/node_modules/lucide-react/dist/esm/icons/zap.js +9 -0
  437. package/dist/node_modules/lucide-react/dist/esm/icons/zap.js.map +1 -0
  438. package/dist/package.cjs +1 -1
  439. package/dist/package.cjs.map +1 -1
  440. package/dist/package.js +6 -3
  441. package/dist/package.js.map +1 -1
  442. package/dist/services/child-conversation-launch.cjs +2 -0
  443. package/dist/services/child-conversation-launch.cjs.map +1 -0
  444. package/dist/services/child-conversation-launch.d.ts +41 -0
  445. package/dist/services/child-conversation-launch.js +182 -0
  446. package/dist/services/child-conversation-launch.js.map +1 -0
  447. package/dist/stores/conversation-panel-preferences-store.cjs +1 -1
  448. package/dist/stores/conversation-panel-preferences-store.cjs.map +1 -1
  449. package/dist/stores/conversation-panel-preferences-store.d.ts +5 -1
  450. package/dist/stores/conversation-panel-preferences-store.js +8 -2
  451. package/dist/stores/conversation-panel-preferences-store.js.map +1 -1
  452. package/dist/types/agent-server/core/base/action.d.ts +17 -1
  453. package/dist/types/agent-server/core/base/base.d.ts +2 -1
  454. package/dist/types/agent-server/type-guards.cjs +1 -1
  455. package/dist/types/agent-server/type-guards.cjs.map +1 -1
  456. package/dist/types/agent-server/type-guards.d.ts +8 -1
  457. package/dist/types/agent-server/type-guards.js +4 -3
  458. package/dist/types/agent-server/type-guards.js.map +1 -1
  459. package/dist/types/automation.d.ts +14 -0
  460. package/dist/utils/custom-toast-handlers.cjs +1 -1
  461. package/dist/utils/custom-toast-handlers.cjs.map +1 -1
  462. package/dist/utils/custom-toast-handlers.js +18 -1
  463. package/dist/utils/custom-toast-handlers.js.map +1 -1
  464. package/package.json +6 -3
  465. package/scripts/brand-dev-electron.mjs +244 -0
  466. package/scripts/check-translation-completeness.cjs +4 -0
  467. package/scripts/generate-icons.mjs +109 -0
  468. package/build/assets/agent-server-conversation-service.api-km_8sOVf.js +0 -41
  469. package/build/assets/agent-settings-nmO-KSXr.js +0 -1
  470. package/build/assets/backend-form-modal-B_lXjOGa.js +0 -1
  471. package/build/assets/command-menu-CA3IjGNc.js +0 -1
  472. package/build/assets/conversation-B6t6EiVp.js +0 -1
  473. package/build/assets/conversation-panel-B6t6EiVp.js +0 -1
  474. package/build/assets/copy-DaHuDtG4.js +0 -1
  475. package/build/assets/git-repo-dropdown-TzOuG5Ef.js +0 -1
  476. package/build/assets/home-OEx0XtfP.js +0 -1
  477. package/build/assets/index-home-OEx0XtfP.js +0 -1
  478. package/build/assets/info-C9lpK5pw.js +0 -1
  479. package/build/assets/install-server-modal-DnjZrJUy.js +0 -1
  480. package/build/assets/list-filter-C86CBRDE.js +0 -1
  481. package/build/assets/llm-settings-CRsLqxgu.js +0 -1
  482. package/build/assets/llm-settings-RBm_3kNm.js +0 -1
  483. package/build/assets/manifest-c352d453.js +0 -1
  484. package/build/assets/map-provider-CXU6issd.js +0 -1
  485. package/build/assets/markdown-renderer-lsvsp7jn.js +0 -8
  486. package/build/assets/mcp-DD4hPTRE.js +0 -9
  487. package/build/assets/messages-Dt77e0qi.js +0 -40
  488. package/build/assets/recommended-automations-launcher-6xmbf7lh.js +0 -1
  489. package/build/assets/root-BQPNqNvD.js +0 -2
  490. package/build/assets/root-BeuHFY2s.css +0 -1
  491. package/build/assets/root-layout-Dl_2CDoq.js +0 -3
  492. package/build/assets/settings-Co-M5bK9.js +0 -1
  493. package/build/assets/sidebar-store-B04sX8aP.js +0 -1
  494. package/build/assets/skills-settings-DnbIu2eO.js +0 -2
  495. package/build/assets/use-settings-nav-items-y-Oyc93G.js +0 -16
  496. package/build/assets/utils-BX9XJ0IE.js +0 -1
  497. package/dist/node_modules/lucide-react/dist/esm/icons/chevron-up.cjs +0 -2
  498. package/dist/node_modules/lucide-react/dist/esm/icons/chevron-up.cjs.map +0 -1
  499. package/dist/node_modules/lucide-react/dist/esm/icons/chevron-up.js +0 -9
  500. package/dist/node_modules/lucide-react/dist/esm/icons/chevron-up.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"should-render-event.cjs","names":[],"sources":["../../../../../src/components/conversation-events/chat/event-content-helpers/should-render-event.ts"],"sourcesContent":["import { MessageEvent, OpenHandsEvent } from \"#/types/agent-server/core\";\nimport {\n isActionEvent,\n isObservationEvent,\n isMessageEvent,\n isAgentErrorEvent,\n isConversationStateUpdateEvent,\n isGoalConversationStateUpdateEvent,\n isHookExecutionEvent,\n isACPToolCallEvent,\n isStreamingDeltaEvent,\n} from \"#/types/agent-server/type-guards\";\n\n// Prefixes of the SDK goal-loop re-prompts (FOLLOWUP_PROMPT / RESUME_PROMPT in\n// openhands.sdk .../conversation/goal/prompts.py). The goal loop injects these\n// as `user` messages each round to steer the agent, and FOLLOWUP_PROMPT embeds\n// the judge's verdict — which the goal banner already surfaces. The persisted\n// event carries no marker distinguishing them from real user input, so we match\n// the prompt text to keep this machinery out of the chat. Brittle by design;\n// keep in sync with the SDK prompts (the durable fix is a persisted goal-loop\n// flag on the event).\nconst GOAL_REPROMPT_PREFIXES = [\n \"The goal is NOT yet complete (audit iteration\",\n \"Resuming a goal that was paused or interrupted.\",\n];\n\nconst isGoalLoopReprompt = (event: MessageEvent): boolean => {\n if (event.llm_message?.role !== \"user\") return false;\n const content = event.llm_message.content;\n const text = Array.isArray(content)\n ? content\n .filter((c) => c.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\")\n : \"\";\n return GOAL_REPROMPT_PREFIXES.some((prefix) => text.startsWith(prefix));\n};\n\nexport const shouldRenderEvent = (event: OpenHandsEvent) => {\n if (isConversationStateUpdateEvent(event)) {\n // A finished `/goal` loop renders inline so it settles into the\n // conversation; the live (active) banner is shown separately by\n // GoalStatusBanner, and all other state updates (and the in-progress goal\n // events) stay hidden.\n return isGoalConversationStateUpdateEvent(event) && !event.value.active;\n }\n\n // Render action events (with filtering)\n if (isActionEvent(event)) {\n // For V1, action is an object with kind property\n const actionType = event.action.kind;\n\n if (!actionType) {\n return false;\n }\n\n // Hide user commands from the chat interface\n if (actionType === \"ExecuteBashAction\" && event.source === \"user\") {\n return false;\n }\n\n // Hide PlanningFileEditorAction - handled separately with PlanPreview component\n if (actionType === \"PlanningFileEditorAction\") {\n return false;\n }\n\n // The model switch tool reuses the same inline model message UI as\n // `/model <profile>` once the observation arrives.\n if (actionType === \"SwitchLLMAction\") {\n return false;\n }\n\n return true;\n }\n\n // Render observation events\n if (isObservationEvent(event)) {\n // Successful model switches are rendered through ModelMessages so they\n // look identical to `/model <profile>` confirmations. Failed switches\n // still render as observations so the error remains visible in chat.\n if (\n event.observation.kind === \"SwitchLLMObservation\" &&\n !event.observation.is_error\n ) {\n return false;\n }\n\n return true;\n }\n\n // Render message events (user and assistant messages), except the goal loop's\n // injected re-prompts — the judge feedback they carry is shown in the goal\n // banner, so otherwise they leak into the chat as fake user turns.\n if (isMessageEvent(event)) {\n return !isGoalLoopReprompt(event);\n }\n\n // Render agent error events\n if (isAgentErrorEvent(event)) {\n return true;\n }\n\n // Render hook execution events\n if (isHookExecutionEvent(event)) {\n return true;\n }\n\n // Render ACP sub-agent tool call events at every lifecycle stage. The SDK\n // now persists exactly two events per ``tool_call_id`` — one early\n // ``started`` event (``pending`` / ``in_progress``) and one terminal\n // (``completed`` / ``failed``) event — the action->observation pair for a\n // tool call. The ``started`` event renders the card as \"running\" (no check\n // mark; see ``getACPToolCallResult``) and ``handleEventForUI`` replaces it\n // in place by ``tool_call_id`` once the terminal event arrives, mirroring\n // how an ObservationEvent supersedes its ActionEvent. The old terminal-only\n // gate existed because the source fanned out one cumulative-output frame per\n // ``ToolCallProgress``, which flashed half-formed cards mid-stream; that\n // fan-out is gone, so the running card is now a single clean event.\n if (isACPToolCallEvent(event)) {\n return true;\n }\n\n if (isStreamingDeltaEvent(event)) {\n return event.content !== null || event.reasoning_content !== null;\n }\n\n // Don't render any other event types (system events, etc.)\n return false;\n};\n\nexport const hasUserEvent = (events: OpenHandsEvent[]) =>\n events.some((event) => event.source === \"user\");\n"],"mappings":"wHAqBA,IAAM,EAAyB,CAC7B,gDACA,iDACF,EAEM,EAAsB,GAAiC,CAC3D,GAAI,EAAM,aAAa,OAAS,OAAQ,MAAO,GAC/C,IAAM,EAAU,EAAM,YAAY,QAC5B,EAAO,MAAM,QAAQ,CAAO,EAC9B,EACG,OAAQ,GAAM,EAAE,OAAS,MAAM,EAC/B,IAAK,GAAM,EAAE,IAAI,EACjB,KAAK;CAAI,EACZ,GACJ,OAAO,EAAuB,KAAM,GAAW,EAAK,WAAW,CAAM,CAAC,CACxE,EAEa,EAAqB,GAA0B,CAC1D,GAAI,EAAA,+BAA+B,CAAK,EAKtC,OAAO,EAAA,mCAAmC,CAAK,GAAK,CAAC,EAAM,MAAM,OAInE,GAAI,EAAA,cAAc,CAAK,EAAG,CAExB,IAAM,EAAa,EAAM,OAAO,KAsBhC,MAJA,EAhBI,CAAC,GAKD,IAAe,qBAAuB,EAAM,SAAW,QAKvD,IAAe,4BAMf,IAAe,kBAKrB,CAsDA,OAnDI,EAAA,mBAAmB,CAAK,EAI1B,EACE,EAAM,YAAY,OAAS,wBAC3B,CAAC,EAAM,YAAY,UAWnB,EAAA,eAAe,CAAK,EACf,CAAC,EAAmB,CAAK,EAI9B,EAAA,kBAAkB,CAAK,GAKvB,EAAA,qBAAqB,CAAK,GAe1B,EAAA,mBAAmB,CAAK,EACnB,GAGL,EAAA,sBAAsB,CAAK,EACtB,EAAM,UAAY,MAAQ,EAAM,oBAAsB,KAIxD,EACT,EAEa,EAAgB,GAC3B,EAAO,KAAM,GAAU,EAAM,SAAW,MAAM"}
1
+ {"version":3,"file":"should-render-event.cjs","names":[],"sources":["../../../../../src/components/conversation-events/chat/event-content-helpers/should-render-event.ts"],"sourcesContent":["import { CHILD_CONVERSATION_RESULT_PREFIX } from \"#/constants/child-conversation\";\nimport { MessageEvent, OpenHandsEvent } from \"#/types/agent-server/core\";\nimport {\n isActionEvent,\n isObservationEvent,\n isMessageEvent,\n isAgentErrorEvent,\n isConversationStateUpdateEvent,\n isGoalConversationStateUpdateEvent,\n isHookExecutionEvent,\n isACPToolCallEvent,\n isStreamingDeltaEvent,\n} from \"#/types/agent-server/type-guards\";\n\n// Prefixes of the SDK goal-loop re-prompts (FOLLOWUP_PROMPT / RESUME_PROMPT in\n// openhands.sdk .../conversation/goal/prompts.py). The goal loop injects these\n// as `user` messages each round to steer the agent, and FOLLOWUP_PROMPT embeds\n// the judge's verdict — which the goal banner already surfaces. The persisted\n// event carries no marker distinguishing them from real user input, so we match\n// the prompt text to keep this machinery out of the chat. Brittle by design;\n// keep in sync with the SDK prompts (the durable fix is a persisted goal-loop\n// flag on the event).\nconst GOAL_REPROMPT_PREFIXES = [\n \"The goal is NOT yet complete (audit iteration\",\n \"Resuming a goal that was paused or interrupted.\",\n];\n\nconst userMessageText = (event: MessageEvent): string | null => {\n if (event.llm_message?.role !== \"user\") return null;\n const content = event.llm_message.content;\n return Array.isArray(content)\n ? content\n .filter((c) => c.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\")\n : \"\";\n};\n\nconst isGoalLoopReprompt = (event: MessageEvent): boolean => {\n const text = userMessageText(event);\n if (text === null) return false;\n return GOAL_REPROMPT_PREFIXES.some((prefix) => text.startsWith(prefix));\n};\n\n// The frontend posts the outcome of a `launch_child_conversation` call back as\n// a `user` message because client tools have no result channel (see\n// `services/child-conversation-launch.ts`). It is a JSON payload addressed to\n// the agent, which reports the child's id and link in its own reply, so the\n// raw message does not belong in the chat.\nconst isChildConversationResult = (event: MessageEvent): boolean =>\n userMessageText(event)?.startsWith(CHILD_CONVERSATION_RESULT_PREFIX) ?? false;\n\nexport const shouldRenderEvent = (event: OpenHandsEvent) => {\n if (isConversationStateUpdateEvent(event)) {\n // A finished `/goal` loop renders inline so it settles into the\n // conversation; the live (active) banner is shown separately by\n // GoalStatusBanner, and all other state updates (and the in-progress goal\n // events) stay hidden.\n return isGoalConversationStateUpdateEvent(event) && !event.value.active;\n }\n\n // Render action events (with filtering)\n if (isActionEvent(event)) {\n // For V1, action is an object with kind property\n const actionType = event.action.kind;\n\n if (!actionType) {\n return false;\n }\n\n // Hide user commands from the chat interface\n if (actionType === \"ExecuteBashAction\" && event.source === \"user\") {\n return false;\n }\n\n // Hide PlanningFileEditorAction - handled separately with PlanPreview component\n if (actionType === \"PlanningFileEditorAction\") {\n return false;\n }\n\n // The model switch tool reuses the same inline model message UI as\n // `/model <profile>` once the observation arrives.\n if (actionType === \"SwitchLLMAction\") {\n return false;\n }\n\n return true;\n }\n\n // Render observation events\n if (isObservationEvent(event)) {\n // Successful model switches are rendered through ModelMessages so they\n // look identical to `/model <profile>` confirmations. Failed switches\n // still render as observations so the error remains visible in chat.\n if (\n event.observation.kind === \"SwitchLLMObservation\" &&\n !event.observation.is_error\n ) {\n return false;\n }\n\n return true;\n }\n\n // Render message events (user and assistant messages), except the goal loop's\n // injected re-prompts — the judge feedback they carry is shown in the goal\n // banner, so otherwise they leak into the chat as fake user turns — and the\n // child-conversation launch results, which are machine payloads the agent\n // relays in its own reply.\n if (isMessageEvent(event)) {\n return !isGoalLoopReprompt(event) && !isChildConversationResult(event);\n }\n\n // Render agent error events\n if (isAgentErrorEvent(event)) {\n return true;\n }\n\n // Render hook execution events\n if (isHookExecutionEvent(event)) {\n return true;\n }\n\n // Render ACP sub-agent tool call events at every lifecycle stage. The SDK\n // now persists exactly two events per ``tool_call_id`` — one early\n // ``started`` event (``pending`` / ``in_progress``) and one terminal\n // (``completed`` / ``failed``) event — the action->observation pair for a\n // tool call. The ``started`` event renders the card as \"running\" (no check\n // mark; see ``getACPToolCallResult``) and ``handleEventForUI`` replaces it\n // in place by ``tool_call_id`` once the terminal event arrives, mirroring\n // how an ObservationEvent supersedes its ActionEvent. The old terminal-only\n // gate existed because the source fanned out one cumulative-output frame per\n // ``ToolCallProgress``, which flashed half-formed cards mid-stream; that\n // fan-out is gone, so the running card is now a single clean event.\n if (isACPToolCallEvent(event)) {\n return true;\n }\n\n if (isStreamingDeltaEvent(event)) {\n return event.content !== null || event.reasoning_content !== null;\n }\n\n // Don't render any other event types (system events, etc.)\n return false;\n};\n\nexport const hasUserEvent = (events: OpenHandsEvent[]) =>\n events.some((event) => event.source === \"user\");\n"],"mappings":"gLAsBA,IAAM,EAAyB,CAC7B,gDACA,iDACF,EAEM,EAAmB,GAAuC,CAC9D,GAAI,EAAM,aAAa,OAAS,OAAQ,OAAO,KAC/C,IAAM,EAAU,EAAM,YAAY,QAClC,OAAO,MAAM,QAAQ,CAAO,EACxB,EACG,OAAQ,GAAM,EAAE,OAAS,MAAM,EAC/B,IAAK,GAAM,EAAE,IAAI,EACjB,KAAK;CAAI,EACZ,EACN,EAEM,EAAsB,GAAiC,CAC3D,IAAM,EAAO,EAAgB,CAAK,EAElC,OADI,IAAS,KAAa,GACnB,EAAuB,KAAM,GAAW,EAAK,WAAW,CAAM,CAAC,CACxE,EAOM,EAA6B,GACjC,EAAgB,CAAK,GAAG,WAAA,uBAA2C,GAAK,GAE7D,EAAqB,GAA0B,CAC1D,GAAI,EAAA,+BAA+B,CAAK,EAKtC,OAAO,EAAA,mCAAmC,CAAK,GAAK,CAAC,EAAM,MAAM,OAInE,GAAI,EAAA,cAAc,CAAK,EAAG,CAExB,IAAM,EAAa,EAAM,OAAO,KAsBhC,MAJA,EAhBI,CAAC,GAKD,IAAe,qBAAuB,EAAM,SAAW,QAKvD,IAAe,4BAMf,IAAe,kBAKrB,CAwDA,OArDI,EAAA,mBAAmB,CAAK,EAI1B,EACE,EAAM,YAAY,OAAS,wBAC3B,CAAC,EAAM,YAAY,UAanB,EAAA,eAAe,CAAK,EACf,CAAC,EAAmB,CAAK,GAAK,CAAC,EAA0B,CAAK,EAInE,EAAA,kBAAkB,CAAK,GAKvB,EAAA,qBAAqB,CAAK,GAe1B,EAAA,mBAAmB,CAAK,EACnB,GAGL,EAAA,sBAAsB,CAAK,EACtB,EAAM,UAAY,MAAQ,EAAM,oBAAsB,KAIxD,EACT,EAEa,EAAgB,GAC3B,EAAO,KAAM,GAAU,EAAM,SAAW,MAAM"}
@@ -1,18 +1,22 @@
1
+ import "../../../../constants/child-conversation.js";
1
2
  import { isACPToolCallEvent as e, isActionEvent as t, isAgentErrorEvent as n, isConversationStateUpdateEvent as r, isGoalConversationStateUpdateEvent as i, isHookExecutionEvent as a, isMessageEvent as o, isObservationEvent as s, isStreamingDeltaEvent as c } from "../../../../types/agent-server/type-guards.js";
2
3
  //#region src/components/conversation-events/chat/event-content-helpers/should-render-event.ts
3
4
  var l = ["The goal is NOT yet complete (audit iteration", "Resuming a goal that was paused or interrupted."], u = (e) => {
4
- if (e.llm_message?.role !== "user") return !1;
5
- let t = e.llm_message.content, n = Array.isArray(t) ? t.filter((e) => e.type === "text").map((e) => e.text).join("\n") : "";
6
- return l.some((e) => n.startsWith(e));
7
- }, d = (l) => {
5
+ if (e.llm_message?.role !== "user") return null;
6
+ let t = e.llm_message.content;
7
+ return Array.isArray(t) ? t.filter((e) => e.type === "text").map((e) => e.text).join("\n") : "";
8
+ }, d = (e) => {
9
+ let t = u(e);
10
+ return t === null ? !1 : l.some((e) => t.startsWith(e));
11
+ }, f = (e) => u(e)?.startsWith("[child-conversation] ") ?? !1, p = (l) => {
8
12
  if (r(l)) return i(l) && !l.value.active;
9
13
  if (t(l)) {
10
14
  let e = l.action.kind;
11
15
  return !(!e || e === "ExecuteBashAction" && l.source === "user" || e === "PlanningFileEditorAction" || e === "SwitchLLMAction");
12
16
  }
13
- return s(l) ? !(l.observation.kind === "SwitchLLMObservation" && !l.observation.is_error) : o(l) ? !u(l) : n(l) || a(l) || e(l) ? !0 : c(l) ? l.content !== null || l.reasoning_content !== null : !1;
14
- }, f = (e) => e.some((e) => e.source === "user");
17
+ return s(l) ? !(l.observation.kind === "SwitchLLMObservation" && !l.observation.is_error) : o(l) ? !d(l) && !f(l) : n(l) || a(l) || e(l) ? !0 : c(l) ? l.content !== null || l.reasoning_content !== null : !1;
18
+ }, m = (e) => e.some((e) => e.source === "user");
15
19
  //#endregion
16
- export { f as hasUserEvent, d as shouldRenderEvent };
20
+ export { m as hasUserEvent, p as shouldRenderEvent };
17
21
 
18
22
  //# sourceMappingURL=should-render-event.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"should-render-event.js","names":[],"sources":["../../../../../src/components/conversation-events/chat/event-content-helpers/should-render-event.ts"],"sourcesContent":["import { MessageEvent, OpenHandsEvent } from \"#/types/agent-server/core\";\nimport {\n isActionEvent,\n isObservationEvent,\n isMessageEvent,\n isAgentErrorEvent,\n isConversationStateUpdateEvent,\n isGoalConversationStateUpdateEvent,\n isHookExecutionEvent,\n isACPToolCallEvent,\n isStreamingDeltaEvent,\n} from \"#/types/agent-server/type-guards\";\n\n// Prefixes of the SDK goal-loop re-prompts (FOLLOWUP_PROMPT / RESUME_PROMPT in\n// openhands.sdk .../conversation/goal/prompts.py). The goal loop injects these\n// as `user` messages each round to steer the agent, and FOLLOWUP_PROMPT embeds\n// the judge's verdict — which the goal banner already surfaces. The persisted\n// event carries no marker distinguishing them from real user input, so we match\n// the prompt text to keep this machinery out of the chat. Brittle by design;\n// keep in sync with the SDK prompts (the durable fix is a persisted goal-loop\n// flag on the event).\nconst GOAL_REPROMPT_PREFIXES = [\n \"The goal is NOT yet complete (audit iteration\",\n \"Resuming a goal that was paused or interrupted.\",\n];\n\nconst isGoalLoopReprompt = (event: MessageEvent): boolean => {\n if (event.llm_message?.role !== \"user\") return false;\n const content = event.llm_message.content;\n const text = Array.isArray(content)\n ? content\n .filter((c) => c.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\")\n : \"\";\n return GOAL_REPROMPT_PREFIXES.some((prefix) => text.startsWith(prefix));\n};\n\nexport const shouldRenderEvent = (event: OpenHandsEvent) => {\n if (isConversationStateUpdateEvent(event)) {\n // A finished `/goal` loop renders inline so it settles into the\n // conversation; the live (active) banner is shown separately by\n // GoalStatusBanner, and all other state updates (and the in-progress goal\n // events) stay hidden.\n return isGoalConversationStateUpdateEvent(event) && !event.value.active;\n }\n\n // Render action events (with filtering)\n if (isActionEvent(event)) {\n // For V1, action is an object with kind property\n const actionType = event.action.kind;\n\n if (!actionType) {\n return false;\n }\n\n // Hide user commands from the chat interface\n if (actionType === \"ExecuteBashAction\" && event.source === \"user\") {\n return false;\n }\n\n // Hide PlanningFileEditorAction - handled separately with PlanPreview component\n if (actionType === \"PlanningFileEditorAction\") {\n return false;\n }\n\n // The model switch tool reuses the same inline model message UI as\n // `/model <profile>` once the observation arrives.\n if (actionType === \"SwitchLLMAction\") {\n return false;\n }\n\n return true;\n }\n\n // Render observation events\n if (isObservationEvent(event)) {\n // Successful model switches are rendered through ModelMessages so they\n // look identical to `/model <profile>` confirmations. Failed switches\n // still render as observations so the error remains visible in chat.\n if (\n event.observation.kind === \"SwitchLLMObservation\" &&\n !event.observation.is_error\n ) {\n return false;\n }\n\n return true;\n }\n\n // Render message events (user and assistant messages), except the goal loop's\n // injected re-prompts — the judge feedback they carry is shown in the goal\n // banner, so otherwise they leak into the chat as fake user turns.\n if (isMessageEvent(event)) {\n return !isGoalLoopReprompt(event);\n }\n\n // Render agent error events\n if (isAgentErrorEvent(event)) {\n return true;\n }\n\n // Render hook execution events\n if (isHookExecutionEvent(event)) {\n return true;\n }\n\n // Render ACP sub-agent tool call events at every lifecycle stage. The SDK\n // now persists exactly two events per ``tool_call_id`` — one early\n // ``started`` event (``pending`` / ``in_progress``) and one terminal\n // (``completed`` / ``failed``) event — the action->observation pair for a\n // tool call. The ``started`` event renders the card as \"running\" (no check\n // mark; see ``getACPToolCallResult``) and ``handleEventForUI`` replaces it\n // in place by ``tool_call_id`` once the terminal event arrives, mirroring\n // how an ObservationEvent supersedes its ActionEvent. The old terminal-only\n // gate existed because the source fanned out one cumulative-output frame per\n // ``ToolCallProgress``, which flashed half-formed cards mid-stream; that\n // fan-out is gone, so the running card is now a single clean event.\n if (isACPToolCallEvent(event)) {\n return true;\n }\n\n if (isStreamingDeltaEvent(event)) {\n return event.content !== null || event.reasoning_content !== null;\n }\n\n // Don't render any other event types (system events, etc.)\n return false;\n};\n\nexport const hasUserEvent = (events: OpenHandsEvent[]) =>\n events.some((event) => event.source === \"user\");\n"],"mappings":";;AAqBA,IAAM,IAAyB,CAC7B,iDACA,iDACF,GAEM,KAAsB,MAAiC;CAC3D,IAAI,EAAM,aAAa,SAAS,QAAQ,OAAO;CAC/C,IAAM,IAAU,EAAM,YAAY,SAC5B,IAAO,MAAM,QAAQ,CAAO,IAC9B,EACG,QAAQ,MAAM,EAAE,SAAS,MAAM,EAC/B,KAAK,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI,IACZ;CACJ,OAAO,EAAuB,MAAM,MAAW,EAAK,WAAW,CAAM,CAAC;AACxE,GAEa,KAAqB,MAA0B;CAC1D,IAAI,EAA+B,CAAK,GAKtC,OAAO,EAAmC,CAAK,KAAK,CAAC,EAAM,MAAM;CAInE,IAAI,EAAc,CAAK,GAAG;EAExB,IAAM,IAAa,EAAM,OAAO;EAsBhC,OAJA,EAhBI,CAAC,KAKD,MAAe,uBAAuB,EAAM,WAAW,UAKvD,MAAe,8BAMf,MAAe;CAKrB;CAsDA,OAnDI,EAAmB,CAAK,IAI1B,EACE,EAAM,YAAY,SAAS,0BAC3B,CAAC,EAAM,YAAY,YAWnB,EAAe,CAAK,IACf,CAAC,EAAmB,CAAK,IAI9B,EAAkB,CAAK,KAKvB,EAAqB,CAAK,KAe1B,EAAmB,CAAK,IACnB,KAGL,EAAsB,CAAK,IACtB,EAAM,YAAY,QAAQ,EAAM,sBAAsB,OAIxD;AACT,GAEa,KAAgB,MAC3B,EAAO,MAAM,MAAU,EAAM,WAAW,MAAM"}
1
+ {"version":3,"file":"should-render-event.js","names":[],"sources":["../../../../../src/components/conversation-events/chat/event-content-helpers/should-render-event.ts"],"sourcesContent":["import { CHILD_CONVERSATION_RESULT_PREFIX } from \"#/constants/child-conversation\";\nimport { MessageEvent, OpenHandsEvent } from \"#/types/agent-server/core\";\nimport {\n isActionEvent,\n isObservationEvent,\n isMessageEvent,\n isAgentErrorEvent,\n isConversationStateUpdateEvent,\n isGoalConversationStateUpdateEvent,\n isHookExecutionEvent,\n isACPToolCallEvent,\n isStreamingDeltaEvent,\n} from \"#/types/agent-server/type-guards\";\n\n// Prefixes of the SDK goal-loop re-prompts (FOLLOWUP_PROMPT / RESUME_PROMPT in\n// openhands.sdk .../conversation/goal/prompts.py). The goal loop injects these\n// as `user` messages each round to steer the agent, and FOLLOWUP_PROMPT embeds\n// the judge's verdict — which the goal banner already surfaces. The persisted\n// event carries no marker distinguishing them from real user input, so we match\n// the prompt text to keep this machinery out of the chat. Brittle by design;\n// keep in sync with the SDK prompts (the durable fix is a persisted goal-loop\n// flag on the event).\nconst GOAL_REPROMPT_PREFIXES = [\n \"The goal is NOT yet complete (audit iteration\",\n \"Resuming a goal that was paused or interrupted.\",\n];\n\nconst userMessageText = (event: MessageEvent): string | null => {\n if (event.llm_message?.role !== \"user\") return null;\n const content = event.llm_message.content;\n return Array.isArray(content)\n ? content\n .filter((c) => c.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\")\n : \"\";\n};\n\nconst isGoalLoopReprompt = (event: MessageEvent): boolean => {\n const text = userMessageText(event);\n if (text === null) return false;\n return GOAL_REPROMPT_PREFIXES.some((prefix) => text.startsWith(prefix));\n};\n\n// The frontend posts the outcome of a `launch_child_conversation` call back as\n// a `user` message because client tools have no result channel (see\n// `services/child-conversation-launch.ts`). It is a JSON payload addressed to\n// the agent, which reports the child's id and link in its own reply, so the\n// raw message does not belong in the chat.\nconst isChildConversationResult = (event: MessageEvent): boolean =>\n userMessageText(event)?.startsWith(CHILD_CONVERSATION_RESULT_PREFIX) ?? false;\n\nexport const shouldRenderEvent = (event: OpenHandsEvent) => {\n if (isConversationStateUpdateEvent(event)) {\n // A finished `/goal` loop renders inline so it settles into the\n // conversation; the live (active) banner is shown separately by\n // GoalStatusBanner, and all other state updates (and the in-progress goal\n // events) stay hidden.\n return isGoalConversationStateUpdateEvent(event) && !event.value.active;\n }\n\n // Render action events (with filtering)\n if (isActionEvent(event)) {\n // For V1, action is an object with kind property\n const actionType = event.action.kind;\n\n if (!actionType) {\n return false;\n }\n\n // Hide user commands from the chat interface\n if (actionType === \"ExecuteBashAction\" && event.source === \"user\") {\n return false;\n }\n\n // Hide PlanningFileEditorAction - handled separately with PlanPreview component\n if (actionType === \"PlanningFileEditorAction\") {\n return false;\n }\n\n // The model switch tool reuses the same inline model message UI as\n // `/model <profile>` once the observation arrives.\n if (actionType === \"SwitchLLMAction\") {\n return false;\n }\n\n return true;\n }\n\n // Render observation events\n if (isObservationEvent(event)) {\n // Successful model switches are rendered through ModelMessages so they\n // look identical to `/model <profile>` confirmations. Failed switches\n // still render as observations so the error remains visible in chat.\n if (\n event.observation.kind === \"SwitchLLMObservation\" &&\n !event.observation.is_error\n ) {\n return false;\n }\n\n return true;\n }\n\n // Render message events (user and assistant messages), except the goal loop's\n // injected re-prompts — the judge feedback they carry is shown in the goal\n // banner, so otherwise they leak into the chat as fake user turns — and the\n // child-conversation launch results, which are machine payloads the agent\n // relays in its own reply.\n if (isMessageEvent(event)) {\n return !isGoalLoopReprompt(event) && !isChildConversationResult(event);\n }\n\n // Render agent error events\n if (isAgentErrorEvent(event)) {\n return true;\n }\n\n // Render hook execution events\n if (isHookExecutionEvent(event)) {\n return true;\n }\n\n // Render ACP sub-agent tool call events at every lifecycle stage. The SDK\n // now persists exactly two events per ``tool_call_id`` — one early\n // ``started`` event (``pending`` / ``in_progress``) and one terminal\n // (``completed`` / ``failed``) event — the action->observation pair for a\n // tool call. The ``started`` event renders the card as \"running\" (no check\n // mark; see ``getACPToolCallResult``) and ``handleEventForUI`` replaces it\n // in place by ``tool_call_id`` once the terminal event arrives, mirroring\n // how an ObservationEvent supersedes its ActionEvent. The old terminal-only\n // gate existed because the source fanned out one cumulative-output frame per\n // ``ToolCallProgress``, which flashed half-formed cards mid-stream; that\n // fan-out is gone, so the running card is now a single clean event.\n if (isACPToolCallEvent(event)) {\n return true;\n }\n\n if (isStreamingDeltaEvent(event)) {\n return event.content !== null || event.reasoning_content !== null;\n }\n\n // Don't render any other event types (system events, etc.)\n return false;\n};\n\nexport const hasUserEvent = (events: OpenHandsEvent[]) =>\n events.some((event) => event.source === \"user\");\n"],"mappings":";;;AAsBA,IAAM,IAAyB,CAC7B,iDACA,iDACF,GAEM,KAAmB,MAAuC;CAC9D,IAAI,EAAM,aAAa,SAAS,QAAQ,OAAO;CAC/C,IAAM,IAAU,EAAM,YAAY;CAClC,OAAO,MAAM,QAAQ,CAAO,IACxB,EACG,QAAQ,MAAM,EAAE,SAAS,MAAM,EAC/B,KAAK,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI,IACZ;AACN,GAEM,KAAsB,MAAiC;CAC3D,IAAM,IAAO,EAAgB,CAAK;CAElC,OADI,MAAS,OAAa,KACnB,EAAuB,MAAM,MAAW,EAAK,WAAW,CAAM,CAAC;AACxE,GAOM,KAA6B,MACjC,EAAgB,CAAK,GAAG,WAAA,uBAA2C,KAAK,IAE7D,KAAqB,MAA0B;CAC1D,IAAI,EAA+B,CAAK,GAKtC,OAAO,EAAmC,CAAK,KAAK,CAAC,EAAM,MAAM;CAInE,IAAI,EAAc,CAAK,GAAG;EAExB,IAAM,IAAa,EAAM,OAAO;EAsBhC,OAJA,EAhBI,CAAC,KAKD,MAAe,uBAAuB,EAAM,WAAW,UAKvD,MAAe,8BAMf,MAAe;CAKrB;CAwDA,OArDI,EAAmB,CAAK,IAI1B,EACE,EAAM,YAAY,SAAS,0BAC3B,CAAC,EAAM,YAAY,YAanB,EAAe,CAAK,IACf,CAAC,EAAmB,CAAK,KAAK,CAAC,EAA0B,CAAK,IAInE,EAAkB,CAAK,KAKvB,EAAqB,CAAK,KAe1B,EAAmB,CAAK,IACnB,KAGL,EAAsB,CAAK,IACtB,EAAM,YAAY,QAAQ,EAAM,sBAAsB,OAIxD;AACT,GAEa,KAAgB,MAC3B,EAAO,MAAM,MAAU,EAAM,WAAW,MAAM"}
@@ -1,3 +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/status.cjs"),r=require("../../../../utils/utils.cjs"),i=require("../../../../constants/acp-providers.cjs"),a=require("../../../../api/agent-server-adapter.cjs"),o=require("../../../../utils/format-time-delta.cjs"),s=require("../../../../utils/format-model-name.cjs"),c=require("../../../shared/agent-brand-icon.cjs"),l=require("./conversation-repo-link.cjs"),u=require("./no-repository.cjs");let d=require("react/jsx-runtime");function f({selectedRepository:f,lastUpdatedAt:p,createdAt:m,executionStatus:h,workspaceWorkingDir:g,showRepositoryMetadata:_=!0,showTimestamp:v=!0,llmModel:y,showAgentChip:b=!1,agentKind:x=null,acpServer:S=null,tags:C=null,showTags:w=!1}){let{t:T}=e.useTranslation(`openhands`),E=n.isExecutionPaused(h),D=null;if(b)if(x===`acp`){let e=i.getAcpProviderDisplayName(S)??T(t.I18nKey.CONVERSATION$ACP_AGENT_GENERIC),n=i.labelForAcpModel(S,y),r=n??e;D={kind:i.resolveAcpProviderIcon(S),text:r,tooltip:n?`${e} · ${n}`:e}}else y&&(D={kind:`openhands`,text:s.formatNativeModelName(y)??y,tooltip:y});let O=h===void 0?void 0:`pl-[26px]`,k=w?a.getDisplayConversationTags(C):[],A=k.slice(0,3),j=k.slice(3);return(0,d.jsxs)(`div`,{className:r.cn(`flex flex-col gap-0.5 mt-0.5 w-full min-w-0`,E&&`opacity-60`),children:[D?(0,d.jsx)(`div`,{className:O,children:(0,d.jsxs)(`span`,{"data-testid":`conversation-card-agent-chip`,className:`inline-flex items-center gap-1 text-xs text-[var(--oh-muted)] max-w-full min-w-0`,title:D.tooltip,children:[(0,d.jsx)(c.AgentBrandIcon,{kind:D.kind}),(0,d.jsx)(`span`,{className:`truncate`,children:D.text})]})}):null,k.length>0?(0,d.jsxs)(`div`,{className:r.cn(`flex flex-row flex-wrap items-center gap-1 min-w-0`,O),children:[A.map(([e,t])=>(0,d.jsx)(`span`,{"data-testid":`conversation-card-tag-chip`,title:`${e}: ${t}`,className:`inline-flex max-w-full min-w-0 items-center rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]`,children:(0,d.jsx)(`span`,{className:`truncate`,children:`${e}: ${t}`})},e)),j.length>0?(0,d.jsx)(`span`,{"data-testid":`conversation-card-tag-overflow`,title:j.map(([e,t])=>`${e}: ${t}`).join(`
2
- `),className:`inline-flex items-center rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]`,children:`+${j.length}`}):null]}):null,(0,d.jsxs)(`div`,{className:r.cn(`flex flex-row items-center gap-2 w-full min-w-0`,_&&O),children:[_&&(f?.selected_repository?(0,d.jsx)(l.ConversationRepoLink,{selectedRepository:f}):(0,d.jsx)(u.NoRepository,{workspaceWorkingDir:g})),(0,d.jsx)(`div`,{className:`flex items-center gap-2 shrink-0 ml-auto`,children:v&&(m??p)&&(0,d.jsx)(`p`,{className:`text-xs text-[var(--oh-muted)] text-right`,children:(0,d.jsx)(`time`,{children:`${o.formatTimeDelta(p??m)} ${T(t.I18nKey.CONVERSATION$AGO)}`})})})]})]})}exports.ConversationCardFooter=f;
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/status.cjs"),r=require("../../../../utils/utils.cjs"),i=require("../../../../constants/acp-providers.cjs"),a=require("../../../../api/agent-server-adapter.cjs"),o=require("../../../../utils/format-time-delta.cjs"),s=require("../../../../utils/format-model-name.cjs"),c=require("../../../shared/agent-brand-icon.cjs"),l=require("./conversation-card-meta-chip.cjs"),u=require("./conversation-repo-link.cjs"),d=require("./no-repository.cjs"),f=require("./conversation-tag-chips.cjs");let p=require("react/jsx-runtime");function m({selectedRepository:m,lastUpdatedAt:h,createdAt:g,executionStatus:_,workspaceWorkingDir:v,showRepositoryMetadata:y=!0,showTimestamp:b=!0,llmModel:x,showAgentChip:S=!1,agentKind:C=null,acpServer:w=null,tags:T=null,showTags:E=!1}){let{t:D}=e.useTranslation(`openhands`),O=n.isExecutionPaused(_),k=null;if(S)if(C===`acp`){let e=i.getAcpProviderDisplayName(w)??D(t.I18nKey.CONVERSATION$ACP_AGENT_GENERIC),n=i.labelForAcpModel(w,x),r=n??e;k={kind:i.resolveAcpProviderIcon(w),text:r,tooltip:n?`${e} · ${n}`:e}}else x&&(k={kind:`openhands`,text:s.formatNativeModelName(x)??x,tooltip:x});let A=_===void 0?void 0:`pl-[26px]`,j=E?a.getDisplayConversationTags(T):[];return(0,p.jsxs)(`div`,{className:r.cn(`flex flex-col gap-0.5 mt-0.5 w-full min-w-0`,O&&`opacity-60`),children:[(0,p.jsxs)(`div`,{className:r.cn(`flex flex-row items-center gap-2 w-full min-w-0`,y&&A),children:[y&&(m?.selected_repository?(0,p.jsx)(u.ConversationRepoLink,{selectedRepository:m}):(0,p.jsx)(d.NoRepository,{workspaceWorkingDir:v})),(0,p.jsx)(`div`,{className:`flex items-center gap-2 shrink-0 ml-auto`,children:b&&(g??h)&&(0,p.jsx)(`p`,{className:`text-xs text-[var(--oh-muted)] text-right`,children:(0,p.jsx)(`time`,{children:`${o.formatTimeDelta(h??g)} ${D(t.I18nKey.CONVERSATION$AGO)}`})})})]}),k?(0,p.jsx)(`div`,{className:A,children:(0,p.jsxs)(`span`,{"data-testid":`conversation-card-agent-chip`,className:l.CONVERSATION_CARD_META_CHIP_CLASSNAME,title:k.tooltip,children:[(0,p.jsx)(`span`,{className:`inline-flex h-4 shrink-0 items-center justify-center [&_svg]:block`,"aria-hidden":!0,children:(0,p.jsx)(c.AgentBrandIcon,{kind:k.kind,size:12})}),(0,p.jsx)(`span`,{className:`truncate leading-4`,children:k.text})]})}):null,j.length>0?(0,p.jsx)(`div`,{className:A,children:(0,p.jsx)(f.ConversationTagChips,{tags:j})}):null]})}exports.ConversationCardFooter=m;
3
2
  //# sourceMappingURL=conversation-card-footer.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-card-footer.cjs","names":[],"sources":["../../../../../src/components/features/conversation-panel/conversation-card/conversation-card-footer.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { formatTimeDelta } from \"#/utils/format-time-delta\";\nimport { cn } from \"#/utils/utils\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { RepositorySelection } from \"#/api/open-hands.types\";\nimport { ExecutionStatus } from \"#/types/agent-server/core/base/common\";\nimport { isExecutionPaused } from \"#/utils/status\";\nimport {\n getAcpProviderDisplayName,\n labelForAcpModel,\n resolveAcpProviderIcon,\n} from \"#/constants/acp-providers\";\nimport { formatNativeModelName } from \"#/utils/format-model-name\";\nimport {\n AgentBrandIcon,\n type AgentBrandIconKind,\n} from \"#/components/shared/agent-brand-icon\";\nimport { getDisplayConversationTags } from \"#/api/agent-server-adapter\";\nimport { ConversationRepoLink } from \"./conversation-repo-link\";\nimport { NoRepository } from \"./no-repository\";\n\n/**\n * Display budget for the tag-chip row. Tags are server-/API-controlled, so a\n * conversation can carry arbitrarily many; the card shows at most this many\n * chips (sorted by key) and folds the rest into a \"+N\" overflow chip.\n */\nexport const MAX_VISIBLE_TAG_CHIPS = 3;\n\ninterface ConversationCardFooterProps {\n selectedRepository: RepositorySelection | null;\n lastUpdatedAt: string;\n createdAt?: string;\n executionStatus?: ExecutionStatus | null;\n workspaceWorkingDir?: string | null;\n showRepositoryMetadata?: boolean;\n showTimestamp?: boolean;\n llmModel?: string | null;\n /**\n * Whether to render the agent/model chip. Wired to the conversation\n * panel's \"LLM model\" toggle; gates the chip uniformly\n * for both ACP and OpenHands cards.\n */\n showAgentChip?: boolean;\n /**\n * High-level kind of the conversation's agent. Drives the chip's icon:\n * the OpenHands logo for native conversations and the resolved ACP brand\n * mark for ACP conversations. Defensive against stray ``acpServer``\n * values reaching an OpenHands card.\n */\n agentKind?: \"openhands\" | \"acp\" | null;\n /**\n * Registry key of the ACP CLI server (``\"claude-code\"`` / ``\"codex\"`` /\n * ``\"gemini-cli\"`` / unknown / null). Resolved to a human display name\n * via {@link getAcpProviderDisplayName}; unknown / null falls back to\n * a generic \"ACP\" label so a Custom-command preset still produces a\n * useful chip.\n */\n acpServer?: string | null;\n /**\n * Server-side conversation tags (``AppConversation.tags``). Non-reserved\n * entries render as ``key: value`` chips so API-/automation-born\n * conversations can surface attribution (e.g. ``origin: slack``).\n */\n tags?: Record<string, string> | null;\n /**\n * Whether to render the tag-chip row. Wired to the conversation panel's\n * \"Tags\" toggle.\n */\n showTags?: boolean;\n}\n\nexport function ConversationCardFooter({\n selectedRepository,\n lastUpdatedAt,\n createdAt,\n executionStatus,\n workspaceWorkingDir,\n showRepositoryMetadata = true,\n showTimestamp = true,\n llmModel,\n showAgentChip = false,\n agentKind = null,\n acpServer = null,\n tags = null,\n showTags = false,\n}: ConversationCardFooterProps) {\n const { t } = useTranslation(\"openhands\");\n\n const isPaused = isExecutionPaused(executionStatus);\n\n // Single inline chip per conversation: [brand mark] {model text}. Gated by\n // the conversation panel's \"LLM model\" toggle and applied\n // uniformly to both kinds — OpenHands shows the logo + ``agent.llm.model``;\n // ACP shows the provider brand mark + model resolved through PR 730's\n // adapter chain, falling back to the provider display name when no model is\n // available so the chip never collapses to icon-only.\n let chip: {\n kind: AgentBrandIconKind;\n text: string;\n tooltip: string;\n } | null = null;\n if (showAgentChip) {\n if (agentKind === \"acp\") {\n const providerName =\n getAcpProviderDisplayName(acpServer) ??\n t(I18nKey.CONVERSATION$ACP_AGENT_GENERIC);\n // Prefer the provider's picker label (e.g. \"Claude Opus 4.7\") over the\n // raw ``acp_model`` ID; falls back to the raw ID for custom overrides\n // and to the provider name when there's no model at all.\n const modelLabel = labelForAcpModel(acpServer, llmModel);\n const text = modelLabel ?? providerName;\n chip = {\n kind: resolveAcpProviderIcon(acpServer),\n text,\n tooltip: modelLabel ? `${providerName} · ${modelLabel}` : providerName,\n };\n } else if (llmModel) {\n // Strip the routing prefix (e.g. \"anthropic/claude-…\" → \"claude-…\") for\n // the chip text; keep the full routing string in the tooltip.\n chip = {\n kind: \"openhands\",\n text: formatNativeModelName(llmModel) ?? llmModel,\n tooltip: llmModel,\n };\n }\n }\n\n // Match title text start: 18px status column + gap-2 (8px).\n const metadataIndentClass =\n executionStatus !== undefined ? \"pl-[26px]\" : undefined;\n\n const displayTags = showTags ? getDisplayConversationTags(tags) : [];\n // Tags are API-controlled with no server-side count bound, so the card\n // renders a fixed display budget: the first chips in sorted-key order plus\n // a \"+N\" affordance whose tooltip reveals the remainder. The full map stays\n // on ``AppConversation.tags`` for non-display consumers.\n const visibleTags = displayTags.slice(0, MAX_VISIBLE_TAG_CHIPS);\n const overflowTags = displayTags.slice(MAX_VISIBLE_TAG_CHIPS);\n\n return (\n <div\n className={cn(\n \"flex flex-col gap-0.5 mt-0.5 w-full min-w-0\",\n isPaused && \"opacity-60\",\n )}\n >\n {chip ? (\n <div className={metadataIndentClass}>\n <span\n data-testid=\"conversation-card-agent-chip\"\n className=\"inline-flex items-center gap-1 text-xs text-[var(--oh-muted)] max-w-full min-w-0\"\n title={chip.tooltip}\n >\n <AgentBrandIcon kind={chip.kind} />\n <span className=\"truncate\">{chip.text}</span>\n </span>\n </div>\n ) : null}\n {displayTags.length > 0 ? (\n <div\n className={cn(\n \"flex flex-row flex-wrap items-center gap-1 min-w-0\",\n metadataIndentClass,\n )}\n >\n {visibleTags.map(([key, value]) => (\n <span\n key={key}\n data-testid=\"conversation-card-tag-chip\"\n title={`${key}: ${value}`}\n className=\"inline-flex max-w-full min-w-0 items-center rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]\"\n >\n <span className=\"truncate\">{`${key}: ${value}`}</span>\n </span>\n ))}\n {overflowTags.length > 0 ? (\n <span\n data-testid=\"conversation-card-tag-overflow\"\n title={overflowTags\n .map(([key, value]) => `${key}: ${value}`)\n .join(\"\\n\")}\n className=\"inline-flex items-center rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]\"\n >\n {`+${overflowTags.length}`}\n </span>\n ) : null}\n </div>\n ) : null}\n <div\n className={cn(\n \"flex flex-row items-center gap-2 w-full min-w-0\",\n showRepositoryMetadata && metadataIndentClass,\n )}\n >\n {showRepositoryMetadata &&\n (selectedRepository?.selected_repository ? (\n <ConversationRepoLink selectedRepository={selectedRepository} />\n ) : (\n <NoRepository workspaceWorkingDir={workspaceWorkingDir} />\n ))}\n <div className=\"flex items-center gap-2 shrink-0 ml-auto\">\n {showTimestamp && (createdAt ?? lastUpdatedAt) && (\n <p className=\"text-xs text-[var(--oh-muted)] text-right\">\n <time>\n {`${formatTimeDelta(lastUpdatedAt ?? createdAt)} ${t(I18nKey.CONVERSATION$AGO)}`}\n </time>\n </p>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"ioBAuEA,SAAgB,EAAuB,CACrC,qBACA,gBACA,YACA,kBACA,sBACA,yBAAyB,GACzB,gBAAgB,GAChB,WACA,gBAAgB,GAChB,YAAY,KACZ,YAAY,KACZ,OAAO,KACP,WAAW,IACmB,CAC9B,GAAM,CAAE,KAAM,EAAA,eAAe,WAAW,EAElC,EAAW,EAAA,kBAAkB,CAAe,EAQ9C,EAIO,KACX,GAAI,KACE,IAAc,MAAO,CACvB,IAAM,EACJ,EAAA,0BAA0B,CAAS,GACnC,EAAE,EAAA,QAAQ,8BAA8B,EAIpC,EAAa,EAAA,iBAAiB,EAAW,CAAQ,EACjD,EAAO,GAAc,EAC3B,EAAO,CACL,KAAM,EAAA,uBAAuB,CAAS,EACtC,OACA,QAAS,EAAa,GAAG,EAAa,KAAK,IAAe,CAC5D,CACF,MAAW,IAGT,EAAO,CACL,KAAM,YACN,KAAM,EAAA,sBAAsB,CAAQ,GAAK,EACzC,QAAS,CACX,GAKJ,IAAM,EACJ,IAAoB,IAAA,GAA0B,IAAA,GAAd,YAE5B,EAAc,EAAW,EAAA,2BAA2B,CAAI,EAAI,CAAC,EAK7D,EAAc,EAAY,MAAM,EAAA,CAAwB,EACxD,EAAe,EAAY,MAAA,CAA2B,EAE5D,OACE,EAAA,EAAA,MAAC,MAAD,CACE,UAAW,EAAA,GACT,8CACA,GAAY,YACd,WAJF,CAMG,GACC,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,YACd,EAAA,EAAA,MAAC,OAAD,CACE,cAAY,+BACZ,UAAU,mFACV,MAAO,EAAK,iBAHd,EAKE,EAAA,EAAA,KAAC,EAAA,eAAD,CAAgB,KAAM,EAAK,IAAO,CAAA,GAClC,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oBAAY,EAAK,IAAW,CAAA,CACxC,GACH,CAAA,EACH,KACH,EAAY,OAAS,GACpB,EAAA,EAAA,MAAC,MAAD,CACE,UAAW,EAAA,GACT,qDACA,CACF,WAJF,CAMG,EAAY,KAAK,CAAC,EAAK,MACtB,EAAA,EAAA,KAAC,OAAD,CAEE,cAAY,6BACZ,MAAO,GAAG,EAAI,IAAI,IAClB,UAAU,yJAEV,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oBAAY,GAAG,EAAI,IAAI,GAAc,CAAA,CACjD,EANC,CAMD,CACP,EACA,EAAa,OAAS,GACrB,EAAA,EAAA,KAAC,OAAD,CACE,cAAY,iCACZ,MAAO,EACJ,KAAK,CAAC,EAAK,KAAW,GAAG,EAAI,IAAI,GAAO,EACxC,KAAK;CAAI,EACZ,UAAU,qIAET,IAAI,EAAa,QACd,CAAA,EACJ,IACD,IACH,MACJ,EAAA,EAAA,MAAC,MAAD,CACE,UAAW,EAAA,GACT,kDACA,GAA0B,CAC5B,WAJF,CAMG,IACE,GAAoB,qBACnB,EAAA,EAAA,KAAC,EAAA,qBAAD,CAA0C,oBAAqB,CAAA,GAE/D,EAAA,EAAA,KAAC,EAAA,aAAD,CAAmC,qBAAsB,CAAA,IAE7D,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,oDACZ,IAAkB,GAAa,KAC9B,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,sDACX,EAAA,EAAA,KAAC,OAAD,CAAA,SACG,GAAG,EAAA,gBAAgB,GAAiB,CAAS,EAAE,GAAG,EAAE,EAAA,QAAQ,gBAAgB,GACzE,CAAA,CACL,CAAA,CAEF,CAAA,CACF,GACF,GAET"}
1
+ {"version":3,"file":"conversation-card-footer.cjs","names":[],"sources":["../../../../../src/components/features/conversation-panel/conversation-card/conversation-card-footer.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { formatTimeDelta } from \"#/utils/format-time-delta\";\nimport { cn } from \"#/utils/utils\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { RepositorySelection } from \"#/api/open-hands.types\";\nimport { ExecutionStatus } from \"#/types/agent-server/core/base/common\";\nimport { isExecutionPaused } from \"#/utils/status\";\nimport {\n getAcpProviderDisplayName,\n labelForAcpModel,\n resolveAcpProviderIcon,\n} from \"#/constants/acp-providers\";\nimport { formatNativeModelName } from \"#/utils/format-model-name\";\nimport {\n AgentBrandIcon,\n type AgentBrandIconKind,\n} from \"#/components/shared/agent-brand-icon\";\nimport { getDisplayConversationTags } from \"#/api/agent-server-adapter\";\nimport { ConversationRepoLink } from \"./conversation-repo-link\";\nimport { NoRepository } from \"./no-repository\";\nimport { ConversationTagChips } from \"./conversation-tag-chips\";\nimport { CONVERSATION_CARD_META_CHIP_CLASSNAME } from \"./conversation-card-meta-chip\";\n\ninterface ConversationCardFooterProps {\n selectedRepository: RepositorySelection | null;\n lastUpdatedAt: string;\n createdAt?: string;\n executionStatus?: ExecutionStatus | null;\n workspaceWorkingDir?: string | null;\n showRepositoryMetadata?: boolean;\n showTimestamp?: boolean;\n llmModel?: string | null;\n /**\n * Whether to render the agent/model chip. Wired to the conversation\n * panel's \"LLM model\" toggle; gates the chip uniformly\n * for both ACP and OpenHands cards.\n */\n showAgentChip?: boolean;\n /**\n * High-level kind of the conversation's agent. Drives the chip's icon:\n * the OpenHands logo for native conversations and the resolved ACP brand\n * mark for ACP conversations. Defensive against stray ``acpServer``\n * values reaching an OpenHands card.\n */\n agentKind?: \"openhands\" | \"acp\" | null;\n /**\n * Registry key of the ACP CLI server (``\"claude-code\"`` / ``\"codex\"`` /\n * ``\"gemini-cli\"`` / unknown / null). Resolved to a human display name\n * via {@link getAcpProviderDisplayName}; unknown / null falls back to\n * a generic \"ACP\" label so a Custom-command preset still produces a\n * useful chip.\n */\n acpServer?: string | null;\n /**\n * Server-side conversation tags (``AppConversation.tags``). Non-reserved\n * entries render as value-only chips so API-/automation-born\n * conversations can surface attribution (e.g. ``origin: slack`` → ``slack``).\n */\n tags?: Record<string, string> | null;\n /**\n * Whether to render the tag-chip row. Wired to the conversation panel's\n * \"Tags\" toggle.\n */\n showTags?: boolean;\n}\n\nexport function ConversationCardFooter({\n selectedRepository,\n lastUpdatedAt,\n createdAt,\n executionStatus,\n workspaceWorkingDir,\n showRepositoryMetadata = true,\n showTimestamp = true,\n llmModel,\n showAgentChip = false,\n agentKind = null,\n acpServer = null,\n tags = null,\n showTags = false,\n}: ConversationCardFooterProps) {\n const { t } = useTranslation(\"openhands\");\n\n const isPaused = isExecutionPaused(executionStatus);\n\n // Single inline chip per conversation: [brand mark] {model text}. Gated by\n // the conversation panel's \"LLM model\" toggle and applied\n // uniformly to both kinds — OpenHands shows the logo + ``agent.llm.model``;\n // ACP shows the provider brand mark + model resolved through PR 730's\n // adapter chain, falling back to the provider display name when no model is\n // available so the chip never collapses to icon-only.\n let chip: {\n kind: AgentBrandIconKind;\n text: string;\n tooltip: string;\n } | null = null;\n if (showAgentChip) {\n if (agentKind === \"acp\") {\n const providerName =\n getAcpProviderDisplayName(acpServer) ??\n t(I18nKey.CONVERSATION$ACP_AGENT_GENERIC);\n // Prefer the provider's picker label (e.g. \"Claude Opus 4.7\") over the\n // raw ``acp_model`` ID; falls back to the raw ID for custom overrides\n // and to the provider name when there's no model at all.\n const modelLabel = labelForAcpModel(acpServer, llmModel);\n const text = modelLabel ?? providerName;\n chip = {\n kind: resolveAcpProviderIcon(acpServer),\n text,\n tooltip: modelLabel ? `${providerName} · ${modelLabel}` : providerName,\n };\n } else if (llmModel) {\n // Strip the routing prefix (e.g. \"anthropic/claude-…\" → \"claude-…\") for\n // the chip text; keep the full routing string in the tooltip.\n chip = {\n kind: \"openhands\",\n text: formatNativeModelName(llmModel) ?? llmModel,\n tooltip: llmModel,\n };\n }\n }\n\n // Match title text start: 18px status column + gap-2 (8px).\n const metadataIndentClass =\n executionStatus !== undefined ? \"pl-[26px]\" : undefined;\n\n const displayTags = showTags ? getDisplayConversationTags(tags) : [];\n\n return (\n <div\n className={cn(\n \"flex flex-col gap-0.5 mt-0.5 w-full min-w-0\",\n isPaused && \"opacity-60\",\n )}\n >\n <div\n className={cn(\n \"flex flex-row items-center gap-2 w-full min-w-0\",\n showRepositoryMetadata && metadataIndentClass,\n )}\n >\n {showRepositoryMetadata &&\n (selectedRepository?.selected_repository ? (\n <ConversationRepoLink selectedRepository={selectedRepository} />\n ) : (\n <NoRepository workspaceWorkingDir={workspaceWorkingDir} />\n ))}\n <div className=\"flex items-center gap-2 shrink-0 ml-auto\">\n {showTimestamp && (createdAt ?? lastUpdatedAt) && (\n <p className=\"text-xs text-[var(--oh-muted)] text-right\">\n <time>\n {`${formatTimeDelta(lastUpdatedAt ?? createdAt)} ${t(I18nKey.CONVERSATION$AGO)}`}\n </time>\n </p>\n )}\n </div>\n </div>\n {chip ? (\n <div className={metadataIndentClass}>\n <span\n data-testid=\"conversation-card-agent-chip\"\n className={CONVERSATION_CARD_META_CHIP_CLASSNAME}\n title={chip.tooltip}\n >\n {/* Same line-height slot as tag chips; width flexes for the wider OpenHands mark. */}\n <span\n className=\"inline-flex h-4 shrink-0 items-center justify-center [&_svg]:block\"\n aria-hidden\n >\n <AgentBrandIcon kind={chip.kind} size={12} />\n </span>\n <span className=\"truncate leading-4\">{chip.text}</span>\n </span>\n </div>\n ) : null}\n {displayTags.length > 0 ? (\n <div className={metadataIndentClass}>\n <ConversationTagChips tags={displayTags} />\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"0tBAkEA,SAAgB,EAAuB,CACrC,qBACA,gBACA,YACA,kBACA,sBACA,yBAAyB,GACzB,gBAAgB,GAChB,WACA,gBAAgB,GAChB,YAAY,KACZ,YAAY,KACZ,OAAO,KACP,WAAW,IACmB,CAC9B,GAAM,CAAE,KAAM,EAAA,eAAe,WAAW,EAElC,EAAW,EAAA,kBAAkB,CAAe,EAQ9C,EAIO,KACX,GAAI,KACE,IAAc,MAAO,CACvB,IAAM,EACJ,EAAA,0BAA0B,CAAS,GACnC,EAAE,EAAA,QAAQ,8BAA8B,EAIpC,EAAa,EAAA,iBAAiB,EAAW,CAAQ,EACjD,EAAO,GAAc,EAC3B,EAAO,CACL,KAAM,EAAA,uBAAuB,CAAS,EACtC,OACA,QAAS,EAAa,GAAG,EAAa,KAAK,IAAe,CAC5D,CACF,MAAW,IAGT,EAAO,CACL,KAAM,YACN,KAAM,EAAA,sBAAsB,CAAQ,GAAK,EACzC,QAAS,CACX,GAKJ,IAAM,EACJ,IAAoB,IAAA,GAA0B,IAAA,GAAd,YAE5B,EAAc,EAAW,EAAA,2BAA2B,CAAI,EAAI,CAAC,EAEnE,OACE,EAAA,EAAA,MAAC,MAAD,CACE,UAAW,EAAA,GACT,8CACA,GAAY,YACd,WAJF,EAME,EAAA,EAAA,MAAC,MAAD,CACE,UAAW,EAAA,GACT,kDACA,GAA0B,CAC5B,WAJF,CAMG,IACE,GAAoB,qBACnB,EAAA,EAAA,KAAC,EAAA,qBAAD,CAA0C,oBAAqB,CAAA,GAE/D,EAAA,EAAA,KAAC,EAAA,aAAD,CAAmC,qBAAsB,CAAA,IAE7D,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,oDACZ,IAAkB,GAAa,KAC9B,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,sDACX,EAAA,EAAA,KAAC,OAAD,CAAA,SACG,GAAG,EAAA,gBAAgB,GAAiB,CAAS,EAAE,GAAG,EAAE,EAAA,QAAQ,gBAAgB,GACzE,CAAA,CACL,CAAA,CAEF,CAAA,CACF,IACJ,GACC,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,YACd,EAAA,EAAA,MAAC,OAAD,CACE,cAAY,+BACZ,UAAW,EAAA,sCACX,MAAO,EAAK,iBAHd,EAME,EAAA,EAAA,KAAC,OAAD,CACE,UAAU,qEACV,cAAA,aAEA,EAAA,EAAA,KAAC,EAAA,eAAD,CAAgB,KAAM,EAAK,KAAM,KAAM,EAAK,CAAA,CACxC,CAAA,GACN,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,8BAAsB,EAAK,IAAW,CAAA,CAClD,GACH,CAAA,EACH,KACH,EAAY,OAAS,GACpB,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,YACd,EAAA,EAAA,KAAC,EAAA,qBAAD,CAAsB,KAAM,CAAc,CAAA,CACvC,CAAA,EACH,IACD,GAET"}
@@ -1,11 +1,5 @@
1
1
  import { RepositorySelection } from "#/api/open-hands.types";
2
2
  import { ExecutionStatus } from "#/types/agent-server/core/base/common";
3
- /**
4
- * Display budget for the tag-chip row. Tags are server-/API-controlled, so a
5
- * conversation can carry arbitrarily many; the card shows at most this many
6
- * chips (sorted by key) and folds the rest into a "+N" overflow chip.
7
- */
8
- export declare const MAX_VISIBLE_TAG_CHIPS = 3;
9
3
  interface ConversationCardFooterProps {
10
4
  selectedRepository: RepositorySelection | null;
11
5
  lastUpdatedAt: string;
@@ -38,8 +32,8 @@ interface ConversationCardFooterProps {
38
32
  acpServer?: string | null;
39
33
  /**
40
34
  * Server-side conversation tags (``AppConversation.tags``). Non-reserved
41
- * entries render as ``key: value`` chips so API-/automation-born
42
- * conversations can surface attribution (e.g. ``origin: slack``).
35
+ * entries render as value-only chips so API-/automation-born
36
+ * conversations can surface attribution (e.g. ``origin: slack`` → ``slack``).
43
37
  */
44
38
  tags?: Record<string, string> | null;
45
39
  /**
@@ -7,70 +7,67 @@ import { getDisplayConversationTags as s } from "../../../../api/agent-server-ad
7
7
  import { formatTimeDelta as c } from "../../../../utils/format-time-delta.js";
8
8
  import { formatNativeModelName as l } from "../../../../utils/format-model-name.js";
9
9
  import { AgentBrandIcon as u } from "../../../shared/agent-brand-icon.js";
10
- import { ConversationRepoLink as d } from "./conversation-repo-link.js";
11
- import { NoRepository as f } from "./no-repository.js";
12
- import { jsx as p, jsxs as m } from "react/jsx-runtime";
13
- function h({ selectedRepository: h, lastUpdatedAt: g, createdAt: _, executionStatus: v, workspaceWorkingDir: y, showRepositoryMetadata: b = !0, showTimestamp: x = !0, llmModel: S, showAgentChip: C = !1, agentKind: w = null, acpServer: T = null, tags: E = null, showTags: D = !1 }) {
14
- let { t: O } = e("openhands"), k = n(v), A = null;
15
- if (C) if (w === "acp") {
16
- let e = i(T) ?? O(t.CONVERSATION$ACP_AGENT_GENERIC), n = a(T, S), r = n ?? e;
17
- A = {
18
- kind: o(T),
10
+ import { CONVERSATION_CARD_META_CHIP_CLASSNAME as d } from "./conversation-card-meta-chip.js";
11
+ import { ConversationRepoLink as f } from "./conversation-repo-link.js";
12
+ import { NoRepository as p } from "./no-repository.js";
13
+ import { ConversationTagChips as m } from "./conversation-tag-chips.js";
14
+ import { jsx as h, jsxs as g } from "react/jsx-runtime";
15
+ //#region src/components/features/conversation-panel/conversation-card/conversation-card-footer.tsx
16
+ function _({ selectedRepository: _, lastUpdatedAt: v, createdAt: y, executionStatus: b, workspaceWorkingDir: x, showRepositoryMetadata: S = !0, showTimestamp: C = !0, llmModel: w, showAgentChip: T = !1, agentKind: E = null, acpServer: D = null, tags: O = null, showTags: k = !1 }) {
17
+ let { t: A } = e("openhands"), j = n(b), M = null;
18
+ if (T) if (E === "acp") {
19
+ let e = i(D) ?? A(t.CONVERSATION$ACP_AGENT_GENERIC), n = a(D, w), r = n ?? e;
20
+ M = {
21
+ kind: o(D),
19
22
  text: r,
20
23
  tooltip: n ? `${e} · ${n}` : e
21
24
  };
22
- } else S && (A = {
25
+ } else w && (M = {
23
26
  kind: "openhands",
24
- text: l(S) ?? S,
25
- tooltip: S
27
+ text: l(w) ?? w,
28
+ tooltip: w
26
29
  });
27
- let j = v === void 0 ? void 0 : "pl-[26px]", M = D ? s(E) : [], N = M.slice(0, 3), P = M.slice(3);
28
- return /* @__PURE__ */ m("div", {
29
- className: r("flex flex-col gap-0.5 mt-0.5 w-full min-w-0", k && "opacity-60"),
30
+ let N = b === void 0 ? void 0 : "pl-[26px]", P = k ? s(O) : [];
31
+ return /* @__PURE__ */ g("div", {
32
+ className: r("flex flex-col gap-0.5 mt-0.5 w-full min-w-0", j && "opacity-60"),
30
33
  children: [
31
- A ? /* @__PURE__ */ p("div", {
32
- className: j,
33
- children: /* @__PURE__ */ m("span", {
34
- "data-testid": "conversation-card-agent-chip",
35
- className: "inline-flex items-center gap-1 text-xs text-[var(--oh-muted)] max-w-full min-w-0",
36
- title: A.tooltip,
37
- children: [/* @__PURE__ */ p(u, { kind: A.kind }), /* @__PURE__ */ p("span", {
38
- className: "truncate",
39
- children: A.text
40
- })]
41
- })
42
- }) : null,
43
- M.length > 0 ? /* @__PURE__ */ m("div", {
44
- className: r("flex flex-row flex-wrap items-center gap-1 min-w-0", j),
45
- children: [N.map(([e, t]) => /* @__PURE__ */ p("span", {
46
- "data-testid": "conversation-card-tag-chip",
47
- title: `${e}: ${t}`,
48
- className: "inline-flex max-w-full min-w-0 items-center rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]",
49
- children: /* @__PURE__ */ p("span", {
50
- className: "truncate",
51
- children: `${e}: ${t}`
52
- })
53
- }, e)), P.length > 0 ? /* @__PURE__ */ p("span", {
54
- "data-testid": "conversation-card-tag-overflow",
55
- title: P.map(([e, t]) => `${e}: ${t}`).join("\n"),
56
- className: "inline-flex items-center rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]",
57
- children: `+${P.length}`
58
- }) : null]
59
- }) : null,
60
- /* @__PURE__ */ m("div", {
61
- className: r("flex flex-row items-center gap-2 w-full min-w-0", b && j),
62
- children: [b && (h?.selected_repository ? /* @__PURE__ */ p(d, { selectedRepository: h }) : /* @__PURE__ */ p(f, { workspaceWorkingDir: y })), /* @__PURE__ */ p("div", {
34
+ /* @__PURE__ */ g("div", {
35
+ className: r("flex flex-row items-center gap-2 w-full min-w-0", S && N),
36
+ children: [S && (_?.selected_repository ? /* @__PURE__ */ h(f, { selectedRepository: _ }) : /* @__PURE__ */ h(p, { workspaceWorkingDir: x })), /* @__PURE__ */ h("div", {
63
37
  className: "flex items-center gap-2 shrink-0 ml-auto",
64
- children: x && (_ ?? g) && /* @__PURE__ */ p("p", {
38
+ children: C && (y ?? v) && /* @__PURE__ */ h("p", {
65
39
  className: "text-xs text-[var(--oh-muted)] text-right",
66
- children: /* @__PURE__ */ p("time", { children: `${c(g ?? _)} ${O(t.CONVERSATION$AGO)}` })
40
+ children: /* @__PURE__ */ h("time", { children: `${c(v ?? y)} ${A(t.CONVERSATION$AGO)}` })
67
41
  })
68
42
  })]
69
- })
43
+ }),
44
+ M ? /* @__PURE__ */ h("div", {
45
+ className: N,
46
+ children: /* @__PURE__ */ g("span", {
47
+ "data-testid": "conversation-card-agent-chip",
48
+ className: d,
49
+ title: M.tooltip,
50
+ children: [/* @__PURE__ */ h("span", {
51
+ className: "inline-flex h-4 shrink-0 items-center justify-center [&_svg]:block",
52
+ "aria-hidden": !0,
53
+ children: /* @__PURE__ */ h(u, {
54
+ kind: M.kind,
55
+ size: 12
56
+ })
57
+ }), /* @__PURE__ */ h("span", {
58
+ className: "truncate leading-4",
59
+ children: M.text
60
+ })]
61
+ })
62
+ }) : null,
63
+ P.length > 0 ? /* @__PURE__ */ h("div", {
64
+ className: N,
65
+ children: /* @__PURE__ */ h(m, { tags: P })
66
+ }) : null
70
67
  ]
71
68
  });
72
69
  }
73
70
  //#endregion
74
- export { h as ConversationCardFooter };
71
+ export { _ as ConversationCardFooter };
75
72
 
76
73
  //# sourceMappingURL=conversation-card-footer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-card-footer.js","names":[],"sources":["../../../../../src/components/features/conversation-panel/conversation-card/conversation-card-footer.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { formatTimeDelta } from \"#/utils/format-time-delta\";\nimport { cn } from \"#/utils/utils\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { RepositorySelection } from \"#/api/open-hands.types\";\nimport { ExecutionStatus } from \"#/types/agent-server/core/base/common\";\nimport { isExecutionPaused } from \"#/utils/status\";\nimport {\n getAcpProviderDisplayName,\n labelForAcpModel,\n resolveAcpProviderIcon,\n} from \"#/constants/acp-providers\";\nimport { formatNativeModelName } from \"#/utils/format-model-name\";\nimport {\n AgentBrandIcon,\n type AgentBrandIconKind,\n} from \"#/components/shared/agent-brand-icon\";\nimport { getDisplayConversationTags } from \"#/api/agent-server-adapter\";\nimport { ConversationRepoLink } from \"./conversation-repo-link\";\nimport { NoRepository } from \"./no-repository\";\n\n/**\n * Display budget for the tag-chip row. Tags are server-/API-controlled, so a\n * conversation can carry arbitrarily many; the card shows at most this many\n * chips (sorted by key) and folds the rest into a \"+N\" overflow chip.\n */\nexport const MAX_VISIBLE_TAG_CHIPS = 3;\n\ninterface ConversationCardFooterProps {\n selectedRepository: RepositorySelection | null;\n lastUpdatedAt: string;\n createdAt?: string;\n executionStatus?: ExecutionStatus | null;\n workspaceWorkingDir?: string | null;\n showRepositoryMetadata?: boolean;\n showTimestamp?: boolean;\n llmModel?: string | null;\n /**\n * Whether to render the agent/model chip. Wired to the conversation\n * panel's \"LLM model\" toggle; gates the chip uniformly\n * for both ACP and OpenHands cards.\n */\n showAgentChip?: boolean;\n /**\n * High-level kind of the conversation's agent. Drives the chip's icon:\n * the OpenHands logo for native conversations and the resolved ACP brand\n * mark for ACP conversations. Defensive against stray ``acpServer``\n * values reaching an OpenHands card.\n */\n agentKind?: \"openhands\" | \"acp\" | null;\n /**\n * Registry key of the ACP CLI server (``\"claude-code\"`` / ``\"codex\"`` /\n * ``\"gemini-cli\"`` / unknown / null). Resolved to a human display name\n * via {@link getAcpProviderDisplayName}; unknown / null falls back to\n * a generic \"ACP\" label so a Custom-command preset still produces a\n * useful chip.\n */\n acpServer?: string | null;\n /**\n * Server-side conversation tags (``AppConversation.tags``). Non-reserved\n * entries render as ``key: value`` chips so API-/automation-born\n * conversations can surface attribution (e.g. ``origin: slack``).\n */\n tags?: Record<string, string> | null;\n /**\n * Whether to render the tag-chip row. Wired to the conversation panel's\n * \"Tags\" toggle.\n */\n showTags?: boolean;\n}\n\nexport function ConversationCardFooter({\n selectedRepository,\n lastUpdatedAt,\n createdAt,\n executionStatus,\n workspaceWorkingDir,\n showRepositoryMetadata = true,\n showTimestamp = true,\n llmModel,\n showAgentChip = false,\n agentKind = null,\n acpServer = null,\n tags = null,\n showTags = false,\n}: ConversationCardFooterProps) {\n const { t } = useTranslation(\"openhands\");\n\n const isPaused = isExecutionPaused(executionStatus);\n\n // Single inline chip per conversation: [brand mark] {model text}. Gated by\n // the conversation panel's \"LLM model\" toggle and applied\n // uniformly to both kinds — OpenHands shows the logo + ``agent.llm.model``;\n // ACP shows the provider brand mark + model resolved through PR 730's\n // adapter chain, falling back to the provider display name when no model is\n // available so the chip never collapses to icon-only.\n let chip: {\n kind: AgentBrandIconKind;\n text: string;\n tooltip: string;\n } | null = null;\n if (showAgentChip) {\n if (agentKind === \"acp\") {\n const providerName =\n getAcpProviderDisplayName(acpServer) ??\n t(I18nKey.CONVERSATION$ACP_AGENT_GENERIC);\n // Prefer the provider's picker label (e.g. \"Claude Opus 4.7\") over the\n // raw ``acp_model`` ID; falls back to the raw ID for custom overrides\n // and to the provider name when there's no model at all.\n const modelLabel = labelForAcpModel(acpServer, llmModel);\n const text = modelLabel ?? providerName;\n chip = {\n kind: resolveAcpProviderIcon(acpServer),\n text,\n tooltip: modelLabel ? `${providerName} · ${modelLabel}` : providerName,\n };\n } else if (llmModel) {\n // Strip the routing prefix (e.g. \"anthropic/claude-…\" → \"claude-…\") for\n // the chip text; keep the full routing string in the tooltip.\n chip = {\n kind: \"openhands\",\n text: formatNativeModelName(llmModel) ?? llmModel,\n tooltip: llmModel,\n };\n }\n }\n\n // Match title text start: 18px status column + gap-2 (8px).\n const metadataIndentClass =\n executionStatus !== undefined ? \"pl-[26px]\" : undefined;\n\n const displayTags = showTags ? getDisplayConversationTags(tags) : [];\n // Tags are API-controlled with no server-side count bound, so the card\n // renders a fixed display budget: the first chips in sorted-key order plus\n // a \"+N\" affordance whose tooltip reveals the remainder. The full map stays\n // on ``AppConversation.tags`` for non-display consumers.\n const visibleTags = displayTags.slice(0, MAX_VISIBLE_TAG_CHIPS);\n const overflowTags = displayTags.slice(MAX_VISIBLE_TAG_CHIPS);\n\n return (\n <div\n className={cn(\n \"flex flex-col gap-0.5 mt-0.5 w-full min-w-0\",\n isPaused && \"opacity-60\",\n )}\n >\n {chip ? (\n <div className={metadataIndentClass}>\n <span\n data-testid=\"conversation-card-agent-chip\"\n className=\"inline-flex items-center gap-1 text-xs text-[var(--oh-muted)] max-w-full min-w-0\"\n title={chip.tooltip}\n >\n <AgentBrandIcon kind={chip.kind} />\n <span className=\"truncate\">{chip.text}</span>\n </span>\n </div>\n ) : null}\n {displayTags.length > 0 ? (\n <div\n className={cn(\n \"flex flex-row flex-wrap items-center gap-1 min-w-0\",\n metadataIndentClass,\n )}\n >\n {visibleTags.map(([key, value]) => (\n <span\n key={key}\n data-testid=\"conversation-card-tag-chip\"\n title={`${key}: ${value}`}\n className=\"inline-flex max-w-full min-w-0 items-center rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]\"\n >\n <span className=\"truncate\">{`${key}: ${value}`}</span>\n </span>\n ))}\n {overflowTags.length > 0 ? (\n <span\n data-testid=\"conversation-card-tag-overflow\"\n title={overflowTags\n .map(([key, value]) => `${key}: ${value}`)\n .join(\"\\n\")}\n className=\"inline-flex items-center rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]\"\n >\n {`+${overflowTags.length}`}\n </span>\n ) : null}\n </div>\n ) : null}\n <div\n className={cn(\n \"flex flex-row items-center gap-2 w-full min-w-0\",\n showRepositoryMetadata && metadataIndentClass,\n )}\n >\n {showRepositoryMetadata &&\n (selectedRepository?.selected_repository ? (\n <ConversationRepoLink selectedRepository={selectedRepository} />\n ) : (\n <NoRepository workspaceWorkingDir={workspaceWorkingDir} />\n ))}\n <div className=\"flex items-center gap-2 shrink-0 ml-auto\">\n {showTimestamp && (createdAt ?? lastUpdatedAt) && (\n <p className=\"text-xs text-[var(--oh-muted)] text-right\">\n <time>\n {`${formatTimeDelta(lastUpdatedAt ?? createdAt)} ${t(I18nKey.CONVERSATION$AGO)}`}\n </time>\n </p>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAuEA,SAAgB,EAAuB,EACrC,uBACA,kBACA,cACA,oBACA,wBACA,4BAAyB,IACzB,mBAAgB,IAChB,aACA,mBAAgB,IAChB,eAAY,MACZ,eAAY,MACZ,UAAO,MACP,cAAW,MACmB;CAC9B,IAAM,EAAE,SAAM,EAAe,WAAW,GAElC,IAAW,EAAkB,CAAe,GAQ9C,IAIO;CACX,IAAI,OACE,MAAc,OAAO;EACvB,IAAM,IACJ,EAA0B,CAAS,KACnC,EAAE,EAAQ,8BAA8B,GAIpC,IAAa,EAAiB,GAAW,CAAQ,GACjD,IAAO,KAAc;EAC3B,IAAO;GACL,MAAM,EAAuB,CAAS;GACtC;GACA,SAAS,IAAa,GAAG,EAAa,KAAK,MAAe;EAC5D;CACF,OAAO,AAAI,MAGT,IAAO;EACL,MAAM;EACN,MAAM,EAAsB,CAAQ,KAAK;EACzC,SAAS;CACX;CAKJ,IAAM,IACJ,MAAoB,KAAA,IAA0B,KAAA,IAAd,aAE5B,IAAc,IAAW,EAA2B,CAAI,IAAI,CAAC,GAK7D,IAAc,EAAY,MAAM,GAAA,CAAwB,GACxD,IAAe,EAAY,MAAA,CAA2B;CAE5D,OACE,kBAAC,OAAD;EACE,WAAW,EACT,+CACA,KAAY,YACd;YAJF;GAMG,IACC,kBAAC,OAAD;IAAK,WAAW;cACd,kBAAC,QAAD;KACE,eAAY;KACZ,WAAU;KACV,OAAO,EAAK;eAHd,CAKE,kBAAC,GAAD,EAAgB,MAAM,EAAK,KAAO,CAAA,GAClC,kBAAC,QAAD;MAAM,WAAU;gBAAY,EAAK;KAAW,CAAA,CACxC;;GACH,CAAA,IACH;GACH,EAAY,SAAS,IACpB,kBAAC,OAAD;IACE,WAAW,EACT,sDACA,CACF;cAJF,CAMG,EAAY,KAAK,CAAC,GAAK,OACtB,kBAAC,QAAD;KAEE,eAAY;KACZ,OAAO,GAAG,EAAI,IAAI;KAClB,WAAU;eAEV,kBAAC,QAAD;MAAM,WAAU;gBAAY,GAAG,EAAI,IAAI;KAAc,CAAA;IACjD,GANC,CAMD,CACP,GACA,EAAa,SAAS,IACrB,kBAAC,QAAD;KACE,eAAY;KACZ,OAAO,EACJ,KAAK,CAAC,GAAK,OAAW,GAAG,EAAI,IAAI,GAAO,EACxC,KAAK,IAAI;KACZ,WAAU;eAET,IAAI,EAAa;IACd,CAAA,IACJ,IACD;QACH;GACJ,kBAAC,OAAD;IACE,WAAW,EACT,mDACA,KAA0B,CAC5B;cAJF,CAMG,MACE,GAAoB,sBACnB,kBAAC,GAAD,EAA0C,sBAAqB,CAAA,IAE/D,kBAAC,GAAD,EAAmC,uBAAsB,CAAA,IAE7D,kBAAC,OAAD;KAAK,WAAU;eACZ,MAAkB,KAAa,MAC9B,kBAAC,KAAD;MAAG,WAAU;gBACX,kBAAC,QAAD,EAAA,UACG,GAAG,EAAgB,KAAiB,CAAS,EAAE,GAAG,EAAE,EAAQ,gBAAgB,IACzE,CAAA;KACL,CAAA;IAEF,CAAA,CACF;;EACF;;AAET"}
1
+ {"version":3,"file":"conversation-card-footer.js","names":[],"sources":["../../../../../src/components/features/conversation-panel/conversation-card/conversation-card-footer.tsx"],"sourcesContent":["import { useTranslation } from \"react-i18next\";\nimport { formatTimeDelta } from \"#/utils/format-time-delta\";\nimport { cn } from \"#/utils/utils\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { RepositorySelection } from \"#/api/open-hands.types\";\nimport { ExecutionStatus } from \"#/types/agent-server/core/base/common\";\nimport { isExecutionPaused } from \"#/utils/status\";\nimport {\n getAcpProviderDisplayName,\n labelForAcpModel,\n resolveAcpProviderIcon,\n} from \"#/constants/acp-providers\";\nimport { formatNativeModelName } from \"#/utils/format-model-name\";\nimport {\n AgentBrandIcon,\n type AgentBrandIconKind,\n} from \"#/components/shared/agent-brand-icon\";\nimport { getDisplayConversationTags } from \"#/api/agent-server-adapter\";\nimport { ConversationRepoLink } from \"./conversation-repo-link\";\nimport { NoRepository } from \"./no-repository\";\nimport { ConversationTagChips } from \"./conversation-tag-chips\";\nimport { CONVERSATION_CARD_META_CHIP_CLASSNAME } from \"./conversation-card-meta-chip\";\n\ninterface ConversationCardFooterProps {\n selectedRepository: RepositorySelection | null;\n lastUpdatedAt: string;\n createdAt?: string;\n executionStatus?: ExecutionStatus | null;\n workspaceWorkingDir?: string | null;\n showRepositoryMetadata?: boolean;\n showTimestamp?: boolean;\n llmModel?: string | null;\n /**\n * Whether to render the agent/model chip. Wired to the conversation\n * panel's \"LLM model\" toggle; gates the chip uniformly\n * for both ACP and OpenHands cards.\n */\n showAgentChip?: boolean;\n /**\n * High-level kind of the conversation's agent. Drives the chip's icon:\n * the OpenHands logo for native conversations and the resolved ACP brand\n * mark for ACP conversations. Defensive against stray ``acpServer``\n * values reaching an OpenHands card.\n */\n agentKind?: \"openhands\" | \"acp\" | null;\n /**\n * Registry key of the ACP CLI server (``\"claude-code\"`` / ``\"codex\"`` /\n * ``\"gemini-cli\"`` / unknown / null). Resolved to a human display name\n * via {@link getAcpProviderDisplayName}; unknown / null falls back to\n * a generic \"ACP\" label so a Custom-command preset still produces a\n * useful chip.\n */\n acpServer?: string | null;\n /**\n * Server-side conversation tags (``AppConversation.tags``). Non-reserved\n * entries render as value-only chips so API-/automation-born\n * conversations can surface attribution (e.g. ``origin: slack`` → ``slack``).\n */\n tags?: Record<string, string> | null;\n /**\n * Whether to render the tag-chip row. Wired to the conversation panel's\n * \"Tags\" toggle.\n */\n showTags?: boolean;\n}\n\nexport function ConversationCardFooter({\n selectedRepository,\n lastUpdatedAt,\n createdAt,\n executionStatus,\n workspaceWorkingDir,\n showRepositoryMetadata = true,\n showTimestamp = true,\n llmModel,\n showAgentChip = false,\n agentKind = null,\n acpServer = null,\n tags = null,\n showTags = false,\n}: ConversationCardFooterProps) {\n const { t } = useTranslation(\"openhands\");\n\n const isPaused = isExecutionPaused(executionStatus);\n\n // Single inline chip per conversation: [brand mark] {model text}. Gated by\n // the conversation panel's \"LLM model\" toggle and applied\n // uniformly to both kinds — OpenHands shows the logo + ``agent.llm.model``;\n // ACP shows the provider brand mark + model resolved through PR 730's\n // adapter chain, falling back to the provider display name when no model is\n // available so the chip never collapses to icon-only.\n let chip: {\n kind: AgentBrandIconKind;\n text: string;\n tooltip: string;\n } | null = null;\n if (showAgentChip) {\n if (agentKind === \"acp\") {\n const providerName =\n getAcpProviderDisplayName(acpServer) ??\n t(I18nKey.CONVERSATION$ACP_AGENT_GENERIC);\n // Prefer the provider's picker label (e.g. \"Claude Opus 4.7\") over the\n // raw ``acp_model`` ID; falls back to the raw ID for custom overrides\n // and to the provider name when there's no model at all.\n const modelLabel = labelForAcpModel(acpServer, llmModel);\n const text = modelLabel ?? providerName;\n chip = {\n kind: resolveAcpProviderIcon(acpServer),\n text,\n tooltip: modelLabel ? `${providerName} · ${modelLabel}` : providerName,\n };\n } else if (llmModel) {\n // Strip the routing prefix (e.g. \"anthropic/claude-…\" → \"claude-…\") for\n // the chip text; keep the full routing string in the tooltip.\n chip = {\n kind: \"openhands\",\n text: formatNativeModelName(llmModel) ?? llmModel,\n tooltip: llmModel,\n };\n }\n }\n\n // Match title text start: 18px status column + gap-2 (8px).\n const metadataIndentClass =\n executionStatus !== undefined ? \"pl-[26px]\" : undefined;\n\n const displayTags = showTags ? getDisplayConversationTags(tags) : [];\n\n return (\n <div\n className={cn(\n \"flex flex-col gap-0.5 mt-0.5 w-full min-w-0\",\n isPaused && \"opacity-60\",\n )}\n >\n <div\n className={cn(\n \"flex flex-row items-center gap-2 w-full min-w-0\",\n showRepositoryMetadata && metadataIndentClass,\n )}\n >\n {showRepositoryMetadata &&\n (selectedRepository?.selected_repository ? (\n <ConversationRepoLink selectedRepository={selectedRepository} />\n ) : (\n <NoRepository workspaceWorkingDir={workspaceWorkingDir} />\n ))}\n <div className=\"flex items-center gap-2 shrink-0 ml-auto\">\n {showTimestamp && (createdAt ?? lastUpdatedAt) && (\n <p className=\"text-xs text-[var(--oh-muted)] text-right\">\n <time>\n {`${formatTimeDelta(lastUpdatedAt ?? createdAt)} ${t(I18nKey.CONVERSATION$AGO)}`}\n </time>\n </p>\n )}\n </div>\n </div>\n {chip ? (\n <div className={metadataIndentClass}>\n <span\n data-testid=\"conversation-card-agent-chip\"\n className={CONVERSATION_CARD_META_CHIP_CLASSNAME}\n title={chip.tooltip}\n >\n {/* Same line-height slot as tag chips; width flexes for the wider OpenHands mark. */}\n <span\n className=\"inline-flex h-4 shrink-0 items-center justify-center [&_svg]:block\"\n aria-hidden\n >\n <AgentBrandIcon kind={chip.kind} size={12} />\n </span>\n <span className=\"truncate leading-4\">{chip.text}</span>\n </span>\n </div>\n ) : null}\n {displayTags.length > 0 ? (\n <div className={metadataIndentClass}>\n <ConversationTagChips tags={displayTags} />\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkEA,SAAgB,EAAuB,EACrC,uBACA,kBACA,cACA,oBACA,wBACA,4BAAyB,IACzB,mBAAgB,IAChB,aACA,mBAAgB,IAChB,eAAY,MACZ,eAAY,MACZ,UAAO,MACP,cAAW,MACmB;CAC9B,IAAM,EAAE,SAAM,EAAe,WAAW,GAElC,IAAW,EAAkB,CAAe,GAQ9C,IAIO;CACX,IAAI,OACE,MAAc,OAAO;EACvB,IAAM,IACJ,EAA0B,CAAS,KACnC,EAAE,EAAQ,8BAA8B,GAIpC,IAAa,EAAiB,GAAW,CAAQ,GACjD,IAAO,KAAc;EAC3B,IAAO;GACL,MAAM,EAAuB,CAAS;GACtC;GACA,SAAS,IAAa,GAAG,EAAa,KAAK,MAAe;EAC5D;CACF,OAAO,AAAI,MAGT,IAAO;EACL,MAAM;EACN,MAAM,EAAsB,CAAQ,KAAK;EACzC,SAAS;CACX;CAKJ,IAAM,IACJ,MAAoB,KAAA,IAA0B,KAAA,IAAd,aAE5B,IAAc,IAAW,EAA2B,CAAI,IAAI,CAAC;CAEnE,OACE,kBAAC,OAAD;EACE,WAAW,EACT,+CACA,KAAY,YACd;YAJF;GAME,kBAAC,OAAD;IACE,WAAW,EACT,mDACA,KAA0B,CAC5B;cAJF,CAMG,MACE,GAAoB,sBACnB,kBAAC,GAAD,EAA0C,sBAAqB,CAAA,IAE/D,kBAAC,GAAD,EAAmC,uBAAsB,CAAA,IAE7D,kBAAC,OAAD;KAAK,WAAU;eACZ,MAAkB,KAAa,MAC9B,kBAAC,KAAD;MAAG,WAAU;gBACX,kBAAC,QAAD,EAAA,UACG,GAAG,EAAgB,KAAiB,CAAS,EAAE,GAAG,EAAE,EAAQ,gBAAgB,IACzE,CAAA;KACL,CAAA;IAEF,CAAA,CACF;;GACJ,IACC,kBAAC,OAAD;IAAK,WAAW;cACd,kBAAC,QAAD;KACE,eAAY;KACZ,WAAW;KACX,OAAO,EAAK;eAHd,CAME,kBAAC,QAAD;MACE,WAAU;MACV,eAAA;gBAEA,kBAAC,GAAD;OAAgB,MAAM,EAAK;OAAM,MAAM;MAAK,CAAA;KACxC,CAAA,GACN,kBAAC,QAAD;MAAM,WAAU;gBAAsB,EAAK;KAAW,CAAA,CAClD;;GACH,CAAA,IACH;GACH,EAAY,SAAS,IACpB,kBAAC,OAAD;IAAK,WAAW;cACd,kBAAC,GAAD,EAAsB,MAAM,EAAc,CAAA;GACvC,CAAA,IACH;EACD;;AAET"}
@@ -0,0 +1,2 @@
1
+ require("../../../../_virtual/_rolldown/runtime.cjs");var e=`inline-flex max-w-full min-w-0 shrink-0 items-center gap-0.5 rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]`,t=`inline-flex h-4 w-3 shrink-0 items-center justify-center [&_svg]:block`,n=`h-3 w-3`;exports.CONVERSATION_CARD_META_CHIP_CLASSNAME=e,exports.CONVERSATION_CARD_META_CHIP_ICON_CLASSNAME=n,exports.CONVERSATION_CARD_META_CHIP_ICON_SLOT_CLASSNAME=t;
2
+ //# sourceMappingURL=conversation-card-meta-chip.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-card-meta-chip.cjs","names":[],"sources":["../../../../../src/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.ts"],"sourcesContent":["/**\n * Shared raised-pill class for conversation-card metadata chips (LLM model,\n * tags, repo, branch, workspace folder). Keep these visually identical so the\n * footer reads as one chip system.\n */\nexport const CONVERSATION_CARD_META_CHIP_CLASSNAME =\n \"inline-flex max-w-full min-w-0 shrink-0 items-center gap-0.5 rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]\";\n\n/**\n * Fixed line-height icon slot matching ``leading-4`` chip text so Lucide /\n * react-icons / local SVGs share the same optical center.\n */\nexport const CONVERSATION_CARD_META_CHIP_ICON_SLOT_CLASSNAME =\n \"inline-flex h-4 w-3 shrink-0 items-center justify-center [&_svg]:block\";\n\nexport const CONVERSATION_CARD_META_CHIP_ICON_CLASSNAME = \"h-3 w-3\";\n"],"mappings":"sDAKA,IAAa,EACX,gKAMW,EACX,yEAEW,EAA6C"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shared raised-pill class for conversation-card metadata chips (LLM model,
3
+ * tags, repo, branch, workspace folder). Keep these visually identical so the
4
+ * footer reads as one chip system.
5
+ */
6
+ export declare const CONVERSATION_CARD_META_CHIP_CLASSNAME = "inline-flex max-w-full min-w-0 shrink-0 items-center gap-0.5 rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]";
7
+ /**
8
+ * Fixed line-height icon slot matching ``leading-4`` chip text so Lucide /
9
+ * react-icons / local SVGs share the same optical center.
10
+ */
11
+ export declare const CONVERSATION_CARD_META_CHIP_ICON_SLOT_CLASSNAME = "inline-flex h-4 w-3 shrink-0 items-center justify-center [&_svg]:block";
12
+ export declare const CONVERSATION_CARD_META_CHIP_ICON_CLASSNAME = "h-3 w-3";
@@ -0,0 +1,6 @@
1
+ //#region src/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.ts
2
+ var e = "inline-flex max-w-full min-w-0 shrink-0 items-center gap-0.5 rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]", t = "inline-flex h-4 w-3 shrink-0 items-center justify-center [&_svg]:block", n = "h-3 w-3";
3
+ //#endregion
4
+ export { e as CONVERSATION_CARD_META_CHIP_CLASSNAME, n as CONVERSATION_CARD_META_CHIP_ICON_CLASSNAME, t as CONVERSATION_CARD_META_CHIP_ICON_SLOT_CLASSNAME };
5
+
6
+ //# sourceMappingURL=conversation-card-meta-chip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-card-meta-chip.js","names":[],"sources":["../../../../../src/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.ts"],"sourcesContent":["/**\n * Shared raised-pill class for conversation-card metadata chips (LLM model,\n * tags, repo, branch, workspace folder). Keep these visually identical so the\n * footer reads as one chip system.\n */\nexport const CONVERSATION_CARD_META_CHIP_CLASSNAME =\n \"inline-flex max-w-full min-w-0 shrink-0 items-center gap-0.5 rounded-sm bg-[var(--oh-surface-raised)] px-1 py-px text-[10px] leading-4 text-[var(--oh-muted)]\";\n\n/**\n * Fixed line-height icon slot matching ``leading-4`` chip text so Lucide /\n * react-icons / local SVGs share the same optical center.\n */\nexport const CONVERSATION_CARD_META_CHIP_ICON_SLOT_CLASSNAME =\n \"inline-flex h-4 w-3 shrink-0 items-center justify-center [&_svg]:block\";\n\nexport const CONVERSATION_CARD_META_CHIP_ICON_CLASSNAME = \"h-3 w-3\";\n"],"mappings":";AAKA,IAAa,IACX,iKAMW,IACX,0EAEW,IAA6C"}
@@ -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("../../../../node_modules/lucide-react/dist/esm/icons/folder.cjs"),r=require("../../../../node_modules/react-icons/fa/index.cjs"),i=require("../../../../node_modules/react-icons/fa6/index.cjs"),a=require("../../../../assets/branding/azure-devops-logo.cjs"),o=require("../conversation-status-dot.cjs");let s=require("react/jsx-runtime");var c={bitbucket:i.FaBitbucket,bitbucket_data_center:i.FaBitbucket,github:i.FaGithub,gitlab:i.FaGitlab};function l({label:e,children:t}){return(0,s.jsxs)(`div`,{className:`flex items-start gap-2 text-xs`,children:[(0,s.jsx)(`span`,{className:`w-20 shrink-0 text-[var(--oh-muted)]`,children:e}),(0,s.jsx)(`span`,{className:`min-w-0 flex-1 break-words text-[var(--oh-foreground)]`,children:t})]})}function u({title:i,executionStatus:u,sandboxStatus:d,selectedRepository:f,workspaceWorkingDir:p,llmModel:m,createdAt:h}){let{t:g}=e.useTranslation(`openhands`),_=f?.selected_repository??null,v=f?.selected_branch??null,y=f?.git_provider??null,b=y?c[y]:null,x=h?new Date(h).toLocaleString(void 0,{dateStyle:`medium`,timeStyle:`short`}):null;return(0,s.jsxs)(`div`,{className:`flex w-[280px] flex-col gap-3 p-3`,children:[(0,s.jsxs)(`div`,{className:`flex items-start gap-2`,children:[u===void 0?null:(0,s.jsx)(`div`,{className:`mt-0.5`,children:(0,s.jsx)(o.ConversationStatusDot,{executionStatus:u,sandboxStatus:d,showTooltip:!1})}),(0,s.jsx)(`span`,{className:`break-words text-sm font-medium text-white`,children:i})]}),(0,s.jsxs)(`dl`,{className:`flex flex-col gap-1.5`,children:[_?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(l,{label:g(t.I18nKey.CONVERSATION$REPOSITORY),children:(0,s.jsxs)(`span`,{className:`inline-flex min-w-0 items-start gap-1.5`,children:[b?(0,s.jsx)(b,{size:12,className:`mt-0.5 shrink-0`}):null,y===`azure_devops`?(0,s.jsx)(a.default,{className:`mt-0.5 h-3 w-3 shrink-0`}):null,(0,s.jsx)(`span`,{className:`break-all`,children:_})]})}),v?(0,s.jsx)(l,{label:g(t.I18nKey.CONVERSATION$BRANCH),children:(0,s.jsxs)(`span`,{className:`inline-flex min-w-0 items-start gap-1.5`,children:[(0,s.jsx)(r.FaCodeBranch,{size:11,className:`mt-0.5 shrink-0`}),(0,s.jsx)(`span`,{className:`break-all`,children:v})]})}):null]}):p?(0,s.jsx)(l,{label:g(t.I18nKey.CONVERSATION_PANEL$PREVIEW_DIRECTORY),children:(0,s.jsxs)(`span`,{className:`inline-flex min-w-0 items-start gap-1.5`,children:[(0,s.jsx)(n.Folder,{size:12,className:`mt-0.5 shrink-0`}),(0,s.jsx)(`span`,{className:`break-all`,children:p})]})}):null,m?(0,s.jsx)(l,{label:g(t.I18nKey.CONVERSATION_PANEL$PREVIEW_MODEL),children:(0,s.jsx)(`span`,{className:`break-all`,children:m})}):null,x?(0,s.jsx)(l,{label:g(t.I18nKey.CONVERSATION$CREATED),children:x}):null]})]})}exports.ConversationCardPreview=u;
1
+ require("../../../../_virtual/_rolldown/runtime.cjs");const e=require("../../../../node_modules/react-i18next/dist/es/useTranslation.cjs"),t=require("../../../../i18n/declaration.cjs"),n=require("../../../../node_modules/lucide-react/dist/esm/icons/folder.cjs"),r=require("../../../../constants/acp-providers.cjs"),i=require("../../../../api/agent-server-adapter.cjs"),a=require("../../../../node_modules/react-icons/fa/index.cjs"),o=require("../../../../node_modules/react-icons/fa6/index.cjs"),s=require("../../../../assets/branding/azure-devops-logo.cjs"),c=require("../conversation-status-dot.cjs"),l=require("../../../shared/agent-brand-icon.cjs"),u=require("./conversation-tag-display.cjs"),d=require("./conversation-tag-icons.cjs");let f=require("react/jsx-runtime");var p={bitbucket:o.FaBitbucket,bitbucket_data_center:o.FaBitbucket,github:o.FaGithub,gitlab:o.FaGitlab};function m({label:e,children:t}){return(0,f.jsxs)(`div`,{className:`flex items-start gap-2 text-xs leading-4`,children:[(0,f.jsx)(`span`,{className:`w-20 shrink-0 whitespace-normal break-words text-[var(--oh-muted)]`,children:e}),(0,f.jsx)(`span`,{className:`min-w-0 flex-1 overflow-visible whitespace-normal break-words text-[var(--oh-foreground)]`,children:t})]})}function h({icon:e,children:t,testId:n,tagKey:r}){return(0,f.jsxs)(`span`,{"data-testid":n,"data-tag-key":r,className:`inline-flex min-w-0 max-w-full items-start gap-1.5`,children:[e?(0,f.jsx)(`span`,{className:`inline-flex h-4 min-w-3 shrink-0 items-center justify-center [&_svg]:block`,children:e}):null,(0,f.jsx)(`span`,{className:`min-w-0 flex-1 whitespace-normal break-all`,children:t})]})}function g({title:o,executionStatus:g,sandboxStatus:_,selectedRepository:v,workspaceWorkingDir:y,llmModel:b,agentKind:x=null,acpServer:S=null,createdAt:C,tags:w=null}){let{t:T}=e.useTranslation(`openhands`),E=v?.selected_repository??null,D=v?.selected_branch??null,O=v?.git_provider??null,k=O?p[O]:null,A=C?new Date(C).toLocaleString(void 0,{dateStyle:`medium`,timeStyle:`short`}):null,j=i.getDisplayConversationTags(w);return(0,f.jsxs)(`div`,{"data-testid":`conversation-card-preview`,className:`flex w-[280px] max-w-[min(280px,90vw)] flex-col gap-3 overflow-visible p-3`,children:[(0,f.jsxs)(`div`,{className:`flex items-start gap-2`,children:[g===void 0?null:(0,f.jsx)(`span`,{className:`inline-flex h-5 w-2.5 shrink-0 items-center justify-center`,children:(0,f.jsx)(c.ConversationStatusDot,{executionStatus:g,sandboxStatus:_,showTooltip:!1})}),(0,f.jsx)(`span`,{className:`break-words text-sm font-medium leading-5 text-white`,children:o})]}),(0,f.jsxs)(`dl`,{className:`flex flex-col gap-1.5`,children:[E?(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(m,{label:T(t.I18nKey.CONVERSATION_PANEL$PREVIEW_REPO),children:(0,f.jsx)(h,{icon:k?(0,f.jsx)(k,{size:12}):O===`azure_devops`?(0,f.jsx)(s.default,{className:`h-3 w-3`}):void 0,children:E})}),D?(0,f.jsx)(m,{label:T(t.I18nKey.CONVERSATION_PANEL$PREVIEW_BRANCH),children:(0,f.jsx)(h,{icon:(0,f.jsx)(a.FaCodeBranch,{size:11}),children:D})}):null]}):y?(0,f.jsx)(m,{label:T(t.I18nKey.CONVERSATION_PANEL$PREVIEW_DIRECTORY),children:(0,f.jsx)(h,{icon:(0,f.jsx)(n.Folder,{size:12}),children:y})}):null,b?(0,f.jsx)(m,{label:T(t.I18nKey.CONVERSATION_PANEL$PREVIEW_MODEL),children:(0,f.jsx)(h,{testId:`conversation-card-preview-model`,icon:(0,f.jsx)(l.AgentBrandIcon,{kind:x===`acp`?r.resolveAcpProviderIcon(S):`openhands`,size:12}),children:b})}):null,j.map(([e,t])=>{let n=d.getConversationTagIcon(e,t);return(0,f.jsx)(m,{label:u.getConversationTagLabel(e,T),children:(0,f.jsx)(h,{testId:`conversation-card-preview-tag-row`,tagKey:e,icon:(0,f.jsx)(n,{"aria-hidden":!0,className:`h-3 w-3`}),children:t})},e)}),A?(0,f.jsx)(m,{label:T(t.I18nKey.CONVERSATION$CREATED),children:A}):null]})]})}exports.ConversationCardPreview=g;
2
2
  //# sourceMappingURL=conversation-card-preview.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-card-preview.cjs","names":[],"sources":["../../../../../src/components/features/conversation-panel/conversation-card/conversation-card-preview.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Folder } from \"lucide-react\";\nimport { FaBitbucket, FaGithub, FaGitlab } from \"react-icons/fa6\";\nimport { FaCodeBranch } from \"react-icons/fa\";\nimport type { IconType } from \"react-icons/lib\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport type { RepositorySelection } from \"#/api/open-hands.types\";\nimport type { Provider } from \"#/types/settings\";\nimport type { ExecutionStatus } from \"#/types/agent-server/core/base/common\";\nimport type { SandboxStatus } from \"#/api/conversation-service/agent-server-conversation-service.types\";\nimport AzureDevOpsLogo from \"#/assets/branding/azure-devops-logo.svg?react\";\nimport { ConversationStatusDot } from \"../conversation-status-dot\";\n\ninterface ConversationCardPreviewProps {\n title: string;\n executionStatus?: ExecutionStatus | null;\n sandboxStatus?: SandboxStatus | null;\n selectedRepository: RepositorySelection | null;\n workspaceWorkingDir?: string | null;\n llmModel?: string | null;\n createdAt?: string;\n}\n\nconst providerIcon: Partial<Record<Provider, IconType>> = {\n bitbucket: FaBitbucket,\n bitbucket_data_center: FaBitbucket,\n github: FaGithub,\n gitlab: FaGitlab,\n};\n\ninterface PreviewRowProps {\n label: string;\n children: ReactNode;\n}\n\nfunction PreviewRow({ label, children }: PreviewRowProps) {\n return (\n <div className=\"flex items-start gap-2 text-xs\">\n <span className=\"w-20 shrink-0 text-[var(--oh-muted)]\">{label}</span>\n <span className=\"min-w-0 flex-1 break-words text-[var(--oh-foreground)]\">\n {children}\n </span>\n </div>\n );\n}\n\nexport function ConversationCardPreview({\n title,\n executionStatus,\n sandboxStatus,\n selectedRepository,\n workspaceWorkingDir,\n llmModel,\n createdAt,\n}: ConversationCardPreviewProps) {\n const { t } = useTranslation(\"openhands\");\n\n const repository = selectedRepository?.selected_repository ?? null;\n const branch = selectedRepository?.selected_branch ?? null;\n const provider = selectedRepository?.git_provider ?? null;\n const ProviderIcon = provider ? providerIcon[provider] : null;\n\n const createdLabel = createdAt\n ? new Date(createdAt).toLocaleString(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n })\n : null;\n\n return (\n <div className=\"flex w-[280px] flex-col gap-3 p-3\">\n <div className=\"flex items-start gap-2\">\n {executionStatus !== undefined ? (\n <div className=\"mt-0.5\">\n <ConversationStatusDot\n executionStatus={executionStatus}\n sandboxStatus={sandboxStatus}\n showTooltip={false}\n />\n </div>\n ) : null}\n <span className=\"break-words text-sm font-medium text-white\">\n {title}\n </span>\n </div>\n\n <dl className=\"flex flex-col gap-1.5\">\n {repository ? (\n <>\n <PreviewRow label={t(I18nKey.CONVERSATION$REPOSITORY)}>\n <span className=\"inline-flex min-w-0 items-start gap-1.5\">\n {ProviderIcon ? (\n <ProviderIcon size={12} className=\"mt-0.5 shrink-0\" />\n ) : null}\n {provider === \"azure_devops\" ? (\n <AzureDevOpsLogo className=\"mt-0.5 h-3 w-3 shrink-0\" />\n ) : null}\n <span className=\"break-all\">{repository}</span>\n </span>\n </PreviewRow>\n {branch ? (\n <PreviewRow label={t(I18nKey.CONVERSATION$BRANCH)}>\n <span className=\"inline-flex min-w-0 items-start gap-1.5\">\n <FaCodeBranch size={11} className=\"mt-0.5 shrink-0\" />\n <span className=\"break-all\">{branch}</span>\n </span>\n </PreviewRow>\n ) : null}\n </>\n ) : workspaceWorkingDir ? (\n <PreviewRow label={t(I18nKey.CONVERSATION_PANEL$PREVIEW_DIRECTORY)}>\n <span className=\"inline-flex min-w-0 items-start gap-1.5\">\n <Folder size={12} className=\"mt-0.5 shrink-0\" />\n <span className=\"break-all\">{workspaceWorkingDir}</span>\n </span>\n </PreviewRow>\n ) : null}\n\n {llmModel ? (\n <PreviewRow label={t(I18nKey.CONVERSATION_PANEL$PREVIEW_MODEL)}>\n <span className=\"break-all\">{llmModel}</span>\n </PreviewRow>\n ) : null}\n\n {createdLabel ? (\n <PreviewRow label={t(I18nKey.CONVERSATION$CREATED)}>\n {createdLabel}\n </PreviewRow>\n ) : null}\n </dl>\n </div>\n );\n}\n"],"mappings":"mhBAwBA,IAAM,EAAoD,CACxD,UAAW,EAAA,YACX,sBAAuB,EAAA,YACvB,OAAQ,EAAA,SACR,OAAQ,EAAA,QACV,EAOA,SAAS,EAAW,CAAE,QAAO,YAA6B,CACxD,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,0CAAf,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,gDAAwC,CAAY,CAAA,GACpE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,yDACb,UACG,CAAA,CACH,GAET,CAEA,SAAgB,EAAwB,CACtC,QACA,kBACA,gBACA,qBACA,sBACA,WACA,aAC+B,CAC/B,GAAM,CAAE,KAAM,EAAA,eAAe,WAAW,EAElC,EAAa,GAAoB,qBAAuB,KACxD,EAAS,GAAoB,iBAAmB,KAChD,EAAW,GAAoB,cAAgB,KAC/C,EAAe,EAAW,EAAa,GAAY,KAEnD,EAAe,EACjB,IAAI,KAAK,CAAS,EAAE,eAAe,IAAA,GAAW,CAC5C,UAAW,SACX,UAAW,OACb,CAAC,EACD,KAEJ,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,6CAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,kCAAf,CACG,IAAoB,IAAA,GAQjB,MAPF,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,mBACb,EAAA,EAAA,KAAC,EAAA,sBAAD,CACmB,kBACF,gBACf,YAAa,EACd,CAAA,CACE,CAAA,GAEP,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,sDACb,CACG,CAAA,CACH,KAEL,EAAA,EAAA,MAAC,KAAD,CAAI,UAAU,iCAAd,CACG,GACC,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAD,CAAY,MAAO,EAAE,EAAA,QAAQ,uBAAuB,YAClD,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,mDAAhB,CACG,GACC,EAAA,EAAA,KAAC,EAAD,CAAc,KAAM,GAAI,UAAU,iBAAmB,CAAA,EACnD,KACH,IAAa,gBACZ,EAAA,EAAA,KAAC,EAAA,QAAD,CAAiB,UAAU,yBAA2B,CAAA,EACpD,MACJ,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qBAAa,CAAiB,CAAA,CAC1C,GACI,CAAA,EACX,GACC,EAAA,EAAA,KAAC,EAAD,CAAY,MAAO,EAAE,EAAA,QAAQ,mBAAmB,YAC9C,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,mDAAhB,EACE,EAAA,EAAA,KAAC,EAAA,aAAD,CAAc,KAAM,GAAI,UAAU,iBAAmB,CAAA,GACrD,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qBAAa,CAAa,CAAA,CACtC,GACI,CAAA,EACV,IACJ,CAAA,CAAA,EACA,GACF,EAAA,EAAA,KAAC,EAAD,CAAY,MAAO,EAAE,EAAA,QAAQ,oCAAoC,YAC/D,EAAA,EAAA,MAAC,OAAD,CAAM,UAAU,mDAAhB,EACE,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,KAAM,GAAI,UAAU,iBAAmB,CAAA,GAC/C,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qBAAa,CAA0B,CAAA,CACnD,GACI,CAAA,EACV,KAEH,GACC,EAAA,EAAA,KAAC,EAAD,CAAY,MAAO,EAAE,EAAA,QAAQ,gCAAgC,YAC3D,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qBAAa,CAAe,CAAA,CAClC,CAAA,EACV,KAEH,GACC,EAAA,EAAA,KAAC,EAAD,CAAY,MAAO,EAAE,EAAA,QAAQ,oBAAoB,WAC9C,CACS,CAAA,EACV,IACF,GACD,GAET"}
1
+ {"version":3,"file":"conversation-card-preview.cjs","names":[],"sources":["../../../../../src/components/features/conversation-panel/conversation-card/conversation-card-preview.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { Folder } from \"lucide-react\";\nimport { FaBitbucket, FaGithub, FaGitlab } from \"react-icons/fa6\";\nimport { FaCodeBranch } from \"react-icons/fa\";\nimport type { IconType } from \"react-icons/lib\";\nimport { useTranslation } from \"react-i18next\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport type { RepositorySelection } from \"#/api/open-hands.types\";\nimport type { Provider } from \"#/types/settings\";\nimport type { ExecutionStatus } from \"#/types/agent-server/core/base/common\";\nimport type { SandboxStatus } from \"#/api/conversation-service/agent-server-conversation-service.types\";\nimport { getDisplayConversationTags } from \"#/api/agent-server-adapter\";\nimport { resolveAcpProviderIcon } from \"#/constants/acp-providers\";\nimport AzureDevOpsLogo from \"#/assets/branding/azure-devops-logo.svg?react\";\nimport { AgentBrandIcon } from \"#/components/shared/agent-brand-icon\";\nimport { ConversationStatusDot } from \"../conversation-status-dot\";\nimport { getConversationTagLabel } from \"./conversation-tag-display\";\nimport { getConversationTagIcon } from \"./conversation-tag-icons\";\n\ninterface ConversationCardPreviewProps {\n title: string;\n executionStatus?: ExecutionStatus | null;\n sandboxStatus?: SandboxStatus | null;\n selectedRepository: RepositorySelection | null;\n workspaceWorkingDir?: string | null;\n llmModel?: string | null;\n /**\n * High-level kind of the conversation's agent. Drives the model row's brand\n * mark exactly like the card chip does — without it an ACP conversation\n * would show the OpenHands wordmark next to a Claude Code / Codex / Gemini\n * model, contradicting the chip on the very card being hovered.\n */\n agentKind?: \"openhands\" | \"acp\" | null;\n /** Registry key of the ACP CLI server, resolved to its brand mark. */\n acpServer?: string | null;\n createdAt?: string;\n /**\n * Server-side conversation tags. Always shown in the hovercard when present\n * (except keys already covered by repository / branch / directory rows).\n * Sidebar card chips stay gated by the panel's Tags preference.\n */\n tags?: Record<string, string> | null;\n}\n\nconst providerIcon: Partial<Record<Provider, IconType>> = {\n bitbucket: FaBitbucket,\n bitbucket_data_center: FaBitbucket,\n github: FaGithub,\n gitlab: FaGitlab,\n};\n\ninterface PreviewRowProps {\n label: string;\n children: ReactNode;\n}\n\nfunction PreviewRow({ label, children }: PreviewRowProps) {\n return (\n <div className=\"flex items-start gap-2 text-xs leading-4\">\n <span className=\"w-20 shrink-0 whitespace-normal break-words text-[var(--oh-muted)]\">\n {label}\n </span>\n <span className=\"min-w-0 flex-1 overflow-visible whitespace-normal break-words text-[var(--oh-foreground)]\">\n {children}\n </span>\n </div>\n );\n}\n\n/**\n * Icon + value for preview rows. The icon sits in a box matching the first\n * line's height (``leading-4``) so it stays optically centered when the value\n * wraps to multiple lines. The slot has a 12px *minimum* rather than a fixed\n * width so the wider OpenHands wordmark (18px at ``size={12}``) is not clipped,\n * while the square icons still share one column.\n */\nfunction PreviewValueWithIcon({\n icon,\n children,\n testId,\n tagKey,\n}: {\n icon?: ReactNode;\n children: ReactNode;\n testId?: string;\n tagKey?: string;\n}) {\n return (\n <span\n data-testid={testId}\n data-tag-key={tagKey}\n className=\"inline-flex min-w-0 max-w-full items-start gap-1.5\"\n >\n {icon ? (\n <span className=\"inline-flex h-4 min-w-3 shrink-0 items-center justify-center [&_svg]:block\">\n {icon}\n </span>\n ) : null}\n <span className=\"min-w-0 flex-1 whitespace-normal break-all\">\n {children}\n </span>\n </span>\n );\n}\n\nexport function ConversationCardPreview({\n title,\n executionStatus,\n sandboxStatus,\n selectedRepository,\n workspaceWorkingDir,\n llmModel,\n agentKind = null,\n acpServer = null,\n createdAt,\n tags = null,\n}: ConversationCardPreviewProps) {\n const { t } = useTranslation(\"openhands\");\n\n const repository = selectedRepository?.selected_repository ?? null;\n const branch = selectedRepository?.selected_branch ?? null;\n const provider = selectedRepository?.git_provider ?? null;\n const ProviderIcon = provider ? providerIcon[provider] : null;\n\n const createdLabel = createdAt\n ? new Date(createdAt).toLocaleString(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n })\n : null;\n\n const previewTags = getDisplayConversationTags(tags);\n\n return (\n <div\n data-testid=\"conversation-card-preview\"\n className=\"flex w-[280px] max-w-[min(280px,90vw)] flex-col gap-3 overflow-visible p-3\"\n >\n <div className=\"flex items-start gap-2\">\n {executionStatus !== undefined ? (\n <span className=\"inline-flex h-5 w-2.5 shrink-0 items-center justify-center\">\n <ConversationStatusDot\n executionStatus={executionStatus}\n sandboxStatus={sandboxStatus}\n showTooltip={false}\n />\n </span>\n ) : null}\n <span className=\"break-words text-sm font-medium leading-5 text-white\">\n {title}\n </span>\n </div>\n\n <dl className=\"flex flex-col gap-1.5\">\n {repository ? (\n <>\n <PreviewRow label={t(I18nKey.CONVERSATION_PANEL$PREVIEW_REPO)}>\n <PreviewValueWithIcon\n icon={\n ProviderIcon ? (\n <ProviderIcon size={12} />\n ) : provider === \"azure_devops\" ? (\n <AzureDevOpsLogo className=\"h-3 w-3\" />\n ) : undefined\n }\n >\n {repository}\n </PreviewValueWithIcon>\n </PreviewRow>\n {branch ? (\n <PreviewRow label={t(I18nKey.CONVERSATION_PANEL$PREVIEW_BRANCH)}>\n <PreviewValueWithIcon icon={<FaCodeBranch size={11} />}>\n {branch}\n </PreviewValueWithIcon>\n </PreviewRow>\n ) : null}\n </>\n ) : workspaceWorkingDir ? (\n <PreviewRow label={t(I18nKey.CONVERSATION_PANEL$PREVIEW_DIRECTORY)}>\n <PreviewValueWithIcon icon={<Folder size={12} />}>\n {workspaceWorkingDir}\n </PreviewValueWithIcon>\n </PreviewRow>\n ) : null}\n\n {llmModel ? (\n <PreviewRow label={t(I18nKey.CONVERSATION_PANEL$PREVIEW_MODEL)}>\n <PreviewValueWithIcon\n testId=\"conversation-card-preview-model\"\n icon={\n <AgentBrandIcon\n kind={\n agentKind === \"acp\"\n ? resolveAcpProviderIcon(acpServer)\n : \"openhands\"\n }\n size={12}\n />\n }\n >\n {llmModel}\n </PreviewValueWithIcon>\n </PreviewRow>\n ) : null}\n\n {previewTags.map(([key, value]) => {\n const Icon = getConversationTagIcon(key, value);\n const label = getConversationTagLabel(key, t);\n\n return (\n <PreviewRow key={key} label={label}>\n <PreviewValueWithIcon\n testId=\"conversation-card-preview-tag-row\"\n tagKey={key}\n icon={<Icon aria-hidden className=\"h-3 w-3\" />}\n >\n {value}\n </PreviewValueWithIcon>\n </PreviewRow>\n );\n })}\n\n {createdLabel ? (\n <PreviewRow label={t(I18nKey.CONVERSATION$CREATED)}>\n {createdLabel}\n </PreviewRow>\n ) : null}\n </dl>\n </div>\n );\n}\n"],"mappings":"swBA4CA,IAAM,EAAoD,CACxD,UAAW,EAAA,YACX,sBAAuB,EAAA,YACvB,OAAQ,EAAA,SACR,OAAQ,EAAA,QACV,EAOA,SAAS,EAAW,CAAE,QAAO,YAA6B,CACxD,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oDAAf,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,8EACb,CACG,CAAA,GACN,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,4FACb,UACG,CAAA,CACH,GAET,CASA,SAAS,EAAqB,CAC5B,OACA,WACA,SACA,UAMC,CACD,OACE,EAAA,EAAA,MAAC,OAAD,CACE,cAAa,EACb,eAAc,EACd,UAAU,8DAHZ,CAKG,GACC,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,sFACb,CACG,CAAA,EACJ,MACJ,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,6CACb,UACG,CAAA,CACF,GAEV,CAEA,SAAgB,EAAwB,CACtC,QACA,kBACA,gBACA,qBACA,sBACA,WACA,YAAY,KACZ,YAAY,KACZ,YACA,OAAO,MACwB,CAC/B,GAAM,CAAE,KAAM,EAAA,eAAe,WAAW,EAElC,EAAa,GAAoB,qBAAuB,KACxD,EAAS,GAAoB,iBAAmB,KAChD,EAAW,GAAoB,cAAgB,KAC/C,EAAe,EAAW,EAAa,GAAY,KAEnD,EAAe,EACjB,IAAI,KAAK,CAAS,EAAE,eAAe,IAAA,GAAW,CAC5C,UAAW,SACX,UAAW,OACb,CAAC,EACD,KAEE,EAAc,EAAA,2BAA2B,CAAI,EAEnD,OACE,EAAA,EAAA,MAAC,MAAD,CACE,cAAY,4BACZ,UAAU,sFAFZ,EAIE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,kCAAf,CACG,IAAoB,IAAA,GAQjB,MAPF,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,uEACd,EAAA,EAAA,KAAC,EAAA,sBAAD,CACmB,kBACF,gBACf,YAAa,EACd,CAAA,CACG,CAAA,GAER,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,gEACb,CACG,CAAA,CACH,KAEL,EAAA,EAAA,MAAC,KAAD,CAAI,UAAU,iCAAd,CACG,GACC,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAD,CAAY,MAAO,EAAE,EAAA,QAAQ,+BAA+B,YAC1D,EAAA,EAAA,KAAC,EAAD,CACE,KACE,GACE,EAAA,EAAA,KAAC,EAAD,CAAc,KAAM,EAAK,CAAA,EACvB,IAAa,gBACf,EAAA,EAAA,KAAC,EAAA,QAAD,CAAiB,UAAU,SAAW,CAAA,EACpC,IAAA,YAGL,CACmB,CAAA,CACZ,CAAA,EACX,GACC,EAAA,EAAA,KAAC,EAAD,CAAY,MAAO,EAAE,EAAA,QAAQ,iCAAiC,YAC5D,EAAA,EAAA,KAAC,EAAD,CAAsB,MAAM,EAAA,EAAA,KAAC,EAAA,aAAD,CAAc,KAAM,EAAK,CAAA,WAClD,CACmB,CAAA,CACZ,CAAA,EACV,IACJ,CAAA,CAAA,EACA,GACF,EAAA,EAAA,KAAC,EAAD,CAAY,MAAO,EAAE,EAAA,QAAQ,oCAAoC,YAC/D,EAAA,EAAA,KAAC,EAAD,CAAsB,MAAM,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,KAAM,EAAK,CAAA,WAC5C,CACmB,CAAA,CACZ,CAAA,EACV,KAEH,GACC,EAAA,EAAA,KAAC,EAAD,CAAY,MAAO,EAAE,EAAA,QAAQ,gCAAgC,YAC3D,EAAA,EAAA,KAAC,EAAD,CACE,OAAO,kCACP,MACE,EAAA,EAAA,KAAC,EAAA,eAAD,CACE,KACE,IAAc,MACV,EAAA,uBAAuB,CAAS,EAChC,YAEN,KAAM,EACP,CAAA,WAGF,CACmB,CAAA,CACZ,CAAA,EACV,KAEH,EAAY,KAAK,CAAC,EAAK,KAAW,CACjC,IAAM,EAAO,EAAA,uBAAuB,EAAK,CAAK,EAG9C,OACE,EAAA,EAAA,KAAC,EAAD,CAA6B,MAHjB,EAAA,wBAAwB,EAAK,CAGZ,YAC3B,EAAA,EAAA,KAAC,EAAD,CACE,OAAO,oCACP,OAAQ,EACR,MAAM,EAAA,EAAA,KAAC,EAAD,CAAM,cAAA,GAAY,UAAU,SAAW,CAAA,WAE5C,CACmB,CAAA,CACZ,EARK,CAQL,CAEhB,CAAC,EAEA,GACC,EAAA,EAAA,KAAC,EAAD,CAAY,MAAO,EAAE,EAAA,QAAQ,oBAAoB,WAC9C,CACS,CAAA,EACV,IACF,GACD,GAET"}
@@ -8,7 +8,22 @@ interface ConversationCardPreviewProps {
8
8
  selectedRepository: RepositorySelection | null;
9
9
  workspaceWorkingDir?: string | null;
10
10
  llmModel?: string | null;
11
+ /**
12
+ * High-level kind of the conversation's agent. Drives the model row's brand
13
+ * mark exactly like the card chip does — without it an ACP conversation
14
+ * would show the OpenHands wordmark next to a Claude Code / Codex / Gemini
15
+ * model, contradicting the chip on the very card being hovered.
16
+ */
17
+ agentKind?: "openhands" | "acp" | null;
18
+ /** Registry key of the ACP CLI server, resolved to its brand mark. */
19
+ acpServer?: string | null;
11
20
  createdAt?: string;
21
+ /**
22
+ * Server-side conversation tags. Always shown in the hovercard when present
23
+ * (except keys already covered by repository / branch / directory rows).
24
+ * Sidebar card chips stay gated by the panel's Tags preference.
25
+ */
26
+ tags?: Record<string, string> | null;
12
27
  }
13
- export declare function ConversationCardPreview({ title, executionStatus, sandboxStatus, selectedRepository, workspaceWorkingDir, llmModel, createdAt, }: ConversationCardPreviewProps): import("react").JSX.Element;
28
+ export declare function ConversationCardPreview({ title, executionStatus, sandboxStatus, selectedRepository, workspaceWorkingDir, llmModel, agentKind, acpServer, createdAt, tags, }: ConversationCardPreviewProps): import("react").JSX.Element;
14
29
  export {};