@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,92 +1,31 @@
1
1
  import { defineComponent, h, onMounted, ref, watch } from "vue";
2
2
  import type { PropType } from "vue";
3
- import { partialJSONParse } from "@copilotkit/shared";
4
3
  import {
5
- IconCheck,
6
- IconChevronRight,
7
- IconCircle,
8
- IconLoader2,
9
- IconX,
10
- } from "../icons";
4
+ ɵTOOL_CALL_STATUS_ICONS,
5
+ ɵTOOL_CALL_STATUS_LABEL_KEYS,
6
+ ɵcountFailedToolCalls,
7
+ ɵformatLabel,
8
+ ɵgetArgumentPreview,
9
+ ɵstringifyToolCallPayload,
10
+ } from "@copilotkit/core";
11
+ import type {
12
+ CopilotChatLabels,
13
+ ToolCallEntry,
14
+ ɵToolCallRowStatus,
15
+ } from "@copilotkit/core";
16
+ import { CopilotIcon, IconChevronRight } from "../icons";
11
17
  import { useCopilotId } from "../ui/use-id";
12
- import type { ToolCallEntry } from "./tool-call-layout";
13
-
14
- /** A call that never got a result after the run ended (Stop, an error) is "stopped". */
15
- export type ToolCallStatusName = "running" | "done" | "failed" | "stopped";
18
+ import { useChatLabels } from "./use-chat-labels";
16
19
 
17
20
  /**
18
- * A call without a result is running only while the group is active: once
19
- * the run has moved on or ended, its result is never coming.
21
+ * The label for a tool call's status ("Running", "Done", ...).
20
22
  * @internal
21
23
  */
