@copilotkit/vue 2.0.0-rc.3 → 2.0.0-rc.30

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 (343) hide show
  1. package/CONTRIBUTOR_GUIDE.md +1 -1
  2. package/PARITY.md +3 -3
  3. package/dist/hooks/use-copilot-action.d.ts.map +1 -1
  4. package/dist/hooks/use-frontend-tool.d.ts +1 -1
  5. package/dist/hooks/use-frontend-tool.d.ts.map +1 -1
  6. package/dist/hooks/zod-parameters.d.ts +14 -0
  7. package/dist/hooks/zod-parameters.d.ts.map +1 -0
  8. package/dist/index.cjs +1 -73
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.mjs +365 -16920
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/use-render-activity-message-BZJ33B_r.cjs +113 -0
  13. package/dist/use-render-activity-message-BZJ33B_r.cjs.map +1 -0
  14. package/dist/use-render-activity-message-DrR407LQ.js +15901 -0
  15. package/dist/use-render-activity-message-DrR407LQ.js.map +1 -0
  16. package/dist/v2/components/A2UIMessageRenderer.d.ts +14 -0
  17. package/dist/v2/components/A2UIMessageRenderer.d.ts.map +1 -1
  18. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts +10 -3
  19. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts.map +1 -1
  20. package/dist/v2/components/CopilotKitInspector.vue.d.ts +5 -1
  21. package/dist/v2/components/CopilotKitInspector.vue.d.ts.map +1 -1
  22. package/dist/v2/components/InlineFeatureWarning.vue.d.ts.map +1 -1
  23. package/dist/v2/components/LicenseWarningBanner.vue.d.ts +2 -2
  24. package/dist/v2/components/LicenseWarningBanner.vue.d.ts.map +1 -1
  25. package/dist/v2/components/MCPAppsActivityRenderer.d.ts.map +1 -1
  26. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts +13 -59
  27. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts.map +1 -1
  28. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts +3 -11
  29. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts.map +1 -1
  30. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts +10 -15
  31. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts.map +1 -1
  32. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts +14 -130
  33. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts.map +1 -1
  34. package/dist/v2/components/a2ui/catalog.d.ts.map +1 -1
  35. package/dist/v2/components/a2ui/utils.d.ts +3 -15
  36. package/dist/v2/components/a2ui/utils.d.ts.map +1 -1
  37. package/dist/v2/components/a2ui.d.ts +9 -8
  38. package/dist/v2/components/a2ui.d.ts.map +1 -1
  39. package/dist/v2/components/chat/CopilotChat.vue.d.ts +2 -2
  40. package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
  41. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -1
  42. package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -1
  43. package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -1
  44. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts +4 -8
  45. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts.map +1 -1
  46. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts +1 -1
  47. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts.map +1 -1
  48. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +7 -286
  49. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -1
  50. package/dist/v2/components/chat/CopilotChatInspectorButton.vue.d.ts.map +1 -1
  51. package/dist/v2/components/chat/CopilotChatLightbox.vue.d.ts.map +1 -1
  52. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +1 -1
  53. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -1
  54. package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -1
  55. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts +1 -1
  56. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts.map +1 -1
  57. package/dist/v2/components/chat/CopilotChatToolCallItem.vue.d.ts.map +1 -1
  58. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +1 -1
  59. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -1
  60. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -1
  61. package/dist/v2/components/chat/CopilotChatView.vue.d.ts +3 -3
  62. package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
  63. package/dist/v2/components/chat/CopilotChatWorkSummary.vue.d.ts.map +1 -1
  64. package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts.map +1 -1
  65. package/dist/v2/components/chat/CopilotPopup.vue.d.ts +8 -3
  66. package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -1
  67. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts +5 -3
  68. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -1
  69. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts +5 -3
  70. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -1
  71. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts +8 -3
  72. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -1
  73. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +6 -4
  74. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -1
  75. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +6 -4
  76. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -1
  77. package/dist/v2/components/chat/CopilotThreadsDrawer.vue.d.ts.map +1 -1
  78. package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts +1 -0
  79. package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts.map +1 -1
  80. package/dist/v2/components/chat/audioRecorder.d.ts +3 -4
  81. package/dist/v2/components/chat/audioRecorder.d.ts.map +1 -1
  82. package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts +4 -4
  83. package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts.map +1 -1
  84. package/dist/v2/components/chat/forwarded-slots.d.ts +12 -0
  85. package/dist/v2/components/chat/forwarded-slots.d.ts.map +1 -0
  86. package/dist/v2/components/chat/index.d.ts +34 -31
  87. package/dist/v2/components/chat/index.d.ts.map +1 -1
  88. package/dist/v2/components/chat/inspector-shortcuts.d.ts +2 -1
  89. package/dist/v2/components/chat/inspector-shortcuts.d.ts.map +1 -1
  90. package/dist/v2/components/chat/message-feedback.d.ts +38 -49
  91. package/dist/v2/components/chat/message-feedback.d.ts.map +1 -1
  92. package/dist/v2/components/chat/tool-call-display-context.d.ts +4 -19
  93. package/dist/v2/components/chat/tool-call-display-context.d.ts.map +1 -1
  94. package/dist/v2/components/chat/tool-call-group-parts.d.ts +7 -20
  95. package/dist/v2/components/chat/tool-call-group-parts.d.ts.map +1 -1
  96. package/dist/v2/components/chat/turn-work.d.ts +0 -2
  97. package/dist/v2/components/chat/turn-work.d.ts.map +1 -1
  98. package/dist/v2/components/chat/types.d.ts +9 -4
  99. package/dist/v2/components/chat/types.d.ts.map +1 -1
  100. package/dist/v2/components/chat/use-chat-labels.d.ts +8 -0
  101. package/dist/v2/components/chat/use-chat-labels.d.ts.map +1 -0
  102. package/dist/v2/components/chat/use-copy-feedback.d.ts +11 -0
  103. package/dist/v2/components/chat/use-copy-feedback.d.ts.map +1 -0
  104. package/dist/v2/components/chat/use-lightbox.d.ts.map +1 -1
  105. package/dist/v2/components/icons/index.d.ts +968 -1
  106. package/dist/v2/components/icons/index.d.ts.map +1 -1
  107. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts +1 -1
  108. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts.map +1 -1
  109. package/dist/v2/hooks/use-agent-context.d.ts +2 -3
  110. package/dist/v2/hooks/use-agent-context.d.ts.map +1 -1
  111. package/dist/v2/hooks/use-agent.d.ts +4 -1
  112. package/dist/v2/hooks/use-agent.d.ts.map +1 -1
  113. package/dist/v2/hooks/use-attachments.d.ts +7 -0
  114. package/dist/v2/hooks/use-attachments.d.ts.map +1 -1
  115. package/dist/v2/hooks/use-capabilities.d.ts.map +1 -1
  116. package/dist/v2/hooks/use-component.d.ts +1 -0
  117. package/dist/v2/hooks/use-component.d.ts.map +1 -1
  118. package/dist/v2/hooks/use-configure-suggestions.d.ts +4 -9
  119. package/dist/v2/hooks/use-configure-suggestions.d.ts.map +1 -1
  120. package/dist/v2/hooks/use-default-render-tool.d.ts +2 -7
  121. package/dist/v2/hooks/use-default-render-tool.d.ts.map +1 -1
  122. package/dist/v2/hooks/use-frontend-tool.d.ts +5 -0
  123. package/dist/v2/hooks/use-frontend-tool.d.ts.map +1 -1
  124. package/dist/v2/hooks/use-human-in-the-loop.d.ts +2 -1
  125. package/dist/v2/hooks/use-human-in-the-loop.d.ts.map +1 -1
  126. package/dist/v2/hooks/use-interrupt.d.ts +0 -1
  127. package/dist/v2/hooks/use-interrupt.d.ts.map +1 -1
  128. package/dist/v2/hooks/use-keyboard-height.d.ts +1 -1
  129. package/dist/v2/hooks/use-keyboard-height.d.ts.map +1 -1
  130. package/dist/v2/hooks/use-pin-to-send.d.ts +4 -12
  131. package/dist/v2/hooks/use-pin-to-send.d.ts.map +1 -1
  132. package/dist/v2/hooks/use-render-activity-message.d.ts +13 -9
  133. package/dist/v2/hooks/use-render-activity-message.d.ts.map +1 -1
  134. package/dist/v2/hooks/use-render-custom-messages.d.ts +5 -7
  135. package/dist/v2/hooks/use-render-custom-messages.d.ts.map +1 -1
  136. package/dist/v2/hooks/use-render-tool.d.ts +1 -1
  137. package/dist/v2/hooks/use-render-tool.d.ts.map +1 -1
  138. package/dist/v2/hooks/use-suggestions.d.ts.map +1 -1
  139. package/dist/v2/hooks/use-threads.d.ts +6 -23
  140. package/dist/v2/hooks/use-threads.d.ts.map +1 -1
  141. package/dist/v2/index.cjs +1 -1
  142. package/dist/v2/index.mjs +197 -200
  143. package/dist/v2/index.mjs.map +1 -1
  144. package/dist/v2/lib/processPartialHtml.d.ts +1 -2
  145. package/dist/v2/lib/processPartialHtml.d.ts.map +1 -1
  146. package/dist/v2/lib/shallow-stable.d.ts.map +1 -1
  147. package/dist/v2/lib/vue-core.d.ts +33 -19
  148. package/dist/v2/lib/vue-core.d.ts.map +1 -1
  149. package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts.map +1 -1
  150. package/dist/v2/providers/CopilotKitProvider.types.d.ts +9 -129
  151. package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -1
  152. package/dist/v2/providers/CopilotKitProvider.vue.d.ts +9 -10
  153. package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
  154. package/dist/v2/providers/chat-configuration-store-key.d.ts +8 -0
  155. package/dist/v2/providers/chat-configuration-store-key.d.ts.map +1 -0
  156. package/dist/v2/providers/markdown-renderer.d.ts +4 -2
  157. package/dist/v2/providers/markdown-renderer.d.ts.map +1 -1
  158. package/dist/v2/providers/types.d.ts +3 -46
  159. package/dist/v2/providers/types.d.ts.map +1 -1
  160. package/dist/v2/providers/use-inspector-thread-override.d.ts +5 -0
  161. package/dist/v2/providers/use-inspector-thread-override.d.ts.map +1 -1
  162. package/dist/v2/types/defineToolCallRenderer.d.ts +1 -1
  163. package/dist/v2/types/defineToolCallRenderer.d.ts.map +1 -1
  164. package/dist/v2/types/human-in-the-loop.d.ts +8 -29
  165. package/dist/v2/types/human-in-the-loop.d.ts.map +1 -1
  166. package/dist/v2/types/interrupt.d.ts +1 -22
  167. package/dist/v2/types/interrupt.d.ts.map +1 -1
  168. package/dist/v2/types/vue-activity-message-renderer.d.ts +16 -15
  169. package/dist/v2/types/vue-activity-message-renderer.d.ts.map +1 -1
  170. package/dist/v2/types/vue-custom-message-renderer.d.ts +7 -16
  171. package/dist/v2/types/vue-custom-message-renderer.d.ts.map +1 -1
  172. package/dist/v2/types/vue-tool-call-renderer.d.ts +16 -35
  173. package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -1
  174. package/package.json +12 -13
  175. package/src/__tests__/build-entries.test.ts +29 -0
  176. package/src/hooks/__tests__/zod-parameters.test.ts +520 -0
  177. package/src/hooks/use-copilot-action.ts +2 -1
  178. package/src/hooks/use-frontend-tool.ts +3 -6
  179. package/src/hooks/zod-parameters.ts +162 -0
  180. package/src/v2/__tests__/exports.test.ts +10 -0
  181. package/src/v2/__tests__/mocks/web-inspector.ts +6 -0
  182. package/src/v2/__tests__/utils/test-helpers.ts +34 -4
  183. package/src/v2/components/A2UIMessageRenderer.ts +98 -68
  184. package/src/v2/components/A2UISurfaceActivityRenderer.vue +68 -103
  185. package/src/v2/components/CopilotKitInspector.vue +104 -51
  186. package/src/v2/components/InlineFeatureWarning.vue +20 -21
  187. package/src/v2/components/LicenseWarningBanner.vue +27 -135
  188. package/src/v2/components/MCPAppsActivityRenderer.ts +75 -201
  189. package/src/v2/components/OpenGenerativeUIRenderer.ts +122 -446
  190. package/src/v2/components/__tests__/A2UIMessageRenderer.test.ts +171 -8
  191. package/src/v2/components/__tests__/CopilotKitInspector.test.ts +42 -0
  192. package/src/v2/components/__tests__/LicenseWarningBanner.test.ts +60 -0
  193. package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.ts +64 -8
  194. package/src/v2/components/__tests__/OpenGenerativeUIToolRenderer.test.ts +38 -0
  195. package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +6 -26
  196. package/src/v2/components/a2ui/A2UICatalogContext.ts +27 -185
  197. package/src/v2/components/a2ui/A2UIRecoveryStates.ts +127 -327
  198. package/src/v2/components/a2ui/catalog.ts +3 -3
  199. package/src/v2/components/a2ui/utils.ts +13 -65
  200. package/src/v2/components/a2ui.ts +15 -22
  201. package/src/v2/components/chat/CopilotChat.vue +121 -498
  202. package/src/v2/components/chat/CopilotChatAssistantMessage.vue +47 -184
  203. package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +36 -55
  204. package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +14 -6
  205. package/src/v2/components/chat/CopilotChatAudioRecorder.vue +19 -246
  206. package/src/v2/components/chat/CopilotChatFeedbackCommentPopover.vue +12 -77
  207. package/src/v2/components/chat/CopilotChatInput.vue +139 -654
  208. package/src/v2/components/chat/CopilotChatInspectorButton.vue +45 -108
  209. package/src/v2/components/chat/CopilotChatLightbox.vue +10 -31
  210. package/src/v2/components/chat/CopilotChatMessageView.vue +96 -274
  211. package/src/v2/components/chat/CopilotChatReasoningMessage.vue +27 -62
  212. package/src/v2/components/chat/CopilotChatToolCallGroup.vue +63 -71
  213. package/src/v2/components/chat/CopilotChatToolCallItem.vue +8 -6
  214. package/src/v2/components/chat/CopilotChatToolCallsView.vue +31 -32
  215. package/src/v2/components/chat/CopilotChatUserMessage.vue +24 -112
  216. package/src/v2/components/chat/CopilotChatView.vue +123 -161
  217. package/src/v2/components/chat/CopilotChatWorkSummary.vue +26 -36
  218. package/src/v2/components/chat/CopilotModalHeader.vue +11 -23
  219. package/src/v2/components/chat/CopilotPopup.vue +23 -25
  220. package/src/v2/components/chat/CopilotPopupView.vue +10 -39
  221. package/src/v2/components/chat/CopilotPopupViewInternal.vue +49 -185
  222. package/src/v2/components/chat/CopilotSidebar.vue +23 -25
  223. package/src/v2/components/chat/CopilotSidebarView.vue +10 -39
  224. package/src/v2/components/chat/CopilotSidebarViewInternal.vue +56 -100
  225. package/src/v2/components/chat/CopilotThreadsDrawer.vue +43 -105
  226. package/src/v2/components/chat/StreamingMarkdownDefault.vue +15 -28
  227. package/src/v2/components/chat/__tests__/CopilotChat.labels.test.ts +19 -4
  228. package/src/v2/components/chat/__tests__/CopilotChat.test.ts +12 -10
  229. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.ts +26 -9
  230. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.learningFeedback.test.ts +5 -5
  231. package/src/v2/components/chat/__tests__/CopilotChatAttachmentQueue.test.ts +28 -0
  232. package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +132 -1
  233. package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.ts +247 -403
  234. package/src/v2/components/chat/__tests__/CopilotChatMessageView.toolCallDisplay.test.ts +1 -99
  235. package/src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.ts +43 -1
  236. package/src/v2/components/chat/__tests__/CopilotPopup.test.ts +90 -1
  237. package/src/v2/components/chat/__tests__/CopilotPopupView.test.ts +19 -0
  238. package/src/v2/components/chat/__tests__/CopilotSidebar.test.ts +90 -1
  239. package/src/v2/components/chat/__tests__/CopilotSidebarView.position.test.ts +32 -8
  240. package/src/v2/components/chat/__tests__/CopilotSidebarView.test.ts +2 -1
  241. package/src/v2/components/chat/__tests__/StreamingMarkdownDefault.test.ts +54 -0
  242. package/src/v2/components/chat/audioRecorder.ts +4 -7
  243. package/src/v2/components/chat/copilotChatToolCallItemRender.ts +25 -90
  244. package/src/v2/components/chat/forwarded-slots.ts +17 -0
  245. package/src/v2/components/chat/index.ts +0 -1
  246. package/src/v2/components/chat/inspector-shortcuts.ts +10 -16
  247. package/src/v2/components/chat/message-feedback.ts +92 -195
  248. package/src/v2/components/chat/tool-call-display-context.ts +6 -22
  249. package/src/v2/components/chat/tool-call-group-parts.ts +47 -108
  250. package/src/v2/components/chat/turn-work.ts +0 -9
  251. package/src/v2/components/chat/types.ts +12 -4
  252. package/src/v2/components/chat/use-chat-labels.ts +16 -0
  253. package/src/v2/components/chat/use-copy-feedback.ts +21 -0
  254. package/src/v2/components/chat/use-lightbox.ts +15 -33
  255. package/src/v2/components/icons/__tests__/icons.test.ts +72 -68
  256. package/src/v2/components/icons/index.ts +109 -27
  257. package/src/v2/hooks/__tests__/use-agent-error-state.test.ts +5 -3
  258. package/src/v2/hooks/__tests__/use-agent-stability.test.ts +25 -4
  259. package/src/v2/hooks/__tests__/use-agent-throttle.test.ts +5 -1
  260. package/src/v2/hooks/__tests__/use-agent.test.ts +6 -3
  261. package/src/v2/hooks/__tests__/use-component.test.ts +21 -0
  262. package/src/v2/hooks/__tests__/use-configure-suggestions.test.ts +30 -1
  263. package/src/v2/hooks/__tests__/use-default-render-tool.test.ts +10 -10
  264. package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.ts +66 -1
  265. package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.ts +6 -1
  266. package/src/v2/hooks/__tests__/use-human-in-the-loop.test.ts +187 -12
  267. package/src/v2/hooks/__tests__/use-interrupt.test.ts +97 -0
  268. package/src/v2/hooks/__tests__/use-render-activity-message.test.ts +106 -0
  269. package/src/v2/hooks/__tests__/use-render-tool.test.ts +3 -6
  270. package/src/v2/hooks/__tests__/use-threads.test.ts +48 -6
  271. package/src/v2/hooks/__tests__/zod-regression.test.ts +5 -4
  272. package/src/v2/hooks/use-agent-context.ts +4 -10
  273. package/src/v2/hooks/use-agent.ts +86 -290
  274. package/src/v2/hooks/use-attachments.ts +48 -168
  275. package/src/v2/hooks/use-capabilities.ts +2 -7
  276. package/src/v2/hooks/use-component.ts +7 -4
  277. package/src/v2/hooks/use-configure-suggestions.ts +29 -220
  278. package/src/v2/hooks/use-default-render-tool.ts +31 -152
  279. package/src/v2/hooks/use-frontend-tool.ts +15 -25
  280. package/src/v2/hooks/use-human-in-the-loop.ts +11 -80
  281. package/src/v2/hooks/use-interrupt.ts +29 -308
  282. package/src/v2/hooks/use-keyboard-height.ts +17 -40
  283. package/src/v2/hooks/use-pin-to-send.ts +15 -99
  284. package/src/v2/hooks/use-render-activity-message.ts +35 -57
  285. package/src/v2/hooks/use-render-custom-messages.ts +24 -88
  286. package/src/v2/hooks/use-render-tool.ts +2 -4
  287. package/src/v2/hooks/use-suggestions.ts +17 -36
  288. package/src/v2/hooks/use-threads.ts +49 -288
  289. package/src/v2/lib/__tests__/shallow-stable.test.ts +54 -0
  290. package/src/v2/lib/__tests__/vue-core-renderers.test.ts +42 -0
  291. package/src/v2/lib/processPartialHtml.ts +6 -21
  292. package/src/v2/lib/shallow-stable.ts +2 -16
  293. package/src/v2/lib/vue-core.ts +90 -85
  294. package/src/v2/providers/CopilotChatConfigurationProvider.vue +48 -186
  295. package/src/v2/providers/CopilotKitProvider.types.ts +12 -132
  296. package/src/v2/providers/CopilotKitProvider.vue +291 -641
  297. package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.ts +22 -2
  298. package/src/v2/providers/__tests__/CopilotKitProvider.a2ui.test.ts +38 -2
  299. package/src/v2/providers/__tests__/CopilotKitProvider.config.test.ts +124 -0
  300. package/src/v2/providers/__tests__/CopilotKitProvider.headersAtSendTime.test.ts +3 -3
  301. package/src/v2/providers/__tests__/CopilotKitProvider.learning.test.ts +3 -1
  302. package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.ts +4 -1
  303. package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +88 -28
  304. package/src/v2/providers/chat-configuration-store-key.ts +9 -0
  305. package/src/v2/providers/markdown-renderer.ts +8 -2
  306. package/src/v2/providers/types.ts +3 -49
  307. package/src/v2/providers/use-inspector-thread-override.ts +22 -80
  308. package/src/v2/types/__tests__/defineToolCallRenderer.test.ts +28 -33
  309. package/src/v2/types/defineToolCallRenderer.ts +7 -6
  310. package/src/v2/types/human-in-the-loop.ts +8 -32
  311. package/src/v2/types/interrupt.ts +7 -31
  312. package/src/v2/types/vue-activity-message-renderer.ts +24 -15
  313. package/src/v2/types/vue-custom-message-renderer.ts +12 -16
  314. package/src/v2/types/vue-tool-call-renderer.ts +23 -38
  315. package/tsconfig.json +0 -1
  316. package/vite.config.ts +8 -5
  317. package/vitest.config.ts +12 -7
  318. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts +0 -9
  319. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts.map +0 -1
  320. package/dist/v2/components/chat/normalize-auto-scroll.d.ts +0 -3
  321. package/dist/v2/components/chat/normalize-auto-scroll.d.ts.map +0 -1
  322. package/dist/v2/components/chat/tool-call-layout.d.ts +0 -115
  323. package/dist/v2/components/chat/tool-call-layout.d.ts.map +0 -1
  324. package/dist/v2/lib/is-mobile-viewport.d.ts +0 -15
  325. package/dist/v2/lib/is-mobile-viewport.d.ts.map +0 -1
  326. package/dist/v2/lib/message-feedback.d.ts +0 -33
  327. package/dist/v2/lib/message-feedback.d.ts.map +0 -1
  328. package/dist/v2/lib/transcription-client.d.ts +0 -19
  329. package/dist/v2/lib/transcription-client.d.ts.map +0 -1
  330. package/src/v2/components/__tests__/A2UICatalogContext.test.ts +0 -63
  331. package/src/v2/components/a2ui/__tests__/A2UIRecoveryStates.test.ts +0 -175
  332. package/src/v2/components/chat/BasicMarkdown.vue +0 -160
  333. package/src/v2/components/chat/__tests__/BasicMarkdown.test.ts +0 -69
  334. package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +0 -39
  335. package/src/v2/components/chat/normalize-auto-scroll.ts +0 -17
  336. package/src/v2/components/chat/tool-call-layout.ts +0 -304
  337. package/src/v2/lib/__tests__/is-mobile-viewport.test.ts +0 -48
  338. package/src/v2/lib/__tests__/message-feedback.test.ts +0 -152
  339. package/src/v2/lib/__tests__/processPartialHtml.test.ts +0 -84
  340. package/src/v2/lib/__tests__/transcription-client.test.ts +0 -67
  341. package/src/v2/lib/is-mobile-viewport.ts +0 -23
  342. package/src/v2/lib/message-feedback.ts +0 -120
  343. package/src/v2/lib/transcription-client.ts +0 -151
