@vertesia/ui 1.5.0-dev.20260722.120446Z → 1.5.0-dev.20260725.083715Z

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 (307) hide show
  1. package/lib/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
  2. package/lib/core/components/shadcn/filters/filterBar.js +1 -1
  3. package/lib/core/components/shadcn/filters/filterBar.js.map +1 -1
  4. package/lib/core/components/shadcn/modal/dialog.d.ts +1 -1
  5. package/lib/core/components/shadcn/modal/dialog.d.ts.map +1 -1
  6. package/lib/core/components/shadcn/modal/dialog.js +2 -0
  7. package/lib/core/components/shadcn/modal/dialog.js.map +1 -1
  8. package/lib/core/components/shadcn/tabs.d.ts +12 -1
  9. package/lib/core/components/shadcn/tabs.d.ts.map +1 -1
  10. package/lib/core/components/shadcn/tabs.js +12 -4
  11. package/lib/core/components/shadcn/tabs.js.map +1 -1
  12. package/lib/features/agent/chat/AgentRightPanel.d.ts +5 -1
  13. package/lib/features/agent/chat/AgentRightPanel.d.ts.map +1 -1
  14. package/lib/features/agent/chat/AgentRightPanel.js +2 -2
  15. package/lib/features/agent/chat/AgentRightPanel.js.map +1 -1
  16. package/lib/features/agent/chat/ArtifactsTab.d.ts +5 -1
  17. package/lib/features/agent/chat/ArtifactsTab.d.ts.map +1 -1
  18. package/lib/features/agent/chat/ArtifactsTab.js +48 -11
  19. package/lib/features/agent/chat/ArtifactsTab.js.map +1 -1
  20. package/lib/features/agent/chat/DocumentEditingActionCard.d.ts +6 -0
  21. package/lib/features/agent/chat/DocumentEditingActionCard.d.ts.map +1 -0
  22. package/lib/features/agent/chat/DocumentEditingActionCard.js +129 -0
  23. package/lib/features/agent/chat/DocumentEditingActionCard.js.map +1 -0
  24. package/lib/features/agent/chat/ModernAgentConversation.d.ts +19 -1
  25. package/lib/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
  26. package/lib/features/agent/chat/ModernAgentConversation.js +125 -27
  27. package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
  28. package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.d.ts +45 -0
  29. package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.d.ts.map +1 -0
  30. package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.js +40 -0
  31. package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.js.map +1 -0
  32. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +3 -1
  33. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
  34. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +94 -49
  35. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  36. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts +2 -1
  37. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts.map +1 -1
  38. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js +9 -5
  39. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js.map +1 -1
  40. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts +25 -0
  41. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts.map +1 -0
  42. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js +33 -0
  43. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js.map +1 -0
  44. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts +3 -1
  45. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
  46. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +22 -24
  47. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
  48. package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.d.ts +14 -0
  49. package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.d.ts.map +1 -0
  50. package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.js +21 -0
  51. package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.js.map +1 -0
  52. package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.d.ts +30 -0
  53. package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.d.ts.map +1 -0
  54. package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.js +53 -0
  55. package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.js.map +1 -0
  56. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.d.ts.map +1 -1
  57. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +21 -2
  58. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js.map +1 -1
  59. package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.d.ts +6 -0
  60. package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.d.ts.map +1 -0
  61. package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.js +29 -0
  62. package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.js.map +1 -0
  63. package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.d.ts +33 -0
  64. package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.d.ts.map +1 -0
  65. package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.js +129 -0
  66. package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.js.map +1 -0
  67. package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts +7 -0
  68. package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts.map +1 -1
  69. package/lib/features/agent/chat/ModernAgentOutput/utils.js +11 -1
  70. package/lib/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
  71. package/lib/features/agent/chat/hooks/useAgentStream.d.ts +1 -1
  72. package/lib/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -1
  73. package/lib/features/agent/chat/hooks/useAgentStream.js +24 -9
  74. package/lib/features/agent/chat/hooks/useAgentStream.js.map +1 -1
  75. package/lib/features/agent/chat/index.d.ts +2 -1
  76. package/lib/features/agent/chat/index.d.ts.map +1 -1
  77. package/lib/features/agent/chat/index.js +3 -0
  78. package/lib/features/agent/chat/index.js.map +1 -1
  79. package/lib/features/store/objects/DocumentSearchResults.js +2 -2
  80. package/lib/features/store/objects/DocumentSearchResults.js.map +1 -1
  81. package/lib/features/store/objects/components/ContentOverview.d.ts +2 -1
  82. package/lib/features/store/objects/components/ContentOverview.d.ts.map +1 -1
  83. package/lib/features/store/objects/components/ContentOverview.js +86 -15
  84. package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
  85. package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.d.ts +16 -0
  86. package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.d.ts.map +1 -0
  87. package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.js +116 -0
  88. package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.js.map +1 -0
  89. package/lib/features/store/objects/components/DocumentEditingLockStatus.d.ts +7 -0
  90. package/lib/features/store/objects/components/DocumentEditingLockStatus.d.ts.map +1 -0
  91. package/lib/features/store/objects/components/DocumentEditingLockStatus.js +13 -0
  92. package/lib/features/store/objects/components/DocumentEditingLockStatus.js.map +1 -0
  93. package/lib/features/store/objects/components/DocumentEditingPanel.d.ts +48 -0
  94. package/lib/features/store/objects/components/DocumentEditingPanel.d.ts.map +1 -0
  95. package/lib/features/store/objects/components/DocumentEditingPanel.js +720 -0
  96. package/lib/features/store/objects/components/DocumentEditingPanel.js.map +1 -0
  97. package/lib/features/store/objects/components/TextEditorPanel.d.ts.map +1 -1
  98. package/lib/features/store/objects/components/TextEditorPanel.js +22 -9
  99. package/lib/features/store/objects/components/TextEditorPanel.js.map +1 -1
  100. package/lib/features/store/objects/components/documentArtifactRefs.d.ts +26 -0
  101. package/lib/features/store/objects/components/documentArtifactRefs.d.ts.map +1 -0
  102. package/lib/features/store/objects/components/documentArtifactRefs.js +52 -0
  103. package/lib/features/store/objects/components/documentArtifactRefs.js.map +1 -0
  104. package/lib/features/store/objects/components/documentEditingAgentConfig.d.ts +4 -0
  105. package/lib/features/store/objects/components/documentEditingAgentConfig.d.ts.map +1 -0
  106. package/lib/features/store/objects/components/documentEditingAgentConfig.js +40 -0
  107. package/lib/features/store/objects/components/documentEditingAgentConfig.js.map +1 -0
  108. package/lib/features/store/objects/components/documentEditingPrompts.d.ts +3 -0
  109. package/lib/features/store/objects/components/documentEditingPrompts.d.ts.map +1 -0
  110. package/lib/features/store/objects/components/documentEditingPrompts.js +13 -0
  111. package/lib/features/store/objects/components/documentEditingPrompts.js.map +1 -0
  112. package/lib/features/store/objects/components/documentEditingRun.d.ts +27 -0
  113. package/lib/features/store/objects/components/documentEditingRun.d.ts.map +1 -0
  114. package/lib/features/store/objects/components/documentEditingRun.js +126 -0
  115. package/lib/features/store/objects/components/documentEditingRun.js.map +1 -0
  116. package/lib/features/store/objects/components/documentEditingTarget.d.ts +20 -0
  117. package/lib/features/store/objects/components/documentEditingTarget.d.ts.map +1 -0
  118. package/lib/features/store/objects/components/documentEditingTarget.js +40 -0
  119. package/lib/features/store/objects/components/documentEditingTarget.js.map +1 -0
  120. package/lib/features/store/objects/components/index.d.ts +1 -0
  121. package/lib/features/store/objects/components/index.d.ts.map +1 -1
  122. package/lib/features/store/objects/components/index.js +1 -0
  123. package/lib/features/store/objects/components/index.js.map +1 -1
  124. package/lib/features/store/objects/components/useContentPanelHooks.d.ts +5 -1
  125. package/lib/features/store/objects/components/useContentPanelHooks.d.ts.map +1 -1
  126. package/lib/features/store/objects/components/useContentPanelHooks.js +53 -29
  127. package/lib/features/store/objects/components/useContentPanelHooks.js.map +1 -1
  128. package/lib/features/store/objects/components/useDownloadFile.d.ts +2 -1
  129. package/lib/features/store/objects/components/useDownloadFile.d.ts.map +1 -1
  130. package/lib/features/store/objects/components/useDownloadFile.js +3 -0
  131. package/lib/features/store/objects/components/useDownloadFile.js.map +1 -1
  132. package/lib/features/store/objects/selection/actions/StartWorkflowButton.js +1 -1
  133. package/lib/features/store/objects/selection/actions/StartWorkflowButton.js.map +1 -1
  134. package/lib/i18n/locales/ar.json +118 -1
  135. package/lib/i18n/locales/de.json +118 -1
  136. package/lib/i18n/locales/en.json +118 -0
  137. package/lib/i18n/locales/es.json +118 -1
  138. package/lib/i18n/locales/fr.json +118 -1
  139. package/lib/i18n/locales/it.json +118 -1
  140. package/lib/i18n/locales/ja.json +118 -1
  141. package/lib/i18n/locales/ko.json +118 -1
  142. package/lib/i18n/locales/pt.json +118 -1
  143. package/lib/i18n/locales/ru.json +118 -1
  144. package/lib/i18n/locales/tr.json +118 -1
  145. package/lib/i18n/locales/zh-TW.json +118 -1
  146. package/lib/i18n/locales/zh.json +118 -1
  147. package/lib/rich-text/EditorToolbar.d.ts +37 -0
  148. package/lib/rich-text/EditorToolbar.d.ts.map +1 -0
  149. package/lib/rich-text/EditorToolbar.js +215 -0
  150. package/lib/rich-text/EditorToolbar.js.map +1 -0
  151. package/lib/rich-text/VertesiaRichTextEditor.d.ts +26 -0
  152. package/lib/rich-text/VertesiaRichTextEditor.d.ts.map +1 -0
  153. package/lib/rich-text/VertesiaRichTextEditor.js +67 -0
  154. package/lib/rich-text/VertesiaRichTextEditor.js.map +1 -0
  155. package/lib/rich-text/index.d.ts +2 -0
  156. package/lib/rich-text/index.d.ts.map +1 -0
  157. package/lib/rich-text/index.js +2 -0
  158. package/lib/rich-text/index.js.map +1 -0
  159. package/lib/vertesia-ui-core.js +2 -2
  160. package/lib/vertesia-ui-core.js.map +1 -1
  161. package/lib/vertesia-ui-features.js +35 -30
  162. package/lib/vertesia-ui-features.js.map +1 -1
  163. package/lib/vertesia-ui-i18n.js +14 -14
  164. package/lib/vertesia-ui-i18n.js.map +1 -1
  165. package/lib/vertesia-ui-rich-text.js +5 -0
  166. package/lib/vertesia-ui-rich-text.js.map +1 -0
  167. package/lib/vertesia-ui-widgets.js +25 -7
  168. package/lib/vertesia-ui-widgets.js.map +1 -1
  169. package/lib/widgets/markdown/AgentResourceResolver.d.ts +31 -0
  170. package/lib/widgets/markdown/AgentResourceResolver.d.ts.map +1 -0
  171. package/lib/widgets/markdown/AgentResourceResolver.js +39 -0
  172. package/lib/widgets/markdown/AgentResourceResolver.js.map +1 -0
  173. package/lib/widgets/markdown/ArtifactEditingSurface.d.ts +63 -0
  174. package/lib/widgets/markdown/ArtifactEditingSurface.d.ts.map +1 -0
  175. package/lib/widgets/markdown/ArtifactEditingSurface.js +582 -0
  176. package/lib/widgets/markdown/ArtifactEditingSurface.js.map +1 -0
  177. package/lib/widgets/markdown/CollaborativeMarkdownRenderer.d.ts +69 -0
  178. package/lib/widgets/markdown/CollaborativeMarkdownRenderer.d.ts.map +1 -0
  179. package/lib/widgets/markdown/CollaborativeMarkdownRenderer.js +374 -0
  180. package/lib/widgets/markdown/CollaborativeMarkdownRenderer.js.map +1 -0
  181. package/lib/widgets/markdown/MarkdownLink.d.ts +3 -1
  182. package/lib/widgets/markdown/MarkdownLink.d.ts.map +1 -1
  183. package/lib/widgets/markdown/MarkdownLink.js +41 -14
  184. package/lib/widgets/markdown/MarkdownLink.js.map +1 -1
  185. package/lib/widgets/markdown/MarkdownRenderer.d.ts +8 -1
  186. package/lib/widgets/markdown/MarkdownRenderer.d.ts.map +1 -1
  187. package/lib/widgets/markdown/MarkdownRenderer.js +20 -4
  188. package/lib/widgets/markdown/MarkdownRenderer.js.map +1 -1
  189. package/lib/widgets/markdown/index.d.ts +5 -1
  190. package/lib/widgets/markdown/index.d.ts.map +1 -1
  191. package/lib/widgets/markdown/index.js +5 -1
  192. package/lib/widgets/markdown/index.js.map +1 -1
  193. package/lib/widgets/markdown/normalizeCustomSchemeLinks.d.ts.map +1 -1
  194. package/lib/widgets/markdown/normalizeCustomSchemeLinks.js +14 -2
  195. package/lib/widgets/markdown/normalizeCustomSchemeLinks.js.map +1 -1
  196. package/lib/widgets/markdown/textDiff.d.ts +52 -0
  197. package/lib/widgets/markdown/textDiff.d.ts.map +1 -0
  198. package/lib/widgets/markdown/textDiff.js +362 -0
  199. package/lib/widgets/markdown/textDiff.js.map +1 -0
  200. package/lib/widgets/markdown/useArtifactContent.d.ts +5 -3
  201. package/lib/widgets/markdown/useArtifactContent.d.ts.map +1 -1
  202. package/lib/widgets/markdown/useArtifactContent.js +6 -3
  203. package/lib/widgets/markdown/useArtifactContent.js.map +1 -1
  204. package/lib/widgets/markdown/useResolvedUrl.d.ts +1 -5
  205. package/lib/widgets/markdown/useResolvedUrl.d.ts.map +1 -1
  206. package/lib/widgets/markdown/useResolvedUrl.js +19 -31
  207. package/lib/widgets/markdown/useResolvedUrl.js.map +1 -1
  208. package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts +9 -0
  209. package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts.map +1 -1
  210. package/lib/widgets/xml-viewer/hooks/useXMLViewer.js +20 -17
  211. package/lib/widgets/xml-viewer/hooks/useXMLViewer.js.map +1 -1
  212. package/package.json +13 -9
  213. package/src/__tests__/a11y.test.tsx +4 -1
  214. package/src/__tests__/axe-helper.ts +17 -7
  215. package/src/__tests__/setup.ts +25 -0
  216. package/src/core/components/shadcn/filters/filterBar.tsx +1 -0
  217. package/src/core/components/shadcn/modal/dialog.tsx +3 -1
  218. package/src/core/components/shadcn/tabs.test.tsx +65 -0
  219. package/src/core/components/shadcn/tabs.tsx +25 -3
  220. package/src/features/agent/chat/AgentRightPanel.tsx +16 -1
  221. package/src/features/agent/chat/ArtifactsTab.test.tsx +55 -0
  222. package/src/features/agent/chat/ArtifactsTab.tsx +203 -52
  223. package/src/features/agent/chat/DocumentEditingActionCard.test.tsx +105 -0
  224. package/src/features/agent/chat/DocumentEditingActionCard.tsx +210 -0
  225. package/src/features/agent/chat/ModernAgentConversation.test.tsx +237 -40
  226. package/src/features/agent/chat/ModernAgentConversation.tsx +247 -75
  227. package/src/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.test.tsx +79 -0
  228. package/src/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.tsx +94 -0
  229. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +257 -34
  230. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +217 -105
  231. package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +17 -0
  232. package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.test.tsx +44 -0
  233. package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.tsx +88 -0
  234. package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +30 -46
  235. package/src/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.tsx +40 -0
  236. package/src/features/agent/chat/ModernAgentOutput/ResourceChip.test.tsx +148 -0
  237. package/src/features/agent/chat/ModernAgentOutput/ResourceChip.tsx +141 -0
  238. package/src/features/agent/chat/ModernAgentOutput/ToolCallGroup.tsx +33 -1
  239. package/src/features/agent/chat/ModernAgentOutput/resourceLinks.tsx +43 -0
  240. package/src/features/agent/chat/ModernAgentOutput/resourceSummary.test.ts +229 -0
  241. package/src/features/agent/chat/ModernAgentOutput/resourceSummary.ts +152 -0
  242. package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +17 -0
  243. package/src/features/agent/chat/ModernAgentOutput/utils.ts +14 -1
  244. package/src/features/agent/chat/hooks/useAgentStream.test.tsx +188 -0
  245. package/src/features/agent/chat/hooks/useAgentStream.ts +28 -8
  246. package/src/features/agent/chat/index.ts +11 -0
  247. package/src/features/store/objects/DocumentSearchResults.tsx +2 -2
  248. package/src/features/store/objects/components/ContentOverview.tsx +216 -65
  249. package/src/features/store/objects/components/DocumentEditingConfigurationSelector.test.ts +34 -0
  250. package/src/features/store/objects/components/DocumentEditingConfigurationSelector.tsx +211 -0
  251. package/src/features/store/objects/components/DocumentEditingLockStatus.test.tsx +32 -0
  252. package/src/features/store/objects/components/DocumentEditingLockStatus.tsx +45 -0
  253. package/src/features/store/objects/components/DocumentEditingPanel.test.tsx +336 -0
  254. package/src/features/store/objects/components/DocumentEditingPanel.tsx +1236 -0
  255. package/src/features/store/objects/components/TextEditorPanel.test.tsx +48 -0
  256. package/src/features/store/objects/components/TextEditorPanel.tsx +41 -20
  257. package/src/features/store/objects/components/documentArtifactRefs.test.ts +65 -0
  258. package/src/features/store/objects/components/documentArtifactRefs.ts +72 -0
  259. package/src/features/store/objects/components/documentEditingAgentConfig.test.ts +28 -0
  260. package/src/features/store/objects/components/documentEditingAgentConfig.ts +41 -0
  261. package/src/features/store/objects/components/documentEditingPrompts.test.ts +26 -0
  262. package/src/features/store/objects/components/documentEditingPrompts.ts +12 -0
  263. package/src/features/store/objects/components/documentEditingRun.test.ts +176 -0
  264. package/src/features/store/objects/components/documentEditingRun.ts +184 -0
  265. package/src/features/store/objects/components/documentEditingTarget.test.ts +96 -0
  266. package/src/features/store/objects/components/documentEditingTarget.ts +63 -0
  267. package/src/features/store/objects/components/index.ts +1 -0
  268. package/src/features/store/objects/components/useContentPanelHooks.ts +52 -27
  269. package/src/features/store/objects/components/useDownloadFile.test.ts +20 -0
  270. package/src/features/store/objects/components/useDownloadFile.ts +5 -1
  271. package/src/features/store/objects/selection/actions/StartWorkflowButton.tsx +2 -2
  272. package/src/i18n/locales/ar.json +118 -1
  273. package/src/i18n/locales/de.json +118 -1
  274. package/src/i18n/locales/en.json +118 -0
  275. package/src/i18n/locales/es.json +118 -1
  276. package/src/i18n/locales/fr.json +118 -1
  277. package/src/i18n/locales/it.json +118 -1
  278. package/src/i18n/locales/ja.json +118 -1
  279. package/src/i18n/locales/ko.json +118 -1
  280. package/src/i18n/locales/pt.json +118 -1
  281. package/src/i18n/locales/ru.json +118 -1
  282. package/src/i18n/locales/tr.json +118 -1
  283. package/src/i18n/locales/zh-TW.json +118 -1
  284. package/src/i18n/locales/zh.json +118 -1
  285. package/src/rich-text/EditorToolbar.tsx +708 -0
  286. package/src/rich-text/VertesiaRichTextEditor.test.tsx +211 -0
  287. package/src/rich-text/VertesiaRichTextEditor.tsx +241 -0
  288. package/src/rich-text/index.ts +9 -0
  289. package/src/session/UserSession.test.ts +11 -11
  290. package/src/widgets/markdown/AgentResourceResolver.test.ts +24 -0
  291. package/src/widgets/markdown/AgentResourceResolver.tsx +70 -0
  292. package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +537 -0
  293. package/src/widgets/markdown/ArtifactEditingSurface.tsx +878 -0
  294. package/src/widgets/markdown/CollaborativeMarkdownRenderer.test.tsx +484 -0
  295. package/src/widgets/markdown/CollaborativeMarkdownRenderer.tsx +825 -0
  296. package/src/widgets/markdown/MarkdownLink.test.tsx +122 -0
  297. package/src/widgets/markdown/MarkdownLink.tsx +102 -17
  298. package/src/widgets/markdown/MarkdownRenderer.tsx +30 -3
  299. package/src/widgets/markdown/index.ts +39 -1
  300. package/src/widgets/markdown/normalizeCustomSchemeLinks.ts +15 -2
  301. package/src/widgets/markdown/textDiff.test.ts +156 -0
  302. package/src/widgets/markdown/textDiff.ts +399 -0
  303. package/src/widgets/markdown/useArtifactContent.ts +9 -3
  304. package/src/widgets/markdown/useResolvedUrl.test.ts +29 -40
  305. package/src/widgets/markdown/useResolvedUrl.ts +33 -35
  306. package/src/widgets/xml-viewer/hooks/useXMLViewer.test.ts +26 -0
  307. package/src/widgets/xml-viewer/hooks/useXMLViewer.ts +23 -18
