@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,14 +1,5 @@
1
1
  <script setup lang="ts">
2
- import {
3
- computed,
4
- inject,
5
- onBeforeUnmount,
6
- onUpdated,
7
- ref,
8
- shallowRef,
9
- toRef,
10
- watch,
11
- } from "vue";
2
+ import { computed, inject, onUpdated, ref, toRef, watch } from "vue";
12
3
  import type { Component } from "vue";
13
4
  import type { AssistantMessage, Message } from "@ag-ui/core";
14
5
  import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
@@ -34,7 +25,13 @@ import CopilotChatInspectorButton from "./CopilotChatInspectorButton.vue";
34
25
  import { useInspectorShortcutsHidden } from "./inspector-shortcuts";
35
26
  import { InspectorKey } from "../../providers/keys";
36
27
  import { useFeedbackComment, useMessageFeedback } from "./message-feedback";
37
- import type { MessageFeedbackRating } from "../../lib/message-feedback";
28
+ import {
29
+ ɵflattenUserMessageContent,
30
+ ɵhasAssistantMessageText,
31
+ ɵshouldShowAssistantToolbar,
32
+ } from "@copilotkit/core";
33
+ import type { ɵMessageFeedbackRating as MessageFeedbackRating } from "@copilotkit/core";
34
+ import { useCopyFeedback } from "./use-copy-feedback";
38
35
  import type {
39
36
  CopilotChatAssistantMessageCopyButtonSlotProps,
40
37
  CopilotChatAssistantMessageFeedbackCommentSlotProps,
@@ -109,44 +106,15 @@ const emit = defineEmits<{
109
106
 
110
107
  const config = useCopilotChatConfiguration();
111
108
  const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
112
- const copied = ref(false);
113
- let copiedResetTimeout: ReturnType<typeof setTimeout> | null = null;
114
-
115
- function normalizeContent(content: unknown): string {
116
- if (!content) {
117
- return "";
118
- }
119
-
120
- if (typeof content === "string") {
121
- return content;
122
- }
123
-
124
- if (Array.isArray(content)) {
125
- const parts = content as Array<{ type?: unknown; text?: unknown }>;
126
- return parts
127
- .map((part) => {
128
- if (
129
- part &&
130
- typeof part === "object" &&
131
- "type" in part &&
132
- part.type === "text" &&
133
- typeof part.text === "string"
134
- ) {
135
- return part.text;
136
- }
137
- return "";
138
- })
139
- .filter((text) => text.length > 0)
140
- .join("\n");
141
- }
142
-
143
- return "";
144
- }
109
+ const { copied, copy } = useCopyFeedback();
145
110
 
111
+ // Assistant text, also from untyped data that sends content parts.
146
112
  const normalizedContent = computed(() =>
147
- normalizeContent(props.message.content),
113
+ ɵflattenUserMessageContent(props.message.content),
114
+ );
115
+ const hasContent = computed(() =>
116
+ ɵhasAssistantMessageText(normalizedContent.value),
148
117
  );
149
- const hasContent = computed(() => normalizedContent.value.trim().length > 0);
150
118
 
151
119
  const providerMarkdownRenderer = useMarkdownRenderer();
152
120
  const providerIsComponent = computed(() =>
@@ -174,10 +142,6 @@ const feedback = useMessageFeedback(toRef(props, "message"));
174
142
  const comment = useFeedbackComment(feedback);
175
143
  const rating = computed(() => feedback.value?.feedback?.rating);
176
144
  const root = ref<HTMLElement | null>(null);
177
- // The chosen thumb the comment popover points at, and the rating the open
178
- // comment answers.
179
- const commentAnchor = shallowRef<HTMLElement | null>(null);
180
- let commentRating = rating.value;
181
145
 
182
146
  const hasThumbsUp = computed(
183
147
  () => typeof props.onThumbsUp === "function" || !!feedback.value,
@@ -190,115 +154,52 @@ const hasRegenerate = computed(() => typeof props.onRegenerate === "function");
190
154
  const isLatestAssistantMessage = computed(
191
155
  () => props.messages[props.messages.length - 1]?.id === props.message.id,
192
156
  );
193
- const shouldShowToolbar = computed(
194
- () =>
195
- props.toolbarVisible &&
196
- (hasContent.value || showInspectorShortcut.value) &&
197
- !(props.isRunning && isLatestAssistantMessage.value),
157
+ const shouldShowToolbar = computed(() =>
158
+ ɵshouldShowAssistantToolbar({
159
+ toolbarVisible: props.toolbarVisible,
160
+ hasContent: hasContent.value,
161
+ showInspectorShortcut: showInspectorShortcut.value,
162
+ isRunning: props.isRunning,
163
+ isLatest: isLatestAssistantMessage.value,
164
+ }),
198
165
  );
199
166
 
200
167
  // A custom thumb that calls its handler without an event gives no element:
201
168
  // point at the chosen thumb once it renders, before the popover reads it.
202
- function findCommentAnchor() {
203
- if (
204
- comment.open.value &&
205
- !commentAnchor.value?.isConnected &&
206
- rating.value &&
207
- root.value
208
- ) {
209
- commentAnchor.value =
210
- root.value.querySelector<HTMLElement>(
211
- `[data-copilotkit-rating="${rating.value}"]`,
212
- ) ??
213
- // A custom thumb that binds only `aria-pressed`.
214
- root.value.querySelector<HTMLElement>('button[aria-pressed="true"]') ??
215
- null;
216
- }
217
- }
169
+ const findCommentAnchor = () => comment.findAnchor(root.value);
218
170
  onUpdated(findCommentAnchor);
219
171
  watch(() => comment.open.value, findCommentAnchor, { flush: "post" });
220
172
 
221
- /** Whether focus came from the keyboard; a pointer click also focuses buttons. */
222
- function isFocusVisible(element: Element): boolean {
223
- try {
224
- return element.matches(":focus-visible");
225
- } catch {
226
- return false;
227
- }
228
- }
229
-
230
- // Checks `visibility: hidden` too, which a detached popover uses.
231
- const HIDDEN_TOO = { checkVisibilityCSS: true, visibilityProperty: true };
232
-
233
173
  /**
234
- * Thumbs are toggles: a new rating is saved and opens its comment, and
235
- * clicking the chosen thumb again removes the rating. A keyboard click
236
- * (`detail` 0) moves focus into the comment, as there is no pointer. Custom
237
- * thumb slots may call the handler without an event.
238
- *
239
- * @returns Whether the app's handler should run: true for a new rating and
240
- * whenever this chat does not record ratings, false when one is removed.
174
+ * A thumb click. A keyboard click (`detail` 0) moves focus into the comment;
175
+ * custom thumb slots may call the handler without an event.
241
176
  */
242
177
  function rate(value: MessageFeedbackRating, event?: MouseEvent): boolean {
243
- const controls = feedback.value;
244
- if (!controls) return true;
245
- if (rating.value === value) {
246
- comment.close({ save: false });
247
- controls.clear();
248
- return false;
249
- }
250
- controls.rate(value);
251
- commentRating = value;
252
- commentAnchor.value =
253
- event?.currentTarget instanceof HTMLElement ? event.currentTarget : null;
254
- comment.show({ comment: "", focus: event?.detail === 0 });
255
- return true;
178
+ return comment.rate(value, {
179
+ target:
180
+ event?.currentTarget instanceof HTMLElement ? event.currentTarget : null,
181
+ keyboard: event?.detail === 0,
182
+ });
256
183
  }
257
184
 
258
185
  /** Attributes that let the chosen thumb open and point at its comment. */
259
186
  function thumbFeedbackProps(
260
187
  value: MessageFeedbackRating,
261
188
  ): Record<string, unknown> {
262
- if (!feedback.value) return {};
263
- const thumb = { "data-copilotkit-rating": value };
264
- if (rating.value !== value) return { ...thumb, "aria-pressed": false };
265
- const enter = (target: HTMLElement, via: "pointer" | "focus") => {
266
- if (!comment.open.value) commentRating = value;
267
- commentAnchor.value = target;
268
- comment.enter(via);
269
- };
189
+ // Read so the thumbs update when the rating or the popover changes.
190
+ void feedback.value;
191
+ void comment.open.value;
192
+ const thumb = comment.thumb(value);
193
+ if (!thumb) return {};
194
+ const { handlers } = thumb;
195
+ if (!handlers) return thumb.attributes;
270
196
  return {
271
- ...thumb,
272
- "aria-pressed": true,
273
- "aria-haspopup": "dialog",
274
- "aria-expanded": comment.open.value,
275
- onPointerenter: (event: PointerEvent) => {
276
- if (event.pointerType !== "touch")
277
- enter(event.currentTarget as HTMLElement, "pointer");
278
- },
279
- onPointerleave: (event: PointerEvent) => {
280
- if (event.pointerType !== "touch") comment.leave("pointer");
281
- },
282
- // Keyboard focus opens the comment; Tab moves on into its field.
283
- onFocus: (event: FocusEvent) => {
284
- const target = event.currentTarget as HTMLElement;
285
- if (isFocusVisible(target)) enter(target, "focus");
286
- },
287
- onBlur: () => comment.leave(),
288
- onKeydown: (event: KeyboardEvent) => {
289
- const input = comment.input.value;
290
- // Not while the popover hides because its thumb scrolled away.
291
- if (
292
- event.key === "Tab" &&
293
- !event.shiftKey &&
294
- comment.open.value &&
295
- input &&
296
- input.checkVisibility?.(HIDDEN_TOO) !== false
297
- ) {
298
- event.preventDefault();
299
- input.focus();
300
- }
301
- },
197
+ ...thumb.attributes,
198
+ onPointerenter: handlers.pointerEnter,
199
+ onPointerleave: handlers.pointerLeave,
200
+ onFocus: handlers.focus,
201
+ onBlur: handlers.blur,
202
+ onKeydown: handlers.keyDown,
302
203
  };
303
204
  }
304
205
 
@@ -307,14 +208,8 @@ const thumbsDownProps = computed(() => thumbFeedbackProps("down"));
307
208
 
308
209
  // The popover shows only with the toolbar and a rating. Hiding the toolbar
309
210
  // keeps the edit; a rating removed elsewhere or Learning turned off ends it.
310
- watch(
311
- [() => comment.open.value, shouldShowToolbar, rating],
312
- ([open, showToolbar, currentRating]) => {
313
- if (!open) return;
314
- // Changed or removed elsewhere: the draft answered the old rating.
315
- if (currentRating !== commentRating) comment.close({ save: false });
316
- else if (!showToolbar) comment.close();
317
- },
211
+ watch([() => comment.open.value, shouldShowToolbar, rating], () =>
212
+ comment.sync({ showsToolbar: shouldShowToolbar.value }),
318
213
  );
319
214
 
320
215
  function handleInspect() {
@@ -325,34 +220,8 @@ function handleInspect() {
325
220
  });
326
221
  }
327
222
 
328
- function resetCopiedStateWithDelay() {
329
- if (copiedResetTimeout) {
330
- clearTimeout(copiedResetTimeout);
331
- }
332
- copied.value = true;
333
- copiedResetTimeout = setTimeout(() => {
334
- copied.value = false;
335
- copiedResetTimeout = null;
336
- }, 2000);
337
- }
338
-
339
223
  async function handleCopyMessage() {
340
- const content = normalizedContent.value;
341
- if (!content) return;
342
-
343
- if (
344
- typeof navigator === "undefined" ||
345
- typeof navigator.clipboard?.writeText !== "function"
346
- ) {
347
- return;
348
- }
349
-
350
- try {
351
- await navigator.clipboard.writeText(content);
352
- resetCopiedStateWithDelay();
353
- } catch (error) {
354
- console.error("Failed to copy to clipboard:", error);
355
- }
224
+ await copy(normalizedContent.value);
356
225
  }
357
226
 
358
227
  function handleThumbsUp(event?: MouseEvent) {
@@ -371,12 +240,6 @@ function handleReadAloud() {
371
240
  function handleRegenerate() {
372
241
  emit("regenerate", props.message);
373
242
  }
374
-
375
- onBeforeUnmount(() => {
376
- if (copiedResetTimeout) {
377
- clearTimeout(copiedResetTimeout);
378
- }
379
- });
380
243
  </script>
381
244
 
382
245
  <template>
@@ -563,7 +426,7 @@ onBeforeUnmount(() => {
563
426
  :comment="comment"
564
427
  :saved-comment="feedback.feedback.comment ?? ''"
565
428
  :rating="feedback.feedback.rating"
566
- :anchor="commentAnchor"
429
+ :anchor="comment.anchor.value"
567
430
  :message-id="message.id"
568
431
  >
569
432
  <template v-if="$slots['feedback-comment']" #feedback-comment="slotProps">
@@ -6,11 +6,15 @@ import {
6
6
  getSourceUrl,
7
7
  } from "@copilotkit/shared";
8
8
  import type { Attachment } from "@copilotkit/shared";
9
+ import {
10
+ ɵcanPreviewDocument,
11
+ ɵcreateObjectUrlFromSource,
12
+ ɵdecodeTextSource,
13
+ } from "@copilotkit/core";
9
14
  import type { CopilotChatAttachmentQueueProps } from "./types";
10
15
  import { IconPlay } from "../icons";
11
16
  import CopilotChatLightbox from "./CopilotChatLightbox.vue";
12
- import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
13
- import { CopilotChatDefaultLabels } from "../../providers/types";
17
+ import { useChatLabels } from "./use-chat-labels";
14
18
 
15
19
  const props = withDefaults(defineProps<CopilotChatAttachmentQueueProps>(), {
16
20
  attachments: () => [],
@@ -21,38 +25,32 @@ const emit = defineEmits<{
21
25
  "remove-attachment": [id: string];
22
26
  }>();
23
27
 
24
- const config = useCopilotChatConfiguration();
25
- const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
28
+ const labels = useChatLabels();
26
29
 
27
30
  const activeLightboxAttachment = ref<Attachment | null>(null);
28
31
  const documentBlobUrl = ref<string | null>(null);
32
+ let revokeDocumentBlobUrl = () => {};
29
33
 
30
34
  const lightboxLabel = computed(() => {
31
35
  const attachment = activeLightboxAttachment.value;
32
36
  if (!attachment) return undefined;
33
37
  if (attachment.filename) return attachment.filename;
34
38
  return attachment.type === "image"
35
- ? "Image attachment"
39
+ ? labels.value.attachmentImageAltText
36
40
  : attachment.type === "video"
37
41
  ? "Video attachment"
38
- : "Document";
42
+ : labels.value.attachmentDocumentLabel;
39
43
  });
40
44
  const isPreviewableDocument = computed(() => {
41
45
  const attachment = activeLightboxAttachment.value;
42
46
  if (!attachment || attachment.type !== "document") return false;
43
- const mimeType = attachment.source.mimeType;
44
- return isPdf(mimeType) || isText(mimeType);
47
+ return ɵcanPreviewDocument(attachment.source.mimeType) !== null;
45
48
  });
46
49
  const decodedTextPreview = computed(() => {
47
50
  const attachment = activeLightboxAttachment.value;
48
51
  if (!attachment || attachment.type !== "document") return null;
49
- const mimeType = attachment.source.mimeType;
50
- if (!isText(mimeType) || attachment.source.type !== "data") return null;
51
- try {
52
- return atob(attachment.source.value);
53
- } catch {
54
- return attachment.source.value;
55
- }
52
+ if (ɵcanPreviewDocument(attachment.source.mimeType) !== "text") return null;
53
+ return ɵdecodeTextSource(attachment.source);
56
54
  });
57
55
  const lightboxDocumentSource = computed(() => {
58
56
  const attachment = activeLightboxAttachment.value;
@@ -64,10 +62,7 @@ const lightboxDocumentSource = computed(() => {
64
62
  watch(
65
63
  activeLightboxAttachment,
66
64
  (next, previous) => {
67
- if (documentBlobUrl.value) {
68
- URL.revokeObjectURL(documentBlobUrl.value);
69
- documentBlobUrl.value = null;
70
- }
65
+ revokeDocumentBlobUrl();
71
66
 
72
67
  if (
73
68
  !next ||
@@ -78,22 +73,22 @@ watch(
78
73
  return;
79
74
  }
80
75
 
81
- const mimeType = next.source.mimeType;
82
- if (!isPdf(mimeType) && !isText(mimeType)) {
76
+ if (ɵcanPreviewDocument(next.source.mimeType) === null) {
83
77
  return;
84
78
  }
85
79
 
86
- const blobUrl = createBlobUrl(next.source.value, mimeType);
87
- documentBlobUrl.value = blobUrl;
80
+ const objectUrl = ɵcreateObjectUrlFromSource(next.source);
81
+ documentBlobUrl.value = objectUrl?.url ?? null;
82
+ revokeDocumentBlobUrl = () => {
83
+ objectUrl?.revoke();
84
+ documentBlobUrl.value = null;
85
+ };
88
86
  },
89
87
  { immediate: true },
90
88
  );
91
89
 
92
90
  onBeforeUnmount(() => {
93
- if (documentBlobUrl.value) {
94
- URL.revokeObjectURL(documentBlobUrl.value);
95
- documentBlobUrl.value = null;
96
- }
91
+ revokeDocumentBlobUrl();
97
92
  });
98
93
 
99
94
  function openLightbox(attachment: Attachment) {
@@ -125,32 +120,12 @@ function cardClassName(attachment: Attachment) {
125
120
  return "cpk-attachment-queue-item-document";
126
121
  }
127
122
 
128
- function isPdf(mimeType: string | undefined): boolean {
129
- return !!mimeType && mimeType.includes("pdf");
123
+ function isPdf(mimeType: string | undefined) {
124
+ return ɵcanPreviewDocument(mimeType) === "pdf";
130
125
  }
131
126
 
132
- function isText(mimeType: string | undefined): boolean {
133
- return !!mimeType && mimeType.startsWith("text/");
134
- }
135
-
136
- function createBlobUrl(
137
- base64Value: string,
138
- mimeType: string | undefined,
139
- ): string | null {
140
- try {
141
- const binary = atob(base64Value);
142
- const bytes = new Uint8Array(binary.length);
143
- for (let i = 0; i < binary.length; i += 1) {
144
- bytes[i] = binary.charCodeAt(i);
145
- }
146
- const blob = new Blob([bytes], {
147
- type: mimeType || "application/octet-stream",
148
- });
149
- return URL.createObjectURL(blob);
150
- } catch (error) {
151
- console.error("[CopilotKit] Failed to decode attachment data:", error);
152
- return null;
153
- }
127
+ function isText(mimeType: string | undefined) {
128
+ return ɵcanPreviewDocument(mimeType) === "text";
154
129
  }
155
130
  </script>
156
131
 
@@ -267,7 +242,7 @@ function createBlobUrl(
267
242
  class="cpk-attachment-queue-document-name"
268
243
  data-testid="copilot-chat-attachment-document-filename"
269
244
  >
270
- {{ attachment.filename || "Document" }}
245
+ {{ attachment.filename || labels.attachmentDocumentLabel }}
271
246
  </span>
272
247
  <span
273
248
  v-if="attachment.size != null"
@@ -369,10 +344,16 @@ function createBlobUrl(
369
344
  </div>
370
345
  <div class="cpk-attachment-queue-document-card-details">
371
346
  <div class="cpk-attachment-queue-document-card-name">
372
- {{ activeLightboxAttachment.filename || "Document" }}
347
+ {{
348
+ activeLightboxAttachment.filename ||
349
+ labels.attachmentDocumentLabel
350
+ }}
373
351
  </div>
374
352
  <div class="cpk-attachment-queue-document-card-meta">
375
- {{ activeLightboxAttachment.source.mimeType || "Unknown type" }}
353
+ {{
354
+ activeLightboxAttachment.source.mimeType ||
355
+ labels.attachmentUnknownTypeText
356
+ }}
376
357
  {{
377
358
  activeLightboxAttachment.size != null
378
359
  ? ` · ${formatFileSize(activeLightboxAttachment.size)}`
@@ -381,7 +362,7 @@ function createBlobUrl(
381
362
  </div>
382
363
  </div>
383
364
  <div class="cpk-attachment-queue-document-card-note">
384
- No preview available for this file type
365
+ {{ labels.attachmentNoPreviewText }}
385
366
  </div>
386
367
  </div>
387
368
  </template>
@@ -4,19 +4,27 @@ import { getDocumentIcon, getSourceUrl } from "@copilotkit/shared";
4
4
  import type { CopilotChatAttachmentRendererProps } from "./types";
5
5
  import CopilotChatLightbox from "./CopilotChatLightbox.vue";
6
6
  import { useLightbox } from "./use-lightbox";
7
+ import { useChatLabels } from "./use-chat-labels";
7
8
 
8
9
  const props = withDefaults(defineProps<CopilotChatAttachmentRendererProps>(), {
9
10
  filename: undefined,
10
11
  className: "",
11
12
  });
12
13
 
14
+ const labels = useChatLabels();
13
15
  const imageLoadFailed = ref(false);
14
16
  const sourceUrl = computed(() => getSourceUrl(props.source));
15
17
  const documentLabel = computed(
16
- () => props.filename || props.source.mimeType || "Unknown type",
18
+ () =>
19
+ props.filename ||
20
+ props.source.mimeType ||
21
+ labels.value.attachmentUnknownTypeText,
17
22
  );
18
23
  const documentAriaLabel = computed(
19
- () => props.filename || props.source.mimeType || "Document attachment",
24
+ () =>
25
+ props.filename ||
26
+ props.source.mimeType ||
27
+ labels.value.attachmentDocumentAltText,
20
28
  );
21
29
 
22
30
  const imageButton = ref<HTMLButtonElement | null>(null);
@@ -43,7 +51,7 @@ const {
43
51
  <img
44
52
  ref="thumbnailRef"
45
53
  :src="sourceUrl"
46
- alt="Image attachment"
54
+ :alt="labels.attachmentImageAltText"
47
55
  class="cpk-attachment-renderer cpk-attachment-renderer-image"
48
56
  :class="props.className"
49
57
  data-testid="copilot-chat-attachment-renderer-image"
@@ -52,14 +60,14 @@ const {
52
60
  <!-- Teleported to the body; inside the button only to keep one root. -->
53
61
  <CopilotChatLightbox
54
62
  v-if="lightboxOpen"
55
- label="Image attachment"
63
+ :label="labels.attachmentImageAltText"
56
64
  :return-focus-to="imageButton"
57
65
  @close="closeLightbox"
58
66
  >
59
67
  <img
60
68
  :style="{ viewTransitionName: vtName }"
61
69
  :src="sourceUrl"
62
- alt="Image attachment"
70
+ :alt="labels.attachmentImageAltText"
63
71
  class="cpk-attachment-renderer-lightbox-image"
64
72
  data-testid="copilot-chat-attachment-renderer-lightbox-image"
65
73
  />
@@ -71,7 +79,7 @@ const {
71
79
  :class="props.className"
72
80
  data-testid="copilot-chat-attachment-renderer-image-fallback"
73
81
  >
74
- <span>Failed to load image</span>
82
+ <span>{{ labels.attachmentImageLoadErrorText }}</span>
75
83
  </div>
76
84
 
77
85
  <div