@@ -1,188 +1,172 @@
1
- import { defineComponent } from "vue";
1
+ import { defineComponent, h } from "vue";
2
2
  import { render, screen } from "@testing-library/vue";
3
3
  import { describe, expect, it } from "vitest";
4
4
  import { z } from "zod";
5
- import type {
6
- ActivityMessage,
7
- AssistantMessage,
8
- Message,
9
- UserMessage,
10
- } from "@ag-ui/core";
5
+ import type { Message, ToolCall } from "@ag-ui/core";
11
6
  import CopilotKitProvider from "../../../providers/CopilotKitProvider.vue";
12
7
  import CopilotChatConfigurationProvider from "../../../providers/CopilotChatConfigurationProvider.vue";
13
8
  import CopilotChatMessageView from "../CopilotChatMessageView.vue";
9
+ import type { VueActivityMessageRenderer } from "../../../types";
10
+
11
+ const agentId = "default";
12
+ const threadId = "thread-test";
13
+
14
+ /** Slot templates that print what the view hands each message slot. */
15
+ const assistantContentSlot = `
16
+ <template #assistant-message="{ message }">
17
+ <div data-testid="assistant-content">{{ message.content }}</div>
18
+ </template>`;
19
+ const assistantToolCallsSlot = `
20
+ <template #assistant-message="{ message }">
21
+ <div data-testid="assistant-tool-calls-count">{{ message.toolCalls?.length ?? 0 }}</div>
22
+ <div data-testid="assistant-tool-call-args">{{ (message.toolCalls ?? []).map((call) => call.function.arguments).join("|") }}</div>
23
+ <div data-testid="assistant-content">{{ message.content }}</div>
24
+ </template>`;
25
+ const userContentSlot = `
26
+ <template #user-message="{ message }">
27
+ <div data-testid="user-content">{{ message.content }}</div>
28
+ </template>`;
29
+
30
+ /**
31
+ * Renders a message view inside the providers.
32
+ *
33
+ * @param options.slots - Slot templates placed inside the message view.
34
+ * @param options.renderActivityMessages - Activity renderers to register.
35
+ */
36
+ function renderMessageView(options: {
37
+ messages: Message[];
38
+ slots?: string;
39
+ renderActivityMessages?: VueActivityMessageRenderer<unknown>[];
40
+ }) {
41
+ const { messages, slots = "", renderActivityMessages = [] } = options;
42
+ const Host = defineComponent({
43
+ components: {
44
+ CopilotKitProvider,
45
+ CopilotChatConfigurationProvider,
46
+ CopilotChatMessageView,
47
+ },
48
+ setup() {
49
+ return { messages, agentId, threadId, renderActivityMessages };
50
+ },
51
+ template: `
52
+ <CopilotKitProvider
53
+ runtime-url="/api/copilotkit"
54
+ :render-activity-messages="renderActivityMessages"
55
+ >
56
+ <CopilotChatConfigurationProvider :agent-id="agentId" :thread-id="threadId">
57
+ <CopilotChatMessageView :messages="messages">${slots}</CopilotChatMessageView>
58
+ </CopilotChatConfigurationProvider>
59
+ </CopilotKitProvider>
60
+ `,
61
+ });
14
62
 
15
- describe("CopilotChatMessageView activity rendering", () => {
16
- const agentId = "default";
17
- const threadId = "thread-test";
18
-
19
- function renderMessageView({
20
- messages,
21
- hostTemplate = `<CopilotChatMessageView :messages="messages" />`,
22
- }: {
23
- messages: Message[];
24
- hostTemplate?: string;
25
- }) {
26
- const ActivityRenderer = defineComponent({
27
- name: "ActivityRenderer",
28
- props: {
29
- content: { type: Object, required: true },
30
- },
31
- setup(props) {
32
- return {
33
- percent: (props.content as { percent: number }).percent,
34
- };
35
- },
36
- template: `
37
- <div data-testid="activity-renderer">
38
- Progress: {{ percent }}%
39
- </div>
40
- `,
41
- });
42
-
43
- const Host = defineComponent({
44
- components: {
45
- CopilotKitProvider,
46
- CopilotChatConfigurationProvider,
47
- CopilotChatMessageView,
48
- ActivityRenderer,
49
- },
50
- setup() {
51
- return { messages, agentId, threadId };
52
- },
53
- template: `
54
- <CopilotKitProvider runtime-url="/api/copilotkit">
55
- <CopilotChatConfigurationProvider :agent-id="agentId" :thread-id="threadId">
56
- ${hostTemplate}
57
- </CopilotChatConfigurationProvider>
58
- </CopilotKitProvider>
59
- `,
60
- });
63
+ return render(Host);
64
+ }
61
65
 
62
- return render(Host);
63
- }
64
-
65
- it("renders activity messages via matching custom renderer", () => {
66
- const messages: Message[] = [
67
- {
68
- id: "act-1",
69
- role: "activity",
70
- activityType: "search-progress",
71
- content: { percent: 42 },
72
- } as ActivityMessage,
73
- ];
74
-
75
- const renderers = [
76
- {
77
- activityType: "search-progress",
78
- content: z.object({ percent: z.number() }),
79
- },
80
- ];
81
- expect(renderers).toHaveLength(1);
66
+ function toolCall(id: string, name: string, args = "{}"): ToolCall {
67
+ return { id, type: "function", function: { name, arguments: args } };
68
+ }
82
69
 
70
+ describe("CopilotChatMessageView activity rendering", () => {
71
+ const progress: Message = {
72
+ id: "act-1",
73
+ role: "activity",
74
+ activityType: "search-progress",
75
+ content: { percent: 42 },
76
+ };
77
+
78
+ /** A `"*"` renderer that prints the content it was given. */
79
+ const wildcardRenderer: VueActivityMessageRenderer<unknown> = {
80
+ activityType: "*",
81
+ content: z.object({ percent: z.number() }),
82
+ render: (props) =>
83
+ h(
84
+ "div",
85
+ { "data-testid": "wildcard-activity" },
86
+ JSON.stringify(props.content),
87
+ ),
88
+ };
89
+
90
+ it("renders activity messages through their activity-<type> slot", () => {
83
91
  renderMessageView({
84
- messages,
85
- hostTemplate: `
86
- <CopilotChatMessageView :messages="messages">
87
- <template #activity-search-progress="{ content }">
88
- <ActivityRenderer :content="content" />
89
- </template>
90
- </CopilotChatMessageView>
91
- `,
92
+ messages: [progress],
93
+ slots: `
94
+ <template #activity-search-progress="{ content }">
95
+ <div data-testid="activity-renderer">Progress: {{ content.percent }}%</div>
96
+ </template>`,
92
97
  });
93
98
 
94
99
  expect(screen.getByTestId("activity-renderer").textContent).toContain("42");
95
100
  });
96
101
 
97
102
  it("skips rendering when no activity renderer matches", () => {
98
- const messages: Message[] = [
99
- {
100
- id: "act-2",
101
- role: "activity",
102
- activityType: "unknown-type",
103
- content: { message: "should not render" },
104
- } as ActivityMessage,
105
- ];
103
+ renderMessageView({
104
+ messages: [
105
+ {
106
+ id: "act-2",
107
+ role: "activity",
108
+ activityType: "unknown-type",
109
+ content: { message: "should not render" },
110
+ },
111
+ ],
112
+ });
113
+
114
+ expect(screen.queryByText("should not render")).toBeNull();
115
+ });
106
116
 
117
+ it("falls back to the * renderer for a type with no renderer of its own", () => {
107
118
  renderMessageView({
108
- messages,
109
- hostTemplate: `<CopilotChatMessageView :messages="messages" />`,
119
+ messages: [progress],
120
+ renderActivityMessages: [wildcardRenderer],
110
121
  });
111
122
 
112
- expect(screen.queryByTestId("activity-renderer")).toBeNull();
123
+ expect(screen.getByTestId("wildcard-activity").textContent).toBe(
124
+ '{"percent":42}',
125
+ );
113
126
  });
114
- });
115
127
 
116
- describe("CopilotChatMessageView duplicate message deduplication", () => {
117
- const agentId = "default";
118
- const threadId = "thread-test";
119
-
120
- function renderMessageView({ messages }: { messages: Message[] }) {
121
- const Host = defineComponent({
122
- components: {
123
- CopilotKitProvider,
124
- CopilotChatConfigurationProvider,
125
- CopilotChatMessageView,
126
- },
127
- setup() {
128
- return { messages, agentId, threadId };
129
- },
130
- template: `
131
- <CopilotKitProvider runtime-url="/api/copilotkit">
132
- <CopilotChatConfigurationProvider :agent-id="agentId" :thread-id="threadId">
133
- <CopilotChatMessageView :messages="messages" />
134
- </CopilotChatConfigurationProvider>
135
- </CopilotKitProvider>
136
- `,
128
+ it("uses an activity-<type> slot before the * renderer", () => {
129
+ renderMessageView({
130
+ messages: [progress],
131
+ renderActivityMessages: [wildcardRenderer],
132
+ slots: `
133
+ <template #activity-search-progress>
134
+ <div data-testid="activity-slot">slot</div>
135
+ </template>`,
137
136
  });
138
137
 
139
- return render(Host);
140
- }
138
+ expect(screen.getByTestId("activity-slot")).toBeTruthy();
139
+ expect(screen.queryByTestId("wildcard-activity")).toBeNull();
140
+ });
141
+ });
141
142
 
143
+ describe("CopilotChatMessageView duplicate message deduplication", () => {
142
144
  it("preserves assistant text content when later duplicate has empty content (multi-tool-call scenario)", () => {
143
- const messages: Message[] = [
144
- {
145
- id: "user-1",
146
- role: "user",
147
- content: "Record a headache",
148
- } as UserMessage,
149
- {
150
- id: "assistant-1",
151
- role: "assistant",
152
- content: "Let me record that...",
153
- } as AssistantMessage,
154
- {
155
- id: "assistant-1",
156
- role: "assistant",
157
- content: "",
158
- toolCalls: [
159
- {
160
- id: "tc-1",
161
- type: "function",
162
- function: { name: "captureData", arguments: "{}" },
163
- },
164
- ],
165
- } as AssistantMessage,
166
- {
167
- id: "assistant-1",
168
- role: "assistant",
169
- content: "",
170
- toolCalls: [
171
- {
172
- id: "tc-1",
173
- type: "function",
174
- function: { name: "captureData", arguments: "{}" },
175
- },
176
- {
177
- id: "tc-2",
178
- type: "function",
179
- function: { name: "updateMemory", arguments: "{}" },
180
- },
181
- ],
182
- } as AssistantMessage,
183
- ];
184
-
185
- renderMessageView({ messages });
145
+ renderMessageView({
146
+ messages: [
147
+ { id: "user-1", role: "user", content: "Record a headache" },
148
+ {
149
+ id: "assistant-1",
150
+ role: "assistant",
151
+ content: "Let me record that...",
152
+ },
153
+ {
154
+ id: "assistant-1",
155
+ role: "assistant",
156
+ content: "",
157
+ toolCalls: [toolCall("tc-1", "captureData")],
158
+ },
159
+ {
160
+ id: "assistant-1",
161
+ role: "assistant",
162
+ content: "",
163
+ toolCalls: [
164
+ toolCall("tc-1", "captureData"),
165
+ toolCall("tc-2", "updateMemory"),
166
+ ],
167
+ },
168
+ ],
169
+ });
186
170
 
187
171
  const assistantMessages = screen.getAllByTestId(
188
172
  "copilot-assistant-message",
@@ -194,25 +178,21 @@ describe("CopilotChatMessageView duplicate message deduplication", () => {
194
178
  });
195
179
 
196
180
  it("uses latest content when all assistant duplicates have non-empty content", () => {
197
- const messages: Message[] = [
198
- {
199
- id: "user-1",
200
- role: "user",
201
- content: "Hello",
202
- } as UserMessage,
203
- {
204
- id: "assistant-1",
205
- role: "assistant",
206
- content: "Partial response...",
207
- } as AssistantMessage,
208
- {
209
- id: "assistant-1",
210
- role: "assistant",
211
- content: "Full response from the assistant.",
212
- } as AssistantMessage,
213
- ];
214
-
215
- renderMessageView({ messages });
181
+ renderMessageView({
182
+ messages: [
183
+ { id: "user-1", role: "user", content: "Hello" },
184
+ {
185
+ id: "assistant-1",
186
+ role: "assistant",
187
+ content: "Partial response...",
188
+ },
189
+ {
190
+ id: "assistant-1",
191
+ role: "assistant",
192
+ content: "Full response from the assistant.",
193
+ },
194
+ ],
195
+ });
216
196
 
217
197
  const assistantMessages = screen.getAllByTestId(
218
198
  "copilot-assistant-message",
@@ -221,100 +201,45 @@ describe("CopilotChatMessageView duplicate message deduplication", () => {
221
201
  expect(assistantMessages[0]?.textContent).toContain(
222
202
  "Full response from the assistant.",
223
203
  );
224
-
225
- const userMessages = screen.getAllByTestId("copilot-user-message");
226
- expect(userMessages).toHaveLength(1);
204
+ expect(screen.getAllByTestId("copilot-user-message")).toHaveLength(1);
227
205
  });
228
206
 
229
207
  it("uses later content when earlier content is empty", () => {
230
- const messages: Message[] = [
231
- {
232
- id: "assistant-1",
233
- role: "assistant",
234
- content: "",
235
- } as AssistantMessage,
236
- {
237
- id: "assistant-1",
238
- role: "assistant",
239
- content: "Here is the result.",
240
- } as AssistantMessage,
241
- ];
242
-
243
- const Host = defineComponent({
244
- components: {
245
- CopilotKitProvider,
246
- CopilotChatConfigurationProvider,
247
- CopilotChatMessageView,
248
- },
249
- setup() {
250
- return { messages, agentId, threadId };
251
- },
252
- template: `
253
- <CopilotKitProvider runtime-url="/api/copilotkit">
254
- <CopilotChatConfigurationProvider :agent-id="agentId" :thread-id="threadId">
255
- <CopilotChatMessageView :messages="messages">
256
- <template #assistant-message="{ message }">
257
- <div data-testid="assistant-content">{{ message.content }}</div>
258
- </template>
259
- </CopilotChatMessageView>
260
- </CopilotChatConfigurationProvider>
261
- </CopilotKitProvider>
262
- `,
208
+ renderMessageView({
209
+ messages: [
210
+ { id: "assistant-1", role: "assistant", content: "" },
211
+ {
212
+ id: "assistant-1",
213
+ role: "assistant",
214
+ content: "Here is the result.",
215
+ },
216
+ ],
217
+ slots: assistantContentSlot,
263
218
  });
264
219
 
265
- render(Host);
266
-
267
220
  expect(screen.getByTestId("assistant-content").textContent).toContain(
268
221
  "Here is the result.",
269
222
  );
270
223
  });
271
224
 
272
225
  it("recovers toolCalls when later duplicate has content but undefined toolCalls", () => {
273
- const messages: Message[] = [
274
- {
275
- id: "assistant-1",
276
- role: "assistant",
277
- content: "",
278
- toolCalls: [
279
- {
280
- id: "tc-1",
281
- type: "function",
282
- function: { name: "captureData", arguments: "{}" },
283
- },
284
- ],
285
- } as AssistantMessage,
286
- {
287
- id: "assistant-1",
288
- role: "assistant",
289
- content: "Here is the result.",
290
- } as AssistantMessage,
291
- ];
292
-
293
- const Host = defineComponent({
294
- components: {
295
- CopilotKitProvider,
296
- CopilotChatConfigurationProvider,
297
- CopilotChatMessageView,
298
- },
299
- setup() {
300
- return { messages, agentId, threadId };
301
- },
302
- template: `
303
- <CopilotKitProvider runtime-url="/api/copilotkit">
304
- <CopilotChatConfigurationProvider :agent-id="agentId" :thread-id="threadId">
305
- <CopilotChatMessageView :messages="messages">
306
- <template #assistant-message="{ message }">
307
- <div data-testid="assistant-tool-calls-count">{{ message.toolCalls?.length ?? 0 }}</div>
308
- <div data-testid="assistant-content">{{ message.content }}</div>
309
- </template>
310
- </CopilotChatMessageView>
311
- </CopilotChatConfigurationProvider>
312
- </CopilotKitProvider>
313
- `,
226
+ renderMessageView({
227
+ messages: [
228
+ {
229
+ id: "assistant-1",
230
+ role: "assistant",
231
+ content: "",
232
+ toolCalls: [toolCall("tc-1", "captureData")],
233
+ },
234
+ {
235
+ id: "assistant-1",
236
+ role: "assistant",
237
+ content: "Here is the result.",
238
+ },
239
+ ],
240
+ slots: assistantToolCallsSlot,
314
241
  });
315
242
 
316
- render(Host);
317
-
318
243
  expect(screen.getByTestId("assistant-content").textContent).toContain(
319
244
  "Here is the result.",
320
245
  );
@@ -324,171 +249,90 @@ describe("CopilotChatMessageView duplicate message deduplication", () => {
324
249
  });
325
250
 
326
251
  it("keeps empty toolCalls array from later chunk", () => {
327
- const messages: Message[] = [
328
- {
329
- id: "assistant-1",
330
- role: "assistant",
331
- content: "",
332
- toolCalls: [
333
- {
334
- id: "tc-1",
335
- type: "function",
336
- function: { name: "captureData", arguments: "{}" },
337
- },
338
- ],
339
- } as AssistantMessage,
340
- {
341
- id: "assistant-1",
342
- role: "assistant",
343
- content: "Done.",
344
- toolCalls: [],
345
- } as AssistantMessage,
346
- ];
347
-
348
- const Host = defineComponent({
349
- components: {
350
- CopilotKitProvider,
351
- CopilotChatConfigurationProvider,
352
- CopilotChatMessageView,
353
- },
354
- setup() {
355
- return { messages, agentId, threadId };
356
- },
357
- template: `
358
- <CopilotKitProvider runtime-url="/api/copilotkit">
359
- <CopilotChatConfigurationProvider :agent-id="agentId" :thread-id="threadId">
360
- <CopilotChatMessageView :messages="messages">
361
- <template #assistant-message="{ message }">
362
- <div data-testid="assistant-tool-calls-count">{{ message.toolCalls?.length ?? 0 }}</div>
363
- </template>
364
- </CopilotChatMessageView>
365
- </CopilotChatConfigurationProvider>
366
- </CopilotKitProvider>
367
- `,
252
+ renderMessageView({
253
+ messages: [
254
+ {
255
+ id: "assistant-1",
256
+ role: "assistant",
257
+ content: "",
258
+ toolCalls: [toolCall("tc-1", "captureData")],
259
+ },
260
+ {
261
+ id: "assistant-1",
262
+ role: "assistant",
263
+ content: "Done.",
264
+ toolCalls: [],
265
+ },
266
+ ],
267
+ slots: assistantToolCallsSlot,
368
268
  });
369
269
 
370
- render(Host);
371
-
372
270
  expect(screen.getByTestId("assistant-tool-calls-count").textContent).toBe(
373
271
  "0",
374
272
  );
375
273
  });
376
274
 
377
- it("handles undefined content on both occurrences", () => {
378
- const messages: Message[] = [
379
- {
380
- id: "assistant-1",
381
- role: "assistant",
382
- content: undefined,
383
- } as AssistantMessage,
384
- {
385
- id: "assistant-1",
386
- role: "assistant",
387
- content: undefined,
388
- } as AssistantMessage,
389
- ];
390
-
391
- const Host = defineComponent({
392
- components: {
393
- CopilotKitProvider,
394
- CopilotChatConfigurationProvider,
395
- CopilotChatMessageView,
396
- },
397
- setup() {
398
- return { messages, agentId, threadId };
399
- },
400
- template: `
401
- <CopilotKitProvider runtime-url="/api/copilotkit">
402
- <CopilotChatConfigurationProvider :agent-id="agentId" :thread-id="threadId">
403
- <CopilotChatMessageView :messages="messages">
404
- <template #assistant-message="{ message }">
405
- <div data-testid="assistant-content">{{ message.content }}</div>
406
- </template>
407
- </CopilotChatMessageView>
408
- </CopilotChatConfigurationProvider>
409
- </CopilotKitProvider>
410
- `,
275
+ it("collapses a tool call that repeats in one message, keeping the copy with arguments", () => {
276
+ renderMessageView({
277
+ messages: [
278
+ {
279
+ id: "assistant-1",
280
+ role: "assistant",
281
+ content: "",
282
+ toolCalls: [
283
+ toolCall("tc-1", "getWeather", '{"city":"Paris"}'),
284
+ toolCall("tc-1", "getWeather", ""),
285
+ ],
286
+ },
287
+ ],
288
+ slots: assistantToolCallsSlot,
411
289
  });
412
290
 
413
- render(Host);
291
+ expect(screen.getByTestId("assistant-tool-calls-count").textContent).toBe(
292
+ "1",
293
+ );
294
+ expect(screen.getByTestId("assistant-tool-call-args").textContent).toBe(
295
+ '{"city":"Paris"}',
296
+ );
297
+ });
298
+
299
+ it("handles undefined content on both occurrences", () => {
300
+ renderMessageView({
301
+ messages: [
302
+ { id: "assistant-1", role: "assistant", content: undefined },
303
+ { id: "assistant-1", role: "assistant", content: undefined },
304
+ ],
305
+ slots: assistantContentSlot,
306
+ });
414
307
 
415
308
  expect(screen.getByTestId("assistant-content").textContent).toBe("");
416
309
  });
417
310
 
418
311
  it("keeps last entry for non-assistant roles", () => {
419
- const messages: Message[] = [
420
- {
421
- id: "user-1",
422
- role: "user",
423
- content: "Hello",
424
- } as UserMessage,
425
- {
426
- id: "user-1",
427
- role: "user",
428
- content: "Hello (updated)",
429
- } as UserMessage,
430
- ];
431
-
432
- const Host = defineComponent({
433
- components: {
434
- CopilotKitProvider,
435
- CopilotChatConfigurationProvider,
436
- CopilotChatMessageView,
437
- },
438
- setup() {
439
- return { messages, agentId, threadId };
440
- },
441
- template: `
442
- <CopilotKitProvider runtime-url="/api/copilotkit">
443
- <CopilotChatConfigurationProvider :agent-id="agentId" :thread-id="threadId">
444
- <CopilotChatMessageView :messages="messages">
445
- <template #user-message="{ message }">
446
- <div data-testid="user-content">{{ message.content }}</div>
447
- </template>
448
- </CopilotChatMessageView>
449
- </CopilotChatConfigurationProvider>
450
- </CopilotKitProvider>
451
- `,
312
+ renderMessageView({
313
+ messages: [
314
+ { id: "user-1", role: "user", content: "Hello" },
315
+ { id: "user-1", role: "user", content: "Hello (updated)" },
316
+ ],
317
+ slots: userContentSlot,
452
318
  });
453
319
 
454
- render(Host);
455
-
456
320
  expect(screen.getByTestId("user-content").textContent).toBe(
457
321
  "Hello (updated)",
458
322
  );
459
323
  });
460
324
 
461
325
  it("preserves order of unique messages", () => {
462
- const messages: Message[] = [
463
- {
464
- id: "user-1",
465
- role: "user",
466
- content: "First question",
467
- } as UserMessage,
468
- {
469
- id: "assistant-1",
470
- role: "assistant",
471
- content: "First answer",
472
- } as AssistantMessage,
473
- {
474
- id: "user-2",
475
- role: "user",
476
- content: "Second question",
477
- } as UserMessage,
478
- {
479
- id: "assistant-2",
480
- role: "assistant",
481
- content: "Second answer",
482
- } as AssistantMessage,
483
- ];
484
-
485
- renderMessageView({ messages });
486
-
487
- const userMessages = screen.getAllByTestId("copilot-user-message");
488
- const assistantMessages = screen.getAllByTestId(
489
- "copilot-assistant-message",
490
- );
491
- expect(userMessages).toHaveLength(2);
492
- expect(assistantMessages).toHaveLength(2);
326
+ renderMessageView({
327
+ messages: [
328
+ { id: "user-1", role: "user", content: "First question" },
329
+ { id: "assistant-1", role: "assistant", content: "First answer" },
330
+ { id: "user-2", role: "user", content: "Second question" },
331
+ { id: "assistant-2", role: "assistant", content: "Second answer" },
332
+ ],
333
+ });
334
+
335
+ expect(screen.getAllByTestId("copilot-user-message")).toHaveLength(2);
336
+ expect(screen.getAllByTestId("copilot-assistant-message")).toHaveLength(2);
493
337
  });
494
338
  });