@vertesia/ui 1.0.0-dev.20260128.144200 → 1.0.0-dev.20260225.024852Z

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/lib/esm/core/components/InputList.js +1 -1
  2. package/lib/esm/core/components/InputList.js.map +1 -1
  3. package/lib/esm/core/components/Overlay.js +1 -1
  4. package/lib/esm/core/components/Overlay.js.map +1 -1
  5. package/lib/esm/core/components/SidePanel.js +8 -2
  6. package/lib/esm/core/components/SidePanel.js.map +1 -1
  7. package/lib/esm/core/components/Switch.js +1 -1
  8. package/lib/esm/core/components/Switch.js.map +1 -1
  9. package/lib/esm/core/components/index.js +0 -8
  10. package/lib/esm/core/components/index.js.map +1 -1
  11. package/lib/esm/core/components/shadcn/MessageBox.js.map +1 -0
  12. package/lib/esm/core/components/shadcn/Panel.js +13 -0
  13. package/lib/esm/core/components/shadcn/Panel.js.map +1 -0
  14. package/lib/esm/core/components/{Badge.js → shadcn/badge.js} +2 -2
  15. package/lib/esm/core/components/shadcn/badge.js.map +1 -0
  16. package/lib/esm/core/components/shadcn/command.js +1 -1
  17. package/lib/esm/core/components/shadcn/command.js.map +1 -1
  18. package/lib/esm/core/components/shadcn/filters/filterBar.js +73 -83
  19. package/lib/esm/core/components/shadcn/filters/filterBar.js.map +1 -1
  20. package/lib/esm/core/components/shadcn/index.js +4 -2
  21. package/lib/esm/core/components/shadcn/index.js.map +1 -1
  22. package/lib/esm/core/components/shadcn/modal/ConfirmModal.js +10 -0
  23. package/lib/esm/core/components/shadcn/modal/ConfirmModal.js.map +1 -0
  24. package/lib/esm/core/components/{DeleteModal.js → shadcn/modal/DeleteModal.js} +1 -1
  25. package/lib/esm/core/components/shadcn/modal/DeleteModal.js.map +1 -0
  26. package/lib/esm/core/components/shadcn/{dialog.js → modal/dialog.js} +19 -15
  27. package/lib/esm/core/components/shadcn/modal/dialog.js.map +1 -0
  28. package/lib/esm/core/components/shadcn/modal/index.js +4 -0
  29. package/lib/esm/core/components/shadcn/modal/index.js.map +1 -0
  30. package/lib/esm/core/components/shadcn/popover.js +4 -2
  31. package/lib/esm/core/components/shadcn/popover.js.map +1 -1
  32. package/lib/esm/core/components/shadcn/selectBox.js +19 -15
  33. package/lib/esm/core/components/shadcn/selectBox.js.map +1 -1
  34. package/lib/esm/core/components/shadcn/tabs.js +16 -14
  35. package/lib/esm/core/components/shadcn/tabs.js.map +1 -1
  36. package/lib/esm/core/components/shadcn/textarea.js +30 -2
  37. package/lib/esm/core/components/shadcn/textarea.js.map +1 -1
  38. package/lib/esm/core/components/shadcn/tooltip.js +5 -1
  39. package/lib/esm/core/components/shadcn/tooltip.js.map +1 -1
  40. package/lib/esm/features/agent/PayloadBuilder.js +45 -0
  41. package/lib/esm/features/agent/PayloadBuilder.js.map +1 -1
  42. package/lib/esm/features/agent/chat/AgentChart.js +12 -232
  43. package/lib/esm/features/agent/chat/AgentChart.js.map +1 -1
  44. package/lib/esm/features/agent/chat/AskUserWidget.js +2 -1
  45. package/lib/esm/features/agent/chat/AskUserWidget.js.map +1 -1
  46. package/lib/esm/features/agent/chat/DocumentPanel.js +46 -0
  47. package/lib/esm/features/agent/chat/DocumentPanel.js.map +1 -0
  48. package/lib/esm/features/agent/chat/DocumentTabBar.js +17 -0
  49. package/lib/esm/features/agent/chat/DocumentTabBar.js.map +1 -0
  50. package/lib/esm/features/agent/chat/ModernAgentConversation.js +159 -402
  51. package/lib/esm/features/agent/chat/ModernAgentConversation.js.map +1 -1
  52. package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +99 -57
  53. package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  54. package/lib/esm/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js +4 -4
  55. package/lib/esm/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js.map +1 -1
  56. package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js +4 -4
  57. package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
  58. package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js +3 -3
  59. package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js.map +1 -1
  60. package/lib/esm/features/agent/chat/ModernAgentOutput/MessageInput.js +25 -22
  61. package/lib/esm/features/agent/chat/ModernAgentOutput/MessageInput.js.map +1 -1
  62. package/lib/esm/features/agent/chat/ModernAgentOutput/MessageItem.js +110 -55
  63. package/lib/esm/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
  64. package/lib/esm/features/agent/chat/ModernAgentOutput/StreamingMessage.js +2 -2
  65. package/lib/esm/features/agent/chat/ModernAgentOutput/StreamingMessage.js.map +1 -1
  66. package/lib/esm/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +146 -55
  67. package/lib/esm/features/agent/chat/ModernAgentOutput/ToolCallGroup.js.map +1 -1
  68. package/lib/esm/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js +5 -6
  69. package/lib/esm/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js.map +1 -1
  70. package/lib/esm/features/agent/chat/ModernAgentOutput/utils.js +110 -2
  71. package/lib/esm/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
  72. package/lib/esm/features/agent/chat/SkillWidgetProvider.js +28 -15
  73. package/lib/esm/features/agent/chat/SkillWidgetProvider.js.map +1 -1
  74. package/lib/esm/features/agent/chat/hooks/useAgentPlans.js +146 -0
  75. package/lib/esm/features/agent/chat/hooks/useAgentPlans.js.map +1 -0
  76. package/lib/esm/features/agent/chat/hooks/useAgentStream.js +180 -0
  77. package/lib/esm/features/agent/chat/hooks/useAgentStream.js.map +1 -0
  78. package/lib/esm/features/agent/chat/hooks/useDocumentPanel.js +100 -0
  79. package/lib/esm/features/agent/chat/hooks/useDocumentPanel.js.map +1 -0
  80. package/lib/esm/features/agent/chat/hooks/useFileProcessing.js +90 -0
  81. package/lib/esm/features/agent/chat/hooks/useFileProcessing.js.map +1 -0
  82. package/lib/esm/features/agent/chat/index.js +6 -5
  83. package/lib/esm/features/agent/chat/index.js.map +1 -1
  84. package/lib/esm/features/agent/chat/types/document.js +2 -0
  85. package/lib/esm/features/agent/chat/types/document.js.map +1 -0
  86. package/lib/esm/features/agent/index.js +0 -2
  87. package/lib/esm/features/agent/index.js.map +1 -1
  88. package/lib/esm/features/store/collections/BrowseCollectionView.js +4 -6
  89. package/lib/esm/features/store/collections/BrowseCollectionView.js.map +1 -1
  90. package/lib/esm/features/store/collections/CreateCollection.js +4 -4
  91. package/lib/esm/features/store/collections/CreateCollection.js.map +1 -1
  92. package/lib/esm/features/store/collections/EditCollectionView.js +1 -1
  93. package/lib/esm/features/store/collections/EditCollectionView.js.map +1 -1
  94. package/lib/esm/features/store/objects/DocumentSearchResults.js +5 -5
  95. package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
  96. package/lib/esm/features/store/objects/ExportPropertiesModal.js +3 -3
  97. package/lib/esm/features/store/objects/ExportPropertiesModal.js.map +1 -1
  98. package/lib/esm/features/store/objects/components/ContentOverview.js +19 -120
  99. package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
  100. package/lib/esm/features/store/objects/components/PropertiesEditorModal.js +1 -1
  101. package/lib/esm/features/store/objects/components/PropertiesEditorModal.js.map +1 -1
  102. package/lib/esm/features/store/objects/components/SelectDocumentModal.js +2 -2
  103. package/lib/esm/features/store/objects/components/SelectDocumentModal.js.map +1 -1
  104. package/lib/esm/features/store/objects/components/VectorSearchWidget.js +1 -1
  105. package/lib/esm/features/store/objects/components/VectorSearchWidget.js.map +1 -1
  106. package/lib/esm/features/store/objects/components/index.js +1 -1
  107. package/lib/esm/features/store/objects/components/index.js.map +1 -1
  108. package/lib/esm/features/store/objects/components/useDownloadFile.js +192 -0
  109. package/lib/esm/features/store/objects/components/useDownloadFile.js.map +1 -0
  110. package/lib/esm/features/store/objects/search/DocumentSearchContext.js +1 -2
  111. package/lib/esm/features/store/objects/search/DocumentSearchContext.js.map +1 -1
  112. package/lib/esm/features/store/objects/selection/SelectionActions.js +5 -8
  113. package/lib/esm/features/store/objects/selection/SelectionActions.js.map +1 -1
  114. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js +4 -4
  115. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js.map +1 -1
  116. package/lib/esm/features/store/objects/selection/actions/ChangeTypeAction.js +2 -2
  117. package/lib/esm/features/store/objects/selection/actions/ChangeTypeAction.js.map +1 -1
  118. package/lib/esm/features/store/objects/selection/actions/ExportPropertiesAction.js +1 -1
  119. package/lib/esm/features/store/objects/selection/actions/ExportPropertiesAction.js.map +1 -1
  120. package/lib/esm/features/store/objects/selection/actions/StartWorkflowComponent.js +3 -3
  121. package/lib/esm/features/store/objects/selection/actions/StartWorkflowComponent.js.map +1 -1
  122. package/lib/esm/features/store/objects/upload/DocumentUploadModal.js +13 -13
  123. package/lib/esm/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
  124. package/lib/esm/features/store/objects/upload/useSmartFileUploadProcessing.js +15 -8
  125. package/lib/esm/features/store/objects/upload/useSmartFileUploadProcessing.js.map +1 -1
  126. package/lib/esm/features/store/types/ObjectSchemaEditor.js +6 -5
  127. package/lib/esm/features/store/types/ObjectSchemaEditor.js.map +1 -1
  128. package/lib/esm/features/store/types/SelectContentType.js +3 -3
  129. package/lib/esm/features/store/types/SelectContentType.js.map +1 -1
  130. package/lib/esm/features/store/types/SelectContentTypeModal.js +5 -4
  131. package/lib/esm/features/store/types/SelectContentTypeModal.js.map +1 -1
  132. package/lib/esm/features/store/types/TableLayoutEditor.js +4 -4
  133. package/lib/esm/features/store/types/TableLayoutEditor.js.map +1 -1
  134. package/lib/esm/features/user/UserInfo.js +73 -9
  135. package/lib/esm/features/user/UserInfo.js.map +1 -1
  136. package/lib/esm/features/utils/print.js +0 -1
  137. package/lib/esm/features/utils/print.js.map +1 -1
  138. package/lib/esm/layout/AppLayout.js +3 -4
  139. package/lib/esm/layout/AppLayout.js.map +1 -1
  140. package/lib/esm/layout/Sidebar.js +5 -5
  141. package/lib/esm/layout/Sidebar.js.map +1 -1
  142. package/lib/esm/router/HistoryNavigator.js +7 -1
  143. package/lib/esm/router/HistoryNavigator.js.map +1 -1
  144. package/lib/esm/router/Nav.js +2 -2
  145. package/lib/esm/router/Nav.js.map +1 -1
  146. package/lib/esm/session/UserSession.js +35 -9
  147. package/lib/esm/session/UserSession.js.map +1 -1
  148. package/lib/esm/session/UserSessionProvider.js +3 -2
  149. package/lib/esm/session/UserSessionProvider.js.map +1 -1
  150. package/lib/esm/shell/apps/AppProjectSelector.js +2 -2
  151. package/lib/esm/shell/apps/AppProjectSelector.js.map +1 -1
  152. package/lib/esm/shell/apps/StandaloneApp.js +2 -2
  153. package/lib/esm/shell/apps/StandaloneApp.js.map +1 -1
  154. package/lib/esm/shell/login/InviteAcceptModal.js +2 -2
  155. package/lib/esm/shell/login/InviteAcceptModal.js.map +1 -1
  156. package/lib/esm/shell/login/SignInModal.js +1 -1
  157. package/lib/esm/shell/login/SignInModal.js.map +1 -1
  158. package/lib/esm/shell/login/SignupForm.js +2 -2
  159. package/lib/esm/shell/login/SignupForm.js.map +1 -1
  160. package/lib/esm/shell/login/UserInfo.js +2 -2
  161. package/lib/esm/shell/login/UserInfo.js.map +1 -1
  162. package/lib/esm/widgets/json-view/JSONCode.js +1 -1
  163. package/lib/esm/widgets/json-view/JSONCode.js.map +1 -1
  164. package/lib/esm/widgets/json-view/JSONDisplay.js +1 -1
  165. package/lib/esm/widgets/json-view/JSONDisplay.js.map +1 -1
  166. package/lib/esm/widgets/markdown/ArtifactContentRenderer.js +84 -13
  167. package/lib/esm/widgets/markdown/ArtifactContentRenderer.js.map +1 -1
  168. package/lib/esm/widgets/markdown/MarkdownFigure.js +40 -0
  169. package/lib/esm/widgets/markdown/MarkdownFigure.js.map +1 -0
  170. package/lib/esm/widgets/markdown/MarkdownRenderer.js +42 -7
  171. package/lib/esm/widgets/markdown/MarkdownRenderer.js.map +1 -1
  172. package/lib/esm/widgets/markdown/MermaidDiagram.js +80 -5
  173. package/lib/esm/widgets/markdown/MermaidDiagram.js.map +1 -1
  174. package/lib/esm/widgets/markdown/codeBlockHandlers.js +33 -33
  175. package/lib/esm/widgets/markdown/codeBlockHandlers.js.map +1 -1
  176. package/lib/esm/widgets/markdown/codeBlockHandlers.test.js +2 -29
  177. package/lib/esm/widgets/markdown/codeBlockHandlers.test.js.map +1 -1
  178. package/lib/esm/widgets/markdown/index.js +1 -0
  179. package/lib/esm/widgets/markdown/index.js.map +1 -1
  180. package/lib/esm/widgets/markdown/normalizeCustomSchemeLinks.js +77 -0
  181. package/lib/esm/widgets/markdown/normalizeCustomSchemeLinks.js.map +1 -0
  182. package/lib/esm/widgets/markdown/normalizeDirectives.js +45 -0
  183. package/lib/esm/widgets/markdown/normalizeDirectives.js.map +1 -0
  184. package/lib/esm/widgets/markdown/remarkDirectiveHandler.js +96 -0
  185. package/lib/esm/widgets/markdown/remarkDirectiveHandler.js.map +1 -0
  186. package/lib/esm/widgets/monacoEditor/MonacoEditor.js +8 -14
  187. package/lib/esm/widgets/monacoEditor/MonacoEditor.js.map +1 -1
  188. package/lib/esm/widgets/schema-editor/ManagedSchema.js.map +1 -1
  189. package/lib/esm/widgets/schema-editor/editor/PropertyEditor.js +3 -3
  190. package/lib/esm/widgets/schema-editor/editor/PropertyEditor.js.map +1 -1
  191. package/lib/esm/widgets/schema-editor/json-schema4-utils.js.map +1 -1
  192. package/lib/tsconfig.tsbuildinfo +1 -1
  193. package/lib/types/core/components/SidePanel.d.ts +4 -1
  194. package/lib/types/core/components/SidePanel.d.ts.map +1 -1
  195. package/lib/types/core/components/index.d.ts +0 -8
  196. package/lib/types/core/components/index.d.ts.map +1 -1
  197. package/lib/types/core/components/shadcn/MessageBox.d.ts.map +1 -0
  198. package/lib/types/core/components/{Panel.d.ts → shadcn/Panel.d.ts} +3 -1
  199. package/lib/types/core/components/shadcn/Panel.d.ts.map +1 -0
  200. package/lib/types/core/components/{Badge.d.ts → shadcn/badge.d.ts} +4 -4
  201. package/lib/types/core/components/shadcn/badge.d.ts.map +1 -0
  202. package/lib/types/core/components/shadcn/button.d.ts +1 -1
  203. package/lib/types/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
  204. package/lib/types/core/components/shadcn/index.d.ts +4 -2
  205. package/lib/types/core/components/shadcn/index.d.ts.map +1 -1
  206. package/lib/types/core/components/shadcn/input.d.ts +1 -1
  207. package/lib/types/core/components/shadcn/modal/ConfirmModal.d.ts.map +1 -0
  208. package/lib/types/core/components/shadcn/modal/DeleteModal.d.ts.map +1 -0
  209. package/lib/types/core/components/shadcn/{dialog.d.ts → modal/dialog.d.ts} +7 -4
  210. package/lib/types/core/components/shadcn/modal/dialog.d.ts.map +1 -0
  211. package/lib/types/core/components/shadcn/modal/index.d.ts +4 -0
  212. package/lib/types/core/components/shadcn/modal/index.d.ts.map +1 -0
  213. package/lib/types/core/components/shadcn/popover.d.ts.map +1 -1
  214. package/lib/types/core/components/shadcn/selectBox.d.ts +9 -5
  215. package/lib/types/core/components/shadcn/selectBox.d.ts.map +1 -1
  216. package/lib/types/core/components/shadcn/tabs.d.ts +14 -5
  217. package/lib/types/core/components/shadcn/tabs.d.ts.map +1 -1
  218. package/lib/types/core/components/shadcn/textarea.d.ts +6 -2
  219. package/lib/types/core/components/shadcn/textarea.d.ts.map +1 -1
  220. package/lib/types/core/components/shadcn/tooltip.d.ts.map +1 -1
  221. package/lib/types/features/agent/PayloadBuilder.d.ts +22 -4
  222. package/lib/types/features/agent/PayloadBuilder.d.ts.map +1 -1
  223. package/lib/types/features/agent/chat/AgentChart.d.ts +3 -44
  224. package/lib/types/features/agent/chat/AgentChart.d.ts.map +1 -1
  225. package/lib/types/features/agent/chat/AskUserWidget.d.ts.map +1 -1
  226. package/lib/types/features/agent/chat/DocumentPanel.d.ts +16 -0
  227. package/lib/types/features/agent/chat/DocumentPanel.d.ts.map +1 -0
  228. package/lib/types/features/agent/chat/DocumentTabBar.d.ts +10 -0
  229. package/lib/types/features/agent/chat/DocumentTabBar.d.ts.map +1 -0
  230. package/lib/types/features/agent/chat/ModernAgentConversation.d.ts +69 -1
  231. package/lib/types/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
  232. package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +36 -1
  233. package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
  234. package/lib/types/features/agent/chat/ModernAgentOutput/BatchProgressPanel.d.ts +18 -2
  235. package/lib/types/features/agent/chat/ModernAgentOutput/BatchProgressPanel.d.ts.map +1 -1
  236. package/lib/types/features/agent/chat/ModernAgentOutput/Header.d.ts +4 -7
  237. package/lib/types/features/agent/chat/ModernAgentOutput/Header.d.ts.map +1 -1
  238. package/lib/types/features/agent/chat/ModernAgentOutput/MessageInput.d.ts +2 -1
  239. package/lib/types/features/agent/chat/ModernAgentOutput/MessageInput.d.ts.map +1 -1
  240. package/lib/types/features/agent/chat/ModernAgentOutput/MessageItem.d.ts +35 -7
  241. package/lib/types/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
  242. package/lib/types/features/agent/chat/ModernAgentOutput/StreamingMessage.d.ts +11 -1
  243. package/lib/types/features/agent/chat/ModernAgentOutput/StreamingMessage.d.ts.map +1 -1
  244. package/lib/types/features/agent/chat/ModernAgentOutput/ToolCallGroup.d.ts +20 -2
  245. package/lib/types/features/agent/chat/ModernAgentOutput/ToolCallGroup.d.ts.map +1 -1
  246. package/lib/types/features/agent/chat/ModernAgentOutput/WorkstreamTabs.d.ts.map +1 -1
  247. package/lib/types/features/agent/chat/ModernAgentOutput/utils.d.ts +18 -1
  248. package/lib/types/features/agent/chat/ModernAgentOutput/utils.d.ts.map +1 -1
  249. package/lib/types/features/agent/chat/SkillWidgetProvider.d.ts.map +1 -1
  250. package/lib/types/features/agent/chat/hooks/useAgentPlans.d.ts +22 -0
  251. package/lib/types/features/agent/chat/hooks/useAgentPlans.d.ts.map +1 -0
  252. package/lib/types/features/agent/chat/hooks/useAgentStream.d.ts +42 -0
  253. package/lib/types/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -0
  254. package/lib/types/features/agent/chat/hooks/useDocumentPanel.d.ts +22 -0
  255. package/lib/types/features/agent/chat/hooks/useDocumentPanel.d.ts.map +1 -0
  256. package/lib/types/features/agent/chat/hooks/useFileProcessing.d.ts +27 -0
  257. package/lib/types/features/agent/chat/hooks/useFileProcessing.d.ts.map +1 -0
  258. package/lib/types/features/agent/chat/index.d.ts +12 -8
  259. package/lib/types/features/agent/chat/index.d.ts.map +1 -1
  260. package/lib/types/features/agent/chat/types/document.d.ts +5 -0
  261. package/lib/types/features/agent/chat/types/document.d.ts.map +1 -0
  262. package/lib/types/features/agent/index.d.ts +0 -2
  263. package/lib/types/features/agent/index.d.ts.map +1 -1
  264. package/lib/types/features/store/collections/BrowseCollectionView.d.ts.map +1 -1
  265. package/lib/types/features/store/objects/ExportPropertiesModal.d.ts.map +1 -1
  266. package/lib/types/features/store/objects/components/ContentOverview.d.ts.map +1 -1
  267. package/lib/types/features/store/objects/components/PropertiesEditorModal.d.ts.map +1 -1
  268. package/lib/types/features/store/objects/components/index.d.ts +1 -1
  269. package/lib/types/features/store/objects/components/index.d.ts.map +1 -1
  270. package/lib/types/features/store/objects/components/useDownloadFile.d.ts +35 -0
  271. package/lib/types/features/store/objects/components/useDownloadFile.d.ts.map +1 -0
  272. package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
  273. package/lib/types/features/store/objects/selection/SelectionActions.d.ts +1 -1
  274. package/lib/types/features/store/objects/selection/SelectionActions.d.ts.map +1 -1
  275. package/lib/types/features/store/objects/selection/actions/ChangeTypeAction.d.ts.map +1 -1
  276. package/lib/types/features/store/objects/selection/actions/ExportPropertiesAction.d.ts.map +1 -1
  277. package/lib/types/features/store/objects/upload/useSmartFileUploadProcessing.d.ts.map +1 -1
  278. package/lib/types/features/store/types/ObjectSchemaEditor.d.ts +2 -1
  279. package/lib/types/features/store/types/ObjectSchemaEditor.d.ts.map +1 -1
  280. package/lib/types/features/store/types/SelectContentTypeModal.d.ts +1 -1
  281. package/lib/types/features/store/types/SelectContentTypeModal.d.ts.map +1 -1
  282. package/lib/types/features/store/types/TableLayoutEditor.d.ts +2 -1
  283. package/lib/types/features/store/types/TableLayoutEditor.d.ts.map +1 -1
  284. package/lib/types/features/user/UserInfo.d.ts +12 -1
  285. package/lib/types/features/user/UserInfo.d.ts.map +1 -1
  286. package/lib/types/features/utils/print.d.ts.map +1 -1
  287. package/lib/types/layout/AppLayout.d.ts.map +1 -1
  288. package/lib/types/layout/Sidebar.d.ts +4 -2
  289. package/lib/types/layout/Sidebar.d.ts.map +1 -1
  290. package/lib/types/router/HistoryNavigator.d.ts.map +1 -1
  291. package/lib/types/router/Nav.d.ts +6 -1
  292. package/lib/types/router/Nav.d.ts.map +1 -1
  293. package/lib/types/session/UserSession.d.ts.map +1 -1
  294. package/lib/types/session/UserSessionProvider.d.ts +1 -0
  295. package/lib/types/session/UserSessionProvider.d.ts.map +1 -1
  296. package/lib/types/widgets/json-view/JSONCode.d.ts.map +1 -1
  297. package/lib/types/widgets/markdown/ArtifactContentRenderer.d.ts +10 -1
  298. package/lib/types/widgets/markdown/ArtifactContentRenderer.d.ts.map +1 -1
  299. package/lib/types/widgets/markdown/MarkdownFigure.d.ts +15 -0
  300. package/lib/types/widgets/markdown/MarkdownFigure.d.ts.map +1 -0
  301. package/lib/types/widgets/markdown/MarkdownRenderer.d.ts.map +1 -1
  302. package/lib/types/widgets/markdown/MermaidDiagram.d.ts.map +1 -1
  303. package/lib/types/widgets/markdown/codeBlockHandlers.d.ts +5 -2
  304. package/lib/types/widgets/markdown/codeBlockHandlers.d.ts.map +1 -1
  305. package/lib/types/widgets/markdown/index.d.ts +1 -0
  306. package/lib/types/widgets/markdown/index.d.ts.map +1 -1
  307. package/lib/types/widgets/markdown/normalizeCustomSchemeLinks.d.ts +9 -0
  308. package/lib/types/widgets/markdown/normalizeCustomSchemeLinks.d.ts.map +1 -0
  309. package/lib/types/widgets/markdown/normalizeDirectives.d.ts +20 -0
  310. package/lib/types/widgets/markdown/normalizeDirectives.d.ts.map +1 -0
  311. package/lib/types/widgets/markdown/remarkDirectiveHandler.d.ts +2 -0
  312. package/lib/types/widgets/markdown/remarkDirectiveHandler.d.ts.map +1 -0
  313. package/lib/types/widgets/monacoEditor/MonacoEditor.d.ts +1 -3
  314. package/lib/types/widgets/monacoEditor/MonacoEditor.d.ts.map +1 -1
  315. package/lib/types/widgets/schema-editor/ManagedSchema.d.ts +1 -1
  316. package/lib/types/widgets/schema-editor/ManagedSchema.d.ts.map +1 -1
  317. package/lib/vertesia-ui-core.js +1 -1
  318. package/lib/vertesia-ui-core.js.map +1 -1
  319. package/lib/vertesia-ui-features.js +1 -1
  320. package/lib/vertesia-ui-features.js.map +1 -1
  321. package/lib/vertesia-ui-layout.js +1 -1
  322. package/lib/vertesia-ui-layout.js.map +1 -1
  323. package/lib/vertesia-ui-router.js +1 -1
  324. package/lib/vertesia-ui-router.js.map +1 -1
  325. package/lib/vertesia-ui-session.js +1 -1
  326. package/lib/vertesia-ui-session.js.map +1 -1
  327. package/lib/vertesia-ui-shell.js +1 -1
  328. package/lib/vertesia-ui-shell.js.map +1 -1
  329. package/lib/vertesia-ui-widgets.js +1 -1
  330. package/lib/vertesia-ui-widgets.js.map +1 -1
  331. package/package.json +14 -10
  332. package/src/core/components/InputList.tsx +1 -1
  333. package/src/core/components/Overlay.tsx +1 -1
  334. package/src/core/components/SidePanel.tsx +29 -15
  335. package/src/core/components/Switch.tsx +1 -1
  336. package/src/core/components/index.ts +0 -8
  337. package/src/core/components/shadcn/Panel.tsx +50 -0
  338. package/src/core/components/{Badge.tsx → shadcn/badge.tsx} +3 -3
  339. package/src/core/components/shadcn/command.tsx +1 -1
  340. package/src/core/components/shadcn/filters/filterBar.tsx +76 -87
  341. package/src/core/components/shadcn/index.ts +5 -3
  342. package/src/core/components/{ConfirmModal.tsx → shadcn/modal/ConfirmModal.tsx} +8 -8
  343. package/src/core/components/{DeleteModal.tsx → shadcn/modal/DeleteModal.tsx} +1 -1
  344. package/src/core/components/shadcn/{dialog.tsx → modal/dialog.tsx} +43 -32
  345. package/src/core/components/shadcn/modal/index.ts +3 -0
  346. package/src/core/components/shadcn/popover.tsx +4 -2
  347. package/src/core/components/shadcn/selectBox.tsx +71 -52
  348. package/src/core/components/shadcn/tabs.tsx +36 -19
  349. package/src/core/components/shadcn/textarea.tsx +43 -2
  350. package/src/core/components/shadcn/tooltip.tsx +23 -17
  351. package/src/features/agent/PayloadBuilder.tsx +70 -9
  352. package/src/features/agent/chat/AgentChart.tsx +46 -678
  353. package/src/features/agent/chat/AskUserWidget.tsx +4 -3
  354. package/src/features/agent/chat/DocumentPanel.tsx +120 -0
  355. package/src/features/agent/chat/DocumentTabBar.tsx +49 -0
  356. package/src/features/agent/chat/ModernAgentConversation.tsx +403 -549
  357. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +162 -55
  358. package/src/features/agent/chat/ModernAgentOutput/BatchProgressPanel.tsx +40 -10
  359. package/src/features/agent/chat/ModernAgentOutput/Header.tsx +12 -16
  360. package/src/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.tsx +3 -3
  361. package/src/features/agent/chat/ModernAgentOutput/MessageInput.tsx +68 -75
  362. package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +206 -94
  363. package/src/features/agent/chat/ModernAgentOutput/StreamingMessage.tsx +22 -5
  364. package/src/features/agent/chat/ModernAgentOutput/ToolCallGroup.tsx +295 -113
  365. package/src/features/agent/chat/ModernAgentOutput/WorkstreamTabs.tsx +11 -8
  366. package/src/features/agent/chat/ModernAgentOutput/utils.ts +133 -4
  367. package/src/features/agent/chat/SkillWidgetProvider.tsx +32 -15
  368. package/src/features/agent/chat/hooks/useAgentPlans.ts +190 -0
  369. package/src/features/agent/chat/hooks/useAgentStream.ts +239 -0
  370. package/src/features/agent/chat/hooks/useDocumentPanel.ts +118 -0
  371. package/src/features/agent/chat/hooks/useFileProcessing.ts +126 -0
  372. package/src/features/agent/chat/index.ts +18 -17
  373. package/src/features/agent/chat/types/document.ts +4 -0
  374. package/src/features/agent/index.ts +0 -2
  375. package/src/features/store/collections/BrowseCollectionView.tsx +5 -8
  376. package/src/features/store/collections/CreateCollection.tsx +8 -8
  377. package/src/features/store/collections/EditCollectionView.tsx +1 -1
  378. package/src/features/store/objects/DocumentSearchResults.tsx +9 -13
  379. package/src/features/store/objects/ExportPropertiesModal.tsx +9 -7
  380. package/src/features/store/objects/components/ContentOverview.tsx +29 -155
  381. package/src/features/store/objects/components/PropertiesEditorModal.tsx +0 -1
  382. package/src/features/store/objects/components/SelectDocumentModal.tsx +6 -6
  383. package/src/features/store/objects/components/VectorSearchWidget.tsx +2 -2
  384. package/src/features/store/objects/components/index.ts +1 -1
  385. package/src/features/store/objects/components/useDownloadFile.ts +237 -0
  386. package/src/features/store/objects/search/DocumentSearchContext.ts +1 -2
  387. package/src/features/store/objects/selection/SelectionActions.tsx +0 -4
  388. package/src/features/store/objects/selection/actions/AddToCollectionAction.tsx +13 -13
  389. package/src/features/store/objects/selection/actions/ChangeTypeAction.tsx +2 -6
  390. package/src/features/store/objects/selection/actions/ExportPropertiesAction.tsx +1 -3
  391. package/src/features/store/objects/selection/actions/StartWorkflowComponent.tsx +8 -8
  392. package/src/features/store/objects/upload/DocumentUploadModal.tsx +25 -25
  393. package/src/features/store/objects/upload/useSmartFileUploadProcessing.ts +16 -10
  394. package/src/features/store/types/ObjectSchemaEditor.tsx +32 -29
  395. package/src/features/store/types/SelectContentType.tsx +3 -3
  396. package/src/features/store/types/SelectContentTypeModal.tsx +17 -30
  397. package/src/features/store/types/TableLayoutEditor.tsx +14 -18
  398. package/src/features/user/UserInfo.tsx +176 -10
  399. package/src/features/utils/print.ts +0 -1
  400. package/src/layout/AppLayout.tsx +16 -44
  401. package/src/layout/Sidebar.tsx +7 -5
  402. package/src/router/HistoryNavigator.ts +9 -1
  403. package/src/router/Nav.tsx +7 -2
  404. package/src/session/UserSession.ts +38 -9
  405. package/src/session/UserSessionProvider.tsx +3 -2
  406. package/src/shell/apps/AppProjectSelector.tsx +2 -2
  407. package/src/shell/apps/StandaloneApp.tsx +3 -3
  408. package/src/shell/login/InviteAcceptModal.tsx +6 -6
  409. package/src/shell/login/SignInModal.tsx +1 -1
  410. package/src/shell/login/SignupForm.tsx +3 -3
  411. package/src/shell/login/UserInfo.tsx +5 -5
  412. package/src/widgets/json-view/JSONCode.tsx +1 -3
  413. package/src/widgets/json-view/JSONDisplay.tsx +1 -1
  414. package/src/widgets/markdown/ArtifactContentRenderer.tsx +115 -14
  415. package/src/widgets/markdown/MarkdownFigure.tsx +100 -0
  416. package/src/widgets/markdown/MarkdownRenderer.tsx +62 -9
  417. package/src/widgets/markdown/MermaidDiagram.tsx +97 -5
  418. package/src/widgets/markdown/codeBlockHandlers.test.tsx +3 -34
  419. package/src/widgets/markdown/codeBlockHandlers.tsx +47 -42
  420. package/src/widgets/markdown/index.ts +1 -0
  421. package/src/widgets/markdown/markdown.css +192 -0
  422. package/src/widgets/markdown/normalizeCustomSchemeLinks.test.ts +86 -0
  423. package/src/widgets/markdown/normalizeCustomSchemeLinks.ts +91 -0
  424. package/src/widgets/markdown/normalizeDirectives.ts +50 -0
  425. package/src/widgets/markdown/remarkDirectiveHandler.ts +119 -0
  426. package/src/widgets/monacoEditor/MonacoEditor.tsx +8 -22
  427. package/src/widgets/schema-editor/ManagedSchema.ts +1 -1
  428. package/src/widgets/schema-editor/editor/PropertyEditor.tsx +5 -5
  429. package/src/widgets/schema-editor/json-schema4-utils.ts +1 -1
  430. package/lib/esm/core/components/Badge.js.map +0 -1
  431. package/lib/esm/core/components/Button.js +0 -32
  432. package/lib/esm/core/components/Button.js.map +0 -1
  433. package/lib/esm/core/components/ConfirmModal.js +0 -10
  434. package/lib/esm/core/components/ConfirmModal.js.map +0 -1
  435. package/lib/esm/core/components/DeleteModal.js.map +0 -1
  436. package/lib/esm/core/components/MessageBox.js.map +0 -1
  437. package/lib/esm/core/components/Modal.js +0 -26
  438. package/lib/esm/core/components/Modal.js.map +0 -1
  439. package/lib/esm/core/components/Panel.js +0 -8
  440. package/lib/esm/core/components/Panel.js.map +0 -1
  441. package/lib/esm/core/components/SelectBox.js +0 -67
  442. package/lib/esm/core/components/SelectBox.js.map +0 -1
  443. package/lib/esm/core/components/shadcn/dialog.js.map +0 -1
  444. package/lib/esm/core/components/tabs/Tabs.js +0 -78
  445. package/lib/esm/core/components/tabs/Tabs.js.map +0 -1
  446. package/lib/esm/core/components/tabs/TabsContext.js +0 -7
  447. package/lib/esm/core/components/tabs/TabsContext.js.map +0 -1
  448. package/lib/esm/core/components/tabs/index.js +0 -3
  449. package/lib/esm/core/components/tabs/index.js.map +0 -1
  450. package/lib/esm/features/agent/createChartTool.js +0 -632
  451. package/lib/esm/features/agent/createChartTool.js.map +0 -1
  452. package/lib/esm/features/agent/examples.js +0 -295
  453. package/lib/esm/features/agent/examples.js.map +0 -1
  454. package/lib/esm/features/agent/visualization.js +0 -165
  455. package/lib/esm/features/agent/visualization.js.map +0 -1
  456. package/lib/esm/features/store/objects/components/useDownloadObject.js +0 -21
  457. package/lib/esm/features/store/objects/components/useDownloadObject.js.map +0 -1
  458. package/lib/types/core/components/Badge.d.ts.map +0 -1
  459. package/lib/types/core/components/Button.d.ts +0 -14
  460. package/lib/types/core/components/Button.d.ts.map +0 -1
  461. package/lib/types/core/components/ConfirmModal.d.ts.map +0 -1
  462. package/lib/types/core/components/DeleteModal.d.ts.map +0 -1
  463. package/lib/types/core/components/MessageBox.d.ts.map +0 -1
  464. package/lib/types/core/components/Modal.d.ts +0 -30
  465. package/lib/types/core/components/Modal.d.ts.map +0 -1
  466. package/lib/types/core/components/Panel.d.ts.map +0 -1
  467. package/lib/types/core/components/SelectBox.d.ts +0 -36
  468. package/lib/types/core/components/SelectBox.d.ts.map +0 -1
  469. package/lib/types/core/components/shadcn/dialog.d.ts.map +0 -1
  470. package/lib/types/core/components/tabs/Tabs.d.ts +0 -25
  471. package/lib/types/core/components/tabs/Tabs.d.ts.map +0 -1
  472. package/lib/types/core/components/tabs/TabsContext.d.ts +0 -17
  473. package/lib/types/core/components/tabs/TabsContext.d.ts.map +0 -1
  474. package/lib/types/core/components/tabs/index.d.ts +0 -3
  475. package/lib/types/core/components/tabs/index.d.ts.map +0 -1
  476. package/lib/types/features/agent/createChartTool.d.ts +0 -178
  477. package/lib/types/features/agent/createChartTool.d.ts.map +0 -1
  478. package/lib/types/features/agent/examples.d.ts +0 -59
  479. package/lib/types/features/agent/examples.d.ts.map +0 -1
  480. package/lib/types/features/agent/visualization.d.ts +0 -95
  481. package/lib/types/features/agent/visualization.d.ts.map +0 -1
  482. package/lib/types/features/store/objects/components/useDownloadObject.d.ts +0 -4
  483. package/lib/types/features/store/objects/components/useDownloadObject.d.ts.map +0 -1
  484. package/src/core/components/Button.tsx +0 -63
  485. package/src/core/components/Modal.tsx +0 -144
  486. package/src/core/components/Panel.tsx +0 -34
  487. package/src/core/components/SelectBox.tsx +0 -188
  488. package/src/core/components/tabs/Tabs.tsx +0 -132
  489. package/src/core/components/tabs/TabsContext.ts +0 -25
  490. package/src/core/components/tabs/index.ts +0 -2
  491. package/src/features/agent/CHART_INSTRUCTIONS.md +0 -228
  492. package/src/features/agent/createChartTool.ts +0 -643
  493. package/src/features/agent/examples.ts +0 -321
  494. package/src/features/agent/visualization.ts +0 -227
  495. package/src/features/store/objects/components/useDownloadObject.ts +0 -29
  496. /package/lib/esm/core/components/{MessageBox.js → shadcn/MessageBox.js} +0 -0
  497. /package/lib/types/core/components/{MessageBox.d.ts → shadcn/MessageBox.d.ts} +0 -0
  498. /package/lib/types/core/components/{ConfirmModal.d.ts → shadcn/modal/ConfirmModal.d.ts} +0 -0
  499. /package/lib/types/core/components/{DeleteModal.d.ts → shadcn/modal/DeleteModal.d.ts} +0 -0
  500. /package/src/core/components/{MessageBox.tsx → shadcn/MessageBox.tsx} +0 -0
