@copilotkit/vue 2.0.0-rc.2 → 2.0.0-rc.21

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 (335) hide show
  1. package/PARITY.md +3 -3
  2. package/dist/hooks/use-copilot-action.d.ts.map +1 -1
  3. package/dist/hooks/use-frontend-tool.d.ts +1 -1
  4. package/dist/hooks/use-frontend-tool.d.ts.map +1 -1
  5. package/dist/hooks/zod-parameters.d.ts +14 -0
  6. package/dist/hooks/zod-parameters.d.ts.map +1 -0
  7. package/dist/index.cjs +1 -73
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.mjs +365 -16920
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/use-render-activity-message-BAhbpSDh.js +16200 -0
  12. package/dist/use-render-activity-message-BAhbpSDh.js.map +1 -0
  13. package/dist/use-render-activity-message-DJ6q1qHV.cjs +114 -0
  14. package/dist/use-render-activity-message-DJ6q1qHV.cjs.map +1 -0
  15. package/dist/v2/components/A2UIMessageRenderer.d.ts +14 -0
  16. package/dist/v2/components/A2UIMessageRenderer.d.ts.map +1 -1
  17. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts +10 -3
  18. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts.map +1 -1
  19. package/dist/v2/components/CopilotKitInspector.vue.d.ts +5 -1
  20. package/dist/v2/components/CopilotKitInspector.vue.d.ts.map +1 -1
  21. package/dist/v2/components/InlineFeatureWarning.vue.d.ts.map +1 -1
  22. package/dist/v2/components/LicenseWarningBanner.vue.d.ts +2 -2
  23. package/dist/v2/components/LicenseWarningBanner.vue.d.ts.map +1 -1
  24. package/dist/v2/components/MCPAppsActivityRenderer.d.ts.map +1 -1
  25. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts +13 -59
  26. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts.map +1 -1
  27. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts +0 -5
  28. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts.map +1 -1
  29. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts +10 -15
  30. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts.map +1 -1
  31. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts +14 -130
  32. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts.map +1 -1
  33. package/dist/v2/components/a2ui/catalog.d.ts.map +1 -1
  34. package/dist/v2/components/a2ui/utils.d.ts +3 -15
  35. package/dist/v2/components/a2ui/utils.d.ts.map +1 -1
  36. package/dist/v2/components/a2ui.d.ts +9 -8
  37. package/dist/v2/components/a2ui.d.ts.map +1 -1
  38. package/dist/v2/components/chat/CopilotChat.vue.d.ts +2 -2
  39. package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
  40. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -1
  41. package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -1
  42. package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -1
  43. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts +4 -8
  44. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts.map +1 -1
  45. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts +1 -1
  46. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts.map +1 -1
  47. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +6 -270
  48. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -1
  49. package/dist/v2/components/chat/CopilotChatInspectorButton.vue.d.ts.map +1 -1
  50. package/dist/v2/components/chat/CopilotChatLightbox.vue.d.ts.map +1 -1
  51. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +1 -1
  52. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -1
  53. package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -1
  54. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts +1 -1
  55. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts.map +1 -1
  56. package/dist/v2/components/chat/CopilotChatToolCallItem.vue.d.ts.map +1 -1
  57. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +1 -1
  58. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -1
  59. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -1
  60. package/dist/v2/components/chat/CopilotChatView.vue.d.ts +3 -3
  61. package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
  62. package/dist/v2/components/chat/CopilotChatWorkSummary.vue.d.ts.map +1 -1
  63. package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts.map +1 -1
  64. package/dist/v2/components/chat/CopilotPopup.vue.d.ts +8 -3
  65. package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -1
  66. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts +5 -3
  67. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -1
  68. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts +5 -3
  69. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -1
  70. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts +8 -3
  71. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -1
  72. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +6 -4
  73. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -1
  74. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +6 -4
  75. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -1
  76. package/dist/v2/components/chat/CopilotThreadsDrawer.vue.d.ts.map +1 -1
  77. package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts +1 -0
  78. package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts.map +1 -1
  79. package/dist/v2/components/chat/audioRecorder.d.ts +3 -4
  80. package/dist/v2/components/chat/audioRecorder.d.ts.map +1 -1
  81. package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts +3 -3
  82. package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts.map +1 -1
  83. package/dist/v2/components/chat/forwarded-slots.d.ts +12 -0
  84. package/dist/v2/components/chat/forwarded-slots.d.ts.map +1 -0
  85. package/dist/v2/components/chat/index.d.ts +34 -31
  86. package/dist/v2/components/chat/index.d.ts.map +1 -1
  87. package/dist/v2/components/chat/inspector-shortcuts.d.ts +2 -1
  88. package/dist/v2/components/chat/inspector-shortcuts.d.ts.map +1 -1
  89. package/dist/v2/components/chat/message-feedback.d.ts +18 -49
  90. package/dist/v2/components/chat/message-feedback.d.ts.map +1 -1
  91. package/dist/v2/components/chat/tool-call-display-context.d.ts +4 -19
  92. package/dist/v2/components/chat/tool-call-display-context.d.ts.map +1 -1
  93. package/dist/v2/components/chat/tool-call-group-parts.d.ts +7 -20
  94. package/dist/v2/components/chat/tool-call-group-parts.d.ts.map +1 -1
  95. package/dist/v2/components/chat/turn-work.d.ts +0 -2
  96. package/dist/v2/components/chat/turn-work.d.ts.map +1 -1
  97. package/dist/v2/components/chat/types.d.ts +9 -4
  98. package/dist/v2/components/chat/types.d.ts.map +1 -1
  99. package/dist/v2/components/chat/use-chat-labels.d.ts +8 -0
  100. package/dist/v2/components/chat/use-chat-labels.d.ts.map +1 -0
  101. package/dist/v2/components/chat/use-copy-feedback.d.ts +11 -0
  102. package/dist/v2/components/chat/use-copy-feedback.d.ts.map +1 -0
  103. package/dist/v2/components/chat/use-lightbox.d.ts.map +1 -1
  104. package/dist/v2/components/icons/index.d.ts +968 -1
  105. package/dist/v2/components/icons/index.d.ts.map +1 -1
  106. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts +1 -1
  107. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts.map +1 -1
  108. package/dist/v2/hooks/use-agent-context.d.ts +2 -3
  109. package/dist/v2/hooks/use-agent-context.d.ts.map +1 -1
  110. package/dist/v2/hooks/use-agent.d.ts +4 -1
  111. package/dist/v2/hooks/use-agent.d.ts.map +1 -1
  112. package/dist/v2/hooks/use-attachments.d.ts +7 -0
  113. package/dist/v2/hooks/use-attachments.d.ts.map +1 -1
  114. package/dist/v2/hooks/use-capabilities.d.ts.map +1 -1
  115. package/dist/v2/hooks/use-component.d.ts +1 -0
  116. package/dist/v2/hooks/use-component.d.ts.map +1 -1
  117. package/dist/v2/hooks/use-configure-suggestions.d.ts +4 -9
  118. package/dist/v2/hooks/use-configure-suggestions.d.ts.map +1 -1
  119. package/dist/v2/hooks/use-default-render-tool.d.ts.map +1 -1
  120. package/dist/v2/hooks/use-frontend-tool.d.ts +5 -0
  121. package/dist/v2/hooks/use-frontend-tool.d.ts.map +1 -1
  122. package/dist/v2/hooks/use-human-in-the-loop.d.ts +2 -1
  123. package/dist/v2/hooks/use-human-in-the-loop.d.ts.map +1 -1
  124. package/dist/v2/hooks/use-interrupt.d.ts +0 -1
  125. package/dist/v2/hooks/use-interrupt.d.ts.map +1 -1
  126. package/dist/v2/hooks/use-keyboard-height.d.ts +1 -1
  127. package/dist/v2/hooks/use-keyboard-height.d.ts.map +1 -1
  128. package/dist/v2/hooks/use-pin-to-send.d.ts +4 -12
  129. package/dist/v2/hooks/use-pin-to-send.d.ts.map +1 -1
  130. package/dist/v2/hooks/use-render-activity-message.d.ts +13 -9
  131. package/dist/v2/hooks/use-render-activity-message.d.ts.map +1 -1
  132. package/dist/v2/hooks/use-render-custom-messages.d.ts +5 -7
  133. package/dist/v2/hooks/use-render-custom-messages.d.ts.map +1 -1
  134. package/dist/v2/hooks/use-suggestions.d.ts.map +1 -1
  135. package/dist/v2/hooks/use-threads.d.ts +0 -8
  136. package/dist/v2/hooks/use-threads.d.ts.map +1 -1
  137. package/dist/v2/index.cjs +1 -1
  138. package/dist/v2/index.mjs +197 -200
  139. package/dist/v2/index.mjs.map +1 -1
  140. package/dist/v2/lib/processPartialHtml.d.ts +1 -2
  141. package/dist/v2/lib/processPartialHtml.d.ts.map +1 -1
  142. package/dist/v2/lib/shallow-stable.d.ts.map +1 -1
  143. package/dist/v2/lib/vue-core.d.ts +12 -12
  144. package/dist/v2/lib/vue-core.d.ts.map +1 -1
  145. package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts.map +1 -1
  146. package/dist/v2/providers/CopilotKitProvider.types.d.ts +9 -129
  147. package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -1
  148. package/dist/v2/providers/CopilotKitProvider.vue.d.ts +9 -10
  149. package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
  150. package/dist/v2/providers/chat-configuration-store-key.d.ts +8 -0
  151. package/dist/v2/providers/chat-configuration-store-key.d.ts.map +1 -0
  152. package/dist/v2/providers/markdown-renderer.d.ts +4 -2
  153. package/dist/v2/providers/markdown-renderer.d.ts.map +1 -1
  154. package/dist/v2/providers/types.d.ts +3 -46
  155. package/dist/v2/providers/types.d.ts.map +1 -1
  156. package/dist/v2/providers/use-inspector-thread-override.d.ts +5 -0
  157. package/dist/v2/providers/use-inspector-thread-override.d.ts.map +1 -1
  158. package/dist/v2/types/human-in-the-loop.d.ts +8 -29
  159. package/dist/v2/types/human-in-the-loop.d.ts.map +1 -1
  160. package/dist/v2/types/interrupt.d.ts +1 -22
  161. package/dist/v2/types/interrupt.d.ts.map +1 -1
  162. package/dist/v2/types/vue-activity-message-renderer.d.ts +16 -15
  163. package/dist/v2/types/vue-activity-message-renderer.d.ts.map +1 -1
  164. package/dist/v2/types/vue-custom-message-renderer.d.ts +7 -16
  165. package/dist/v2/types/vue-custom-message-renderer.d.ts.map +1 -1
  166. package/dist/v2/types/vue-tool-call-renderer.d.ts +16 -35
  167. package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -1
  168. package/package.json +10 -11
  169. package/src/__tests__/build-entries.test.ts +27 -0
  170. package/src/hooks/__tests__/zod-parameters.test.ts +520 -0
  171. package/src/hooks/use-copilot-action.ts +2 -1
  172. package/src/hooks/use-frontend-tool.ts +3 -6
  173. package/src/hooks/zod-parameters.ts +162 -0
  174. package/src/v2/__tests__/exports.test.ts +10 -0
  175. package/src/v2/__tests__/mocks/web-inspector.ts +6 -0
  176. package/src/v2/__tests__/utils/test-helpers.ts +34 -4
  177. package/src/v2/components/A2UIMessageRenderer.ts +98 -68
  178. package/src/v2/components/A2UISurfaceActivityRenderer.vue +68 -103
  179. package/src/v2/components/CopilotKitInspector.vue +104 -51
  180. package/src/v2/components/InlineFeatureWarning.vue +20 -21
  181. package/src/v2/components/LicenseWarningBanner.vue +27 -135
  182. package/src/v2/components/MCPAppsActivityRenderer.ts +75 -201
  183. package/src/v2/components/OpenGenerativeUIRenderer.ts +122 -446
  184. package/src/v2/components/__tests__/A2UIMessageRenderer.test.ts +171 -8
  185. package/src/v2/components/__tests__/CopilotKitInspector.test.ts +42 -0
  186. package/src/v2/components/__tests__/LicenseWarningBanner.test.ts +60 -0
  187. package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.ts +64 -8
  188. package/src/v2/components/__tests__/OpenGenerativeUIToolRenderer.test.ts +38 -0
  189. package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +2 -7
  190. package/src/v2/components/a2ui/A2UICatalogContext.ts +27 -185
  191. package/src/v2/components/a2ui/A2UIRecoveryStates.ts +127 -327
  192. package/src/v2/components/a2ui/catalog.ts +3 -3
  193. package/src/v2/components/a2ui/utils.ts +13 -65
  194. package/src/v2/components/a2ui.ts +15 -22
  195. package/src/v2/components/chat/CopilotChat.vue +147 -356
  196. package/src/v2/components/chat/CopilotChatAssistantMessage.vue +19 -43
  197. package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +36 -55
  198. package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +14 -6
  199. package/src/v2/components/chat/CopilotChatAudioRecorder.vue +19 -246
  200. package/src/v2/components/chat/CopilotChatFeedbackCommentPopover.vue +2 -2
  201. package/src/v2/components/chat/CopilotChatInput.vue +108 -436
  202. package/src/v2/components/chat/CopilotChatInspectorButton.vue +45 -108
  203. package/src/v2/components/chat/CopilotChatLightbox.vue +10 -31
  204. package/src/v2/components/chat/CopilotChatMessageView.vue +82 -210
  205. package/src/v2/components/chat/CopilotChatReasoningMessage.vue +7 -15
  206. package/src/v2/components/chat/CopilotChatToolCallGroup.vue +63 -71
  207. package/src/v2/components/chat/CopilotChatToolCallItem.vue +8 -6
  208. package/src/v2/components/chat/CopilotChatToolCallsView.vue +31 -32
  209. package/src/v2/components/chat/CopilotChatUserMessage.vue +24 -112
  210. package/src/v2/components/chat/CopilotChatView.vue +33 -28
  211. package/src/v2/components/chat/CopilotChatWorkSummary.vue +26 -36
  212. package/src/v2/components/chat/CopilotModalHeader.vue +11 -23
  213. package/src/v2/components/chat/CopilotPopup.vue +23 -25
  214. package/src/v2/components/chat/CopilotPopupView.vue +10 -39
  215. package/src/v2/components/chat/CopilotPopupViewInternal.vue +35 -131
  216. package/src/v2/components/chat/CopilotSidebar.vue +23 -25
  217. package/src/v2/components/chat/CopilotSidebarView.vue +10 -39
  218. package/src/v2/components/chat/CopilotSidebarViewInternal.vue +38 -59
  219. package/src/v2/components/chat/CopilotThreadsDrawer.vue +37 -102
  220. package/src/v2/components/chat/StreamingMarkdownDefault.vue +15 -28
  221. package/src/v2/components/chat/__tests__/CopilotChat.labels.test.ts +19 -4
  222. package/src/v2/components/chat/__tests__/CopilotChat.test.ts +12 -10
  223. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.ts +26 -9
  224. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.learningFeedback.test.ts +5 -5
  225. package/src/v2/components/chat/__tests__/CopilotChatAttachmentQueue.test.ts +28 -0
  226. package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +89 -1
  227. package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.ts +247 -403
  228. package/src/v2/components/chat/__tests__/CopilotChatMessageView.toolCallDisplay.test.ts +1 -99
  229. package/src/v2/components/chat/__tests__/CopilotPopup.test.ts +90 -1
  230. package/src/v2/components/chat/__tests__/CopilotPopupView.test.ts +19 -0
  231. package/src/v2/components/chat/__tests__/CopilotSidebar.test.ts +90 -1
  232. package/src/v2/components/chat/__tests__/CopilotSidebarView.position.test.ts +32 -8
  233. package/src/v2/components/chat/__tests__/CopilotSidebarView.test.ts +2 -1
  234. package/src/v2/components/chat/__tests__/StreamingMarkdownDefault.test.ts +54 -0
  235. package/src/v2/components/chat/audioRecorder.ts +4 -7
  236. package/src/v2/components/chat/copilotChatToolCallItemRender.ts +24 -89
  237. package/src/v2/components/chat/forwarded-slots.ts +17 -0
  238. package/src/v2/components/chat/index.ts +0 -1
  239. package/src/v2/components/chat/inspector-shortcuts.ts +10 -16
  240. package/src/v2/components/chat/message-feedback.ts +62 -197
  241. package/src/v2/components/chat/tool-call-display-context.ts +6 -22
  242. package/src/v2/components/chat/tool-call-group-parts.ts +47 -108
  243. package/src/v2/components/chat/turn-work.ts +0 -9
  244. package/src/v2/components/chat/types.ts +12 -4
  245. package/src/v2/components/chat/use-chat-labels.ts +16 -0
  246. package/src/v2/components/chat/use-copy-feedback.ts +21 -0
  247. package/src/v2/components/chat/use-lightbox.ts +15 -33
  248. package/src/v2/components/icons/__tests__/icons.test.ts +72 -68
  249. package/src/v2/components/icons/index.ts +109 -27
  250. package/src/v2/hooks/__tests__/use-agent-error-state.test.ts +5 -3
  251. package/src/v2/hooks/__tests__/use-agent-stability.test.ts +25 -4
  252. package/src/v2/hooks/__tests__/use-agent-throttle.test.ts +5 -1
  253. package/src/v2/hooks/__tests__/use-agent.test.ts +6 -3
  254. package/src/v2/hooks/__tests__/use-component.test.ts +21 -0
  255. package/src/v2/hooks/__tests__/use-configure-suggestions.test.ts +30 -1
  256. package/src/v2/hooks/__tests__/use-default-render-tool.test.ts +10 -10
  257. package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.ts +66 -1
  258. package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.ts +6 -1
  259. package/src/v2/hooks/__tests__/use-human-in-the-loop.test.ts +187 -12
  260. package/src/v2/hooks/__tests__/use-interrupt.test.ts +97 -0
  261. package/src/v2/hooks/__tests__/use-render-activity-message.test.ts +106 -0
  262. package/src/v2/hooks/__tests__/use-render-tool.test.ts +3 -6
  263. package/src/v2/hooks/__tests__/use-threads.test.ts +48 -6
  264. package/src/v2/hooks/__tests__/zod-regression.test.ts +5 -4
  265. package/src/v2/hooks/use-agent-context.ts +4 -10
  266. package/src/v2/hooks/use-agent.ts +86 -290
  267. package/src/v2/hooks/use-attachments.ts +48 -168
  268. package/src/v2/hooks/use-capabilities.ts +2 -7
  269. package/src/v2/hooks/use-component.ts +7 -4
  270. package/src/v2/hooks/use-configure-suggestions.ts +28 -218
  271. package/src/v2/hooks/use-default-render-tool.ts +34 -94
  272. package/src/v2/hooks/use-frontend-tool.ts +10 -10
  273. package/src/v2/hooks/use-human-in-the-loop.ts +11 -80
  274. package/src/v2/hooks/use-interrupt.ts +29 -308
  275. package/src/v2/hooks/use-keyboard-height.ts +17 -40
  276. package/src/v2/hooks/use-pin-to-send.ts +15 -99
  277. package/src/v2/hooks/use-render-activity-message.ts +31 -55
  278. package/src/v2/hooks/use-render-custom-messages.ts +24 -88
  279. package/src/v2/hooks/use-suggestions.ts +9 -33
  280. package/src/v2/hooks/use-threads.ts +43 -273
  281. package/src/v2/lib/__tests__/shallow-stable.test.ts +54 -0
  282. package/src/v2/lib/__tests__/vue-core-renderers.test.ts +42 -0
  283. package/src/v2/lib/processPartialHtml.ts +6 -21
  284. package/src/v2/lib/shallow-stable.ts +2 -16
  285. package/src/v2/lib/vue-core.ts +69 -78
  286. package/src/v2/providers/CopilotChatConfigurationProvider.vue +48 -186
  287. package/src/v2/providers/CopilotKitProvider.types.ts +12 -132
  288. package/src/v2/providers/CopilotKitProvider.vue +237 -510
  289. package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.ts +22 -2
  290. package/src/v2/providers/__tests__/CopilotKitProvider.a2ui.test.ts +20 -2
  291. package/src/v2/providers/__tests__/CopilotKitProvider.config.test.ts +124 -0
  292. package/src/v2/providers/__tests__/CopilotKitProvider.headersAtSendTime.test.ts +3 -3
  293. package/src/v2/providers/__tests__/CopilotKitProvider.learning.test.ts +3 -1
  294. package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.ts +4 -1
  295. package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +53 -26
  296. package/src/v2/providers/chat-configuration-store-key.ts +9 -0
  297. package/src/v2/providers/markdown-renderer.ts +8 -2
  298. package/src/v2/providers/types.ts +3 -49
  299. package/src/v2/providers/use-inspector-thread-override.ts +22 -80
  300. package/src/v2/types/__tests__/defineToolCallRenderer.test.ts +28 -33
  301. package/src/v2/types/defineToolCallRenderer.ts +5 -4
  302. package/src/v2/types/human-in-the-loop.ts +8 -32
  303. package/src/v2/types/interrupt.ts +7 -31
  304. package/src/v2/types/vue-activity-message-renderer.ts +24 -15
  305. package/src/v2/types/vue-custom-message-renderer.ts +12 -16
  306. package/src/v2/types/vue-tool-call-renderer.ts +23 -38
  307. package/tsconfig.json +0 -1
  308. package/vite.config.ts +8 -5
  309. package/vitest.config.ts +12 -7
  310. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts +0 -9
  311. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts.map +0 -1
  312. package/dist/v2/components/chat/normalize-auto-scroll.d.ts +0 -3
  313. package/dist/v2/components/chat/normalize-auto-scroll.d.ts.map +0 -1
  314. package/dist/v2/components/chat/tool-call-layout.d.ts +0 -115
  315. package/dist/v2/components/chat/tool-call-layout.d.ts.map +0 -1
  316. package/dist/v2/lib/is-mobile-viewport.d.ts +0 -15
  317. package/dist/v2/lib/is-mobile-viewport.d.ts.map +0 -1
  318. package/dist/v2/lib/message-feedback.d.ts +0 -33
  319. package/dist/v2/lib/message-feedback.d.ts.map +0 -1
  320. package/dist/v2/lib/transcription-client.d.ts +0 -19
  321. package/dist/v2/lib/transcription-client.d.ts.map +0 -1
  322. package/src/v2/components/__tests__/A2UICatalogContext.test.ts +0 -63
  323. package/src/v2/components/a2ui/__tests__/A2UIRecoveryStates.test.ts +0 -175
  324. package/src/v2/components/chat/BasicMarkdown.vue +0 -160
  325. package/src/v2/components/chat/__tests__/BasicMarkdown.test.ts +0 -69
  326. package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +0 -39
  327. package/src/v2/components/chat/normalize-auto-scroll.ts +0 -17
  328. package/src/v2/components/chat/tool-call-layout.ts +0 -304
  329. package/src/v2/lib/__tests__/is-mobile-viewport.test.ts +0 -48
  330. package/src/v2/lib/__tests__/message-feedback.test.ts +0 -152
  331. package/src/v2/lib/__tests__/processPartialHtml.test.ts +0 -84
  332. package/src/v2/lib/__tests__/transcription-client.test.ts +0 -67
  333. package/src/v2/lib/is-mobile-viewport.ts +0 -23
  334. package/src/v2/lib/message-feedback.ts +0 -120
  335. package/src/v2/lib/transcription-client.ts +0 -151