@@ -1,20 +1,26 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { AgentMessageType, } from '@vertesia/common';
3
- import { Badge, Button, cn } from '@vertesia/ui/core';
2
+ import { AgentMessageType, getResourcesFromMessage, } from '@vertesia/common';
3
+ import { Badge, Button, cn, VTooltip } from '@vertesia/ui/core';
4
4
  import { i18nInstance, NAMESPACE, useUITranslation } from '@vertesia/ui/i18n';
5
- import { NavLink } from '@vertesia/ui/router';
5
+ import { useRouterContext } from '@vertesia/ui/router';
6
6
  import { MarkdownRenderer } from '@vertesia/ui/widgets';
7
7
  import { AlertTriangle, ArrowLeft, Bot, Brain, CheckCircle, ChevronDown, ChevronRight, CopyIcon, FileText, Pencil, Search, Terminal, Wrench, } from 'lucide-react';
8
8
  import React, { Component, useCallback, useEffect, useMemo, useRef, useState } from 'react';
9
9
  import { AnimatedThinkingDots, PulsatingCircle } from '../AnimatedThinkingDots';
10
10
  import { AskUserWidget } from '../AskUserWidget';
11
+ import { DocumentEditingActionCard, parseMarkdownEditingAction } from '../DocumentEditingActionCard.js';
11
12
  import { ThinkingMessages } from '../WaitingMessages';
