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

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-BMTHA_P2.js +15901 -0
  13. package/dist/use-render-activity-message-BMTHA_P2.js.map +1 -0
  14. package/dist/use-render-activity-message-CH3beu7z.cjs +113 -0
  15. package/dist/use-render-activity-message-CH3beu7z.cjs.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,115 +0,0 @@
1
- import type { Message, ToolCall, ToolMessage } from "@ag-ui/core";
2
- /**
3
- * How the chat shows tool calls.
4
- *
5
- * - `"grouped"` (default): calls made in a row share one card, collapsed to a
6
- * summary ("Used 3 tools") that opens to a row per call.
7
- * - `"line"`: the same grouping as a quiet line of text, like the reasoning
8
- * message's "Thought for 4 seconds".
9
- * - `"stacked"`: the latest call on top of a stack of the earlier ones; click
10
- * to fan the stack out into its cards.
11
- * - `"turn"`: the agent works in the open (narration, then a row per call),
12
- * and when the reply is done everything before it folds into "Worked for 9s".
13
- * - `"separate"`: every call gets its own card, as before grouping existed.
14
- *
15
- * Only calls drawn by a renderer that opts into grouping (`group: true`) are
16
- * grouped; CopilotKit's built-in card from `useDefaultRenderTool()` does. Any
17
- * other call always shows on its own and splits the group around it.
18
- */
19
- export type CopilotChatToolCallDisplay = "grouped" | "line" | "stacked" | "turn" | "separate";
20
- /** One tool call and, once it has finished, the message carrying its result. */
21
- export interface ToolCallEntry {
22
- toolCall: ToolCall;
23
- toolMessage?: ToolMessage;
24
- }
25
- export type ToolCallSegment =
26
- /** Consecutive calls drawn by renderers that opted into grouping. */
27
- {
28
- kind: "group";
29
- id: string;
30
- calls: ToolCallEntry[];
31
- /** Nothing renders after this group yet, so a running agent may add to it. */
32
- trailing: boolean;
33
- }
34
- /**
35
- * A call drawn by a renderer that didn't opt into grouping, or with no
36
- * renderer at all. The latter renders nothing (and warns in development)
37
- * without breaking a group.
38
- */
39
- | {
40
- kind: "call";
41
- id: string;
42
- call: ToolCallEntry;
43
- rendered: boolean;
44
- };
45
- /** What one assistant message's tool-call area renders. */
46
- export interface ToolCallLayout {
47
- segments: ToolCallSegment[];
48
- /** Changes whenever anything this layout renders changes; for memoization. */
49
- signature: string;
50
- }
51
- /** Which tool-call renderers are registered. */
52
- export interface ToolCallRendererNames {
53
- /** Tool names with a renderer of their own. */
54
- named: ReadonlySet<string>;
55
- /** Of those, the ones whose renderer opted into grouping. */
56
- groupedNames: ReadonlySet<string>;
57
- /** A wildcard (`"*"`) renderer is registered. */
58
- wildcard: boolean;
59
- /** The wildcard renderer opted into grouping (the built-in card does). */
60
- wildcardGroups: boolean;
61
- }
62
- /** Index of tool results by the call they answer. */
63
- export declare function getToolResults(messages: Message[]): Map<string, ToolMessage>;
64
- /**
65
- * Lays out the tool calls of every assistant message in `rendered`.
66
- *
67
- * Calls drawn by a renderer that opted into grouping join the group that's
68
- * open; anything else that shows between them closes it: assistant text, a
69
- * user, reasoning or activity message, or a call drawn by any other renderer. A group belongs to
70
- * the message where it starts, so later messages whose calls joined it render
71
- * no tool calls themselves.
72
- *
73
- * @param rendered - The messages as the chat renders them, in order.
74
- * @param all - Every message, for finding tool results (a transform may hide them).
75
- * @param renderers - The registered renderers.
76
- */
77
- export declare function getToolCallLayouts(rendered: Message[], all: Message[], renderers: ToolCallRendererNames): Map<string, ToolCallLayout>;
78
- /**
79
- * Which renderers draw tool calls, from the registered renderers and the
80
- * view's tool-call slots. A slot wins over a registered renderer and never
81
- * groups, since the chat can't tell what it draws: `#tool-call-<name>` takes
82
- * that tool, and `#tool-call` takes every tool.
83
- *
84
- * @param renderers - The registered renderers (`copilotkit.renderToolCalls`).
85
- * @param slotNames - The names of the slots the view was given.
86
- */
87
- export declare function getToolCallRendererNames(renderers: readonly {
88
- name: string;
89
- group?: boolean;
90
- }[], slotNames?: readonly string[]): ToolCallRendererNames;
91
- /** A reply's working phase, for the `"turn"` display. */
92
- export interface TurnWork {
93
- /** Stable across the turn's life: the id of the user message it answers. */
94
- key: string;
95
- /** The first assistant-side message, where the "Worked for" line goes. */
96
- firstMessageId: string;
97
- /** Everything up to and including the last message with a tool call. */
98
- workMessageIds: ReadonlySet<string>;
99
- /**
100
- * The reply's last assistant message, when it has text and is part of the
101
- * work (it also calls a tool). Its text is the answer, so it stays out.
102
- */
103
- replyTextMessageId?: string;
104
- calls: ToolCallEntry[];
105
- /** No user message follows, so the agent may still be working on it. */
106
- isLatest: boolean;
107
- }
108
- /**
109
- * Finds the working phase of every reply in `rendered`: its messages up to the
110
- * last one that calls a tool. Text in there was narration; what follows is the
111
- * reply itself. Replies that called no tools are omitted, except the latest,
112
- * which may be about to.
113
- */
114
- export declare function getTurnWork(rendered: Message[], layouts: ReadonlyMap<string, ToolCallLayout>): Map<string, TurnWork>;
115
- //# sourceMappingURL=tool-call-layout.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tool-call-layout.d.ts","sourceRoot":"","sources":["../../../../src/v2/components/chat/tool-call-layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAElE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,0BAA0B,GAClC,SAAS,GACT,MAAM,GACN,SAAS,GACT,MAAM,GACN,UAAU,CAAC;AAEf,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,MAAM,MAAM,eAAe;AACzB,qEAAqE;AACnE;IACE,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,8EAA8E;IAC9E,QAAQ,EAAE,OAAO,CAAC;CACnB;AACH;;;;GAIG;GACD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC;AAEzE,2DAA2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,gDAAgD;AAChD,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,6DAA6D;IAC7D,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,iDAAiD;IACjD,QAAQ,EAAE,OAAO,CAAC;IAClB,0EAA0E;IAC1E,cAAc,EAAE,OAAO,CAAC;CACzB;AA4BD,qDAAqD;AACrD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAM5E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,OAAO,EAAE,EACnB,GAAG,EAAE,OAAO,EAAE,EACd,SAAS,EAAE,qBAAqB,GAC/B,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAuD7B;AAID;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,EACvD,SAAS,GAAE,SAAS,MAAM,EAAO,GAChC,qBAAqB,CAuBvB;AAED,yDAAyD;AACzD,MAAM,WAAW,QAAQ;IACvB,4EAA4E;IAC5E,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,cAAc,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,wEAAwE;IACxE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,GAC3C,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CA6DvB"}
@@ -1,15 +0,0 @@
1
- /**
2
- * Media query for the mobile breakpoint, shared so the string literal isn't
3
- * duplicated across call sites within this package (e.g. `CopilotModalHeader`,
4
- * which needs a live `matchMedia` change-listener and so can't call
5
- * `isMobileViewport()` directly).
6
- */
7
- export declare const MOBILE_MAX_WIDTH_QUERY = "(max-width: 767px)";
8
- /**
9
- * Reports whether the viewport is in the mobile range (`<768px`), where the
10
- * drawer and chat modal are mutually exclusive. SSR-safe (returns `false`
11
- * when `window` is absent) and guards environments where `window` exists but
12
- * `window.matchMedia` does not (some test runners, embedded webviews).
13
- */
14
- export declare function isMobileViewport(): boolean;
15
- //# sourceMappingURL=is-mobile-viewport.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"is-mobile-viewport.d.ts","sourceRoot":"","sources":["../../../src/v2/lib/is-mobile-viewport.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAE3D;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAQ1C"}
@@ -1,33 +0,0 @@
1
- import type { AssistantMessage } from "@ag-ui/core";
2
- import type { CopilotKitCore } from "@copilotkit/core";
3
- /** Trajectory event name for a rating of one assistant message. */
4
- export declare const MESSAGE_FEEDBACK_EVENT_NAME = "message.feedback";
5
- /** Longest comment kept, in characters; the rest is cut so the event stays small. */
6
- export declare const MESSAGE_FEEDBACK_MAX_COMMENT_LENGTH = 1000;
7
- export type MessageFeedbackRating = "up" | "down";
8
- /** The rating this page gave one assistant message. */
9
- export interface MessageFeedback {
10
- readonly rating: MessageFeedbackRating;
11
- readonly comment?: string;
12
- }
13
- /** The rating this page gave one message, if any. */
14
- export declare function getMessageFeedback(agentId: string, threadId: string, messageId: string): MessageFeedback | undefined;
15
- /** Calls `listener` whenever a rating in this Thread changes. */
16
- export declare function subscribeToMessageFeedback(agentId: string, threadId: string, listener: () => void): () => void;
17
- /**
18
- * Sets (or, with `null`, clears) this page's rating of one message and sends
19
- * it to the active Trajectory. Every change is a new event; the newest event
20
- * for a `feedbackId` is the current one. Like any Trajectory event, a change
21
- * made while no Trajectory captures, for example during a reconnect, is not
22
- * sent; the page still shows it.
23
- */
24
- export declare function setMessageFeedback(params: {
25
- copilotkit: CopilotKitCore;
26
- agentId: string;
27
- threadId: string;
28
- message: AssistantMessage;
29
- feedback: MessageFeedback | null;
30
- }): void;
31
- /** @internal Forgets every rating, so each test starts empty. */
32
- export declare function ɵresetMessageFeedbackCache(): void;
33
- //# sourceMappingURL=message-feedback.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"message-feedback.d.ts","sourceRoot":"","sources":["../../../src/v2/lib/message-feedback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,mEAAmE;AACnE,eAAO,MAAM,2BAA2B,qBAAqB,CAAC;AAE9D,qFAAqF;AACrF,eAAO,MAAM,mCAAmC,OAAO,CAAC;AAKxD,MAAM,MAAM,qBAAqB,GAAG,IAAI,GAAG,MAAM,CAAC;AAElD,uDAAuD;AACvD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AA2BD,qDAAqD;AACrD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,eAAe,GAAG,SAAS,CAE7B;AAED,iEAAiE;AACjE,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,IAAI,GACnB,MAAM,IAAI,CAYZ;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,UAAU,EAAE,cAAc,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;CAClC,GAAG,IAAI,CA4BP;AAED,iEAAiE;AACjE,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}
@@ -1,19 +0,0 @@
1
- import type { CopilotKitCoreVue } from "./vue-core";
2
- import { TranscriptionErrorCode } from "@copilotkit/shared";
3
- export interface TranscriptionResult {
4
- text: string;
5
- size: number;
6
- type: string;
7
- }
8
- export interface TranscriptionErrorInfo {
9
- code: TranscriptionErrorCode;
10
- message: string;
11
- retryable: boolean;
12
- }
13
- export { TranscriptionErrorCode };
14
- export declare class TranscriptionError extends Error {
15
- readonly info: TranscriptionErrorInfo;
16
- constructor(info: TranscriptionErrorInfo);
17
- }
18
- export declare function transcribeAudio(core: CopilotKitCoreVue, audioBlob: Blob, filename?: string): Promise<TranscriptionResult>;
19
- //# sourceMappingURL=transcription-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transcription-client.d.ts","sourceRoot":"","sources":["../../../src/v2/lib/transcription-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAuClC,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,SAAgB,IAAI,EAAE,sBAAsB,CAAC;gBAEjC,IAAI,EAAE,sBAAsB;CAKzC;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,iBAAiB,EACvB,SAAS,EAAE,IAAI,EACf,QAAQ,GAAE,MAAyB,GAClC,OAAO,CAAC,mBAAmB,CAAC,CAiF9B"}
@@ -1,63 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { z } from "zod";
3
- import { Catalog } from "@a2ui/web_core/v0_9";
4
- import type { ComponentApi } from "@a2ui/web_core/v0_9";
5
- import { buildCatalogContextValue } from "../a2ui/A2UICatalogContext";
6
- import { vueBasicCatalog } from "../a2ui/catalog";
7
-
8
- function makeCustomCatalog(): Catalog<ComponentApi> {
9
- const components: ComponentApi[] = [
10
- { name: "FlightCard", schema: z.object({ airline: z.string() }) },
11
- {
12
- name: "PieChart",
13
- schema: z.object({ innerRadius: z.number().optional() }),
14
- },
15
- ];
16
- return new Catalog<ComponentApi>(
17
- "copilotkit://custom-catalog",
18
- components,
19
- [],
20
- );
21
- }
22
-
23
- describe("buildCatalogContextValue", () => {
24
- it("includes each custom component's JSON schema by default", () => {
25
- const value = buildCatalogContextValue(makeCustomCatalog());
26
-
27
- expect(value).toContain("- copilotkit://custom-catalog");
28
- expect(value).toContain(" - FlightCard:");
29
- expect(value).toContain('"airline"');
30
- expect(value).toContain('"innerRadius"');
31
- });
32
-
33
- it("includes schemas when includeSchema is true", () => {
34
- const catalog = makeCustomCatalog();
35
-
36
- expect(buildCatalogContextValue(catalog, { includeSchema: true })).toBe(
37
- buildCatalogContextValue(catalog),
38
- );
39
- });
40
-
41
- it("lists custom components by name only when includeSchema is false", () => {
42
- const value = buildCatalogContextValue(makeCustomCatalog(), {
43
- includeSchema: false,
44
- });
45
-
46
- expect(value).toBe(
47
- [
48
- "Available A2UI catalog:",
49
- "- copilotkit://custom-catalog",
50
- " Custom catalog (does NOT include all basic components).",
51
- " Custom components:",
52
- " - FlightCard",
53
- " - PieChart",
54
- ].join("\n"),
55
- );
56
- });
57
-
58
- it("describes the basic catalog the same way regardless of includeSchema", () => {
59
- expect(
60
- buildCatalogContextValue(vueBasicCatalog, { includeSchema: false }),
61
- ).toBe(buildCatalogContextValue(vueBasicCatalog));
62
- });
63
- });
@@ -1,175 +0,0 @@
1
- import { describe, it, expect, vi, afterEach } from "vitest";
2
- import { h, nextTick } from "vue";
3
- import type { Component } from "vue";
4
- import { render as renderVue } from "@testing-library/vue";
5
- import {
6
- A2UIBuildingState,
7
- A2UIRetryingState,
8
- A2UIRecoveryFailure,
9
- resolveDebugExposure,
10
- } from "../A2UIRecoveryStates";
11
-
12
- // Ported from React's A2UIRecoveryStates tests; renders each Vue component
13
- // with the same props the React tests pass.
14
- const render = (component: Component, props: Record<string, unknown>) =>
15
- renderVue({ render: () => h(component, props) });
16
-
17
- afterEach(() => {
18
- vi.useRealTimers();
19
- });
20
-
21
- describe("A2UI lifecycle states (OSS-162)", () => {
22
- describe("building", () => {
23
- it("shows the 'Building interface' skeleton", () => {
24
- const { container } = render(A2UIBuildingState, {
25
- content: { status: "building" },
26
- });
27
- expect(container.textContent).toContain("Building interface");
28
- });
29
-
30
- it("shows a live token count when progressTokens is present", () => {
31
- const { container } = render(A2UIBuildingState, {
32
- content: { status: "building", progressTokens: 97 },
33
- });
34
- expect(container.textContent).toContain("Building interface");
35
- expect(container.textContent).toContain("97 tokens");
36
- });
37
-
38
- it("omits the token count when progressTokens is absent or zero", () => {
39
- const { container } = render(A2UIBuildingState, {
40
- content: { status: "building", progressTokens: 0 },
41
- });
42
- expect(container.textContent).not.toContain("tokens");
43
- });
44
- });
45
-
46
- describe("retrying (threshold-gated label)", () => {
47
- it("stays the generic building skeleton before the delay on a fast first retry", () => {
48
- vi.useFakeTimers();
49
- const { container } = render(A2UIRetryingState, {
50
- content: { status: "retrying", attempt: 1, maxAttempts: 3 },
51
- showAfterMs: 2000,
52
- showAfterAttempts: 2,
53
- debugExposure: "collapsed",
54
- });
55
- expect(container.textContent).toContain("Building interface");
56
- expect(container.textContent).not.toContain("Retrying");
57
- });
58
-
59
- it("reveals 'Retrying generation… (N/M attempts)' once the delay elapses", async () => {
60
- vi.useFakeTimers();
61
- const { container } = render(A2UIRetryingState, {
62
- content: { status: "retrying", attempt: 1, maxAttempts: 3 },
63
- showAfterMs: 2000,
64
- showAfterAttempts: 2,
65
- debugExposure: "collapsed",
66
- });
67
- vi.advanceTimersByTime(2100);
68
- await nextTick();
69
- expect(container.textContent).toContain("Retrying generation");
70
- expect(container.textContent).toContain("(1/3 attempts)");
71
- });
72
-
73
- it("reveals the retry label immediately once attempts cross the threshold", () => {
74
- vi.useFakeTimers();
75
- const { container } = render(A2UIRetryingState, {
76
- content: { status: "retrying", attempt: 2, maxAttempts: 3 },
77
- showAfterMs: 999999,
78
- showAfterAttempts: 2,
79
- debugExposure: "collapsed",
80
- });
81
- expect(container.textContent).toContain("Retrying generation");
82
- expect(container.textContent).toContain("(2/3 attempts)");
83
- });
84
-
85
- it("shows validation-issue detail once revealed, unless debugExposure is 'hidden'", () => {
86
- const shown = render(A2UIRetryingState, {
87
- content: {
88
- status: "retrying",
89
- attempt: 2,
90
- maxAttempts: 3,
91
- errors: [{ code: "missing_required_prop" }],
92
- },
93
- showAfterMs: 0,
94
- showAfterAttempts: 1,
95
- debugExposure: "collapsed",
96
- });
97
- expect(shown.container.querySelector("details")).not.toBeNull();
98
- expect(shown.container.textContent).toContain("missing_required_prop");
99
-
100
- const hidden = render(A2UIRetryingState, {
101
- content: {
102
- status: "retrying",
103
- attempt: 2,
104
- maxAttempts: 3,
105
- errors: [{ code: "missing_required_prop" }],
106
- },
107
- showAfterMs: 0,
108
- showAfterAttempts: 1,
109
- debugExposure: "hidden",
110
- });
111
- expect(hidden.container.querySelector("details")).toBeNull();
112
- });
113
- });
114
-
115
- describe("failed (replaces the skeleton in place)", () => {
116
- it("renders a clean message with expandable developer detail (collapsed default)", () => {
117
- const { container } = render(A2UIRecoveryFailure, {
118
- content: {
119
- status: "failed",
120
- error: "Failed to generate valid A2UI after 3 attempt(s)",
121
- attempts: [
122
- {
123
- attempt: 1,
124
- ok: false,
125
- errors: [{ code: "missing_required_prop" }],
126
- },
127
- ],
128
- },
129
- debugExposure: "collapsed",
130
- });
131
- expect(container.textContent).toContain("Couldn't generate");
132
- const details = container.querySelector("details");
133
- expect(details).not.toBeNull();
134
- expect(details!.hasAttribute("open")).toBe(false);
135
- expect(container.textContent).toContain("missing_required_prop");
136
- });
137
-
138
- it("hides developer detail entirely when debugExposure is 'hidden'", () => {
139
- const { container } = render(A2UIRecoveryFailure, {
140
- content: {
141
- status: "failed",
142
- error: "boom",
143
- attempts: [{ attempt: 1, ok: false }],
144
- },
145
- debugExposure: "hidden",
146
- });
147
- expect(container.textContent).toContain("Couldn't generate");
148
- expect(container.querySelector("details")).toBeNull();
149
- });
150
-
151
- it("opens the developer detail when debugExposure is 'verbose'", () => {
152
- const { container } = render(A2UIRecoveryFailure, {
153
- content: { status: "failed", error: "boom", attempts: [] },
154
- debugExposure: "verbose",
155
- });
156
- const details = container.querySelector("details");
157
- expect(details).not.toBeNull();
158
- expect(details!.hasAttribute("open")).toBe(true);
159
- });
160
- });
161
-
162
- describe("resolveDebugExposure precedence", () => {
163
- it("server-stamped content.debugExposure wins over the client option", () => {
164
- expect(resolveDebugExposure({ debugExposure: "hidden" }, "verbose")).toBe(
165
- "hidden",
166
- );
167
- });
168
- it("falls back to the client option when content has none", () => {
169
- expect(resolveDebugExposure({}, "verbose")).toBe("verbose");
170
- });
171
- it("falls back to the resolved default when neither is set", () => {
172
- expect(resolveDebugExposure(undefined, "collapsed")).toBe("collapsed");
173
- });
174
- });
175
- });
@@ -1,160 +0,0 @@
1
- <script setup lang="ts">
2
- import { computed, h } from "vue";
3
- import type { VNode } from "vue";
4
- import { parseMarkdown } from "@copilotkit/core";
5
- import type { MarkdownToken } from "@copilotkit/core";
6
-
7
- const props = withDefaults(
8
- defineProps<{ content: string; isStreaming?: boolean }>(),
9
- { isStreaming: false },
10
- );
11
-
12
- const tokens = computed(() => parseMarkdown(props.content ?? ""));
13
-
14
- // Allowlist URL schemes to prevent XSS via javascript:/data:/vbscript: URIs.
15
- const SAFE_HREF = /^(https?:|mailto:|tel:|#|\/|\.\/|\.\.\/)/i;
16
- const SAFE_IMG_SRC = /^(https?:|data:image\/(?!svg)|\/|\.\/|\.\.\/)/i;
17
-
18
- function sanitizeHref(href: string | undefined): string | undefined {
19
- if (!href) return undefined;
20
- return SAFE_HREF.test(href.trim()) ? href : undefined;
21
- }
22
- function sanitizeImgSrc(src: string | undefined): string | undefined {
23
- if (!src) return undefined;
24
- return SAFE_IMG_SRC.test(src.trim()) ? src : undefined;
25
- }
26
-
27
- function inline(toks: MarkdownToken[] | undefined): (VNode | string)[] {
28
- if (!toks) return [];
29
- return toks.map((t) => {
30
- switch (t.type) {
31
- case "text":
32
- return "tokens" in t && (t as any).tokens
33
- ? h("span", inline((t as any).tokens))
34
- : (t as any).text;
35
- case "strong":
36
- return h("strong", inline((t as any).tokens));
37
- case "em":
38
- return h("em", inline((t as any).tokens));
39
- case "del":
40
- return h("del", inline((t as any).tokens));
41
- case "codespan":
42
- return h(
43
- "code",
44
- { class: "cpk-markdown-inline-code" },
45
- (t as any).text,
46
- );
47
- case "br":
48
- return h("br");
49
- case "link":
50
- return h(
51
- "a",
52
- {
53
- href: sanitizeHref((t as any).href),
54
- target: "_blank",
55
- rel: "noopener noreferrer",
56
- },
57
- (t as any).tokens ? inline((t as any).tokens) : (t as any).text,
58
- );
59
- case "image":
60
- return h("img", {
61
- src: sanitizeImgSrc((t as any).href),
62
- alt: (t as any).text,
63
- class: "cpk-markdown-image",
64
- });
65
- case "escape":
66
- return (t as any).text;
67
- default:
68
- return "text" in t ? (t as any).text : "";
69
- }
70
- });
71
- }
72
-
73
- function block(t: MarkdownToken): VNode | null {
74
- switch (t.type) {
75
- case "space":
76
- return null;
77
- case "heading": {
78
- const depth = Math.min(Math.max((t as any).depth, 1), 6);
79
- return h(`h${depth}`, inline((t as any).tokens));
80
- }
81
- case "paragraph":
82
- return h("p", inline((t as any).tokens));
83
- case "blockquote":
84
- return h(
85
- "blockquote",
86
- (((t as any).tokens as MarkdownToken[] | undefined) ?? [])
87
- .map(block)
88
- .filter(Boolean),
89
- );
90
- case "code":
91
- return h("pre", { class: "cpk-markdown-code-block" }, [
92
- h(
93
- "code",
94
- { "data-language": (t as any).lang || undefined },
95
- (t as any).text,
96
- ),
97
- ]);
98
- case "hr":
99
- return h("hr");
100
- case "list": {
101
- const list = t as any;
102
- const items = list.items.map((it: any) =>
103
- h(
104
- "li",
105
- ((it.tokens as MarkdownToken[] | undefined) ?? [])
106
- .map(block)
107
- .filter(Boolean),
108
- ),
109
- );
110
- return list.ordered
111
- ? h(
112
- "ol",
113
- { start: typeof list.start === "number" ? list.start : undefined },
114
- items,
115
- )
116
- : h("ul", items);
117
- }
118
- case "table": {
119
- const tbl = t as any;
120
- return h("div", { class: "cpk-markdown-table-container" }, [
121
- h("table", [
122
- h("thead", [
123
- h(
124
- "tr",
125
- tbl.header.map((c: any) => h("th", inline(c.tokens))),
126
- ),
127
- ]),
128
- h(
129
- "tbody",
130
- tbl.rows.map((row: any) =>
131
- h(
132
- "tr",
133
- row.map((c: any) => h("td", inline(c.tokens))),
134
- ),
135
- ),
136
- ),
137
- ]),
138
- ]);
139
- }
140
- case "text":
141
- return h(
142
- "p",
143
- (t as any).tokens ? inline((t as any).tokens) : (t as any).text,
144
- );
145
- default:
146
- return "text" in t ? h("span", (t as any).text) : null;
147
- }
148
- }
149
-
150
- const Rendered = () =>
151
- h(
152
- "div",
153
- { class: "copilot-chat-assistant-markdown" },
154
- tokens.value.map(block).filter(Boolean),
155
- );
156
- </script>
157
-
158
- <template>
159
- <Rendered v-if="tokens.length" />
160
- </template>
@@ -1,69 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { mount } from "@vue/test-utils";
3
- import BasicMarkdown from "../BasicMarkdown.vue";
4
-
5
- describe("BasicMarkdown.vue", () => {
6
- it("renders headings", () => {
7
- const w = mount(BasicMarkdown, { props: { content: "# Title" } });
8
- expect(w.find("h1").text()).toBe("Title");
9
- });
10
-
11
- it("renders bold/italic", () => {
12
- const w = mount(BasicMarkdown, { props: { content: "**b** *i*" } });
13
- expect(w.find("strong").text()).toBe("b");
14
- expect(w.find("em").text()).toBe("i");
15
- });
16
-
17
- it("renders code blocks", () => {
18
- const w = mount(BasicMarkdown, { props: { content: "```\nx\n```" } });
19
- expect(w.find("pre code").text()).toContain("x");
20
- });
21
-
22
- it("renders tables", () => {
23
- const w = mount(BasicMarkdown, {
24
- props: { content: "| a | b |\n| --- | --- |\n| 1 | 2 |" },
25
- });
26
- expect(w.findAll("th")).toHaveLength(2);
27
- expect(w.findAll("tbody td")).toHaveLength(2);
28
- });
29
-
30
- it("renders links with safe href", () => {
31
- const w = mount(BasicMarkdown, {
32
- props: { content: "[CK](https://copilotkit.ai)" },
33
- });
34
- expect(w.find("a").attributes("href")).toBe("https://copilotkit.ai");
35
- });
36
-
37
- it("neutralizes javascript: URIs in links (no XSS)", () => {
38
- const w = mount(BasicMarkdown, {
39
- props: { content: "[x](javascript:alert(1))" },
40
- });
41
- expect(w.find("a").attributes("href")).toBeUndefined();
42
- });
43
-
44
- it("neutralizes javascript: image src", () => {
45
- const w = mount(BasicMarkdown, {
46
- props: { content: "![x](javascript:alert(1))" },
47
- });
48
- expect(w.find("img").attributes("src")).toBeUndefined();
49
- });
50
-
51
- it("renders nothing for empty content", () => {
52
- const w = mount(BasicMarkdown, { props: { content: "" } });
53
- expect(w.text()).toBe("");
54
- });
55
-
56
- it("rejects data:image/svg+xml image src (SVG script vector)", () => {
57
- const w = mount(BasicMarkdown, {
58
- props: { content: "![x](data:image/svg+xml;base64,PHN2Zz48L3N2Zz4=)" },
59
- });
60
- expect(w.find("img").attributes("src")).toBeUndefined();
61
- });
62
-
63
- it("still allows data:image/png image src", () => {
64
- const w = mount(BasicMarkdown, {
65
- props: { content: "![x](data:image/png;base64,iVBORw0KGgo=)" },
66
- });
67
- expect(w.find("img").attributes("src")).toContain("data:image/png");
68
- });
69
- });