@@ -2,7 +2,6 @@
2
2
  import {
3
3
  computed,
4
4
  inject,
5
- onBeforeUnmount,
6
5
  onUpdated,
7
6
  ref,
8
7
  shallowRef,
@@ -34,7 +33,12 @@ import CopilotChatInspectorButton from "./CopilotChatInspectorButton.vue";
34
33
  import { useInspectorShortcutsHidden } from "./inspector-shortcuts";
35
34
  import { InspectorKey } from "../../providers/keys";
36
35
  import { useFeedbackComment, useMessageFeedback } from "./message-feedback";
37
- import type { MessageFeedbackRating } from "../../lib/message-feedback";
36
+ import {
37
+ ɵhasAssistantMessageText,
38
+ ɵshouldShowAssistantToolbar,
39
+ } from "@copilotkit/core";
40
+ import type { ɵMessageFeedbackRating as MessageFeedbackRating } from "@copilotkit/core";
41
+ import { useCopyFeedback } from "./use-copy-feedback";
38
42
  import type {
39
43
  CopilotChatAssistantMessageCopyButtonSlotProps,
40
44
  CopilotChatAssistantMessageFeedbackCommentSlotProps,
@@ -109,8 +113,7 @@ const emit = defineEmits<{
109
113
 
110
114
  const config = useCopilotChatConfiguration();
111
115
  const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
112
- const copied = ref(false);
113
- let copiedResetTimeout: ReturnType<typeof setTimeout> | null = null;
116
+ const { copied, copy } = useCopyFeedback();
114
117
 
115
118
  function normalizeContent(content: unknown): string {
116
119
  if (!content) {
@@ -146,7 +149,9 @@ function normalizeContent(content: unknown): string {
146
149
  const normalizedContent = computed(() =>
147
150
  normalizeContent(props.message.content),
148
151
  );
149
- const hasContent = computed(() => normalizedContent.value.trim().length > 0);
152
+ const hasContent = computed(() =>
153
+ ɵhasAssistantMessageText(normalizedContent.value),
154
+ );
150
155
 
151
156
  const providerMarkdownRenderer = useMarkdownRenderer();
152
157
  const providerIsComponent = computed(() =>
@@ -190,11 +195,14 @@ const hasRegenerate = computed(() => typeof props.onRegenerate === "function");
190
195
  const isLatestAssistantMessage = computed(
191
196
  () => props.messages[props.messages.length - 1]?.id === props.message.id,
192
197
  );
193
- const shouldShowToolbar = computed(
194
- () =>
195
- props.toolbarVisible &&
196
- (hasContent.value || showInspectorShortcut.value) &&
197
- !(props.isRunning && isLatestAssistantMessage.value),
198
+ const shouldShowToolbar = computed(() =>
199
+ ɵshouldShowAssistantToolbar({
200
+ toolbarVisible: props.toolbarVisible,
201
+ hasContent: hasContent.value,
202
+ showInspectorShortcut: showInspectorShortcut.value,
203
+ isRunning: props.isRunning,
204
+ isLatest: isLatestAssistantMessage.value,
205
+ }),
198
206
  );
199
207
 
200
208
  // A custom thumb that calls its handler without an event gives no element:
@@ -325,34 +333,8 @@ function handleInspect() {
325
333
  });
326
334
  }
327
335
 
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
336
  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
- }
337
+ await copy(normalizedContent.value);
356
338
  }
357
339
 
358
340
  function handleThumbsUp(event?: MouseEvent) {
@@ -371,12 +353,6 @@ function handleReadAloud() {
371
353
  function handleRegenerate() {
372
354
  emit("regenerate", props.message);
373
355
  }
374
-
375
- onBeforeUnmount(() => {
376
- if (copiedResetTimeout) {
377
- clearTimeout(copiedResetTimeout);
378
- }
379
- });
380
356
  </script>
381
357
 
382
358
  <template>
@@ -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
@@ -1,264 +1,37 @@
1
1
  <script setup lang="ts">
2
- import { onBeforeUnmount, ref, useAttrs, watch } from "vue";
3
- import { AudioRecorderError } from "./audioRecorder";
4
- import type { AudioRecorderState } from "./audioRecorder";
2
+ /**
3
+ * Records from the microphone and draws the live level as a scrolling
4
+ * waveform. The recording itself is `ɵAudioRecorder` from
5
+ * `@copilotkit/core`; control it through the exposed ref.
6
+ */
7
+ import { onBeforeUnmount, onMounted, ref, useAttrs } from "vue";
8
+ import { ɵAudioRecorder, ɵcreateWaveformRenderer } from "@copilotkit/core";
5
9
 
6
10
  defineOptions({ inheritAttrs: false });
7
11
 
8
12
  const attrs = useAttrs();
9
13
  const canvasRef = ref<HTMLCanvasElement | null>(null);
10
- const recorderState = ref<AudioRecorderState>("idle");
11
- const mediaRecorderRef = ref<MediaRecorder | null>(null);
12
- const streamRef = ref<MediaStream | null>(null);
13
- const analyserRef = ref<AnalyserNode | null>(null);
14
- const audioContextRef = ref<AudioContext | null>(null);
15
- const animationIdRef = ref<number | null>(null);
16
- const audioChunksRef = ref<Blob[]>([]);
17
- const amplitudeHistoryRef = ref<number[]>([]);
18
- const scrollOffsetRef = ref(0);
19
- const smoothedAmplitudeRef = ref(0);
20
- const fadeOpacityRef = ref(0);
14
+ const recorder = new ɵAudioRecorder();
15
+ let waveform: { dispose: () => void } | undefined;
21
16
 
22
- function cleanup() {
23
- if (animationIdRef.value !== null) {
24
- cancelAnimationFrame(animationIdRef.value);
25
- animationIdRef.value = null;
17
+ onMounted(() => {
18
+ if (canvasRef.value) {
19
+ waveform = ɵcreateWaveformRenderer(canvasRef.value, recorder);
26
20
  }
27
-
28
- const recorder = mediaRecorderRef.value;
29
- if (recorder && recorder.state !== "inactive") {
30
- try {
31
- recorder.stop();
32
- } catch {
33
- // ignore cleanup stop failures
34
- }
35
- }
36
-
37
- if (streamRef.value) {
38
- streamRef.value.getTracks().forEach((track) => track.stop());
39
- streamRef.value = null;
40
- }
41
-
42
- const audioContext = audioContextRef.value;
43
- if (audioContext && audioContext.state !== "closed") {
44
- audioContext.close().catch(() => {
45
- // ignore close errors
46
- });
47
- }
48
-
49
- mediaRecorderRef.value = null;
50
- analyserRef.value = null;
51
- audioContextRef.value = null;
52
- audioChunksRef.value = [];
53
- amplitudeHistoryRef.value = [];
54
- scrollOffsetRef.value = 0;
55
- smoothedAmplitudeRef.value = 0;
56
- fadeOpacityRef.value = 0;
57
- }
58
-
59
- async function start() {
60
- if (recorderState.value !== "idle") {
61
- throw new AudioRecorderError("Recorder is already active");
62
- }
63
-
64
- try {
65
- const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
66
- streamRef.value = stream;
67
-
68
- const audioContext = new AudioContext();
69
- audioContextRef.value = audioContext;
70
- const source = audioContext.createMediaStreamSource(stream);
71
- const analyser = audioContext.createAnalyser();
72
- analyser.fftSize = 2048;
73
- source.connect(analyser);
74
- analyserRef.value = analyser;
75
-
76
- const mimeType = MediaRecorder.isTypeSupported("audio/webm;codecs=opus")
77
- ? "audio/webm;codecs=opus"
78
- : MediaRecorder.isTypeSupported("audio/webm")
79
- ? "audio/webm"
80
- : MediaRecorder.isTypeSupported("audio/mp4")
81
- ? "audio/mp4"
82
- : "";
83
-
84
- const options = mimeType ? { mimeType } : {};
85
- const recorder = new MediaRecorder(stream, options);
86
- mediaRecorderRef.value = recorder;
87
- audioChunksRef.value = [];
88
-
89
- recorder.ondataavailable = (event) => {
90
- if (event.data.size > 0) {
91
- audioChunksRef.value.push(event.data);
92
- }
93
- };
94
-
95
- recorder.start(100);
96
- recorderState.value = "recording";
97
- } catch (error) {
98
- cleanup();
99
- if (error instanceof Error && error.name === "NotAllowedError") {
100
- throw new AudioRecorderError("Microphone permission denied");
101
- }
102
- if (error instanceof Error && error.name === "NotFoundError") {
103
- throw new AudioRecorderError("No microphone found");
104
- }
105
- throw new AudioRecorderError(
106
- error instanceof Error ? error.message : "Failed to start recording",
107
- );
108
- }
109
- }
110
-
111
- function stop() {
112
- return new Promise<Blob>((resolve, reject) => {
113
- const recorder = mediaRecorderRef.value;
114
- if (!recorder || recorderState.value !== "recording") {
115
- reject(new AudioRecorderError("No active recording"));
116
- return;
117
- }
118
-
119
- recorderState.value = "processing";
120
- recorder.onstop = () => {
121
- const audioBlob = new Blob(audioChunksRef.value, {
122
- type: recorder.mimeType || "audio/webm",
123
- });
124
- cleanup();
125
- recorderState.value = "idle";
126
- resolve(audioBlob);
127
- };
128
- recorder.onerror = () => {
129
- cleanup();
130
- recorderState.value = "idle";
131
- reject(new AudioRecorderError("Recording failed"));
132
- };
133
- recorder.stop();
134
- });
135
- }
136
-
137
- function calculateAmplitude(dataArray: Uint8Array) {
138
- let sum = 0;
139
- for (let index = 0; index < dataArray.length; index += 1) {
140
- const sample = (dataArray[index] ?? 128) / 128 - 1;
141
- sum += sample * sample;
142
- }
143
- return Math.sqrt(sum / dataArray.length);
144
- }
145
-
146
- function drawFrame() {
147
- const canvas = canvasRef.value;
148
- if (!canvas) {
149
- return;
150
- }
151
-
152
- const context = canvas.getContext("2d");
153
- if (!context) {
154
- return;
155
- }
156
-
157
- const rect = canvas.getBoundingClientRect();
158
- const dpr = window.devicePixelRatio || 1;
159
- if (
160
- canvas.width !== rect.width * dpr ||
161
- canvas.height !== rect.height * dpr
162
- ) {
163
- canvas.width = rect.width * dpr;
164
- canvas.height = rect.height * dpr;
165
- context.scale(dpr, dpr);
166
- }
167
-
168
- const barWidth = 2;
169
- const barGap = 1;
170
- const barSpacing = barWidth + barGap;
171
- const maxBars = Math.floor(rect.width / barSpacing) + 2;
172
-
173
- if (analyserRef.value && recorderState.value === "recording") {
174
- if (amplitudeHistoryRef.value.length === 0) {
175
- amplitudeHistoryRef.value = Array.from({ length: maxBars }, () => 0);
176
- }
177
-
178
- if (fadeOpacityRef.value < 1) {
179
- fadeOpacityRef.value = Math.min(1, fadeOpacityRef.value + 0.03);
180
- }
181
-
182
- scrollOffsetRef.value += 1 / 3;
183
- const bufferLength = analyserRef.value.fftSize;
184
- const dataArray = new Uint8Array(bufferLength);
185
- analyserRef.value.getByteTimeDomainData(dataArray);
186
- const rawAmplitude = calculateAmplitude(dataArray);
187
- const attackSpeed = 0.12;
188
- const decaySpeed = 0.08;
189
- const speed =
190
- rawAmplitude > smoothedAmplitudeRef.value ? attackSpeed : decaySpeed;
191
- smoothedAmplitudeRef.value +=
192
- (rawAmplitude - smoothedAmplitudeRef.value) * speed;
193
-
194
- if (scrollOffsetRef.value >= barSpacing) {
195
- scrollOffsetRef.value -= barSpacing;
196
- amplitudeHistoryRef.value.push(smoothedAmplitudeRef.value);
197
- if (amplitudeHistoryRef.value.length > maxBars) {
198
- amplitudeHistoryRef.value = amplitudeHistoryRef.value.slice(-maxBars);
199
- }
200
- }
201
- }
202
-
203
- context.clearRect(0, 0, rect.width, rect.height);
204
- const computedStyle = window.getComputedStyle(canvas);
205
- context.fillStyle = computedStyle.color;
206
- context.globalAlpha = fadeOpacityRef.value;
207
-
208
- const centerY = rect.height / 2;
209
- const maxAmplitude = rect.height / 2 - 2;
210
- const edgeFadeWidth = 12;
211
-
212
- for (let index = 0; index < amplitudeHistoryRef.value.length; index += 1) {
213
- const amplitude = amplitudeHistoryRef.value[index] ?? 0;
214
- const scaledAmplitude = Math.min(amplitude * 4, 1);
215
- const barHeight = Math.max(2, scaledAmplitude * maxAmplitude * 2);
216
- const x =
217
- rect.width -
218
- (amplitudeHistoryRef.value.length - index) * barSpacing -
219
- scrollOffsetRef.value;
220
- const y = centerY - barHeight / 2;
221
- if (x + barWidth <= 0 || x >= rect.width) {
222
- continue;
223
- }
224
-
225
- let edgeOpacity = 1;
226
- if (x < edgeFadeWidth) {
227
- edgeOpacity = Math.max(0, x / edgeFadeWidth);
228
- } else if (x > rect.width - edgeFadeWidth) {
229
- edgeOpacity = Math.max(0, (rect.width - x) / edgeFadeWidth);
230
- }
231
-
232
- context.globalAlpha = fadeOpacityRef.value * edgeOpacity;
233
- context.fillRect(x, y, barWidth, barHeight);
234
- }
235
-
236
- animationIdRef.value = requestAnimationFrame(drawFrame);
237
- }
238
-
239
- watch(
240
- recorderState,
241
- () => {
242
- if (animationIdRef.value !== null) {
243
- cancelAnimationFrame(animationIdRef.value);
244
- animationIdRef.value = null;
245
- }
246
- animationIdRef.value = requestAnimationFrame(drawFrame);
247
- },
248
- { immediate: true },
249
- );
21
+ });
250
22
 
251
23
  onBeforeUnmount(() => {
252
- cleanup();
24
+ waveform?.dispose();
25
+ recorder.dispose();
253
26
  });
254
27
 
255
28
  defineExpose({
256
29
  get state() {
257
- return recorderState.value;
30
+ return recorder.getSnapshot();
258
31
  },
259
- start,
260
- stop,
261
- dispose: cleanup,
32
+ start: () => recorder.start(),
33
+ stop: () => recorder.stop(),
34
+ dispose: () => recorder.dispose(),
262
35
  });
263
36
  </script>
264
37
 
@@ -12,8 +12,8 @@
12
12
  import { computed, nextTick, ref, watch } from "vue";
13
13
  import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
14
14
  import { CopilotChatDefaultLabels } from "../../providers/types";
15
- import { MESSAGE_FEEDBACK_MAX_COMMENT_LENGTH } from "../../lib/message-feedback";
16
- import type { MessageFeedbackRating } from "../../lib/message-feedback";
15
+ import { ɵMESSAGE_FEEDBACK_MAX_COMMENT_LENGTH as MESSAGE_FEEDBACK_MAX_COMMENT_LENGTH } from "@copilotkit/core";
16
+ import type { ɵMessageFeedbackRating as MessageFeedbackRating } from "@copilotkit/core";
17
17
  import CopilotPopover from "../ui/CopilotPopover.vue";
18
18
  import { IconArrowUp } from "../icons";
19
19
  import type { FeedbackComment } from "./message-feedback";