@@ -1,5 +1,5 @@
1
- import { AgentMessage } from "@vertesia/common";
2
- import { Button, useToast } from "@vertesia/ui/core";
1
+ import { AgentMessage, AgentMessageType } from "@vertesia/common";
2
+ import { Button, cn, useToast } from "@vertesia/ui/core";
3
3
  import { useUserSession } from "@vertesia/ui/session";
4
4
  import { MarkdownRenderer } from "@vertesia/ui/widgets";
5
5
  import dayjs from "dayjs";
@@ -10,11 +10,80 @@ import { useImageLightbox } from "../ImageLightbox";
10
10
  import { useArtifactUrlCache, getArtifactCacheKey } from "../useArtifactUrlCache.js";
11
11
  import { ToolExecutionStatus } from "./utils";
12
12
 
13
- interface ToolCallGroupProps {
13
+ /** Keys that are internal metadata and not interesting to display */
14
+ const META_KEYS = new Set([
15
+ 'tool', 'tool_run_id', 'activity_group_id', 'event_class',
16
+ 'tool_iteration', 'tool_status', 'tools', 'streamed',
17
+ 'files', 'outputFiles',
18
+ ]);
19
+
20
+ /** Filter out internal metadata keys, return user-facing detail entries */
21
+ function extractInterestingDetails(
22
+ details: Record<string, unknown> | undefined
23
+ ): Array<[string, unknown]> {
24
+ if (!details) return [];
25
+ return Object.entries(details).filter(
26
+ ([key, value]) => !META_KEYS.has(key) && value !== undefined && value !== null && value !== ''
27
+ );
28
+ }
29
+
30
+ /** Convert snake_case or camelCase key to a readable label */
31
+ function formatDetailKey(key: string): string {
32
+ return key
33
+ .replace(/_/g, ' ')
34
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
35
+ .replace(/^./, c => c.toUpperCase());
36
+ }
37
+
38
+ /** Badge color per status */
39
+ function statusBadgeClass(status?: ToolExecutionStatus): string {
40
+ switch (status) {
41
+ case 'completed':
42
+ return 'bg-green-50 dark:bg-green-900/30 text-green-700 dark:text-green-300 border-green-200 dark:border-green-800';
43
+ case 'running':
44
+ return 'bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 border-blue-200 dark:border-blue-800';
45
+ case 'error':
46
+ return 'bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-300 border-red-200 dark:border-red-800';
47
+ case 'warning':
48
+ return 'bg-yellow-50 dark:bg-yellow-900/30 text-yellow-700 dark:text-yellow-300 border-yellow-200 dark:border-yellow-800';
49
+ default:
50
+ return '';
51
+ }
52
+ }
53
+
54
+ export interface ToolCallGroupProps {
14
55
  messages: AgentMessage[];
15
56
  showPulsatingCircle?: boolean;
16
57
  toolRunId?: string;
17
58
  toolStatus?: ToolExecutionStatus;
59
+ /** Additional className for the root container */
60
+ rootClassName?: string;
61
+ /** Additional className for the header row */
62
+ headerClassName?: string;
63
+ /** Additional className for the sender label */
64
+ senderClassName?: string;
65
+ /** Additional className for the tool summary text */
66
+ toolSummaryClassName?: string;
67
+ /** Additional className for the tool name badge */
68
+ toolBadgeClassName?: string;
69
+ /** Additional className for individual item wrappers */
70
+ itemClassName?: string;
71
+ /** Additional className for item header rows */
72
+ itemHeaderClassName?: string;
73
+ /** Additional className for expanded item content */
74
+ itemContentClassName?: string;
75
+ }
76
+
77
+ /** className overrides for ToolCallGroup — subset of ToolCallGroupProps containing only className props. */
78
+ export type ToolCallGroupClassNames = Partial<Pick<ToolCallGroupProps,
79
+ 'rootClassName' | 'headerClassName' | 'senderClassName' | 'toolSummaryClassName' |
80
+ 'toolBadgeClassName' | 'itemClassName' | 'itemHeaderClassName' | 'itemContentClassName'>>;
81
+
82
+ interface ToolCallItemClassNames {
83
+ toolBadgeClassName?: string;
84
+ itemClassName?: string;
85
+ itemHeaderClassName?: string;
86
+ itemContentClassName?: string;
18
87
  }
19
88
 
20
89
  interface ToolCallItemProps {
@@ -22,19 +91,20 @@ interface ToolCallItemProps {
22
91
  isExpanded: boolean;
23
92
  onToggle: () => void;
24
93
  artifactRunId?: string;
94
+ classNames?: ToolCallItemClassNames;
25
95
  }
26
96
 
27
97
  // Helper to check if URL is an image
28
98
  const isImageUrl = (url: string) => /\.(png|jpg|jpeg|gif|webp|svg)(\?|$)/i.test(url);
29
99
 
30
100
  // Component to render files (images inline, others as links)
31
- function FileDisplay({ files }: { files: string[] }) {
101
+ function FileDisplay({ files, className: fileClassName }: { files: string[]; className?: string }) {
32
102
  const { openImage } = useImageLightbox();
33
103
 
34
104
  if (!files || files.length === 0) return null;
35
105
 
36
106
  return (
37
- <div className="mt-2 flex flex-wrap gap-2">
107
+ <div className={cn("mt-2 flex flex-wrap gap-2", fileClassName)}>
38
108
  {files.map((file, idx) => {
39
109
  const fileName = file.split('/').pop()?.split('?')[0] || 'file';
40
110
  if (isImageUrl(file)) {
@@ -76,14 +146,37 @@ const getFilesFromDetails = (details: { files?: string[]; outputFiles?: string[]
76
146
  return Array.isArray(files) ? files : undefined;
77
147
  };
78
148
 
79
- function ToolCallItem({ message, isExpanded, onToggle, artifactRunId }: ToolCallItemProps) {
149
+ const getMessageActivityLabel = (message: AgentMessage): string => {
150
+ const details = message.details as { tool?: string } | undefined;
151
+ if (details?.tool) return details.tool;
152
+
153
+ switch (message.type) {
154
+ case AgentMessageType.UPDATE:
155
+ return "update";
156
+ case AgentMessageType.WARNING:
157
+ return "warning";
158
+ case AgentMessageType.ERROR:
159
+ return "error";
160
+ case AgentMessageType.SYSTEM:
161
+ return "system";
162
+ default:
163
+ return "activity";
164
+ }
165
+ };
166
+
167
+ function ToolCallItem({ message, isExpanded, onToggle, artifactRunId, classNames = {} }: ToolCallItemProps) {
80
168
  const [resolvedFiles, setResolvedFiles] = useState<string[]>([]);
81
169
  const toast = useToast();
82
170
  const { client } = useUserSession();
83
171
  const urlCache = useArtifactUrlCache();
172
+ // PERFORMANCE: Use refs to avoid triggering effect re-runs when these stable values change identity
173
+ const clientRef = useRef(client);
174
+ clientRef.current = client;
175
+ const urlCacheRef = useRef(urlCache);
176
+ urlCacheRef.current = urlCache;
84
177
 
85
178
  const details = message.details as { tool?: string; files?: string[]; outputFiles?: string[]; [key: string]: unknown } | undefined;
86
- const toolName = details?.tool || "Tool";
179
+ const toolName = getMessageActivityLabel(message);
87
180
  const files = getFilesFromDetails(details);
88
181
  const messageContent = typeof message.message === "string" ? message.message : "";
89
182
 
@@ -96,6 +189,8 @@ function ToolCallItem({ message, isExpanded, onToggle, artifactRunId }: ToolCall
96
189
 
97
190
  let cancelled = false;
98
191
  const resolveFiles = async () => {
192
+ const currentClient = clientRef.current;
193
+ const currentUrlCache = urlCacheRef.current;
99
194
  const resolved = await Promise.all(
100
195
  files.map(async (file) => {
101
196
  if (!file || typeof file !== "string") return null;
@@ -103,10 +198,8 @@ function ToolCallItem({ message, isExpanded, onToggle, artifactRunId }: ToolCall
103
198
  if (file.startsWith("http://") || file.startsWith("https://")) {
104
199
  return file;
105
200
  }
106
- // Resolve artifact path to signed URL
107
- const artifactPath = file.startsWith("out/") || file.startsWith("files/") || file.startsWith("scripts/")
108
- ? file
109
- : `out/${file}`;
201
+ // Strip artifact: protocol prefix to get the artifact-relative path
202
+ const artifactPath = file.startsWith("artifact:") ? file.slice(9) : file;
110
203
  const ext = artifactPath.split(".").pop()?.toLowerCase() || "";
111
204
  const imageExtensions = new Set(["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg"]);
112
205
  const isImage = imageExtensions.has(ext);
@@ -114,13 +207,13 @@ function ToolCallItem({ message, isExpanded, onToggle, artifactRunId }: ToolCall
114
207
 
115
208
  try {
116
209
  const cacheKey = getArtifactCacheKey(artifactRunId, artifactPath, disposition);
117
- if (urlCache) {
118
- return await urlCache.getOrFetch(cacheKey, async () => {
119
- const result = await client.files.getArtifactDownloadUrl(artifactRunId, artifactPath, disposition);
210
+ if (currentUrlCache) {
211
+ return await currentUrlCache.getOrFetch(cacheKey, async () => {
212
+ const result = await currentClient.files.getArtifactDownloadUrl(artifactRunId, artifactPath, disposition);
120
213
  return result.url;
121
214
  });
122
215
  } else {
123
- const result = await client.files.getArtifactDownloadUrl(artifactRunId, artifactPath, disposition);
216
+ const result = await currentClient.files.getArtifactDownloadUrl(artifactRunId, artifactPath, disposition);
124
217
  return result.url;
125
218
  }
126
219
  } catch (err) {
@@ -135,7 +228,7 @@ function ToolCallItem({ message, isExpanded, onToggle, artifactRunId }: ToolCall
135
228
  };
136
229
  resolveFiles();
137
230
  return () => { cancelled = true; };
138
- }, [files, artifactRunId, client, urlCache]);
231
+ }, [files, artifactRunId]);
139
232
 
140
233
  // Separate image files from other files for inline preview
141
234
  const imageFiles = resolvedFiles.filter(f => isImageUrl(f));
@@ -157,10 +250,10 @@ function ToolCallItem({ message, isExpanded, onToggle, artifactRunId }: ToolCall
157
250
  };
158
251
 
159
252
  return (
160
- <div className="border-b border-gray-100 dark:border-gray-800 last:border-b-0">
253
+ <div className={cn("border-b border-gray-100 dark:border-gray-800 last:border-b-0", classNames.itemClassName)}>
161
254
  {/* Collapsed header - always visible */}
162
255
  <div
163
- className="flex items-start justify-between px-3 py-2 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"
256
+ className={cn("flex items-start justify-between px-3 py-2 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors", classNames.itemHeaderClassName)}
164
257
  onClick={onToggle}
165
258
  >
166
259
  <div className="flex items-start gap-2 flex-1 min-w-0">
@@ -178,14 +271,14 @@ function ToolCallItem({ message, isExpanded, onToggle, artifactRunId }: ToolCall
178
271
  {messageContent}
179
272
  </span>
180
273
  ) : (
181
- <span className="text-xs text-muted italic">Tool: {toolName}</span>
274
+ <span className="text-xs text-muted italic">Activity: {toolName}</span>
182
275
  )}
183
276
  </div>
184
277
  </div>
185
278
  <div className="flex items-center gap-2 flex-shrink-0">
186
279
  {/* Tool name badge on the right */}
187
280
  {!isExpanded && (
188
- <span className="text-[10px] px-1.5 py-0.5 rounded-md bg-purple-50 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 border border-purple-200 dark:border-purple-800 font-medium">
281
+ <span className={cn("text-[10px] px-1.5 py-0.5 rounded-md bg-purple-50 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 border border-purple-200 dark:border-purple-800 font-medium", classNames.toolBadgeClassName)}>
189
282
  {toolName}
190
283
  </span>
191
284
  )}
@@ -206,43 +299,65 @@ function ToolCallItem({ message, isExpanded, onToggle, artifactRunId }: ToolCall
206
299
 
207
300
  {/* Always show images inline, regardless of expanded state */}
208
301
  {imageFiles.length > 0 && (
209
- <div className="px-4 pb-2">
302
+ <div className="px-3 pb-1.5">
210
303
  <FileDisplay files={imageFiles} />
211
304
  </div>
212
305
  )}
213
306
 
214
- {/* Expanded content */}
215
- {isExpanded && (
216
- <div className="px-4 py-2 bg-gray-50/50 dark:bg-gray-800/30">
217
- {/* Tool name badge shown when expanded */}
218
- <div className="mb-2">
219
- <span className="text-[10px] px-1.5 py-0.5 rounded-md bg-purple-50 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 border border-purple-200 dark:border-purple-800 font-medium">
220
- {toolName}
221
- </span>
222
- </div>
223
-
224
- {messageContent && (
225
- <div className="vprose prose prose-slate dark:prose-invert prose-p:leading-relaxed prose-p:my-1.5 max-w-none text-sm">
226
- <MarkdownRenderer artifactRunId={artifactRunId}>{messageContent}</MarkdownRenderer>
307
+ {/* Expanded content — shows tool metadata, key params, then raw details */}
308
+ {isExpanded && (() => {
309
+ const toolStatusValue = (details as Record<string, unknown> | undefined)?.tool_status as ToolExecutionStatus | undefined;
310
+ const interestingDetails = extractInterestingDetails(details as Record<string, unknown> | undefined);
311
+ return (
312
+ <div className={cn("px-4 py-2 bg-gray-50/50 dark:bg-gray-800/30", classNames.itemContentClassName)}>
313
+ {/* Badges row: tool name + status + timestamp */}
314
+ <div className="flex items-center gap-2 mb-2 flex-wrap">
315
+ <span className={cn("text-[10px] px-1.5 py-0.5 rounded-md bg-purple-50 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 border border-purple-200 dark:border-purple-800 font-medium", classNames.toolBadgeClassName)}>
316
+ {toolName}
317
+ </span>
318
+ {toolStatusValue && (
319
+ <span className={cn("text-[10px] px-1.5 py-0.5 rounded-md border font-medium", statusBadgeClass(toolStatusValue))}>
320
+ {toolStatusValue}
321
+ </span>
322
+ )}
323
+ <span className="text-[10px] text-muted/70">{dayjs(message.timestamp).format("HH:mm:ss")}</span>
227
324
  </div>
228
- )}
229
325
 
230
- {/* Non-image files display */}
231
- {nonImageFiles.length > 0 && <FileDisplay files={nonImageFiles} />}
232
-
233
- {/* Technical details - collapsible */}
234
- {details && Object.keys(details).length > 1 && (
235
- <details className="mt-3 text-xs border rounded p-2 bg-muted/30" onClick={(e) => e.stopPropagation()}>
236
- <summary className="cursor-pointer text-muted">
237
- Technical Details
238
- </summary>
239
- <pre className="mt-2 p-2 bg-muted rounded text-xs overflow-x-auto font-mono whitespace-pre-wrap">
240
- {JSON.stringify(details, null, 2)}
241
- </pre>
242
- </details>
243
- )}
244
- </div>
245
- )}
326
+ {/* Key parameters */}
327
+ {interestingDetails.length > 0 && (
328
+ <div className="mb-2 space-y-0.5">
329
+ {interestingDetails.map(([key, value]) => (
330
+ <div key={key} className="flex gap-1.5 text-xs">
331
+ <span className="text-muted font-medium flex-shrink-0">{formatDetailKey(key)}:</span>
332
+ <span className="text-foreground break-all">
333
+ {typeof value === 'object' ? JSON.stringify(value) : String(value)}
334
+ </span>
335
+ </div>
336
+ ))}
337
+ </div>
338
+ )}
339
+
340
+ {messageContent && (
341
+ <div className="vprose prose prose-slate dark:prose-invert prose-p:leading-relaxed prose-p:my-1.5 max-w-none text-sm">
342
+ <MarkdownRenderer artifactRunId={artifactRunId}>{messageContent}</MarkdownRenderer>
343
+ </div>
344
+ )}
345
+
346
+ {/* Non-image files display */}
347
+ {nonImageFiles.length > 0 && <FileDisplay files={nonImageFiles} />}
348
+
349
+ {/* Raw details — demoted to collapsible */}
350
+ {details && Object.keys(details).length > 1 && (
351
+ <details className="mt-2 text-xs border rounded p-1.5 bg-muted/30" onClick={(e) => e.stopPropagation()}>
352
+ <summary className="cursor-pointer text-muted">Raw details</summary>
353
+ <pre className="mt-2 p-2 bg-muted rounded text-xs overflow-x-auto font-mono whitespace-pre-wrap">
354
+ {JSON.stringify(details, null, 2)}
355
+ </pre>
356
+ </details>
357
+ )}
358
+ </div>
359
+ );
360
+ })()}
246
361
  </div>
247
362
  );
248
363
  }
@@ -253,6 +368,10 @@ function CollapsedItemFiles({ files, artifactRunId }: { files: string[] | undefi
253
368
  const [resolvedFiles, setResolvedFiles] = useState<string[]>([]);
254
369
  const { client } = useUserSession();
255
370
  const urlCache = useArtifactUrlCache();
371
+ const clientRef = useRef(client);
372
+ clientRef.current = client;
373
+ const urlCacheRef = useRef(urlCache);
374
+ urlCacheRef.current = urlCache;
256
375
 
257
376
  useEffect(() => {
258
377
  if (!files || files.length === 0 || !artifactRunId) {
@@ -262,31 +381,33 @@ function CollapsedItemFiles({ files, artifactRunId }: { files: string[] | undefi
262
381
 
263
382
  let cancelled = false;
264
383
  const resolveFiles = async () => {
384
+ const currentClient = clientRef.current;
385
+ const currentUrlCache = urlCacheRef.current;
265
386
  const resolved = await Promise.all(
266
387
  files.map(async (file) => {
267
388
  if (!file || typeof file !== "string") return null;
268
389
 
390
+ // Strip artifact: protocol prefix to get the artifact-relative path
391
+ const artifactPath = file.startsWith("artifact:") ? file.slice(9) : file;
392
+
269
393
  // Skip image files - they're shown at the group level
270
- const ext = file.split(".").pop()?.toLowerCase() || "";
394
+ const ext = artifactPath.split(".").pop()?.toLowerCase() || "";
271
395
  const imageExtensions = new Set(["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg"]);
272
396
  if (imageExtensions.has(ext)) return null;
273
397
 
274
- if (file.startsWith("http://") || file.startsWith("https://")) {
275
- return file;
398
+ if (artifactPath.startsWith("http://") || artifactPath.startsWith("https://")) {
399
+ return artifactPath;
276
400
  }
277
- const artifactPath = file.startsWith("out/") || file.startsWith("files/") || file.startsWith("scripts/")
278
- ? file
279
- : `out/${file}`;
280
401
 
281
402
  try {
282
403
  const cacheKey = getArtifactCacheKey(artifactRunId, artifactPath, "attachment");
283
- if (urlCache) {
284
- return await urlCache.getOrFetch(cacheKey, async () => {
285
- const result = await client.files.getArtifactDownloadUrl(artifactRunId, artifactPath, "attachment");
404
+ if (currentUrlCache) {
405
+ return await currentUrlCache.getOrFetch(cacheKey, async () => {
406
+ const result = await currentClient.files.getArtifactDownloadUrl(artifactRunId, artifactPath, "attachment");
286
407
  return result.url;
287
408
  });
288
409
  } else {
289
- const result = await client.files.getArtifactDownloadUrl(artifactRunId, artifactPath, "attachment");
410
+ const result = await currentClient.files.getArtifactDownloadUrl(artifactRunId, artifactPath, "attachment");
290
411
  return result.url;
291
412
  }
292
413
  } catch (err) {
@@ -301,13 +422,13 @@ function CollapsedItemFiles({ files, artifactRunId }: { files: string[] | undefi
301
422
  };
302
423
  resolveFiles();
303
424
  return () => { cancelled = true; };
304
- }, [files, artifactRunId, client, urlCache]);
425
+ }, [files, artifactRunId]);
305
426
 
306
427
  // Only show non-image files (images are shown at group level)
307
428
  if (resolvedFiles.length === 0) return null;
308
429
 
309
430
  return (
310
- <div className="pl-5 pr-3 pb-2">
431
+ <div className="pl-4 pr-2 pb-1.5">
311
432
  <FileDisplay files={resolvedFiles} />
312
433
  </div>
313
434
  );
@@ -318,6 +439,10 @@ function GroupImageDisplay({ messages, artifactRunId }: { messages: AgentMessage
318
439
  const [resolvedImages, setResolvedImages] = useState<string[]>([]);
319
440
  const { client } = useUserSession();
320
441
  const urlCache = useArtifactUrlCache();
442
+ const clientRef = useRef(client);
443
+ clientRef.current = client;
444
+ const urlCacheRef = useRef(urlCache);
445
+ urlCacheRef.current = urlCache;
321
446
 
322
447
  // Only show files from the last (most recent) message in the group
323
448
  useEffect(() => {
@@ -338,34 +463,34 @@ function GroupImageDisplay({ messages, artifactRunId }: { messages: AgentMessage
338
463
 
339
464
  let cancelled = false;
340
465
  const resolveFiles = async () => {
466
+ const currentClient = clientRef.current;
467
+ const currentUrlCache = urlCacheRef.current;
341
468
  const resolved = await Promise.all(
342
469
  files.map(async (file) => {
343
470
  if (!file || typeof file !== "string") return null;
344
471
 
472
+ // Strip artifact: protocol prefix to get the artifact-relative path
473
+ const artifactPath = file.startsWith("artifact:") ? file.slice(9) : file;
474
+
345
475
  // Check if it's an image file
346
- const ext = file.split(".").pop()?.toLowerCase() || "";
476
+ const ext = artifactPath.split(".").pop()?.toLowerCase() || "";
347
477
  const imageExtensions = new Set(["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg"]);
348
478
  if (!imageExtensions.has(ext)) return null;
349
479
 
350
480
  // If it's already a full URL, return as-is
351
- if (file.startsWith("http://") || file.startsWith("https://")) {
352
- return file;
481
+ if (artifactPath.startsWith("http://") || artifactPath.startsWith("https://")) {
482
+ return artifactPath;
353
483
  }
354
484
 
355
- // Resolve artifact path to signed URL
356
- const artifactPath = file.startsWith("out/") || file.startsWith("files/") || file.startsWith("scripts/")
357
- ? file
358
- : `out/${file}`;
359
-
360
485
  try {
361
486
  const cacheKey = getArtifactCacheKey(artifactRunId, artifactPath, "inline");
362
- if (urlCache) {
363
- return await urlCache.getOrFetch(cacheKey, async () => {
364
- const result = await client.files.getArtifactDownloadUrl(artifactRunId, artifactPath, "inline");
487
+ if (currentUrlCache) {
488
+ return await currentUrlCache.getOrFetch(cacheKey, async () => {
489
+ const result = await currentClient.files.getArtifactDownloadUrl(artifactRunId, artifactPath, "inline");
365
490
  return result.url;
366
491
  });
367
492
  } else {
368
- const result = await client.files.getArtifactDownloadUrl(artifactRunId, artifactPath, "inline");
493
+ const result = await currentClient.files.getArtifactDownloadUrl(artifactRunId, artifactPath, "inline");
369
494
  return result.url;
370
495
  }
371
496
  } catch (err) {
@@ -380,18 +505,31 @@ function GroupImageDisplay({ messages, artifactRunId }: { messages: AgentMessage
380
505
  };
381
506
  resolveFiles();
382
507
  return () => { cancelled = true; };
383
- }, [messages, artifactRunId, client, urlCache]);
508
+ }, [messages, artifactRunId]);
384
509
 
385
510
  if (resolvedImages.length === 0) return null;
386
511
 
387
512
  return (
388
- <div className="px-4 py-2 border-b border-gray-100 dark:border-gray-800">
513
+ <div className="px-3 py-1.5 border-b border-gray-100 dark:border-gray-800">
389
514
  <FileDisplay files={resolvedImages} />
390
515
  </div>
391
516
  );
392
517
  }
393
518
 
394
- function ToolCallGroupComponent({ messages, showPulsatingCircle = false, toolRunId: _toolRunId, toolStatus }: ToolCallGroupProps) {
519
+ function ToolCallGroupComponent({
520
+ messages,
521
+ showPulsatingCircle = false,
522
+ toolRunId: _toolRunId,
523
+ toolStatus,
524
+ rootClassName,
525
+ headerClassName,
526
+ senderClassName,
527
+ toolSummaryClassName,
528
+ toolBadgeClassName,
529
+ itemClassName,
530
+ itemHeaderClassName,
531
+ itemContentClassName,
532
+ }: ToolCallGroupProps) {
395
533
  const [isCollapsed, setIsCollapsed] = useState(true);
396
534
  const [expandedItems, setExpandedItems] = useState<Set<number>>(new Set());
397
535
  const [animatingIndices, setAnimatingIndices] = useState<Set<number>>(new Set());
@@ -404,9 +542,13 @@ function ToolCallGroupComponent({ messages, showPulsatingCircle = false, toolRun
404
542
 
405
543
  // Render status indicator based on tool execution status
406
544
  const renderStatusIndicator = () => {
407
- if (showPulsatingCircle || toolStatus === "running") {
545
+ // Only pulse for the currently active/latest group
546
+ if (showPulsatingCircle) {
408
547
  return <PulsatingCircle size="sm" color="blue" />;
409
548
  }
549
+ if (toolStatus === "running") {
550
+ return <span className="size-2 rounded-full bg-blue-500 inline-block" />;
551
+ }
410
552
  if (toolStatus === "completed") {
411
553
  return <CheckCircle className="size-4 text-success" />;
412
554
  }
@@ -458,15 +600,12 @@ function ToolCallGroupComponent({ messages, showPulsatingCircle = false, toolRun
458
600
  const lastTimestamp = lastMessage.timestamp;
459
601
 
460
602
  // Get tool names for summary
461
- const toolNames = messages.map(m => {
462
- const details = m.details as { tool?: string } | undefined;
463
- return details?.tool || "tool";
464
- });
603
+ const toolNames = messages.map((m) => getMessageActivityLabel(m));
465
604
 
466
605
  const uniqueToolCount = new Set(toolNames).size;
467
606
  const toolSummary = uniqueToolCount === 1
468
607
  ? `${messages.length}× ${toolNames[0]}`
469
- : `${messages.length} tool calls`;
608
+ : `${messages.length} activity updates`;
470
609
 
471
610
  const toggleItem = (index: number) => {
472
611
  setExpandedItems(prev => {
@@ -483,7 +622,7 @@ function ToolCallGroupComponent({ messages, showPulsatingCircle = false, toolRun
483
622
  const copyAllToClipboard = () => {
484
623
  const allContent = messages.map(m => {
485
624
  const details = m.details as { tool?: string; [key: string]: unknown } | undefined;
486
- return `[${details?.tool || "tool"}] ${m.message || ""}\n${details ? JSON.stringify(details, null, 2) : ""}`;
625
+ return `[${getMessageActivityLabel(m)}] ${m.message || ""}\n${details ? JSON.stringify(details, null, 2) : ""}`;
487
626
  }).join("\n\n---\n\n");
488
627
 
489
628
  navigator.clipboard.writeText(allContent).then(() => {
@@ -497,17 +636,17 @@ function ToolCallGroupComponent({ messages, showPulsatingCircle = false, toolRun
497
636
 
498
637
  return (
499
638
  <div
500
- className={`border-l-4 ${getBorderColor()} overflow-hidden bg-white dark:bg-gray-900 mb-4`}
639
+ className={cn("border-l-4 overflow-hidden bg-white dark:bg-gray-900 mb-4", getBorderColor(), rootClassName)}
501
640
  >
502
641
  {/* Compact header */}
503
642
  <div
504
- className="flex items-center justify-between px-4 py-1.5 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"
643
+ className={cn("flex items-center justify-between px-4 py-1.5 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors", headerClassName)}
505
644
  onClick={() => setIsCollapsed(!isCollapsed)}
506
645
  >
507
- <div className="flex items-center gap-1.5">
646
+ <div className="flex items-center gap-1">
508
647
  {renderStatusIndicator()}
509
- <span className="text-xs font-medium text-muted">Agent</span>
510
- <span className="text-xs text-purple-600 dark:text-purple-400 font-medium">
648
+ <span className={cn("text-xs font-medium text-muted", senderClassName)}>Agent</span>
649
+ <span className={cn("text-xs text-purple-600 dark:text-purple-400 font-medium", toolSummaryClassName)}>
511
650
  {toolSummary}
512
651
  </span>
513
652
  {isCollapsed ? (
@@ -517,7 +656,7 @@ function ToolCallGroupComponent({ messages, showPulsatingCircle = false, toolRun
517
656
  )}
518
657
  </div>
519
658
 
520
- <div className="flex items-center gap-1.5">
659
+ <div className="flex items-center gap-1">
521
660
  <span className="text-[11px] text-muted/70">
522
661
  {dayjs(firstTimestamp).format("HH:mm:ss")}
523
662
  {messages.length > 1 && ` - ${dayjs(lastTimestamp).format("HH:mm:ss")}`}
@@ -542,10 +681,10 @@ function ToolCallGroupComponent({ messages, showPulsatingCircle = false, toolRun
542
681
 
543
682
  {/* Collapsed summary - show tool calls as single-line rows with expand option */}
544
683
  {isCollapsed && (
545
- <div className="px-4 py-1 space-y-0">
684
+ <div className="px-3 py-0.5 space-y-0">
546
685
  {messages.map((m, idx) => {
547
686
  const details = m.details as { tool?: string; files?: string[]; outputFiles?: string[] } | undefined;
548
- const toolName = details?.tool || "tool";
687
+ const toolName = getMessageActivityLabel(m);
549
688
  const fullMessage = typeof m.message === "string" ? m.message : "";
550
689
  const isAnimating = animatingIndices.has(idx);
551
690
  const isItemExpanded = expandedItems.has(idx);
@@ -554,7 +693,7 @@ function ToolCallGroupComponent({ messages, showPulsatingCircle = false, toolRun
554
693
  return (
555
694
  <div
556
695
  key={`${m.timestamp}-${idx}`}
557
- className="border-b border-gray-100 dark:border-gray-800 last:border-b-0"
696
+ className={cn("border-b border-gray-100 dark:border-gray-800 last:border-b-0", itemClassName)}
558
697
  style={{
559
698
  opacity: isAnimating ? 0 : 1,
560
699
  transform: isAnimating ? 'translateX(-10px)' : 'translateX(0)',
@@ -566,7 +705,7 @@ function ToolCallGroupComponent({ messages, showPulsatingCircle = false, toolRun
566
705
  >
567
706
  {/* Row header - clickable to expand */}
568
707
  <div
569
- className="flex items-start gap-2 py-2 text-xs cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800/50"
708
+ className={cn("flex items-start gap-2 py-1.5 text-xs cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800/50", itemHeaderClassName)}
570
709
  onClick={() => toggleItem(idx)}
571
710
  title={fullMessage}
572
711
  >
@@ -584,35 +723,69 @@ function ToolCallGroupComponent({ messages, showPulsatingCircle = false, toolRun
584
723
  {fullMessage}
585
724
  </span>
586
725
  ) : (
587
- <span className="text-muted italic">Tool: {toolName}</span>
726
+ <span className="text-muted italic">Activity: {toolName}</span>
588
727
  )}
589
728
  </div>
590
729
  {/* Tool name badge on the right */}
591
730
  {!isItemExpanded && (
592
- <span className="text-[10px] px-1.5 py-0.5 rounded-md bg-purple-50 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 border border-purple-200 dark:border-purple-800 font-medium flex-shrink-0">
731
+ <span className={cn("text-[10px] px-1.5 py-0.5 rounded-md bg-purple-50 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 border border-purple-200 dark:border-purple-800 font-medium flex-shrink-0", toolBadgeClassName)}>
593
732
  {toolName}
594
733
  </span>
595
734
  )}
596
735
  </div>
597
736
  {/* Always show images inline with resolved URLs */}
598
737
  <CollapsedItemFiles files={files} artifactRunId={artifactRunId} />
599
- {/* Expanded content - show full message */}
600
- {isItemExpanded && (
601
- <div className="pl-5 pr-3 pb-2 text-sm">
602
- <div className="vprose prose prose-slate dark:prose-invert prose-p:leading-relaxed prose-p:my-1.5 max-w-none text-sm">
603
- <MarkdownRenderer artifactRunId={artifactRunId}>{fullMessage}</MarkdownRenderer>
738
+ {/* Expanded content tool metadata + key params + raw details */}
739
+ {isItemExpanded && (() => {
740
+ const toolStatusValue = (details as Record<string, unknown> | undefined)?.tool_status as ToolExecutionStatus | undefined;
741
+ const interestingDetails = extractInterestingDetails(details as Record<string, unknown> | undefined);
742
+ return (
743
+ <div className={cn("pl-5 pr-3 pb-2 text-sm", itemContentClassName)}>
744
+ {/* Badges row: tool name + status + timestamp */}
745
+ <div className="flex items-center gap-2 mb-1.5 flex-wrap">
746
+ <span className={cn("text-[10px] px-1.5 py-0.5 rounded-md bg-purple-50 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300 border border-purple-200 dark:border-purple-800 font-medium", toolBadgeClassName)}>
747
+ {toolName}
748
+ </span>
749
+ {toolStatusValue && (
750
+ <span className={cn("text-[10px] px-1.5 py-0.5 rounded-md border font-medium", statusBadgeClass(toolStatusValue))}>
751
+ {toolStatusValue}
752
+ </span>
753
+ )}
754
+ <span className="text-[10px] text-muted/70">{dayjs(m.timestamp).format("HH:mm:ss")}</span>
755
+ </div>
756
+
757
+ {/* Key parameters */}
758
+ {interestingDetails.length > 0 && (
759
+ <div className="mb-1.5 space-y-0.5">
760
+ {interestingDetails.map(([key, value]) => (
761
+ <div key={key} className="flex gap-1.5 text-xs">
762
+ <span className="text-muted font-medium flex-shrink-0">{formatDetailKey(key)}:</span>
763
+ <span className="text-foreground break-all">
764
+ {typeof value === 'object' ? JSON.stringify(value) : String(value)}
765
+ </span>
766
+ </div>
767
+ ))}
768
+ </div>
769
+ )}
770
+
771
+ {fullMessage && (
772
+ <div className="vprose prose prose-slate dark:prose-invert prose-p:leading-relaxed prose-p:my-1.5 max-w-none text-sm">
773
+ <MarkdownRenderer artifactRunId={artifactRunId}>{fullMessage}</MarkdownRenderer>
774
+ </div>
775
+ )}
776
+
777
+ {/* Raw details — demoted to collapsible */}
778
+ {details && Object.keys(details).length > 1 && (
779
+ <details className="mt-1.5 text-xs">
780
+ <summary className="text-muted cursor-pointer">Raw details</summary>
781
+ <pre className="mt-1 p-2 bg-muted rounded text-xs overflow-x-auto">
782
+ {JSON.stringify(details, null, 2)}
783
+ </pre>
784
+ </details>
785
+ )}
604
786
  </div>
605
- {/* Show details if available */}
606
- {details && Object.keys(details).length > 1 && (
607
- <details className="mt-2 text-xs">
608
- <summary className="text-muted cursor-pointer">Show details</summary>
609
- <pre className="mt-1 p-2 bg-muted rounded text-xs overflow-x-auto">
610
- {JSON.stringify(details, null, 2)}
611
- </pre>
612
- </details>
613
- )}
614
- </div>
615
- )}
787
+ );
788
+ })()}
616
789
  </div>
617
790
  );
618
791
  })}
@@ -643,6 +816,7 @@ function ToolCallGroupComponent({ messages, showPulsatingCircle = false, toolRun
643
816
  isExpanded={expandedItems.has(index)}
644
817
  onToggle={() => toggleItem(index)}
645
818
  artifactRunId={artifactRunId}
819
+ classNames={{ toolBadgeClassName, itemClassName, itemHeaderClassName, itemContentClassName }}
646
820
  />
647
821
  ))}
648
822
  </div>
@@ -657,6 +831,14 @@ const ToolCallGroup = memo(ToolCallGroupComponent, (prevProps, nextProps) => {
657
831
  if (prevProps.showPulsatingCircle !== nextProps.showPulsatingCircle) return false;
658
832
  if (prevProps.toolRunId !== nextProps.toolRunId) return false;
659
833
  if (prevProps.toolStatus !== nextProps.toolStatus) return false;
834
+ if (prevProps.rootClassName !== nextProps.rootClassName) return false;
835
+ if (prevProps.headerClassName !== nextProps.headerClassName) return false;
836
+ if (prevProps.senderClassName !== nextProps.senderClassName) return false;
837
+ if (prevProps.toolSummaryClassName !== nextProps.toolSummaryClassName) return false;
838
+ if (prevProps.toolBadgeClassName !== nextProps.toolBadgeClassName) return false;
839
+ if (prevProps.itemClassName !== nextProps.itemClassName) return false;
840
+ if (prevProps.itemHeaderClassName !== nextProps.itemHeaderClassName) return false;
841
+ if (prevProps.itemContentClassName !== nextProps.itemContentClassName) return false;
660
842
  // Compare first and last timestamps as a proxy for content changes
661
843
  return (
662
844
  prevProps.messages[0]?.timestamp === nextProps.messages[0]?.timestamp &&