12
13
  import { formatWorkstreamName, getWorkstreamActivityDetails, getWorkstreamDisplayName, getWorkstreamLaunchDetails, } from '../workstreams.js';
14
+ import { createAgentMarkdownAnchor } from './AgentMarkdownAnchor';
13
15
  import { AttachmentPreviewList, parseUserMessageAttachments } from './AttachmentPreview';
14
16
  import BatchProgressPanel from './BatchProgressPanel';
17
+ import { AGENT_LINE_CLAMP_CLASS, AGENT_PROSE_CLASS as SUMMARY_PROSE_CLASS, AGENT_COLLAPSE_LINES as SUMMARY_THOUGHT_COLLAPSE_LINES, AGENT_COLLAPSE_THRESHOLD as SUMMARY_THOUGHT_COLLAPSE_THRESHOLD, } from './CollapsibleAgentMarkdown.js';
15
18
  import { getMessageDeliveryStatus, MessageDeliveryStatus } from './MessageDeliveryStatus';
16
19
  import MessageItem from './MessageItem';
20
+ import { ResourceChangeSummary } from './ResourceChangeSummary';
21
+ import { ResourceActivityLinkList } from './ResourceChip';
17
22
  import { getAnsweredRequestInputKeys, getAnsweredToolApprovalRequestInputKeys, getHiddenToolApprovalAnswerKeys, getPendingRequestInputMessage, getRequestInputDisplayText, getRequestInputMessageKey, getResolvedToolApprovalKeys, getToolApprovalResponseMetadata, hasRequestInputUx, isRequestInputAnswered, isToolApprovalAnswerHidden, isToolApprovalRequestInput, isToolApprovalRequestInputHidden, } from './requestInputMessages';
23
+ import { interleaveTurnSummaries, isResourceSummaryReady, segmentTurnResources, } from './resourceSummary';
18
24
  import StreamingMessage from './StreamingMessage';
19
25
  import { buildSummaryConversationItems, buildSummaryDisplayMessages, getSummaryActivityAnchorTimestamp, isInitialSummaryActivityFallback, isTransientThinkingMessage, isTransientWorkStatusMessage, shouldShowSummaryActivityFallback, } from './SummaryConversation';
20
26
  import ToolCallGroup from './ToolCallGroup';