22
- export const entryStatus = (
23
- { toolMessage }: ToolCallEntry,
24
- active: boolean,
25
- ): ToolCallStatusName =>
26
- toolMessage
27
- ? toolMessage.error
28
- ? "failed"
29
- : "done"
30
- : active
31
- ? "running"
32
- : "stopped";
33
-
34
- /** @internal */
35
- export const statusLabels: Record<ToolCallStatusName, string> = {
36
- running: "Running",
37
- done: "Done",
38
- failed: "Failed",
39
- stopped: "Stopped",
40
- };
41
-
42
- /** The first non-empty string argument: usually a command, path or query. */
43
- export function argumentPreview(parameters: unknown): string | undefined {
44
- if (!parameters || typeof parameters !== "object") return undefined;
45
- const value = Object.values(parameters).find(
46
- (v): v is string => typeof v === "string" && v.trim().length > 0,
47
- );
48
- return value?.replace(/\s+/g, " ");
49
- }
50
-
51
- /** @internal */
52
- export const entryPreview = (entry: ToolCallEntry) =>
53
- argumentPreview(partialJSONParse(entry.toolCall.function.arguments));
54
-
55
- /** "run_command ×2, read_file" */
56
- export function toolNames(calls: ToolCallEntry[]): string {
57
- const counts = new Map<string, number>();
58
- for (const { toolCall } of calls) {
59
- const name = toolCall.function.name;
60
- counts.set(name, (counts.get(name) ?? 0) + 1);
61
- }
62
- return [...counts]
63
- .map(([name, count]) => (count > 1 ? `${name} ×${count}` : name))
64
- .join(", ");
65
- }
66
-
67
- /** @internal */
68
- export const pluralize = (count: number, noun: string) =>
69
- `${count} ${noun}${count === 1 ? "" : "s"}`;
70
-
71
- /**
72
- * Guarded JSON.stringify for the payload blocks. A circular reference would
73
- * otherwise crash the render.
74
- */
75
- function stringifyPayload(value: unknown): string {
76
- if (typeof value === "string") return value;
77
- try {
78
- return JSON.stringify(value, null, 2);
79
- } catch (err) {
80
- console.warn(
81
- "[CopilotKit] Failed to JSON.stringify tool-call payload; falling back to String():",
82
- err,
83
- );
84
- try {
85
- return String(value);
86
- } catch {
87
- return "[unserializable]";
88
- }
89
- }
24
+ export function toolCallStatusLabel(
25
+ labels: Readonly<CopilotChatLabels>,
26
+ status: ɵToolCallRowStatus,
27
+ ) {
28
+ return labels[ɵTOOL_CALL_STATUS_LABEL_KEYS[status]];
90
29
  }
91
30
 
92
31
  /**
@@ -125,28 +64,21 @@ export const ToolCallStatusIcon = defineComponent({
125
64
  name: "ToolCallStatusIcon",
126
65
  props: {
127
66
  status: {
128
- type: String as PropType<ToolCallStatusName>,
67
+ type: String as PropType<ɵToolCallRowStatus>,
129
68
  required: true,
130
69
  },
131
70
  },
132
71
  setup(props) {
133
72
  return () =>
134
- h(
135
- {
136
- running: IconLoader2,
137
- done: IconCheck,
138
- failed: IconX,
139
- stopped: IconCircle,
140
- }[props.status],
141
- {
142
- "aria-hidden": "true",
143
- class: [
144
- "cpk-tool-call-status-icon",
145
- props.status === "running" && "cpk-tool-call-status-icon-running",
146
- props.status === "failed" && "cpk-tool-call-status-icon-failed",
147
- ],
148
- },
149
- );
73
+ h(CopilotIcon, {
74
+ name: ɵTOOL_CALL_STATUS_ICONS[props.status],
75
+ "aria-hidden": "true",
76
+ class: [
77
+ "cpk-tool-call-status-icon",
78
+ props.status === "running" && "cpk-tool-call-status-icon-running",
79
+ props.status === "failed" && "cpk-tool-call-status-icon-failed",
80
+ ],
81
+ });
150
82
  },
151
83
  });
152
84
 
@@ -173,15 +105,14 @@ export const ToolCallFailedCount = defineComponent({
173
105
  calls: { type: Array as PropType<ToolCallEntry[]>, required: true },
174
106
  },
175
107
  setup(props) {
108
+ const labels = useChatLabels();
176
109
  return () => {
177
- const failed = props.calls.filter(
178
- (call) => call.toolMessage?.error,
179
- ).length;
110
+ const failed = ɵcountFailedToolCalls(props.calls);
180
111
  if (!failed) return null;
181
112
  return h(
182
113
  "span",
183
114
  { class: "cpk-tool-call-failed-count" },
184
- `${failed} failed`,
115
+ ɵformatLabel(labels.value.toolCallFailedCountLabel, { count: failed }),
185
116
  );
186
117
  };
187
118
  },
@@ -190,7 +121,11 @@ export const ToolCallFailedCount = defineComponent({
190
121
  function payload(label: string, value: unknown) {
191
122
  return h("div", [
192
123
  h("div", { class: "cpk-tool-call-payload-label" }, label),
193
- h("pre", { class: "cpk-tool-call-payload-code" }, stringifyPayload(value)),
124
+ h(
125
+ "pre",
126
+ { class: "cpk-tool-call-payload-code" },
127
+ ɵstringifyToolCallPayload(value),
128
+ ),
194
129
  ]);
195
130
  }
196
131
 
@@ -206,7 +141,7 @@ export const ToolCallRow = defineComponent({
206
141
  parameters: { type: null, default: undefined },
207
142
  result: { type: null, default: undefined },
208
143
  status: {
209
- type: String as PropType<ToolCallStatusName>,
144
+ type: String as PropType<ɵToolCallRowStatus>,
210
145
  required: true,
211
146
  },
212
147
  appearance: {
@@ -217,8 +152,9 @@ export const ToolCallRow = defineComponent({
217
152
  setup(props) {
218
153
  const open = ref(false);
219
154
  const detailsId = useCopilotId("cpk-tool-call-row");
155
+ const labels = useChatLabels();
220
156
  return () => {
221
- const preview = argumentPreview(props.parameters);
157
+ const preview = ɵgetArgumentPreview(props.parameters);
222
158
  // Rows draw their own divider: a wrapper with `display: contents`
223
159
  // around each call would escape a parent's divide-y.
224
160
  return h(
@@ -261,7 +197,7 @@ export const ToolCallRow = defineComponent({
261
197
  "data-testid": "copilot-tool-render-status",
262
198
  class: "cpk-tool-call-row-status",
263
199
  },
264
- statusLabels[props.status],
200
+ toolCallStatusLabel(labels.value, props.status),
265
201
  ),
266
202
  h(IconChevronRight, {
267
203
  "aria-hidden": "true",
@@ -278,9 +214,12 @@ export const ToolCallRow = defineComponent({
278
214
  "div",
279
215
  { class: "cpk-tool-call-payloads cpk-tool-call-row-payloads" },
280
216
  [
281
- payload("Arguments", props.parameters ?? {}),
217
+ payload(
218
+ labels.value.toolCallArgumentsLabel,
219
+ props.parameters ?? {},
220
+ ),
282
221
  props.result !== undefined
283
- ? payload("Result", props.result)
222
+ ? payload(labels.value.toolCallResultLabel, props.result)
284
223
  : null,
285
224
  ],
286
225
  ),
@@ -3,15 +3,6 @@ import type { FunctionalComponent } from "vue";
3
3
  import { CopilotChatCollapsible } from "./tool-call-group-parts";
4
4
  import { ToolCallDisplayContextKey } from "./tool-call-display-context";
5
5
 
6
- /** "45s", "1m 5s", "2m". Used for the live timer and the final duration. */
7
- export function formatDuration(ms: number): string {
8
- const seconds = Math.max(0, Math.floor(ms / 1000));
9
- if (seconds < 60) return `${seconds}s`;
10
- const minutes = Math.floor(seconds / 60);
11
- const rest = seconds % 60;
12
- return rest ? `${minutes}m ${rest}s` : `${minutes}m`;
13
- }
14
-
15
6
  /**
16
7
  * Folds its content away with a reply's work in the `"turn"` display. Without
17
8
  * `open` (any other display) it renders the content as is.
@@ -15,13 +15,13 @@ import type {
15
15
  AttachmentModality,
16
16
  InputContentSource,
17
17
  } from "@copilotkit/shared";
18
- import type { CopilotChatLabels } from "../../providers/types";
19
- import type { InterruptEvent } from "../../types";
20
- import type { AutoScrollMode } from "./normalize-auto-scroll";
21
18
  import type {
19
+ CopilotChatLabels,
22
20
  CopilotChatToolCallDisplay,
23
21
  ToolCallEntry,
24
- } from "./tool-call-layout";
22
+ } from "@copilotkit/core";
23
+ import type { InterruptEvent } from "../../types";
24
+ import type { ɵAutoScrollMode as AutoScrollMode } from "@copilotkit/core";
25
25
 
26
26
  export type CopilotChatInputMode = "input" | "transcribe" | "processing";
27
27
  export type { Attachment, AttachmentsConfig, AttachmentModality };
@@ -179,7 +179,15 @@ export interface CopilotChatProps extends Omit<
179
179
  | "onStartTranscribe"
180
180
  | "onCancelTranscribe"
181
181
  | "onFinishTranscribe"
182
+ // Redeclared below, deprecated: the chat sets it from its own state
183
+ | "inputMode"
182
184
  > {
185
+ /**
186
+ * @deprecated Has no effect. `CopilotChat` sets the input mode from its own
187
+ * transcription state. To set it yourself, render `CopilotChatView` and pass
188
+ * `inputMode` there.
189
+ */
190
+ inputMode?: CopilotChatInputMode;
183
191
  agentId?: string;
184
192
  threadId?: string;
185
193
  throttleMs?: number;
@@ -0,0 +1,16 @@
1
+ import { computed } from "vue";
2
+ import { CopilotChatDefaultLabels } from "@copilotkit/core";
3
+ import type { CopilotChatLabels } from "@copilotkit/core";
4
+ import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
5
+
6
+ /**
7
+ * The chat labels in effect: the surrounding chat configuration's, or the
8
+ * default English labels outside a chat.
9
+ * @internal
10
+ */
11
+ export function useChatLabels() {
12
+ const config = useCopilotChatConfiguration();
13
+ return computed<Readonly<CopilotChatLabels>>(
14
+ () => config.value?.labels ?? CopilotChatDefaultLabels,
15
+ );
16
+ }
@@ -0,0 +1,21 @@
1
+ import { onBeforeUnmount, readonly, ref } from "vue";
2
+ import { ɵCopyFeedback } from "@copilotkit/core";
3
+
4
+ /**
5
+ * The "copied" check mark of a copy button, from core's `ɵCopyFeedback`:
6
+ * `copy(text)` writes to the clipboard and shows the check mark for two
7
+ * seconds; a second copy restarts the wait.
8
+ * @internal
9
+ */
10
+ export function useCopyFeedback() {
11
+ const feedback = new ɵCopyFeedback();
12
+ const copied = ref(feedback.getSnapshot());
13
+ const unsubscribe = feedback.subscribe(() => {
14
+ copied.value = feedback.getSnapshot();
15
+ });
16
+ onBeforeUnmount(() => {
17
+ unsubscribe();
18
+ feedback.dispose();
19
+ });
20
+ return { copied: readonly(copied), copy: feedback.copy };
21
+ }
@@ -1,12 +1,7 @@
1
1
  import { nextTick, ref } from "vue";
2
+ import { ɵmorphViewTransition } from "@copilotkit/core";
2
3
  import { useCopilotId } from "../ui/use-id";
3
4
 
4
- type DocWithVT = Document & {
5
- startViewTransition?: (cb: () => void | Promise<void>) => {
6
- finished: Promise<void>;
7
- };
8
- };
9
-
10
5
  /**
11
6
  * Opens and closes a lightbox, using the View Transition API to morph the
12
7
  * thumbnail into the full-screen content, as React's `useLightbox`.
@@ -24,40 +19,27 @@ export function useLightbox() {
24
19
  const vtName = useCopilotId("cpk-lightbox").replace(/[^\w-]/g, "-");
25
20
 
26
21
  const openLightbox = () => {
27
- const thumb = thumbnailRef.value;
28
- const doc =
29
- typeof document === "undefined" ? undefined : (document as DocWithVT);
30
-
31
- if (doc?.startViewTransition && thumb) {
32
- thumb.style.viewTransitionName = vtName;
33
- doc.startViewTransition(async () => {
34
- thumb.style.viewTransitionName = "";
22
+ ɵmorphViewTransition(
23
+ thumbnailRef.value,
24
+ vtName,
25
+ async () => {
35
26
  open.value = true;
36
27
  await nextTick();
37
- });
38
- } else {
39
- open.value = true;
40
- }
28
+ },
29
+ "open",
30
+ );
41
31
  };
42
32
 
43
33
  const closeLightbox = () => {
44
- const thumb = thumbnailRef.value;
45
- const doc =
46
- typeof document === "undefined" ? undefined : (document as DocWithVT);
47
-
48
- if (doc?.startViewTransition && thumb) {
49
- const transition = doc.startViewTransition(async () => {
34
+ ɵmorphViewTransition(
35
+ thumbnailRef.value,
36
+ vtName,
37
+ async () => {
50
38
  open.value = false;
51
39
  await nextTick();
52
- thumb.style.viewTransitionName = vtName;
53
- });
54
- const clear = () => {
55
- thumb.style.viewTransitionName = "";
56
- };
57
- transition.finished.then(clear, clear);
58
- } else {
59
- open.value = false;
60
- }
40
+ },
41
+ "close",
42
+ );
61
43
  };
62
44
 
63
45
  return { thumbnailRef, vtName, open, openLightbox, closeLightbox };
@@ -1,86 +1,90 @@
1
1
  import { describe, expect, it } from "vitest";
2
+ import { h } from "vue";
2
3
  import { mount } from "@vue/test-utils";
3
- import {
4
- IconArrowUp,
5
- IconCheck,
6
- IconCheckCircle,
7
- IconChevronDown,
8
- IconChevronLeft,
9
- IconChevronRight,
10
- IconCircle,
11
- IconCopy,
12
- IconEdit,
13
- IconLoader2,
14
- IconMessageCircle,
15
- IconMic,
16
- IconPlus,
17
- IconRefreshCw,
18
- IconSquare,
19
- IconThumbsDown,
20
- IconThumbsUp,
21
- IconVolume2,
22
- IconX,
23
- } from "../index";
4
+ import { CopilotIcon, IconCircle, IconPlay, IconX } from "../index";
24
5
 
25
- describe("icons adapter", () => {
26
- it("exports all expected icon aliases", () => {
27
- const icons = [
28
- IconMessageCircle,
29
- IconX,
30
- IconChevronDown,
31
- IconPlus,
32
- IconMic,
33
- IconArrowUp,
34
- IconCheck,
35
- IconSquare,
36
- IconLoader2,
37
- IconCopy,
38
- IconEdit,
39
- IconChevronLeft,
40
- IconChevronRight,
41
- IconThumbsUp,
42
- IconThumbsDown,
43
- IconVolume2,
44
- IconRefreshCw,
45
- IconCheckCircle,
46
- IconCircle,
47
- ];
6
+ describe("CopilotIcon", () => {
7
+ it("draws the named icon with Lucide's classes and default attributes", () => {
8
+ const svg = mount(CopilotIcon, { props: { name: "X" } }).find("svg");
48
9
 
49
- for (const icon of icons) {
50
- expect(icon).toBeDefined();
51
- }
10
+ expect(svg.classes()).toEqual(["lucide", "lucide-x"]);
11
+ expect(svg.attributes()).toMatchObject({
12
+ xmlns: "http://www.w3.org/2000/svg",
13
+ width: "24",
14
+ height: "24",
15
+ viewBox: "0 0 24 24",
16
+ fill: "none",
17
+ stroke: "currentColor",
18
+ "stroke-width": "2",
19
+ "stroke-linecap": "round",
20
+ "stroke-linejoin": "round",
21
+ });
22
+ expect(svg.findAll("path").map((path) => path.attributes("d"))).toEqual([
23
+ "M18 6 6 18",
24
+ "m6 6 12 12",
25
+ ]);
52
26
  });
53
27
 
54
- it("renders svg icons from aliases", () => {
55
- const xWrapper = mount(IconX);
56
- const loaderWrapper = mount(IconLoader2);
28
+ it("draws circle and polygon nodes", () => {
29
+ const circle = mount(IconCircle).find("svg").find("circle");
30
+ const polygon = mount(IconPlay).find("svg").find("polygon");
57
31
 
58
- expect(xWrapper.find("svg").exists()).toBe(true);
59
- expect(loaderWrapper.find("svg").exists()).toBe(true);
32
+ expect(circle.attributes()).toMatchObject({ cx: "12", cy: "12", r: "10" });
33
+ expect(polygon.attributes("points")).toBe("6 3 20 12 6 21 6 3");
60
34
  });
61
35
 
62
- it("passes through classes, size, style, and accessibility attributes", () => {
63
- const wrapper = mount(IconX, {
36
+ it("applies size, color and stroke-width", () => {
37
+ const svg = mount(IconX, {
38
+ props: { size: 18, color: "red", strokeWidth: 1.75 },
39
+ }).find("svg");
40
+
41
+ expect(svg.attributes()).toMatchObject({
42
+ width: "18",
43
+ height: "18",
44
+ stroke: "red",
45
+ "stroke-width": "1.75",
46
+ });
47
+ });
48
+
49
+ it("passes other attributes to the svg after the Lucide classes", () => {
50
+ const svg = mount(IconX, {
64
51
  attrs: {
65
52
  class: "icon-class",
66
- width: "18",
67
- height: "20",
68
- "stroke-width": "1.5",
69
- role: "img",
70
- "aria-hidden": "true",
53
+ fill: "currentColor",
54
+ "data-testid": "close-icon",
71
55
  style: "color: rgb(255, 0, 0);",
72
56
  },
73
- });
57
+ }).find("svg");
58
+
59
+ expect(svg.classes()).toEqual(["lucide", "lucide-x", "icon-class"]);
60
+ expect(svg.attributes("fill")).toBe("currentColor");
61
+ expect(svg.attributes("data-testid")).toBe("close-icon");
62
+ expect(svg.attributes("style")).toContain("color: rgb(255, 0, 0)");
63
+ });
74
64
 
75
- const svg = wrapper.find("svg");
65
+ it("hides an unnamed icon from screen readers", () => {
66
+ const svg = mount(IconX).find("svg");
76
67
 
77
- expect(svg.exists()).toBe(true);
78
- expect(svg.classes()).toContain("icon-class");
79
- expect(svg.attributes("width")).toBe("18");
80
- expect(svg.attributes("height")).toBe("20");
81
- expect(svg.attributes("stroke-width")).toBe("1.5");
82
- expect(svg.attributes("role")).toBe("img");
83
68
  expect(svg.attributes("aria-hidden")).toBe("true");
84
- expect(svg.attributes("style")).toContain("color");
69
+ });
70
+
71
+ it("keeps a named icon visible to screen readers", () => {
72
+ const labelled = mount(IconX, { attrs: { "aria-label": "Close" } }).find(
73
+ "svg",
74
+ );
75
+ const withRole = mount(IconX, { attrs: { role: "img" } }).find("svg");
76
+
77
+ expect(labelled.attributes("aria-hidden")).toBeUndefined();
78
+ expect(labelled.attributes("aria-label")).toBe("Close");
79
+ expect(withRole.attributes("aria-hidden")).toBeUndefined();
80
+ });
81
+
82
+ it("keeps an icon with slot content visible to screen readers", () => {
83
+ const svg = mount(IconX, {
84
+ slots: { default: () => h("title", "Close") },
85
+ }).find("svg");
86
+
87
+ expect(svg.attributes("aria-hidden")).toBeUndefined();
88
+ expect(svg.find("title").text()).toBe("Close");
85
89
  });
86
90
  });
@@ -1,27 +1,109 @@
1
- export {
2
- MessageCircle as IconMessageCircle,
3
- X as IconX,
4
- ChevronDown as IconChevronDown,
5
- Plus as IconPlus,
6
- Mic as IconMic,
7
- ArrowUp as IconArrowUp,
8
- Check as IconCheck,
9
- Square as IconSquare,
10
- Loader2 as IconLoader2,
11
- Copy as IconCopy,
12
- Download as IconDownload,
13
- Edit as IconEdit,
14
- ChevronLeft as IconChevronLeft,
15
- ChevronRight as IconChevronRight,
16
- ThumbsUp as IconThumbsUp,
17
- ThumbsDown as IconThumbsDown,
18
- Volume2 as IconVolume2,
19
- RefreshCw as IconRefreshCw,
20
- CheckCircle as IconCheckCircle,
21
- Circle as IconCircle,
22
- PanelLeftOpen as IconPanelLeftOpen,
23
- Play as IconPlay,
24
- Upload as IconUpload,
25
- Wrench as IconWrench,
26
- EyeOff as IconEyeOff,
27
- } from "lucide-vue-next";
1
+ import { defineComponent, h } from "vue";
2
+ import type { PropType } from "vue";
3
+ import { ɵcopilotIcons, ɵcopilotIconSvgAttributes } from "@copilotkit/core";
4
+ import type { CopilotIconName } from "@copilotkit/core";
5
+
6
+ /** True when the attributes give the icon an accessible name or role. */
7
+ function hasAccessibleAttribute(attributes: object) {
8
+ return Object.keys(attributes).some(
9
+ (key) => key.startsWith("aria-") || key === "role" || key === "title",
10
+ );
11
+ }
12
+
13
+ /** Props that change how an icon is drawn. Other attributes go on the `<svg>`. */
14
+ const iconDrawProps = {
15
+ /** Width and height of the icon. Defaults to `24`. */
16
+ size: { type: [Number, String], default: 24 },
17
+ /** Line color. Defaults to `currentColor`. */
18
+ color: { type: String, default: "currentColor" },
19
+ /** Line width. Defaults to `2`. */
20
+ strokeWidth: { type: [Number, String], default: 2 },
21
+ };
22
+
23
+ /**
24
+ * Draws one of the chat icons as an inline `<svg>`.
25
+ *
26
+ * The `<svg>` has the classes `lucide lucide-<icon name>`, so CSS that selects
27
+ * them (for example `svg.lucide-arrow-up`) keeps working. The icon is hidden
28
+ * from screen readers unless you give it an `aria-*` attribute, a `role` or a
29
+ * `title`. Other attributes, such as `class` or `fill`, go on the `<svg>`.
30
+ *
31
+ * Props:
32
+ * - `name`: the chat icon, for example `"ArrowUp"` or `"X"`.
33
+ * - `size`: width and height. Defaults to `24`.
34
+ * - `stroke-width`: line width. Defaults to `2`.
35
+ * - `color`: line color. Defaults to `currentColor`.
36
+ *
37
+ * @example
38
+ * ```vue
39
+ * <CopilotIcon name="ArrowUp" class="cpk-chat-input-send-icon" />
40
+ * <CopilotIcon name="X" aria-label="Close" />
41
+ * ```
42
+ */
43
+ export const CopilotIcon = defineComponent({
44
+ name: "CopilotIcon",
45
+ props: {
46
+ /** The chat icon to draw, for example `"ArrowUp"`. */
47
+ name: { type: String as PropType<CopilotIconName>, required: true },
48
+ ...iconDrawProps,
49
+ },
50
+ setup(props, { attrs, slots }) {
51
+ return () => {
52
+ const icon = ɵcopilotIcons[props.name];
53
+ const content = slots.default?.() ?? [];
54
+ const isDecorative =
55
+ content.length === 0 && !hasAccessibleAttribute(attrs);
56
+ return h(
57
+ "svg",
58
+ {
59
+ ...ɵcopilotIconSvgAttributes,
60
+ width: props.size,
61
+ height: props.size,
62
+ stroke: props.color,
63
+ "stroke-width": props.strokeWidth,
64
+ class: ["lucide", `lucide-${icon.name}`],
65
+ "aria-hidden": isDecorative ? "true" : undefined,
66
+ },
67
+ [...icon.nodes.map((node) => h(node.tag, node.attributes)), ...content],
68
+ );
69
+ };
70
+ },
71
+ });
72
+
73
+ /**
74
+ * Internal. Makes a component that draws one chat icon, such as `IconArrowUp`.
75
+ * It takes the same `size`, `color` and `stroke-width` props as `CopilotIcon`.
76
+ */
77
+ function defineIcon(name: CopilotIconName) {
78
+ return defineComponent({
79
+ name: `Icon${name}`,
80
+ props: iconDrawProps,
81
+ setup(props, { slots }) {
82
+ return () => h(CopilotIcon, { name, ...props }, slots);
83
+ },
84
+ });
85
+ }
86
+
87
+ export const IconArrowUp = defineIcon("ArrowUp");
88
+ export const IconCheck = defineIcon("Check");
89
+ export const IconChevronDown = defineIcon("ChevronDown");
90
+ export const IconChevronLeft = defineIcon("ChevronLeft");
91
+ export const IconChevronRight = defineIcon("ChevronRight");
92
+ export const IconCircle = defineIcon("Circle");
93
+ export const IconCopy = defineIcon("Copy");
94
+ export const IconEdit = defineIcon("Edit");
95
+ export const IconEyeOff = defineIcon("EyeOff");
96
+ export const IconLoader2 = defineIcon("Loader2");
97
+ export const IconMessageCircle = defineIcon("MessageCircle");
98
+ export const IconMic = defineIcon("Mic");
99
+ export const IconPanelLeftOpen = defineIcon("PanelLeftOpen");
100
+ export const IconPlay = defineIcon("Play");
101
+ export const IconPlus = defineIcon("Plus");
102
+ export const IconRefreshCw = defineIcon("RefreshCw");
103
+ export const IconSquare = defineIcon("Square");
104
+ export const IconThumbsDown = defineIcon("ThumbsDown");
105
+ export const IconThumbsUp = defineIcon("ThumbsUp");
106
+ export const IconUpload = defineIcon("Upload");
107
+ export const IconVolume2 = defineIcon("Volume2");
108
+ export const IconWrench = defineIcon("Wrench");
109
+ export const IconX = defineIcon("X");