@@ -196,16 +202,7 @@ function SummaryWorkstreamLaunchMessage({ message, details, onSelectWorkstream,
196
202
  const secondaryName = interactionName && interactionName !== workstreamName ? interactionName : undefined;
197
203
  return (_jsx("div", { className: "mx-auto w-full max-w-3xl px-1", "data-workstream-id": details.workstreamId, children: _jsxs("button", { type: "button", className: cn('group flex w-full items-start gap-3 border-b border-border/70 py-2 text-start text-sm text-muted', 'transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2', 'focus-visible:ring-focus focus-visible:ring-offset-2 focus-visible:ring-offset-background'), onClick: () => onSelectWorkstream?.(details.workstreamId), children: [_jsx(Bot, { className: "mt-0.5 size-4 shrink-0 text-muted", "aria-hidden": "true" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1", children: [_jsx("span", { className: "font-medium text-muted", children: t('agent.workstreams') }), _jsx("span", { className: "min-w-0 truncate text-foreground/85", children: workstreamName })] }), secondaryName && _jsx("div", { className: "mt-0.5 truncate text-xs text-muted/75", children: secondaryName }), _jsx("span", { className: "sr-only", children: getMessageText(message) })] }), _jsx(ChevronRight, { className: "mt-0.5 size-4 shrink-0 text-muted transition-transform group-hover:translate-x-0.5 rtl:rotate-180 rtl:group-hover:-translate-x-0.5" })] }) }));
198
204
  }
199
- const SUMMARY_PROSE_CLASS = [
200
- 'agent-markdown vprose prose max-w-none break-words text-sm leading-6 text-foreground/80',
201
- 'prose-p:my-2 prose-p:leading-6 prose-li:my-0.5 prose-pre:my-3 prose-headings:tracking-normal',
202
- 'prose-headings:text-foreground prose-strong:text-foreground prose-code:text-foreground',
203
- 'prose-a:text-foreground prose-a:underline prose-a:decoration-muted prose-a:underline-offset-4',
204
- '[&_p]:text-foreground/80 [&_li]:text-foreground/80 [&_li::marker]:text-muted',
205
- ].join(' ');
206
205
  const USER_BUBBLE_COLLAPSE_THRESHOLD = 520;
207
- const SUMMARY_THOUGHT_COLLAPSE_LINES = 6;
208
- const SUMMARY_THOUGHT_COLLAPSE_THRESHOLD = 520;
209
206
  const STORE_LINK_MARKDOWN_RE = /\[[^\]]+\]\((?:\/store\/(?:objects|collections)\/|store:|document:|document:\/\/|collection:)[^)]+\)/;
210
207
  const DEFAULT_AGENT_MARKDOWN_COMPONENTS = {
211
208
  table: AgentMarkdownTable,
@@ -358,7 +355,7 @@ function useRotatingThinkingMessageIndex(enabled = true) {
358
355
  }, [enabled]);
359
356
  return thinkingMessageIndex;
360
357
  }
361
- function SummaryUserBubble({ children, message, workstreamId, className, artifactRunId, markdownComponents, }) {
358
+ function SummaryUserBubble({ children, message, workstreamId, className, artifactRunId, onOpenArtifact, markdownComponents, }) {
362
359
  const { t } = useUITranslation();
363
360
  const [isExpanded, setIsExpanded] = useState(false);
364
361
  const contentLength = useMemo(() => getReactNodeTextLength(children), [children]);
@@ -374,42 +371,36 @@ function SummaryUserBubble({ children, message, workstreamId, className, artifac
374
371
  }, [isExpanded, shouldCollapse]);
375
372
  return (_jsx("div", { className: "mx-auto flex w-full max-w-3xl justify-end px-1", children: _jsxs("div", { className: cn('max-w-[min(44rem,82%)] rounded-[1.35rem] bg-mixer-muted/35 px-4 py-2.5', 'text-sm font-normal leading-6 text-foreground/90 shadow-sm shadow-black/5 dark:bg-mixer-muted/15 dark:text-foreground/88 dark:shadow-none', 'break-words [overflow-wrap:anywhere]', className), "data-workstream-id": workstreamId, children: [_jsx("div", { className: cn(isPlainText && !shouldRenderMarkdown && 'whitespace-pre-wrap', shouldCollapse &&
376
373
  !isExpanded &&
377
- 'max-h-72 overflow-hidden [mask-image:linear-gradient(to_bottom,black_76%,transparent_100%)]'), children: shouldRenderMarkdown ? (_jsx(MarkdownRenderer, { artifactRunId: artifactRunId, components: markdownComponents, className: cn('agent-markdown vprose prose max-w-none break-words text-sm leading-6 text-foreground/90', 'prose-p:my-0 prose-p:leading-6 prose-a:text-foreground prose-a:underline prose-a:decoration-muted prose-a:underline-offset-4', '[&_p+_p]:mt-2'), children: textContent })) : (children) }), shouldCollapse && (_jsxs("button", { type: "button", "aria-expanded": isExpanded, className: "mt-2 inline-flex items-center gap-1 text-sm font-medium text-muted transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: () => setIsExpanded((current) => !current), children: [isExpanded ? t('agent.showLess') : t('agent.showMore'), _jsx(ChevronDown, { className: cn('size-4 transition-transform', isExpanded && 'rotate-180'), "aria-hidden": "true" })] })), message && deliveryStatus ? (_jsx("div", { className: "mt-1.5 flex justify-end", children: _jsx(MessageDeliveryStatus, { message: message, className: "h-4 w-4" }) })) : null] }) }));
374
+ 'max-h-72 overflow-hidden [mask-image:linear-gradient(to_bottom,black_76%,transparent_100%)]'), children: shouldRenderMarkdown ? (_jsx(MarkdownRenderer, { artifactRunId: artifactRunId, onArtifactOpen: onOpenArtifact, components: markdownComponents, className: cn('agent-markdown vprose prose max-w-none break-words text-sm leading-6 text-foreground/90', 'prose-p:my-0 prose-p:leading-6 prose-a:text-foreground prose-a:underline prose-a:decoration-muted prose-a:underline-offset-4', '[&_p+_p]:mt-2'), children: textContent })) : (children) }), shouldCollapse && (_jsxs("button", { type: "button", "aria-expanded": isExpanded, className: "mt-2 inline-flex items-center gap-1 text-sm font-medium text-muted transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: () => setIsExpanded((current) => !current), children: [isExpanded ? t('agent.showLess') : t('agent.showMore'), _jsx(ChevronDown, { className: cn('size-4 transition-transform', isExpanded && 'rotate-180'), "aria-hidden": "true" })] })), message && deliveryStatus ? (_jsx("div", { className: "mt-1.5 flex justify-end", children: _jsx(MessageDeliveryStatus, { message: message, className: "h-4 w-4" }) })) : null] }) }));
378
375
  }
379
- function SummaryMessage({ message, onSendMessage, onSelectWorkstream, requestInputAnswered = false, StoreLinkComponent, CollectionLinkComponent, }) {
376
+ function SummaryMessage({ message, onSendMessage, onOpenArtifact, onSelectWorkstream, requestInputAnswered = false, StoreLinkComponent, CollectionLinkComponent, }) {
377
+ const { router } = useRouterContext();
380
378
  const content = message.type === AgentMessageType.REQUEST_INPUT ? getRequestInputDisplayText(message) : getMessageText(message);
381
379
  const workstreamLaunchDetails = getWorkstreamLaunchDetails(message) ?? getWorkstreamActivityDetails(message);
382
380
  const workstreamId = getWorkstreamId(message);
383
381
  const runId = message.workflow_run_id;
384
382
  const parsedQuestion = useMemo(() => (message.type === AgentMessageType.QUESTION ? parseUserMessageAttachments(content) : null), [content, message.type]);
383
+ const editingAction = useMemo(() => message.type === AgentMessageType.QUESTION
384
+ ? parseMarkdownEditingAction(message.details?.editing_action)
385
+ : undefined, [message.details, message.type]);
385
386
  const markdownComponents = useMemo(() => ({
386
387
  ...DEFAULT_AGENT_MARKDOWN_COMPONENTS,
387
- a: ({ node: _node, ref: _ref, ...props }) => {
388
- const href = props.href || '';
389
- if (href.includes('/store/objects')) {
390
- const documentId = href.split('/store/objects/')[1] || '';
391
- if (StoreLinkComponent) {
392
- return (_jsx(StoreLinkComponent, { href: href, documentId: documentId, children: props.children }));
393
- }
394
- return (_jsx(NavLink, { href: href, topLevelNav: true, children: props.children }));
395
- }
396
- if (href.includes('/store/collections')) {
397
- const collectionId = href.split('/store/collections/')[1] || '';
398
- if (CollectionLinkComponent) {
399
- return (_jsx(CollectionLinkComponent, { href: href, collectionId: collectionId, children: props.children }));
400
- }
401
- return (_jsx(NavLink, { href: href, topLevelNav: true, children: props.children }));
402
- }
403
- return _jsx("a", { ...props, target: "_blank", rel: "noopener noreferrer" });
404
- },
405
- }), [StoreLinkComponent, CollectionLinkComponent]);
388
+ a: createAgentMarkdownAnchor({
389
+ StoreLinkComponent,
390
+ CollectionLinkComponent,
391
+ addStickyParams: (href) => router.getTopRouter().navigator.addStickyParams(href),
392
+ }),
393
+ }), [StoreLinkComponent, CollectionLinkComponent, router]);
406
394
  if (workstreamLaunchDetails) {
407
395
  return (_jsx(SummaryWorkstreamLaunchMessage, { message: message, details: workstreamLaunchDetails, onSelectWorkstream: onSelectWorkstream }));
408
396
  }
409
397
  if (message.type === AgentMessageType.QUESTION) {
410
398
  const questionBody = parsedQuestion?.body ?? content;
411
399
  const attachments = parsedQuestion?.attachments ?? [];
412
- return (_jsxs(_Fragment, { children: [attachments.length > 0 && (_jsx("div", { className: "mx-auto flex w-full max-w-3xl justify-end px-1", children: _jsx(AttachmentPreviewList, { items: attachments, artifactRunId: runId, align: "end", variant: "message", StoreLinkComponent: StoreLinkComponent, CollectionLinkComponent: CollectionLinkComponent }) })), questionBody && (_jsx(SummaryUserBubble, { message: message, workstreamId: workstreamId, artifactRunId: runId, markdownComponents: markdownComponents, children: questionBody }))] }));
400
+ return (_jsxs(_Fragment, { children: [attachments.length > 0 && (_jsx("div", { className: "mx-auto flex w-full max-w-3xl justify-end px-1", children: _jsx(AttachmentPreviewList, { items: attachments, artifactRunId: runId, onOpenArtifact: onOpenArtifact, align: "end", variant: "message", StoreLinkComponent: StoreLinkComponent, CollectionLinkComponent: CollectionLinkComponent }) })), questionBody && (_jsx(SummaryUserBubble, { message: message, workstreamId: workstreamId, artifactRunId: runId, onOpenArtifact: onOpenArtifact, markdownComponents: markdownComponents,
401
+ // Comments/edits are user actions: keep the user-message background and end
402
+ // alignment, just give the card a little more room for tables and diffs.
403
+ className: editingAction ? 'max-w-[min(44rem,90%)]' : undefined, children: editingAction ? _jsx(DocumentEditingActionCard, { action: editingAction }) : questionBody }))] }));
413
404
  }
414
405
  const requestInputDetails = message.details;
415
406
  if (message.type === AgentMessageType.REQUEST_INPUT && requestInputDetails?.ux) {
@@ -417,7 +408,7 @@ function SummaryMessage({ message, onSendMessage, onSelectWorkstream, requestInp
417
408
  return (_jsx("div", { className: "mx-auto w-full max-w-3xl px-1", children: _jsx(AskUserWidget, { question: content, options: uxConfig.options, variant: uxConfig.variant, multiSelect: uxConfig.multiSelect, onSelect: (optionId) => onSendMessage?.(optionId, getToolApprovalResponseMetadata(message, optionId)), onMultiSelect: (optionIds) => onSendMessage?.(optionIds.join(', ')), allowFreeResponse: !uxConfig.options?.length || !!uxConfig.free_response, placeholder: uxConfig.free_response?.placeholder, submitLabel: uxConfig.free_response?.submit_label, onSubmit: (value) => onSendMessage?.(value, uxConfig.free_response?.metadata), hideBorder: true, compact: true, answered: requestInputAnswered }) }));
418
409
  }
419
410
  const isError = message.type === AgentMessageType.ERROR || message.type === AgentMessageType.WARNING;
420
- return (_jsxs("div", { className: "mx-auto w-full max-w-3xl px-1", "data-workstream-id": workstreamId, children: [isError && (_jsx("div", { className: "mb-2 text-xs font-medium text-destructive", children: message.type === AgentMessageType.WARNING ? 'Warning' : 'Error' })), content && (_jsx("div", { className: cn(SUMMARY_PROSE_CLASS, isError && 'rounded-lg border border-destructive/20 bg-destructive/5 px-3 py-2'), style: { overflowWrap: 'anywhere' }, children: _jsx(MarkdownRenderer, { artifactRunId: runId, onProposalSelect: (optionId) => onSendMessage?.(optionId), onProposalSubmit: (text) => onSendMessage?.(text), components: markdownComponents, children: content }) }))] }));
411
+ return (_jsxs("div", { className: "mx-auto w-full max-w-3xl px-1", "data-workstream-id": workstreamId, children: [isError && (_jsx("div", { className: "mb-2 text-xs font-medium text-destructive", children: message.type === AgentMessageType.WARNING ? 'Warning' : 'Error' })), content && (_jsx("div", { className: cn(SUMMARY_PROSE_CLASS, isError && 'rounded-lg border border-destructive/20 bg-destructive/5 px-3 py-2'), style: { overflowWrap: 'anywhere' }, children: _jsx(MarkdownRenderer, { artifactRunId: runId, onArtifactOpen: onOpenArtifact, onProposalSelect: (optionId) => onSendMessage?.(optionId), onProposalSubmit: (text) => onSendMessage?.(text), components: markdownComponents, children: content }) }))] }));
421
412
  }
422
413
  function isRecordValue(value) {
423
414
  return !!value && typeof value === 'object' && !Array.isArray(value);
@@ -542,6 +533,7 @@ const TOOL_DETAIL_SYSTEM_KEYS = new Set([
542
533
  'collection_id',
543
534
  'document_id',
544
535
  'display_role',
536
+ 'duration_ms',
545
537
  'event_class',
546
538
  'id',
547
539
  'object_id',
@@ -559,6 +551,7 @@ const TOOL_DETAIL_SYSTEM_KEYS = new Set([
559
551
  'tools',
560
552
  'message_to_human',
561
553
  'progress_messages',
554
+ 'resources',
562
555
  'source',
563
556
  'token_usage',
564
557
  'checkpoint_at',
@@ -868,6 +861,8 @@ function getRenderableGroupKey(group) {
868
861
  const lastKey = lastMessage ? getAgentMessageRenderKey(lastMessage, 'last') : group.firstTimestamp;
869
862
  return ['group', group.toolRunId, group.firstTimestamp, firstKey, lastKey].filter(Boolean).join(':');
870
863
  }
864
+ // Accepts the augmented render list (which may contain interleaved resource_summary items); those
865
+ // are skipped so the previous *group* timestamp is found regardless of inserted summaries.
871
866
  function getPreviousRenderableGroupTimestamp(groups, index) {
872
867
  for (let previousIndex = index - 1; previousIndex >= 0; previousIndex--) {
873
868
  const group = groups[previousIndex];
@@ -970,6 +965,8 @@ function buildSummaryToolDetailItem(message, index) {
970
965
  finishedAt: getTimestampDetail(details[SUMMARY_TOOL_FINISHED_AT_DETAIL_KEY]) ?? message.timestamp,
971
966
  status: approvalDecisionTitle ? 'error' : details.tool_status,
972
967
  decisionText,
968
+ resources: getResourcesFromMessage(message),
969
+ workflowRunId: message.workflow_run_id,
973
970
  sections: getToolDetailSections(message),
974
971
  };
975
972
  }
@@ -1207,6 +1204,11 @@ function formatToolDetailCopyText(item) {
1207
1204
  parts.push(metadata.join('\n'));
1208
1205
  if (item.text)
1209
1206
  parts.push(item.text);
1207
+ if (item.resources.length > 0) {
1208
+ parts.push(`Resources\n${item.resources
1209
+ .map((resource) => `${resource.label} (${resource.type}:${resource.id}) — ${resource.action}`)
1210
+ .join('\n')}`);
1211
+ }
1210
1212
  for (const section of item.sections) {
1211
1213
  parts.push(`${section.label}\n${formatToolSectionValue(section.value)}`);
1212
1214
  }
@@ -1267,13 +1269,19 @@ function SummaryToolDetailPanel({ item }) {
1267
1269
  return (_jsxs("div", { className: "relative mt-2 rounded-lg border border-border/70 bg-mixer-muted/10 p-3 shadow-sm", children: [hasDetailContent ? (_jsx("div", { className: "absolute end-2 top-2", children: _jsx("button", { type: "button", className: cn('inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted opacity-70 transition', 'hover:bg-mixer-muted/20 hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', copyState === 'copied' && 'text-success opacity-100', copyState === 'failed' && 'text-destructive opacity-100'), onClick: copyDetails, "aria-label": "Copy tool details", title: "Copy tool details", children: copyState === 'copied' ? _jsx(CheckCircle, { className: "size-4" }) : _jsx(CopyIcon, { className: "size-4" }) }) })) : null, _jsxs("div", { className: cn(hasDetailContent && 'pe-7'), children: [_jsx(ToolDetailMetadata, { item: item, hasDetailContent: hasDetailContent }), commandText ? (_jsx("pre", { className: "mb-3 whitespace-pre-wrap break-words font-mono text-sm leading-6 text-foreground/85", children: commandText })) : null, fallbackText ? (_jsx("div", { className: "mb-3 break-words text-sm leading-6 text-foreground/75", children: fallbackText })) : null, item.sections.length > 0 ? (_jsx("div", { className: "space-y-3", children: item.sections.map((section) => (_jsx(ToolDetailSection, { section: section }, section.key))) })) : null] }), copyState === 'failed' && hasDetailContent ? (_jsx("div", { className: "mt-3 text-xs text-destructive", children: "Copy failed" })) : null] }));
1268
1270
  }
1269
1271
  function SummaryToolTimelineItem({ item }) {
1272
+ const { t } = useUITranslation();
1270
1273
  const isDecision = Boolean(item.decisionText);
1271
1274
  const isAttention = !isDecision && (item.status === 'error' || item.status === 'warning');
1272
1275
  const hasMetadata = getToolDetailMetadata(item).length > 0;
1273
1276
  const hasDetails = Boolean(item.command || item.text || item.sections.length || hasMetadata);
1277
+ const hasResources = item.resources.length > 0;
1274
1278
  const [isExpanded, setIsExpanded] = useState(false);
1275
1279
  const iconStatus = isDecision ? undefined : item.status;
1276
- return (_jsxs("div", { className: "min-w-0", children: [_jsxs("button", { type: "button", className: cn('grid w-full grid-cols-[1.5rem_1fr_auto] gap-2 text-start outline-none transition-colors', 'focus-visible:text-foreground focus-visible:underline focus-visible:underline-offset-4', hasDetails ? 'cursor-pointer hover:text-foreground' : 'cursor-default'), onClick: () => hasDetails && setIsExpanded((current) => !current), "aria-expanded": hasDetails ? isExpanded : undefined, disabled: !hasDetails, children: [_jsx("span", { className: cn('flex size-5 items-center justify-center pt-0.5', isAttention ? 'text-attention' : 'text-muted'), children: _jsx(ToolDetailIcon, { kind: item.kind, status: iconStatus }) }), _jsxs("span", { className: "min-w-0 text-sm text-muted", children: [_jsx("span", { className: "break-words", children: item.title }), item.decisionText ? (_jsx(Badge, { variant: "destructive", className: "ms-2 rounded-full shadow-sm shadow-destructive/10", children: item.decisionText })) : null] }), hasDetails ? (_jsx(ChevronDown, { className: cn('mt-0.5 size-4 shrink-0 text-muted opacity-50 transition-transform', !isExpanded && '-rotate-90'), "aria-hidden": "true" })) : null] }), hasDetails && isExpanded ? (_jsx("div", { className: "mt-1", children: _jsx(SummaryToolDetailPanel, { item: item }) })) : null] }));
1280
+ const toggleDetailsLabel = isExpanded ? t('agent.hideDetails') : t('agent.showDetails');
1281
+ const detailsSubject = hasResources ? item.resources.map((resource) => resource.label).join(', ') : item.title;
1282
+ const icon = (_jsx("span", { className: cn('flex size-5 items-center justify-center pt-0.5', isAttention ? 'text-attention' : 'text-muted'), children: _jsx(ToolDetailIcon, { kind: item.kind, status: iconStatus }) }));
1283
+ const chevron = (_jsx(ChevronDown, { className: cn('size-4 shrink-0 text-muted opacity-50 transition-transform', !isExpanded && '-rotate-90'), "aria-hidden": "true" }));
1284
+ return (_jsxs("div", { className: "min-w-0", children: [hasResources ? (_jsxs("div", { className: "grid w-full grid-cols-[1.5rem_1fr_auto] items-center gap-2 text-start", children: [icon, _jsx(ResourceActivityLinkList, { resources: item.resources, workflowRunId: item.workflowRunId }), hasDetails ? (_jsx(VTooltip, { description: toggleDetailsLabel, asChild: true, children: _jsx(Button, { variant: "ghost", size: "xs", className: "size-6 p-0 text-muted", onClick: () => setIsExpanded((current) => !current), "aria-expanded": isExpanded, "aria-label": `${toggleDetailsLabel}: ${detailsSubject}`, children: chevron }) })) : null] })) : (_jsxs("button", { type: "button", className: cn('grid w-full grid-cols-[1.5rem_1fr_auto] gap-2 text-start outline-none transition-colors', 'focus-visible:text-foreground focus-visible:underline focus-visible:underline-offset-4', hasDetails ? 'cursor-pointer hover:text-foreground' : 'cursor-default'), onClick: () => hasDetails && setIsExpanded((current) => !current), "aria-expanded": hasDetails ? isExpanded : undefined, disabled: !hasDetails, children: [icon, _jsxs("span", { className: "min-w-0 text-sm text-muted", children: [_jsx("span", { className: "break-words", children: item.title }), item.decisionText ? (_jsx(Badge, { variant: "destructive", className: "ms-2 rounded-full shadow-sm shadow-destructive/10", children: item.decisionText })) : null] }), hasDetails ? chevron : null] })), hasDetails && isExpanded ? (_jsx("div", { className: "mt-1", children: _jsx(SummaryToolDetailPanel, { item: item }) })) : null] }));
1277
1285
  }
1278
1286
  function SummaryThoughtProseItem({ item, artifactRunId, disableCollapse, }) {
1279
1287
  const { t } = useUITranslation();
@@ -1284,10 +1292,7 @@ function SummaryThoughtProseItem({ item, artifactRunId, disableCollapse, }) {
1284
1292
  const isLong = normalizedText.length > SUMMARY_THOUGHT_COLLAPSE_THRESHOLD ||
1285
1293
  explicitLineCount > SUMMARY_THOUGHT_COLLAPSE_LINES;
1286
1294
  const toggleLabel = isExpanded ? t('agent.showLess') : t('agent.showMore');
1287
- return (_jsxs("div", { className: "min-w-0 py-1", children: [_jsx("div", { "data-testid": "summary-thought-prose", className: cn(SUMMARY_PROSE_CLASS, isLong &&
1288
- !disableCollapse &&
1289
- !isExpanded &&
1290
- '[display:-webkit-box] overflow-hidden [-webkit-box-orient:vertical] [-webkit-line-clamp:6]'), style: { overflowWrap: 'anywhere' }, children: _jsx(MarkdownRenderer, { artifactRunId: artifactRunId, components: DEFAULT_AGENT_MARKDOWN_COMPONENTS, children: text }) }), isLong && !disableCollapse ? (_jsx("div", { className: "mt-1.5 flex justify-end", children: _jsxs("button", { type: "button", "aria-expanded": isExpanded, className: cn('inline-flex items-center gap-1 text-sm font-medium text-muted transition-colors', '[text-decoration:none] hover:text-foreground hover:[text-decoration:none]', 'focus-visible:text-foreground focus-visible:[text-decoration:none]', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring'), onClick: () => setIsExpanded((current) => !current), children: [toggleLabel, _jsx(ChevronDown, { className: cn('size-4 transition-transform', isExpanded && 'rotate-180'), "aria-hidden": "true" })] }) })) : null] }));
1295
+ return (_jsxs("div", { className: "min-w-0 py-1", children: [_jsx("div", { "data-testid": "summary-thought-prose", className: cn(SUMMARY_PROSE_CLASS, isLong && !disableCollapse && !isExpanded && AGENT_LINE_CLAMP_CLASS), style: { overflowWrap: 'anywhere' }, children: _jsx(MarkdownRenderer, { artifactRunId: artifactRunId, components: DEFAULT_AGENT_MARKDOWN_COMPONENTS, children: text }) }), isLong && !disableCollapse ? (_jsx("div", { className: "mt-1.5 flex justify-end", children: _jsxs("button", { type: "button", "aria-expanded": isExpanded, className: cn('inline-flex items-center gap-1 text-sm font-medium text-muted transition-colors', '[text-decoration:none] hover:text-foreground hover:[text-decoration:none]', 'focus-visible:text-foreground focus-visible:[text-decoration:none]', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring'), onClick: () => setIsExpanded((current) => !current), children: [toggleLabel, _jsx(ChevronDown, { className: cn('size-4 transition-transform', isExpanded && 'rotate-180'), "aria-hidden": "true" })] }) })) : null] }));
1291
1296
  }
1292
1297
  function SummaryToolTimeline({ items, artifactRunId, disablePreambleCollapse, }) {
1293
1298
  return (_jsx("div", { className: "mt-3", children: _jsx("div", { className: "space-y-3", children: items.map((item) => item.isPreamble || item.kind === 'think' ? (_jsx(SummaryThoughtProseItem, { item: item, artifactRunId: artifactRunId, disableCollapse: disablePreambleCollapse }, item.key)) : (_jsx(SummaryToolTimelineItem, { item: item }, item.key))) }) }));
@@ -1298,7 +1303,7 @@ function SummaryStreamingMessage({ text, artifactRunId, workstreamId, }) {
1298
1303
  function SummaryStoppedMessage({ message, startTimestamp, endTimestamp, className, }) {
1299
1304
  const { t } = useUITranslation();
1300
1305
  const duration = formatDuration(getDurationSeconds(startTimestamp ?? message.timestamp, endTimestamp ?? message.timestamp));
1301
- return (_jsxs("div", { className: cn('mx-auto w-full max-w-3xl px-1', className), "data-testid": "summary-stopped-message", children: [_jsxs("div", { className: "flex items-center justify-end gap-2 text-lg font-medium text-muted sm:text-xl", children: [_jsx("span", { children: t('agent.youStoppedAfter', { duration }) }), _jsx(MessageDeliveryStatus, { message: message, className: "h-5 w-5" })] }), _jsx("div", { className: "mt-5 border-b border-border/70" })] }));
1306
+ return (_jsxs("div", { className: cn('mx-auto w-full max-w-3xl px-1', className), "data-testid": "summary-stopped-message", children: [_jsxs("div", { className: "flex items-center justify-end gap-2 text-sm font-medium text-muted", children: [_jsx("span", { children: t('agent.youStoppedAfter', { duration }) }), _jsx(MessageDeliveryStatus, { message: message, className: "h-4 w-4" })] }), _jsx("div", { className: "mt-5 border-b border-border/70" })] }));
1302
1307
  }
1303
1308
  function SummaryActivityRow({ label, timestamp, durationSeconds, showElapsed, details, emptyDetailsLabel, defaultExpanded = false, disablePreambleCollapse = false, className, artifactRunId, onSendMessage, answeredToolApprovalRequestInputKeys, resolvedToolApprovalKeys, }) {
1304
1309
  const [isExpanded, setIsExpanded] = useState(defaultExpanded);
@@ -1375,7 +1380,7 @@ function sortAndDedupeMessages(messages, hiddenMessageTypes) {
1375
1380
  }
1376
1381
  // PERFORMANCE: Throttle interval for auto-scroll (ms)
1377
1382
  const SCROLL_THROTTLE_MS = 100; // Max 10 scrolls per second
1378
- function AllMessagesMixedComponent({ messages, workstreamSourceMessages, bottomRef, viewMode = 'stacked', isCompleted = false, streamingMessages = new Map(), onSendMessage, messageItemClassNames, messageStyleOverrides, toolCallGroupClassNames, hideToolCallsInViewMode, streamingMessageClassNames, batchProgressPanelClassNames, artifactRunId, hideWorkstreamTabs, workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionLinkComponent, prependFriendlyMessage, initialRequestData, initialRequestSchema, initialRequestTitle, initialRequestTemplate, showInitialRequest, hiddenMessageTypes, disableAutoScroll = false, renderRequestInputControls = true, activeWorkstream: controlledActiveWorkstream, onActiveWorkstreamChange, }) {
1383
+ function AllMessagesMixedComponent({ messages, workstreamSourceMessages, bottomRef, viewMode = 'stacked', isCompleted = false, streamingMessages = new Map(), onSendMessage, onOpenArtifact, messageItemClassNames, messageStyleOverrides, toolCallGroupClassNames, hideToolCallsInViewMode, streamingMessageClassNames, batchProgressPanelClassNames, artifactRunId, hideWorkstreamTabs, workingIndicatorClassName, messageListClassName, StoreLinkComponent, CollectionLinkComponent, prependFriendlyMessage, initialRequestData, initialRequestSchema, initialRequestTitle, initialRequestTemplate, showInitialRequest, hiddenMessageTypes, disableAutoScroll = false, renderRequestInputControls = true, activeWorkstream: controlledActiveWorkstream, onActiveWorkstreamChange, }) {
1379
1384
  if (!artifactRunId) {
1380
1385
  console.warn('[AllMessagesMixed] artifactRunId prop is missing!');
1381
1386
  }
@@ -1588,6 +1593,34 @@ function AllMessagesMixedComponent({ messages, workstreamSourceMessages, bottomR
1588
1593
  return false;
1589
1594
  return isCompleted || !isInProgress(completionDisplayMessages);
1590
1595
  }, [completionDisplayMessages, hasLatestToolApprovalAllow, hasPendingToolApprovalRequest, isCompleted]);
1596
+ // Per-turn resource summaries. Derived from the full source stream (not the active-tab view) so
1597
+ // child-workstream resources are included, but CLIPPED to the playback cursor so scrubbing back
1598
+ // never reveals resources created later in the turn. Gated on the MAIN workstream reaching either
1599
+ // a terminal state or its final ANSWER, so a completed child tab can't surface a summary early while
1600
+ // reusable interactive workflows can summarize a completed turn. Built from structured tool metadata
1601
+ // (details.resources), never parsed from prose.
1602
+ //
1603
+ // Clip by the cursor message's POSITION in the ordered source, not by `timestamp <= cursor`:
1604
+ // millisecond timestamps are not unique, so a later message sharing the cursor's timestamp would
1605
+ // otherwise leak. indexOf works because sortAndDedupeMessages preserves message references; a
1606
+ // timestamp compare is the fallback if the cursor can't be located (e.g. collapsed by dedup).
1607
+ const clippedResourceSource = useMemo(() => {
1608
+ if (workstreamSourceSorted.length === 0)
1609
+ return workstreamSourceSorted;
1610
+ const cursorMessage = messages[messages.length - 1];
1611
+ if (!cursorMessage)
1612
+ return [];
1613
+ const cursorIndex = workstreamSourceSorted.indexOf(cursorMessage);
1614
+ if (cursorIndex >= 0) {
1615
+ return cursorIndex >= workstreamSourceSorted.length - 1
1616
+ ? workstreamSourceSorted
1617
+ : workstreamSourceSorted.slice(0, cursorIndex + 1);
1618
+ }
1619
+ const cursorTs = getTimestampMs(cursorMessage.timestamp);
1620
+ return workstreamSourceSorted.filter((m) => getTimestampMs(m.timestamp) <= cursorTs);
1621
+ }, [workstreamSourceSorted, messages]);
1622
+ const isLatestResourceTurnComplete = useMemo(() => isCompleted || isResourceSummaryReady(clippedResourceSource), [isCompleted, clippedResourceSource]);
1623
+ const turnResourceSummaries = useMemo(() => segmentTurnResources(clippedResourceSource), [clippedResourceSource]);
1591
1624
  // Split streaming messages:
1592
1625
  // - complete (or stale incomplete) ones are interleaved chronologically
1593
1626
  // - actively incomplete ones render at the end
@@ -1629,10 +1662,16 @@ function AllMessagesMixedComponent({ messages, workstreamSourceMessages, bottomR
1629
1662
  return Math.max(latestDisplayMessageTimestamp, latestStreamingTimestamp);
1630
1663
  }, [incompleteStreaming, latestDisplayMessageTimestamp]);
1631
1664
  const summaryConversationItems = React.useMemo(() => buildSummaryConversationItems(visibleSummaryDisplayMessages, isDisplayCompleted, latestSummaryObservedTimestamp), [visibleSummaryDisplayMessages, isDisplayCompleted, latestSummaryObservedTimestamp]);
1665
+ // Interleave per-turn resource summaries into the sliding (summary) timeline, mirroring the
1666
+ // stacked view. Turn boundaries are user QUESTION message items.
1667
+ const slidingRenderItems = React.useMemo(() => interleaveTurnSummaries(summaryConversationItems, (item) => item.type === 'message' && item.message.type === AgentMessageType.QUESTION, turnResourceSummaries, isLatestResourceTurnComplete), [summaryConversationItems, turnResourceSummaries, isLatestResourceTurnComplete]);
1632
1668
  // Group messages with ONLY complete streaming interleaved for stacked view.
1633
1669
  // Incomplete streaming is rendered separately at the end (avoids re-grouping on every chunk).
1634
1670
  // Assistant prose stays as its own timeline item so thoughts remain visible between tool calls.
1635
1671
  const groupedMessages = React.useMemo(() => mergeConsecutiveToolGroups(groupMessagesWithStreaming(displayMessages, completeStreaming, activeWorkstream)), [displayMessages, completeStreaming, activeWorkstream]);
1672
+ // Interleave per-turn resource summaries into the stacked timeline. Turn boundaries are user
1673
+ // QUESTION groups; turn N's resources come from the full-stream segmentation.
1674
+ const stackedRenderItems = React.useMemo(() => interleaveTurnSummaries(groupedMessages, (group) => group.type === 'single' && group.message.type === AgentMessageType.QUESTION, turnResourceSummaries, isLatestResourceTurnComplete), [groupedMessages, turnResourceSummaries, isLatestResourceTurnComplete]);
1636
1675
  // Show an activity indicator when the latest visible conversation state is not terminal.
1637
1676
  // Older idle/complete messages from previous turns must not suppress the new turn.
1638
1677
  const isAgentWorking = useMemo(() => {
@@ -1964,8 +2003,11 @@ function AllMessagesMixedComponent({ messages, workstreamSourceMessages, bottomR
1964
2003
  !hasRenderableInitialRequest &&
1965
2004
  !(isSummaryView && showActivityFallback) ? (activeWorkstream === 'all' && isAgentWorking && incompleteStreaming.length === 0 ? (_jsx("div", { className: "flex-1 px-2 py-6 sm:px-4", children: _jsx(InitialRequestWaitingCard, { label: t('agent.preparing'), timestamp: fallbackWorkingStartedAtRef.current, className: workingIndicatorClassName }) })) : (_jsx("div", { className: "flex items-center justify-center h-full text-center py-8", children: _jsx("div", { className: "flex items-center px-3 py-2 text-sm text-muted", children: activeWorkstream === 'all'
1966
2005
  ? t('agent.waitingForAgentResponse')
1967
- : t('agent.noMessagesInWorkstream') }) }))) : (_jsxs("div", { className: cn('flex-1 flex flex-col justify-start w-full max-w-full', isSummaryView ? 'gap-6 px-2 py-6 sm:px-4' : 'gap-3 pb-4', messageListClassName), children: [isSummaryView && activeWorkstream !== 'all' && activeWorkstreamName && (_jsx("div", { className: "sticky top-0 z-20 -mx-2 bg-background/95 px-2 pb-2 pt-1 backdrop-blur sm:-mx-4 sm:px-4", children: _jsxs("div", { className: "mx-auto flex w-full max-w-3xl items-center gap-2 border-b border-border/70 pb-3", children: [_jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "size-8 shrink-0 text-muted hover:text-foreground", title: t('agent.backToMainAgent'), onClick: handleShowMainAgentChat, children: _jsx(ArrowLeft, { className: "size-4", "aria-hidden": "true" }) }), _jsx("div", { className: "min-w-0 flex-1 truncate text-sm font-medium text-foreground", children: activeWorkstreamName })] }) })), shouldRenderInitialRequest && (_jsx(InitialRequestMessage, { data: initialRequestData, schema: initialRequestSchema, title: initialRequestTitle, template: initialRequestTemplate, prependFriendlyMessage: prependFriendlyMessage, timestamp: displayMessages[0]?.timestamp ?? Date.now(), isSummaryView: isSummaryView, messageItemClassNames: messageItemClassNames, messageStyleOverrides: messageStyleOverrides, StoreLinkComponent: StoreLinkComponent, CollectionLinkComponent: CollectionLinkComponent }, "initial-request")), showInitialRequestWaitingCard && (_jsx(InitialRequestWaitingCard, { label: summaryActivityFallbackLabel, timestamp: activityStartedTimestamp, className: workingIndicatorClassName })), viewMode === 'stacked' ? (_jsxs(_Fragment, { children: [groupedMessages.map((group, groupIndex) => {
1968
- const isLastGroup = groupIndex === groupedMessages.length - 1;
2006
+ : t('agent.noMessagesInWorkstream') }) }))) : (_jsxs("div", { className: cn('flex-1 flex flex-col justify-start w-full max-w-full', isSummaryView ? 'gap-6 px-2 py-6 sm:px-4' : 'gap-3 pb-4', messageListClassName), children: [isSummaryView && activeWorkstream !== 'all' && activeWorkstreamName && (_jsx("div", { className: "sticky top-0 z-20 -mx-2 bg-background/95 px-2 pb-2 pt-1 backdrop-blur sm:-mx-4 sm:px-4", children: _jsxs("div", { className: "mx-auto flex w-full max-w-3xl items-center gap-2 border-b border-border/70 pb-3", children: [_jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "size-8 shrink-0 text-muted hover:text-foreground", title: t('agent.backToMainAgent'), onClick: handleShowMainAgentChat, children: _jsx(ArrowLeft, { className: "size-4", "aria-hidden": "true" }) }), _jsx("div", { className: "min-w-0 flex-1 truncate text-sm font-medium text-foreground", children: activeWorkstreamName })] }) })), shouldRenderInitialRequest && (_jsx(InitialRequestMessage, { data: initialRequestData, schema: initialRequestSchema, title: initialRequestTitle, template: initialRequestTemplate, prependFriendlyMessage: prependFriendlyMessage, timestamp: displayMessages[0]?.timestamp ?? Date.now(), isSummaryView: isSummaryView, messageItemClassNames: messageItemClassNames, messageStyleOverrides: messageStyleOverrides, StoreLinkComponent: StoreLinkComponent, CollectionLinkComponent: CollectionLinkComponent }, "initial-request")), showInitialRequestWaitingCard && (_jsx(InitialRequestWaitingCard, { label: summaryActivityFallbackLabel, timestamp: activityStartedTimestamp, className: workingIndicatorClassName })), viewMode === 'stacked' ? (_jsxs(_Fragment, { children: [stackedRenderItems.map((group, groupIndex) => {
2007
+ const isLastGroup = groupIndex === stackedRenderItems.length - 1;
2008
+ if (group.type === 'resource_summary') {
2009
+ return (_jsx(ResourceChangeSummary, { resources: group.resources, workflowRunId: artifactRunId, className: "my-2" }, group.key));
2010
+ }
1969
2011
  if (group.type === 'tool_group') {
1970
2012
  // Render grouped tool calls
1971
2013
  const lastMessage = group.messages[group.messages.length - 1];
@@ -1992,16 +2034,19 @@ function AllMessagesMixedComponent({ messages, workstreamSourceMessages, bottomR
1992
2034
  if (shouldHideToolApprovalAnswerMessage(message))
1993
2035
  return null;
1994
2036
  if (isUserStoppedMessage(message)) {
1995
- return (_jsx(TimelineEntry, { children: _jsx(SummaryStoppedMessage, { message: message, startTimestamp: getPreviousRenderableGroupTimestamp(groupedMessages, groupIndex) ?? message.timestamp, endTimestamp: message.timestamp }) }, getAgentMessageRenderKey(message, 'stopped')));
2037
+ return (_jsx(TimelineEntry, { children: _jsx(SummaryStoppedMessage, { message: message, startTimestamp: getPreviousRenderableGroupTimestamp(stackedRenderItems, groupIndex) ?? message.timestamp, endTimestamp: message.timestamp }) }, getAgentMessageRenderKey(message, 'stopped')));
1996
2038
  }
1997
2039
  const isLatestMessage = !isCompleted && isLastGroup && !DONE_STATES.includes(message.type);
1998
2040
  // Special handling for batch progress messages
1999
2041
  if (isBatchProgressMessage(message)) {
2000
2042
  return (_jsx(MessageErrorBoundary, { children: _jsx(BatchProgressPanel, { message: message, batchData: message.details, isRunning: !message.details.completed_at, ...batchProgressPanelClassNames }) }, `batch-${message.details.batch_id}-${message.timestamp}`));
2001
2043
  }
2002
- return (_jsx(TimelineEntry, { status: "message", children: _jsx(MessageErrorBoundary, { children: _jsx(MessageItem, { ...messageItemClassNames, message: message, showPulsatingCircle: isLatestMessage, onSendMessage: onSendMessage, requestInputAnswered: isRequestInputAnswered(message, answeredRequestInputKeys), cardClassName: cn('rounded-lg border border-border bg-background/60 shadow-none', messageItemClassNames?.cardClassName), headerClassName: cn('px-3 py-2', messageItemClassNames?.headerClassName), contentClassName: cn('bg-transparent', messageItemClassNames?.contentClassName), messageStyleOverrides: messageStyleOverrides, StoreLinkComponent: StoreLinkComponent, CollectionLinkComponent: CollectionLinkComponent }) }) }, getAgentMessageRenderKey(message)));
2044
+ return (_jsx(TimelineEntry, { status: "message", children: _jsx(MessageErrorBoundary, { children: _jsx(MessageItem, { ...messageItemClassNames, message: message, showPulsatingCircle: isLatestMessage, onSendMessage: onSendMessage, onOpenArtifact: onOpenArtifact, requestInputAnswered: isRequestInputAnswered(message, answeredRequestInputKeys), cardClassName: cn('rounded-lg border border-border bg-background/60 shadow-none', messageItemClassNames?.cardClassName), headerClassName: cn('px-3 py-2', messageItemClassNames?.headerClassName), contentClassName: cn('bg-transparent', messageItemClassNames?.contentClassName), messageStyleOverrides: messageStyleOverrides, StoreLinkComponent: StoreLinkComponent, CollectionLinkComponent: CollectionLinkComponent }) }) }, getAgentMessageRenderKey(message)));
2045
+ }
2046
+ }), incompleteStreaming.map(({ id, data }) => (_jsx(TimelineEntry, { children: _jsx(StreamingMessage, { ...streamingMessageClassNames, text: data.text, workstreamId: data.workstreamId, isComplete: data.isComplete, timestamp: data.startTimestamp, artifactRunId: artifactRunId, cardClassName: cn('rounded-lg border border-border bg-background/60 shadow-none', streamingMessageClassNames?.cardClassName) }) }, `streaming-incomplete-${id}`))), isAgentWorking && incompleteStreaming.length === 0 && !showInitialRequestWaitingCard && (_jsx(TimelineEntry, { children: _jsxs("div", { className: cn('flex items-center gap-2 py-2 text-sm text-muted', workingIndicatorClassName), children: [_jsx(PulsatingCircle, { size: "sm", color: "blue" }), _jsx("span", { children: t('agent.working') })] }) }))] })) : (_jsxs(_Fragment, { children: [slidingRenderItems.map((item) => {
2047
+ if (item.type === 'resource_summary') {
2048
+ return (_jsx(ResourceChangeSummary, { resources: item.resources, workflowRunId: artifactRunId, className: "my-2" }, item.key));
2003
2049
  }
2004
- }), incompleteStreaming.map(({ id, data }) => (_jsx(TimelineEntry, { children: _jsx(StreamingMessage, { ...streamingMessageClassNames, text: data.text, workstreamId: data.workstreamId, isComplete: data.isComplete, timestamp: data.startTimestamp, artifactRunId: artifactRunId, cardClassName: cn('rounded-lg border border-border bg-background/60 shadow-none', streamingMessageClassNames?.cardClassName) }) }, `streaming-incomplete-${id}`))), isAgentWorking && incompleteStreaming.length === 0 && !showInitialRequestWaitingCard && (_jsx(TimelineEntry, { children: _jsxs("div", { className: cn('flex items-center gap-2 py-2 text-sm text-muted', workingIndicatorClassName), children: [_jsx(PulsatingCircle, { size: "sm", color: "blue" }), _jsx("span", { children: t('agent.working') })] }) }))] })) : (_jsxs(_Fragment, { children: [summaryConversationItems.map((item) => {
2005
2050
  if (item.type === 'work') {
2006
2051
  if (hideToolCallsInViewMode?.includes(viewMode))
2007
2052
  return null;
@@ -2021,7 +2066,7 @@ function AllMessagesMixedComponent({ messages, workstreamSourceMessages, bottomR
2021
2066
  if (isBatchProgressMessage(message)) {
2022
2067
  return (_jsx(MessageErrorBoundary, { children: _jsx(BatchProgressPanel, { message: message, batchData: message.details, isRunning: !message.details.completed_at, ...batchProgressPanelClassNames }) }, getAgentMessageRenderKey(message, 'batch')));
2023
2068
  }
2024
- return (_jsx(MessageErrorBoundary, { children: _jsx(SummaryMessage, { message: message, onSendMessage: onSendMessage, onSelectWorkstream: handleSelectWorkstream, requestInputAnswered: isRequestInputAnswered(message, answeredRequestInputKeys), StoreLinkComponent: StoreLinkComponent, CollectionLinkComponent: CollectionLinkComponent }) }, getAgentMessageRenderKey(message, 'summary')));
2069
+ return (_jsx(MessageErrorBoundary, { children: _jsx(SummaryMessage, { message: message, onSendMessage: onSendMessage, onOpenArtifact: onOpenArtifact, onSelectWorkstream: handleSelectWorkstream, requestInputAnswered: isRequestInputAnswered(message, answeredRequestInputKeys), StoreLinkComponent: StoreLinkComponent, CollectionLinkComponent: CollectionLinkComponent }) }, getAgentMessageRenderKey(message, 'summary')));
2025
2070
  }), incompleteStreaming.map(({ id, data }) => (_jsx(SummaryStreamingMessage, { text: data.text, workstreamId: data.workstreamId, artifactRunId: artifactRunId }, `streaming-incomplete-${id}`))), showActivityFallback && !showInitialRequestWaitingCard && (_jsx(SummaryActivityRow, { label: summaryActivityFallbackLabel, status: "running", timestamp: activityStartedTimestamp, showElapsed: true, className: workingIndicatorClassName }))] })), _jsx("div", { ref: bottomRef, className: "h-2" })] }))] }));
2026
2071
  }
2027
2072
  const shouldDedupeAdjacentCompletedToolMessage = (previous, current) => {