@copilotkit/vue 1.57.1

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 (437) hide show
  1. package/AGENTS.md +50 -0
  2. package/CHANGELOG.md +13 -0
  3. package/PARITY.md +434 -0
  4. package/README.md +396 -0
  5. package/dist/components/copilot-provider/CopilotKit.vue.d.ts +20 -0
  6. package/dist/components/copilot-provider/CopilotKit.vue.d.ts.map +1 -0
  7. package/dist/components/copilot-provider/index.d.ts +3 -0
  8. package/dist/components/copilot-provider/index.d.ts.map +1 -0
  9. package/dist/components/copilot-provider/types.d.ts +22 -0
  10. package/dist/components/copilot-provider/types.d.ts.map +1 -0
  11. package/dist/hooks/index.d.ts +7 -0
  12. package/dist/hooks/index.d.ts.map +1 -0
  13. package/dist/hooks/use-copilot-action.d.ts +27 -0
  14. package/dist/hooks/use-copilot-action.d.ts.map +1 -0
  15. package/dist/hooks/use-copilot-readable.d.ts +20 -0
  16. package/dist/hooks/use-copilot-readable.d.ts.map +1 -0
  17. package/dist/hooks/use-frontend-tool.d.ts +21 -0
  18. package/dist/hooks/use-frontend-tool.d.ts.map +1 -0
  19. package/dist/index.cjs +2 -0
  20. package/dist/index.cjs.map +1 -0
  21. package/dist/index.d.cts +10 -0
  22. package/dist/index.d.mts +10 -0
  23. package/dist/index.d.ts +10 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.mjs +252 -0
  26. package/dist/index.mjs.map +1 -0
  27. package/dist/styles.css +2 -0
  28. package/dist/use-render-activity-message-BRL1Rpl-.cjs +85 -0
  29. package/dist/use-render-activity-message-BRL1Rpl-.cjs.map +1 -0
  30. package/dist/use-render-activity-message-CqtxiFSs.js +8927 -0
  31. package/dist/use-render-activity-message-CqtxiFSs.js.map +1 -0
  32. package/dist/v2/components/A2UIMessageRenderer.d.ts +9 -0
  33. package/dist/v2/components/A2UIMessageRenderer.d.ts.map +1 -0
  34. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts +16 -0
  35. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts.map +1 -0
  36. package/dist/v2/components/CopilotKitInspector.vue.d.ts +7 -0
  37. package/dist/v2/components/CopilotKitInspector.vue.d.ts.map +1 -0
  38. package/dist/v2/components/InlineFeatureWarning.vue.d.ts +6 -0
  39. package/dist/v2/components/InlineFeatureWarning.vue.d.ts.map +1 -0
  40. package/dist/v2/components/LicenseWarningBanner.vue.d.ts +18 -0
  41. package/dist/v2/components/LicenseWarningBanner.vue.d.ts.map +1 -0
  42. package/dist/v2/components/MCPAppsActivityRenderer.d.ts +88 -0
  43. package/dist/v2/components/MCPAppsActivityRenderer.d.ts.map +1 -0
  44. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts +154 -0
  45. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts.map +1 -0
  46. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts +19 -0
  47. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts.map +1 -0
  48. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts +16 -0
  49. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts.map +1 -0
  50. package/dist/v2/components/a2ui/VueSurface.d.ts +62 -0
  51. package/dist/v2/components/a2ui/VueSurface.d.ts.map +1 -0
  52. package/dist/v2/components/a2ui/adapter.d.ts +38 -0
  53. package/dist/v2/components/a2ui/adapter.d.ts.map +1 -0
  54. package/dist/v2/components/a2ui/catalog.d.ts +29 -0
  55. package/dist/v2/components/a2ui/catalog.d.ts.map +1 -0
  56. package/dist/v2/components/a2ui/index.d.ts +5 -0
  57. package/dist/v2/components/a2ui/index.d.ts.map +1 -0
  58. package/dist/v2/components/a2ui/utils.d.ts +18 -0
  59. package/dist/v2/components/a2ui/utils.d.ts.map +1 -0
  60. package/dist/v2/components/a2ui.d.ts +12 -0
  61. package/dist/v2/components/a2ui.d.ts.map +1 -0
  62. package/dist/v2/components/chat/CopilotChat.vue.d.ts +50 -0
  63. package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -0
  64. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts +164 -0
  65. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -0
  66. package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts +12 -0
  67. package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -0
  68. package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts +7 -0
  69. package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -0
  70. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts +12 -0
  71. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts.map +1 -0
  72. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +290 -0
  73. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -0
  74. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +72 -0
  75. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -0
  76. package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts +65 -0
  77. package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -0
  78. package/dist/v2/components/chat/CopilotChatSuggestionPill.vue.d.ts +27 -0
  79. package/dist/v2/components/chat/CopilotChatSuggestionPill.vue.d.ts.map +1 -0
  80. package/dist/v2/components/chat/CopilotChatSuggestionView.vue.d.ts +26 -0
  81. package/dist/v2/components/chat/CopilotChatSuggestionView.vue.d.ts.map +1 -0
  82. package/dist/v2/components/chat/CopilotChatToggleButton.vue.d.ts +17 -0
  83. package/dist/v2/components/chat/CopilotChatToggleButton.vue.d.ts.map +1 -0
  84. package/dist/v2/components/chat/CopilotChatToggleButtonCloseIcon.d.ts +5 -0
  85. package/dist/v2/components/chat/CopilotChatToggleButtonCloseIcon.d.ts.map +1 -0
  86. package/dist/v2/components/chat/CopilotChatToggleButtonOpenIcon.d.ts +5 -0
  87. package/dist/v2/components/chat/CopilotChatToggleButtonOpenIcon.d.ts.map +1 -0
  88. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +21 -0
  89. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -0
  90. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts +34 -0
  91. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -0
  92. package/dist/v2/components/chat/CopilotChatView.vue.d.ts +106 -0
  93. package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -0
  94. package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts +15 -0
  95. package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts.map +1 -0
  96. package/dist/v2/components/chat/CopilotModalHeaderCloseButton.d.ts +5 -0
  97. package/dist/v2/components/chat/CopilotModalHeaderCloseButton.d.ts.map +1 -0
  98. package/dist/v2/components/chat/CopilotModalHeaderTitle.d.ts +5 -0
  99. package/dist/v2/components/chat/CopilotModalHeaderTitle.d.ts.map +1 -0
  100. package/dist/v2/components/chat/CopilotPopup.vue.d.ts +50 -0
  101. package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -0
  102. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts +55 -0
  103. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -0
  104. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts +55 -0
  105. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -0
  106. package/dist/v2/components/chat/CopilotPopupWelcomeScreen.vue.d.ts +28 -0
  107. package/dist/v2/components/chat/CopilotPopupWelcomeScreen.vue.d.ts.map +1 -0
  108. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts +48 -0
  109. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -0
  110. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +62 -0
  111. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -0
  112. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +53 -0
  113. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -0
  114. package/dist/v2/components/chat/CopilotSidebarWelcomeScreen.vue.d.ts +28 -0
  115. package/dist/v2/components/chat/CopilotSidebarWelcomeScreen.vue.d.ts.map +1 -0
  116. package/dist/v2/components/chat/audioRecorder.d.ts +11 -0
  117. package/dist/v2/components/chat/audioRecorder.d.ts.map +1 -0
  118. package/dist/v2/components/chat/index.d.ts +682 -0
  119. package/dist/v2/components/chat/index.d.ts.map +1 -0
  120. package/dist/v2/components/chat/last-user-message-context.d.ts +29 -0
  121. package/dist/v2/components/chat/last-user-message-context.d.ts.map +1 -0
  122. package/dist/v2/components/chat/normalize-auto-scroll.d.ts +3 -0
  123. package/dist/v2/components/chat/normalize-auto-scroll.d.ts.map +1 -0
  124. package/dist/v2/components/chat/types.d.ts +380 -0
  125. package/dist/v2/components/chat/types.d.ts.map +1 -0
  126. package/dist/v2/components/icons/index.d.ts +2 -0
  127. package/dist/v2/components/icons/index.d.ts.map +1 -0
  128. package/dist/v2/components/index.d.ts +8 -0
  129. package/dist/v2/components/index.d.ts.map +1 -0
  130. package/dist/v2/hooks/index.d.ts +24 -0
  131. package/dist/v2/hooks/index.d.ts.map +1 -0
  132. package/dist/v2/hooks/use-agent-context.d.ts +24 -0
  133. package/dist/v2/hooks/use-agent-context.d.ts.map +1 -0
  134. package/dist/v2/hooks/use-agent.d.ts +53 -0
  135. package/dist/v2/hooks/use-agent.d.ts.map +1 -0
  136. package/dist/v2/hooks/use-attachments.d.ts +21 -0
  137. package/dist/v2/hooks/use-attachments.d.ts.map +1 -0
  138. package/dist/v2/hooks/use-capabilities.d.ts +16 -0
  139. package/dist/v2/hooks/use-capabilities.d.ts.map +1 -0
  140. package/dist/v2/hooks/use-component.d.ts +13 -0
  141. package/dist/v2/hooks/use-component.d.ts.map +1 -0
  142. package/dist/v2/hooks/use-configure-suggestions.d.ts +24 -0
  143. package/dist/v2/hooks/use-configure-suggestions.d.ts.map +1 -0
  144. package/dist/v2/hooks/use-default-render-tool.d.ts +14 -0
  145. package/dist/v2/hooks/use-default-render-tool.d.ts.map +1 -0
  146. package/dist/v2/hooks/use-frontend-tool.d.ts +19 -0
  147. package/dist/v2/hooks/use-frontend-tool.d.ts.map +1 -0
  148. package/dist/v2/hooks/use-human-in-the-loop.d.ts +19 -0
  149. package/dist/v2/hooks/use-human-in-the-loop.d.ts.map +1 -0
  150. package/dist/v2/hooks/use-interrupt.d.ts +36 -0
  151. package/dist/v2/hooks/use-interrupt.d.ts.map +1 -0
  152. package/dist/v2/hooks/use-katex-styles.d.ts +22 -0
  153. package/dist/v2/hooks/use-katex-styles.d.ts.map +1 -0
  154. package/dist/v2/hooks/use-keyboard-height.d.ts +33 -0
  155. package/dist/v2/hooks/use-keyboard-height.d.ts.map +1 -0
  156. package/dist/v2/hooks/use-pin-to-send.d.ts +28 -0
  157. package/dist/v2/hooks/use-pin-to-send.d.ts.map +1 -0
  158. package/dist/v2/hooks/use-render-activity-message.d.ts +21 -0
  159. package/dist/v2/hooks/use-render-activity-message.d.ts.map +1 -0
  160. package/dist/v2/hooks/use-render-custom-messages.d.ts +27 -0
  161. package/dist/v2/hooks/use-render-custom-messages.d.ts.map +1 -0
  162. package/dist/v2/hooks/use-render-tool.d.ts +36 -0
  163. package/dist/v2/hooks/use-render-tool.d.ts.map +1 -0
  164. package/dist/v2/hooks/use-suggestions.d.ts +26 -0
  165. package/dist/v2/hooks/use-suggestions.d.ts.map +1 -0
  166. package/dist/v2/hooks/use-threads.d.ts +42 -0
  167. package/dist/v2/hooks/use-threads.d.ts.map +1 -0
  168. package/dist/v2/index.cjs +2 -0
  169. package/dist/v2/index.cjs.map +1 -0
  170. package/dist/v2/index.d.cts +9 -0
  171. package/dist/v2/index.d.mts +9 -0
  172. package/dist/v2/index.d.ts +9 -0
  173. package/dist/v2/index.d.ts.map +1 -0
  174. package/dist/v2/index.mjs +75 -0
  175. package/dist/v2/index.mjs.map +1 -0
  176. package/dist/v2/lib/processPartialHtml.d.ts +3 -0
  177. package/dist/v2/lib/processPartialHtml.d.ts.map +1 -0
  178. package/dist/v2/lib/shallow-stable.d.ts +7 -0
  179. package/dist/v2/lib/shallow-stable.d.ts.map +1 -0
  180. package/dist/v2/lib/transcription-client.d.ts +19 -0
  181. package/dist/v2/lib/transcription-client.d.ts.map +1 -0
  182. package/dist/v2/lib/vue-core.d.ts +47 -0
  183. package/dist/v2/lib/vue-core.d.ts.map +1 -0
  184. package/dist/v2/providers/CopilotChatConfigurationProvider.types.d.ts +15 -0
  185. package/dist/v2/providers/CopilotChatConfigurationProvider.types.d.ts.map +1 -0
  186. package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts +17 -0
  187. package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts.map +1 -0
  188. package/dist/v2/providers/CopilotKitProvider.types.d.ts +61 -0
  189. package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -0
  190. package/dist/v2/providers/CopilotKitProvider.vue.d.ts +37 -0
  191. package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -0
  192. package/dist/v2/providers/SandboxFunctionsContext.d.ts +4 -0
  193. package/dist/v2/providers/SandboxFunctionsContext.d.ts.map +1 -0
  194. package/dist/v2/providers/index.d.ts +13 -0
  195. package/dist/v2/providers/index.d.ts.map +1 -0
  196. package/dist/v2/providers/keys.d.ts +17 -0
  197. package/dist/v2/providers/keys.d.ts.map +1 -0
  198. package/dist/v2/providers/license-context.d.ts +7 -0
  199. package/dist/v2/providers/license-context.d.ts.map +1 -0
  200. package/dist/v2/providers/types.d.ts +38 -0
  201. package/dist/v2/providers/types.d.ts.map +1 -0
  202. package/dist/v2/providers/useCopilotChatConfiguration.d.ts +4 -0
  203. package/dist/v2/providers/useCopilotChatConfiguration.d.ts.map +1 -0
  204. package/dist/v2/providers/useCopilotKit.d.ts +2 -0
  205. package/dist/v2/providers/useCopilotKit.d.ts.map +1 -0
  206. package/dist/v2/providers/useLicenseContext.d.ts +14 -0
  207. package/dist/v2/providers/useLicenseContext.d.ts.map +1 -0
  208. package/dist/v2/types/a2ui.d.ts +5 -0
  209. package/dist/v2/types/a2ui.d.ts.map +1 -0
  210. package/dist/v2/types/defineToolCallRenderer.d.ts +15 -0
  211. package/dist/v2/types/defineToolCallRenderer.d.ts.map +1 -0
  212. package/dist/v2/types/frontend-tool.d.ts +6 -0
  213. package/dist/v2/types/frontend-tool.d.ts.map +1 -0
  214. package/dist/v2/types/human-in-the-loop.d.ts +29 -0
  215. package/dist/v2/types/human-in-the-loop.d.ts.map +1 -0
  216. package/dist/v2/types/index.d.ts +10 -0
  217. package/dist/v2/types/index.d.ts.map +1 -0
  218. package/dist/v2/types/interrupt.d.ts +14 -0
  219. package/dist/v2/types/interrupt.d.ts.map +1 -0
  220. package/dist/v2/types/sandbox-function.d.ts +8 -0
  221. package/dist/v2/types/sandbox-function.d.ts.map +1 -0
  222. package/dist/v2/types/vue-activity-message-renderer.d.ts +18 -0
  223. package/dist/v2/types/vue-activity-message-renderer.d.ts.map +1 -0
  224. package/dist/v2/types/vue-custom-message-renderer.d.ts +19 -0
  225. package/dist/v2/types/vue-custom-message-renderer.d.ts.map +1 -0
  226. package/dist/v2/types/vue-tool-call-renderer.d.ts +37 -0
  227. package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -0
  228. package/env.d.ts +7 -0
  229. package/eslint.config.mjs +42 -0
  230. package/package.json +130 -0
  231. package/scripts/scope-preflight.mjs +100 -0
  232. package/src/components/copilot-provider/CopilotKit.vue +18 -0
  233. package/src/components/copilot-provider/index.ts +2 -0
  234. package/src/components/copilot-provider/types.ts +24 -0
  235. package/src/hooks/index.ts +9 -0
  236. package/src/hooks/use-copilot-action.ts +168 -0
  237. package/src/hooks/use-copilot-readable.ts +75 -0
  238. package/src/hooks/use-frontend-tool.ts +76 -0
  239. package/src/index.ts +12 -0
  240. package/src/styles/globals.css +314 -0
  241. package/src/v2/__tests__/exports.test.ts +35 -0
  242. package/src/v2/__tests__/mocks/web-inspector.ts +5 -0
  243. package/src/v2/__tests__/setup.ts +141 -0
  244. package/src/v2/__tests__/utils/agents.ts +391 -0
  245. package/src/v2/__tests__/utils/mount.ts +83 -0
  246. package/src/v2/__tests__/utils/test-helpers.ts +712 -0
  247. package/src/v2/components/A2UIMessageRenderer.ts +125 -0
  248. package/src/v2/components/A2UISurfaceActivityRenderer.vue +186 -0
  249. package/src/v2/components/CopilotKitInspector.vue +42 -0
  250. package/src/v2/components/InlineFeatureWarning.vue +35 -0
  251. package/src/v2/components/LicenseWarningBanner.vue +196 -0
  252. package/src/v2/components/MCPAppsActivityRenderer.ts +778 -0
  253. package/src/v2/components/OpenGenerativeUIRenderer.ts +550 -0
  254. package/src/v2/components/__tests__/A2UIMessageRenderer.test.ts +271 -0
  255. package/src/v2/components/__tests__/CopilotKitInspector.test.ts +57 -0
  256. package/src/v2/components/__tests__/MCPAppsActivityRenderer.e2e.test.ts +851 -0
  257. package/src/v2/components/__tests__/MCPAppsActivityRenderer.test.ts +237 -0
  258. package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.ts +516 -0
  259. package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +295 -0
  260. package/src/v2/components/a2ui/A2UICatalogContext.ts +190 -0
  261. package/src/v2/components/a2ui/VueSurface.ts +144 -0
  262. package/src/v2/components/a2ui/adapter.ts +156 -0
  263. package/src/v2/components/a2ui/catalog.ts +858 -0
  264. package/src/v2/components/a2ui/index.ts +7 -0
  265. package/src/v2/components/a2ui/utils.ts +67 -0
  266. package/src/v2/components/a2ui.ts +30 -0
  267. package/src/v2/components/chat/CopilotChat.vue +777 -0
  268. package/src/v2/components/chat/CopilotChatAssistantMessage.vue +891 -0
  269. package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +411 -0
  270. package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +87 -0
  271. package/src/v2/components/chat/CopilotChatAudioRecorder.vue +269 -0
  272. package/src/v2/components/chat/CopilotChatInput.vue +1271 -0
  273. package/src/v2/components/chat/CopilotChatMessageView.vue +476 -0
  274. package/src/v2/components/chat/CopilotChatReasoningMessage.vue +247 -0
  275. package/src/v2/components/chat/CopilotChatSuggestionPill.vue +56 -0
  276. package/src/v2/components/chat/CopilotChatSuggestionView.vue +93 -0
  277. package/src/v2/components/chat/CopilotChatToggleButton.vue +145 -0
  278. package/src/v2/components/chat/CopilotChatToggleButtonCloseIcon.ts +17 -0
  279. package/src/v2/components/chat/CopilotChatToggleButtonOpenIcon.ts +18 -0
  280. package/src/v2/components/chat/CopilotChatToolCallsView.vue +161 -0
  281. package/src/v2/components/chat/CopilotChatUserMessage.vue +322 -0
  282. package/src/v2/components/chat/CopilotChatView.vue +740 -0
  283. package/src/v2/components/chat/CopilotModalHeader.vue +73 -0
  284. package/src/v2/components/chat/CopilotModalHeaderCloseButton.ts +38 -0
  285. package/src/v2/components/chat/CopilotModalHeaderTitle.ts +22 -0
  286. package/src/v2/components/chat/CopilotPopup.vue +182 -0
  287. package/src/v2/components/chat/CopilotPopupView.vue +168 -0
  288. package/src/v2/components/chat/CopilotPopupViewInternal.vue +453 -0
  289. package/src/v2/components/chat/CopilotPopupWelcomeScreen.vue +140 -0
  290. package/src/v2/components/chat/CopilotSidebar.vue +178 -0
  291. package/src/v2/components/chat/CopilotSidebarView.vue +172 -0
  292. package/src/v2/components/chat/CopilotSidebarViewInternal.vue +366 -0
  293. package/src/v2/components/chat/CopilotSidebarWelcomeScreen.vue +142 -0
  294. package/src/v2/components/chat/__tests__/CopilotChat.attachments.test.ts +237 -0
  295. package/src/v2/components/chat/__tests__/CopilotChat.e2e.test.ts +1240 -0
  296. package/src/v2/components/chat/__tests__/CopilotChat.licenseWarning.test.ts +138 -0
  297. package/src/v2/components/chat/__tests__/CopilotChat.onError.test.ts +85 -0
  298. package/src/v2/components/chat/__tests__/CopilotChat.slots.e2e.test.ts +141 -0
  299. package/src/v2/components/chat/__tests__/CopilotChat.test.ts +652 -0
  300. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.ts +683 -0
  301. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.slots.e2e.test.ts +768 -0
  302. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.test.ts +1108 -0
  303. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.thumbs.test.ts +87 -0
  304. package/src/v2/components/chat/__tests__/CopilotChatAttachmentQueue.test.ts +277 -0
  305. package/src/v2/components/chat/__tests__/CopilotChatAttachmentRenderer.test.ts +124 -0
  306. package/src/v2/components/chat/__tests__/CopilotChatCopyButton.clipboard.test.ts +230 -0
  307. package/src/v2/components/chat/__tests__/CopilotChatInput.bottomAnchored.test.ts +83 -0
  308. package/src/v2/components/chat/__tests__/CopilotChatInput.slots.e2e.test.ts +1139 -0
  309. package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +1051 -0
  310. package/src/v2/components/chat/__tests__/CopilotChatMessageView.slots.e2e.test.ts +141 -0
  311. package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.ts +494 -0
  312. package/src/v2/components/chat/__tests__/CopilotChatPropsRerender.e2e.test.ts +181 -0
  313. package/src/v2/components/chat/__tests__/CopilotChatReasoningMessage.test.ts +73 -0
  314. package/src/v2/components/chat/__tests__/CopilotChatSuggestionPill.test.ts +73 -0
  315. package/src/v2/components/chat/__tests__/CopilotChatSuggestionView.slots.e2e.test.ts +674 -0
  316. package/src/v2/components/chat/__tests__/CopilotChatSuggestionView.test.ts +91 -0
  317. package/src/v2/components/chat/__tests__/CopilotChatToggleButton.test.ts +93 -0
  318. package/src/v2/components/chat/__tests__/CopilotChatToolCallsView.test.ts +382 -0
  319. package/src/v2/components/chat/__tests__/CopilotChatToolRendering.e2e.test.ts +1019 -0
  320. package/src/v2/components/chat/__tests__/CopilotChatToolRerenders.e2e.test.ts +516 -0
  321. package/src/v2/components/chat/__tests__/CopilotChatUserMessage.slots.e2e.test.ts +701 -0
  322. package/src/v2/components/chat/__tests__/CopilotChatUserMessage.test.ts +337 -0
  323. package/src/v2/components/chat/__tests__/CopilotChatView.connectingGate.test.ts +135 -0
  324. package/src/v2/components/chat/__tests__/CopilotChatView.inputOverlay.test.ts +278 -0
  325. package/src/v2/components/chat/__tests__/CopilotChatView.onClick.e2e.test.ts +1082 -0
  326. package/src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.ts +166 -0
  327. package/src/v2/components/chat/__tests__/CopilotChatView.slots.e2e.test.ts +1145 -0
  328. package/src/v2/components/chat/__tests__/CopilotChatView.test.ts +374 -0
  329. package/src/v2/components/chat/__tests__/CopilotModalHeader.slots.e2e.test.ts +636 -0
  330. package/src/v2/components/chat/__tests__/CopilotModalHeader.test.ts +112 -0
  331. package/src/v2/components/chat/__tests__/CopilotPopup.test.ts +58 -0
  332. package/src/v2/components/chat/__tests__/CopilotPopupView.slots.e2e.test.ts +725 -0
  333. package/src/v2/components/chat/__tests__/CopilotPopupView.test.ts +112 -0
  334. package/src/v2/components/chat/__tests__/CopilotSidebar.test.ts +58 -0
  335. package/src/v2/components/chat/__tests__/CopilotSidebarView.slots.e2e.test.ts +603 -0
  336. package/src/v2/components/chat/__tests__/CopilotSidebarView.test.ts +214 -0
  337. package/src/v2/components/chat/__tests__/MCPAppsUiMessage.e2e.test.ts +394 -0
  338. package/src/v2/components/chat/__tests__/copilot-chat-throttle.test.ts +82 -0
  339. package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +39 -0
  340. package/src/v2/components/chat/audioRecorder.ts +15 -0
  341. package/src/v2/components/chat/index.ts +52 -0
  342. package/src/v2/components/chat/last-user-message-context.ts +39 -0
  343. package/src/v2/components/chat/normalize-auto-scroll.ts +17 -0
  344. package/src/v2/components/chat/types.ts +481 -0
  345. package/src/v2/components/icons/__tests__/icons.test.ts +86 -0
  346. package/src/v2/components/icons/index.ts +22 -0
  347. package/src/v2/components/index.ts +7 -0
  348. package/src/v2/hooks/__tests__/standard-schema-types.test.ts +149 -0
  349. package/src/v2/hooks/__tests__/standard-schema.test.ts +315 -0
  350. package/src/v2/hooks/__tests__/use-agent-context-timing.e2e.test.ts +144 -0
  351. package/src/v2/hooks/__tests__/use-agent-context.test.ts +271 -0
  352. package/src/v2/hooks/__tests__/use-agent-error-state.test.ts +64 -0
  353. package/src/v2/hooks/__tests__/use-agent-stability.test.ts +268 -0
  354. package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.ts +433 -0
  355. package/src/v2/hooks/__tests__/use-agent-throttle.test.ts +747 -0
  356. package/src/v2/hooks/__tests__/use-agent.e2e.test.ts +187 -0
  357. package/src/v2/hooks/__tests__/use-agent.test.ts +126 -0
  358. package/src/v2/hooks/__tests__/use-attachments.test.ts +181 -0
  359. package/src/v2/hooks/__tests__/use-component.test.ts +145 -0
  360. package/src/v2/hooks/__tests__/use-configure-suggestions.e2e.test.ts +527 -0
  361. package/src/v2/hooks/__tests__/use-configure-suggestions.test.ts +399 -0
  362. package/src/v2/hooks/__tests__/use-default-render-tool.test.ts +214 -0
  363. package/src/v2/hooks/__tests__/use-frontend-tool-available.test.ts +220 -0
  364. package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.ts +2320 -0
  365. package/src/v2/hooks/__tests__/use-frontend-tool.test.ts +648 -0
  366. package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.ts +1379 -0
  367. package/src/v2/hooks/__tests__/use-human-in-the-loop.test.ts +282 -0
  368. package/src/v2/hooks/__tests__/use-interrupt.test.ts +345 -0
  369. package/src/v2/hooks/__tests__/use-katex-styles.test.ts +69 -0
  370. package/src/v2/hooks/__tests__/use-keyboard-height.test.ts +199 -0
  371. package/src/v2/hooks/__tests__/use-pin-to-send.test.ts +363 -0
  372. package/src/v2/hooks/__tests__/use-render-tool.test.ts +329 -0
  373. package/src/v2/hooks/__tests__/use-suggestions.e2e.test.ts +397 -0
  374. package/src/v2/hooks/__tests__/use-suggestions.test.ts +198 -0
  375. package/src/v2/hooks/__tests__/use-threads.test.ts +1041 -0
  376. package/src/v2/hooks/__tests__/zod-regression.test.ts +339 -0
  377. package/src/v2/hooks/index.ts +29 -0
  378. package/src/v2/hooks/use-agent-context.ts +55 -0
  379. package/src/v2/hooks/use-agent.ts +345 -0
  380. package/src/v2/hooks/use-attachments.ts +261 -0
  381. package/src/v2/hooks/use-capabilities.ts +30 -0
  382. package/src/v2/hooks/use-component.ts +46 -0
  383. package/src/v2/hooks/use-configure-suggestions.ts +252 -0
  384. package/src/v2/hooks/use-default-render-tool.ts +130 -0
  385. package/src/v2/hooks/use-frontend-tool.ts +68 -0
  386. package/src/v2/hooks/use-human-in-the-loop.ts +90 -0
  387. package/src/v2/hooks/use-interrupt.ts +257 -0
  388. package/src/v2/hooks/use-katex-styles.ts +44 -0
  389. package/src/v2/hooks/use-keyboard-height.ts +87 -0
  390. package/src/v2/hooks/use-pin-to-send.ts +160 -0
  391. package/src/v2/hooks/use-render-activity-message.ts +92 -0
  392. package/src/v2/hooks/use-render-custom-messages.ts +129 -0
  393. package/src/v2/hooks/use-render-tool.ts +128 -0
  394. package/src/v2/hooks/use-suggestions.ts +98 -0
  395. package/src/v2/hooks/use-threads.ts +208 -0
  396. package/src/v2/index.ts +11 -0
  397. package/src/v2/lib/__tests__/processPartialHtml.test.ts +84 -0
  398. package/src/v2/lib/__tests__/transcription-client.test.ts +65 -0
  399. package/src/v2/lib/processPartialHtml.ts +21 -0
  400. package/src/v2/lib/shallow-stable.ts +54 -0
  401. package/src/v2/lib/transcription-client.ts +151 -0
  402. package/src/v2/lib/vue-core.ts +161 -0
  403. package/src/v2/providers/CopilotChatConfigurationProvider.types.ts +15 -0
  404. package/src/v2/providers/CopilotChatConfigurationProvider.vue +95 -0
  405. package/src/v2/providers/CopilotKitProvider.types.ts +66 -0
  406. package/src/v2/providers/CopilotKitProvider.vue +653 -0
  407. package/src/v2/providers/SandboxFunctionsContext.ts +11 -0
  408. package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.ts +309 -0
  409. package/src/v2/providers/__tests__/CopilotKitProvider.debug.test.ts +295 -0
  410. package/src/v2/providers/__tests__/CopilotKitProvider.license.test.ts +110 -0
  411. package/src/v2/providers/__tests__/CopilotKitProvider.onError.test.ts +67 -0
  412. package/src/v2/providers/__tests__/CopilotKitProvider.renderCustomMessages.e2e.test.ts +901 -0
  413. package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.ts +141 -0
  414. package/src/v2/providers/__tests__/CopilotKitProvider.stability.test.ts +871 -0
  415. package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +603 -0
  416. package/src/v2/providers/__tests__/CopilotKitProvider.wildcard.test.ts +104 -0
  417. package/src/v2/providers/index.ts +21 -0
  418. package/src/v2/providers/keys.ts +25 -0
  419. package/src/v2/providers/license-context.ts +16 -0
  420. package/src/v2/providers/types.ts +40 -0
  421. package/src/v2/providers/useCopilotChatConfiguration.ts +11 -0
  422. package/src/v2/providers/useCopilotKit.ts +11 -0
  423. package/src/v2/providers/useLicenseContext.ts +21 -0
  424. package/src/v2/types/__tests__/defineToolCallRenderer.test.ts +157 -0
  425. package/src/v2/types/a2ui.ts +5 -0
  426. package/src/v2/types/defineToolCallRenderer.ts +32 -0
  427. package/src/v2/types/frontend-tool.ts +8 -0
  428. package/src/v2/types/human-in-the-loop.ts +38 -0
  429. package/src/v2/types/index.ts +9 -0
  430. package/src/v2/types/interrupt.ts +15 -0
  431. package/src/v2/types/sandbox-function.ts +8 -0
  432. package/src/v2/types/vue-activity-message-renderer.ts +22 -0
  433. package/src/v2/types/vue-custom-message-renderer.ts +24 -0
  434. package/src/v2/types/vue-tool-call-renderer.ts +44 -0
  435. package/tsconfig.json +27 -0
  436. package/vite.config.ts +49 -0
  437. package/vitest.config.ts +23 -0
@@ -0,0 +1,345 @@
1
+ import { computed, shallowRef, toValue, triggerRef, watch } from "vue";
2
+ import type { MaybeRefOrGetter } from "vue";
3
+ import { DEFAULT_AGENT_ID } from "@copilotkit/shared";
4
+ import { HttpAgent } from "@ag-ui/client";
5
+ import type { AbstractAgent } from "@ag-ui/client";
6
+ import {
7
+ ProxiedCopilotRuntimeAgent,
8
+ CopilotKitCoreRuntimeConnectionStatus,
9
+ } from "@copilotkit/core";
10
+ import type {
11
+ CopilotRuntimeTransport,
12
+ SubscribeToAgentSubscriber,
13
+ } from "@copilotkit/core";
14
+ import { useCopilotKit } from "../providers/useCopilotKit";
15
+ import { useCopilotChatConfiguration } from "../providers/useCopilotChatConfiguration";
16
+
17
+ export enum UseAgentUpdate {
18
+ OnMessagesChanged = "OnMessagesChanged",
19
+ OnStateChanged = "OnStateChanged",
20
+ OnRunStatusChanged = "OnRunStatusChanged",
21
+ }
22
+
23
+ const ALL_UPDATES: UseAgentUpdate[] = [
24
+ UseAgentUpdate.OnMessagesChanged,
25
+ UseAgentUpdate.OnStateChanged,
26
+ UseAgentUpdate.OnRunStatusChanged,
27
+ ];
28
+
29
+ export interface UseAgentProps {
30
+ agentId?: MaybeRefOrGetter<string | undefined>;
31
+ threadId?: MaybeRefOrGetter<string | undefined>;
32
+ updates?: UseAgentUpdate[];
33
+ /**
34
+ * Throttle interval (in milliseconds) for re-renders triggered by
35
+ * `onMessagesChanged` and `onStateChanged` notifications. Useful to reduce
36
+ * re-render frequency during high-frequency streaming updates.
37
+ *
38
+ * Uses a leading+trailing pattern with a shared window — first update
39
+ * fires immediately, subsequent updates within the window are coalesced,
40
+ * and a trailing timer ensures the most recent update fires after the
41
+ * window expires. See `CopilotKitCore.subscribeToAgentWithOptions` in
42
+ * `@copilotkit/core` for details.
43
+ *
44
+ * Resolved as: `throttleMs ?? provider defaultThrottleMs ?? 0`.
45
+ * Passing `throttleMs: 0` explicitly disables throttling even when the
46
+ * provider specifies a non-zero `defaultThrottleMs`.
47
+ *
48
+ * Run lifecycle callbacks (`onRunInitialized`, `onRunFinalized`,
49
+ * `onRunFailed`, `onRunErrorEvent`) always fire immediately.
50
+ *
51
+ * @default undefined
52
+ * When unset, inherits from the provider's `defaultThrottleMs`;
53
+ * if that is also unset, the effective value is `0` (no throttle).
54
+ */
55
+ throttleMs?: MaybeRefOrGetter<number | undefined>;
56
+ }
57
+
58
+ function cloneForThread(
59
+ source: AbstractAgent,
60
+ threadId: string,
61
+ headers: Record<string, string>,
62
+ ): AbstractAgent {
63
+ const clone = source.clone();
64
+ if (clone === source) {
65
+ throw new Error(
66
+ `useAgent: ${source.constructor.name}.clone() returned the same instance. ` +
67
+ "clone() must return a new, independent object.",
68
+ );
69
+ }
70
+
71
+ clone.threadId = threadId;
72
+ clone.setMessages([]);
73
+ clone.setState({});
74
+ if (clone instanceof HttpAgent) {
75
+ clone.headers = { ...headers };
76
+ }
77
+ return clone;
78
+ }
79
+
80
+ export const globalThreadCloneMap = new WeakMap<
81
+ AbstractAgent,
82
+ Map<string, AbstractAgent>
83
+ >();
84
+
85
+ export function getThreadClone(
86
+ registryAgent: AbstractAgent | undefined | null,
87
+ threadId: string | undefined | null,
88
+ ): AbstractAgent | undefined {
89
+ if (!registryAgent || !threadId) return undefined;
90
+ return globalThreadCloneMap.get(registryAgent)?.get(threadId);
91
+ }
92
+
93
+ function getOrCreateThreadClone(
94
+ source: AbstractAgent,
95
+ threadId: string,
96
+ headers: Record<string, string>,
97
+ ): AbstractAgent {
98
+ let byThread = globalThreadCloneMap.get(source);
99
+ if (!byThread) {
100
+ byThread = new Map();
101
+ globalThreadCloneMap.set(source, byThread);
102
+ }
103
+
104
+ const existing = byThread.get(threadId);
105
+ if (existing) {
106
+ existing.threadId = threadId;
107
+ if (existing instanceof HttpAgent) {
108
+ existing.headers = { ...headers };
109
+ }
110
+ return existing;
111
+ }
112
+
113
+ const clone = cloneForThread(source, threadId, headers);
114
+ byThread.set(threadId, clone);
115
+ return clone;
116
+ }
117
+
118
+ /**
119
+ * Resolves and subscribes to a CopilotKit agent for the current Vue scope.
120
+ *
121
+ * It returns a reactive `agent` ref that updates when the selected agent
122
+ * changes, when runtime connection state changes, or when subscribed update
123
+ * events fire.
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * const { agent } = useAgent({ agentId: "default" });
128
+ * ```
129
+ */
130
+ export function useAgent(props: UseAgentProps = {}) {
131
+ const agentId = computed(() => toValue(props.agentId) ?? DEFAULT_AGENT_ID);
132
+ const chatConfig = useCopilotChatConfiguration();
133
+ const threadId = computed(
134
+ () => toValue(props.threadId) ?? chatConfig.value?.threadId,
135
+ );
136
+ const { copilotkit } = useCopilotKit();
137
+ const updateFlags = computed(() => props.updates ?? ALL_UPDATES);
138
+ // Read the provider-level default so it appears in the subscribe watcher
139
+ // deps. `subscribeToAgentWithOptions` reads it from the core instance, but
140
+ // Vue still needs the dep to know when to resubscribe (same role it plays
141
+ // in React's `useEffect` dep array).
142
+ const providerThrottleMs = computed(() => copilotkit.value.defaultThrottleMs);
143
+ const hookThrottleMs = computed(() => toValue(props.throttleMs));
144
+
145
+ const agent = shallowRef<AbstractAgent | null>(null);
146
+ const subscriptionAgent = shallowRef<AbstractAgent | null>(null);
147
+ const provisionalAgentCache = new Map<string, ProxiedCopilotRuntimeAgent>();
148
+
149
+ const createProvisionalAgent = (
150
+ id: string,
151
+ runtimeUrl: string,
152
+ transport: CopilotRuntimeTransport,
153
+ headers: Record<string, string>,
154
+ ) => {
155
+ const provisional = new ProxiedCopilotRuntimeAgent({
156
+ runtimeUrl,
157
+ agentId: id,
158
+ transport,
159
+ runtimeMode: "pending",
160
+ });
161
+ provisional.headers = { ...headers };
162
+ return provisional;
163
+ };
164
+
165
+ const resolveAgent = () => {
166
+ const id = agentId.value;
167
+ const resolvedThreadId = threadId.value;
168
+ const cacheKey = resolvedThreadId ? `${id}:${resolvedThreadId}` : id;
169
+ const core = copilotkit.value;
170
+ const existing = core.getAgent(id);
171
+ if (existing) {
172
+ provisionalAgentCache.delete(cacheKey);
173
+ provisionalAgentCache.delete(id);
174
+
175
+ const resolvedAgent = resolvedThreadId
176
+ ? getOrCreateThreadClone(existing, resolvedThreadId, core.headers)
177
+ : existing;
178
+ const shouldForceUpdate = agent.value === resolvedAgent;
179
+ agent.value = resolvedAgent;
180
+ subscriptionAgent.value = resolvedAgent;
181
+ if (shouldForceUpdate) {
182
+ triggerRef(agent);
183
+ }
184
+ return;
185
+ }
186
+
187
+ const isRuntimeConfigured = core.runtimeUrl !== undefined;
188
+ const status = core.runtimeConnectionStatus;
189
+
190
+ if (
191
+ isRuntimeConfigured &&
192
+ (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected ||
193
+ status === CopilotKitCoreRuntimeConnectionStatus.Connecting ||
194
+ status === CopilotKitCoreRuntimeConnectionStatus.Error)
195
+ ) {
196
+ const cached = provisionalAgentCache.get(cacheKey);
197
+ if (cached) {
198
+ cached.headers = { ...core.headers };
199
+ if (resolvedThreadId) {
200
+ cached.threadId = resolvedThreadId;
201
+ }
202
+ agent.value = cached;
203
+ subscriptionAgent.value = cached;
204
+ return;
205
+ }
206
+
207
+ const provisional = createProvisionalAgent(
208
+ id,
209
+ core.runtimeUrl!,
210
+ core.runtimeTransport,
211
+ core.headers,
212
+ );
213
+ if (resolvedThreadId) {
214
+ provisional.threadId = resolvedThreadId;
215
+ }
216
+ provisionalAgentCache.set(cacheKey, provisional);
217
+ agent.value = provisional;
218
+ subscriptionAgent.value = provisional;
219
+ return;
220
+ }
221
+
222
+ const knownAgents = Object.keys(core.agents ?? {});
223
+ const runtimePart = isRuntimeConfigured
224
+ ? `runtimeUrl=${core.runtimeUrl}`
225
+ : "no runtimeUrl";
226
+ throw new Error(
227
+ `useAgent: Agent '${id}' not found after runtime sync (${runtimePart}). ` +
228
+ (knownAgents.length
229
+ ? `Known agents: [${knownAgents.join(", ")}]`
230
+ : "No agents registered.") +
231
+ " Verify your runtime /info and/or agents__unsafe_dev_only.",
232
+ );
233
+ };
234
+
235
+ watch(
236
+ [
237
+ agentId,
238
+ () => copilotkit.value.agents,
239
+ () => copilotkit.value.runtimeConnectionStatus,
240
+ () => copilotkit.value.runtimeUrl,
241
+ () => copilotkit.value.runtimeTransport,
242
+ () =>
243
+ JSON.stringify(
244
+ Object.entries(copilotkit.value.headers ?? {}).sort(([a], [b]) =>
245
+ a.localeCompare(b),
246
+ ),
247
+ ),
248
+ threadId,
249
+ ],
250
+ resolveAgent,
251
+ { immediate: true },
252
+ );
253
+
254
+ watch(
255
+ [
256
+ subscriptionAgent,
257
+ () =>
258
+ JSON.stringify(
259
+ Object.entries(copilotkit.value.headers ?? {}).sort(([a], [b]) =>
260
+ a.localeCompare(b),
261
+ ),
262
+ ),
263
+ ],
264
+ ([currentAgent]) => {
265
+ if (currentAgent instanceof HttpAgent) {
266
+ currentAgent.headers = { ...copilotkit.value.headers };
267
+ }
268
+ },
269
+ { immediate: true },
270
+ );
271
+
272
+ // Subscribe through the shared `CopilotKitCore.subscribeToAgentWithOptions`
273
+ // API. Core owns:
274
+ // - shared leading+trailing throttle window across `onMessagesChanged`
275
+ // and `onStateChanged` (parity with React)
276
+ // - safeCall-guarded callbacks (errors in subscribers never poison the
277
+ // agent notification loop)
278
+ // - validation/fallback for invalid `throttleMs`
279
+ // - `onRunErrorEvent` in the run-status callback set
280
+ //
281
+ // The hook only schedules a microtask-batched `triggerRef(agent)` so
282
+ // multiple synchronous notifications (e.g. state + run-status firing in
283
+ // the same tick) coalesce into a single Vue re-render — matching React's
284
+ // `queueMicrotask`-batched forceUpdate strategy.
285
+ watch(
286
+ [subscriptionAgent, updateFlags, hookThrottleMs, providerThrottleMs],
287
+ ([a, flags], _old, onCleanup) => {
288
+ const f = flags as UseAgentUpdate[];
289
+ if (!a || f.length === 0) return;
290
+
291
+ let active = true;
292
+ let batchScheduled = false;
293
+ const batchedRefresh = () => {
294
+ if (!active) return;
295
+ if (!batchScheduled) {
296
+ batchScheduled = true;
297
+ queueMicrotask(() => {
298
+ batchScheduled = false;
299
+ if (active) {
300
+ triggerRef(agent);
301
+ }
302
+ });
303
+ }
304
+ };
305
+
306
+ const handlers: SubscribeToAgentSubscriber = {};
307
+
308
+ if (f.includes(UseAgentUpdate.OnMessagesChanged)) {
309
+ // Messages fire immediately (no microtask indirection) so shared-
310
+ // window throttling in core sees an unadorned callback. Matches
311
+ // React's `handlers.onMessagesChanged = forceUpdate`.
312
+ handlers.onMessagesChanged = () => {
313
+ if (active) triggerRef(agent);
314
+ };
315
+ }
316
+
317
+ if (f.includes(UseAgentUpdate.OnStateChanged)) {
318
+ handlers.onStateChanged = batchedRefresh;
319
+ }
320
+
321
+ if (f.includes(UseAgentUpdate.OnRunStatusChanged)) {
322
+ handlers.onRunInitialized = batchedRefresh;
323
+ handlers.onRunFinalized = batchedRefresh;
324
+ handlers.onRunFailed = batchedRefresh;
325
+ // Protocol-level RUN_ERROR event (distinct from `onRunFailed`
326
+ // which handles local exceptions like network errors).
327
+ handlers.onRunErrorEvent = batchedRefresh;
328
+ }
329
+
330
+ const subscription = copilotkit.value.subscribeToAgentWithOptions(
331
+ a as AbstractAgent,
332
+ handlers,
333
+ { throttleMs: toValue(props.throttleMs) },
334
+ );
335
+
336
+ onCleanup(() => {
337
+ active = false;
338
+ subscription.unsubscribe();
339
+ });
340
+ },
341
+ { immediate: true },
342
+ );
343
+
344
+ return { agent };
345
+ }
@@ -0,0 +1,261 @@
1
+ import { computed, onBeforeUnmount, onMounted, ref, toValue, watch } from "vue";
2
+ import type { MaybeRefOrGetter, Ref } from "vue";
3
+ import {
4
+ randomUUID,
5
+ getModalityFromMimeType,
6
+ exceedsMaxSize,
7
+ readFileAsBase64,
8
+ generateVideoThumbnail,
9
+ matchesAcceptFilter,
10
+ formatFileSize,
11
+ } from "@copilotkit/shared";
12
+ import type {
13
+ Attachment,
14
+ AttachmentUploadResult,
15
+ AttachmentsConfig,
16
+ } from "@copilotkit/shared";
17
+
18
+ export interface UseAttachmentsProps {
19
+ config?: MaybeRefOrGetter<AttachmentsConfig | undefined>;
20
+ }
21
+
22
+ export interface UseAttachmentsReturn {
23
+ attachments: Ref<Attachment[]>;
24
+ enabled: Ref<boolean>;
25
+ dragOver: Ref<boolean>;
26
+ fileInputRef: Ref<HTMLInputElement | null>;
27
+ containerRef: Ref<HTMLElement | null>;
28
+ processFiles: (files: File[]) => Promise<void>;
29
+ handleFileUpload: (event: Event) => Promise<void>;
30
+ handleDragOver: (event: DragEvent) => void;
31
+ handleDragLeave: (event: DragEvent) => void;
32
+ handleDrop: (event: DragEvent) => Promise<void>;
33
+ removeAttachment: (id: string) => void;
34
+ consumeAttachments: () => Attachment[];
35
+ }
36
+
37
+ export function useAttachments(
38
+ props: UseAttachmentsProps,
39
+ ): UseAttachmentsReturn {
40
+ const attachments = ref<Attachment[]>([]);
41
+ const dragOver = ref(false);
42
+ const fileInputRef = ref<HTMLInputElement | null>(null);
43
+ const containerRef = ref<HTMLElement | null>(null);
44
+ const configRef = ref<AttachmentsConfig | undefined>(toValue(props.config));
45
+ const attachmentsRef = ref<Attachment[]>(attachments.value);
46
+ const enabled = computed(() => configRef.value?.enabled ?? false);
47
+
48
+ watch(
49
+ () => toValue(props.config),
50
+ (next) => {
51
+ configRef.value = next;
52
+ },
53
+ { immediate: true },
54
+ );
55
+
56
+ const setAttachments = (next: Attachment[]) => {
57
+ attachments.value = next;
58
+ attachmentsRef.value = next;
59
+ };
60
+
61
+ const updateAttachments = (
62
+ updater: (previous: Attachment[]) => Attachment[],
63
+ ) => {
64
+ setAttachments(updater(attachmentsRef.value));
65
+ };
66
+
67
+ async function processFiles(files: File[]) {
68
+ const config = configRef.value;
69
+ const accept = config?.accept ?? "*/*";
70
+ const maxSize = config?.maxSize ?? 20 * 1024 * 1024;
71
+
72
+ const rejectedFiles = files.filter(
73
+ (file) => !matchesAcceptFilter(file, accept),
74
+ );
75
+ for (const file of rejectedFiles) {
76
+ config?.onUploadFailed?.({
77
+ reason: "invalid-type",
78
+ file,
79
+ message: `File "${file.name}" is not accepted. Supported types: ${accept}`,
80
+ });
81
+ }
82
+
83
+ const validFiles = files.filter((file) =>
84
+ matchesAcceptFilter(file, accept),
85
+ );
86
+ for (const file of validFiles) {
87
+ if (exceedsMaxSize(file, maxSize)) {
88
+ config?.onUploadFailed?.({
89
+ reason: "file-too-large",
90
+ file,
91
+ message: `File "${file.name}" exceeds the maximum size of ${formatFileSize(maxSize)}`,
92
+ });
93
+ continue;
94
+ }
95
+
96
+ const modality = getModalityFromMimeType(file.type);
97
+ const placeholderId = randomUUID();
98
+ updateAttachments((previous) => [
99
+ ...previous,
100
+ {
101
+ id: placeholderId,
102
+ type: modality,
103
+ source: { type: "data", value: "", mimeType: file.type },
104
+ filename: file.name,
105
+ size: file.size,
106
+ status: "uploading",
107
+ },
108
+ ]);
109
+
110
+ try {
111
+ let source: Attachment["source"];
112
+ let uploadMetadata: Record<string, unknown> | undefined;
113
+ if (config?.onUpload) {
114
+ const uploadResult: AttachmentUploadResult =
115
+ await config.onUpload(file);
116
+ const { metadata, ...uploadSource } = uploadResult;
117
+ source = uploadSource;
118
+ uploadMetadata = metadata;
119
+ } else {
120
+ const base64 = await readFileAsBase64(file);
121
+ source = { type: "data", value: base64, mimeType: file.type };
122
+ }
123
+
124
+ let thumbnail: string | undefined;
125
+ if (modality === "video") {
126
+ thumbnail = await generateVideoThumbnail(file);
127
+ }
128
+
129
+ updateAttachments((previous) =>
130
+ previous.map((attachment) =>
131
+ attachment.id === placeholderId
132
+ ? {
133
+ ...attachment,
134
+ source,
135
+ status: "ready",
136
+ thumbnail,
137
+ metadata: uploadMetadata,
138
+ }
139
+ : attachment,
140
+ ),
141
+ );
142
+ } catch (error) {
143
+ updateAttachments((previous) =>
144
+ previous.filter((attachment) => attachment.id !== placeholderId),
145
+ );
146
+ console.error(`[CopilotKit] Failed to upload "${file.name}":`, error);
147
+ config?.onUploadFailed?.({
148
+ reason: "upload-failed",
149
+ file,
150
+ message:
151
+ error instanceof Error
152
+ ? error.message
153
+ : `Failed to upload "${file.name}"`,
154
+ });
155
+ }
156
+ }
157
+ }
158
+
159
+ async function handleFileUpload(event: Event) {
160
+ const target = event.target as HTMLInputElement | null;
161
+ if (!target?.files?.length) return;
162
+ await processFiles(Array.from(target.files));
163
+ if (target) target.value = "";
164
+ }
165
+
166
+ function handleDragOver(event: DragEvent) {
167
+ if (!enabled.value) return;
168
+ event.preventDefault();
169
+ event.stopPropagation();
170
+ dragOver.value = true;
171
+ }
172
+
173
+ function handleDragLeave(event: DragEvent) {
174
+ event.preventDefault();
175
+ event.stopPropagation();
176
+ dragOver.value = false;
177
+ }
178
+
179
+ async function handleDrop(event: DragEvent) {
180
+ event.preventDefault();
181
+ event.stopPropagation();
182
+ dragOver.value = false;
183
+ if (!enabled.value) return;
184
+
185
+ const files = Array.from(event.dataTransfer?.files ?? []);
186
+ if (files.length > 0) {
187
+ await processFiles(files);
188
+ }
189
+ }
190
+
191
+ function removeAttachment(id: string) {
192
+ updateAttachments((previous) =>
193
+ previous.filter((attachment) => attachment.id !== id),
194
+ );
195
+ }
196
+
197
+ function consumeAttachments() {
198
+ const ready = attachmentsRef.value.filter(
199
+ (attachment) => attachment.status === "ready",
200
+ );
201
+ if (ready.length === 0) {
202
+ return ready;
203
+ }
204
+ updateAttachments((previous) =>
205
+ previous.filter((attachment) => attachment.status !== "ready"),
206
+ );
207
+ if (fileInputRef.value) {
208
+ fileInputRef.value.value = "";
209
+ }
210
+ return ready;
211
+ }
212
+
213
+ async function handlePaste(event: ClipboardEvent) {
214
+ if (!enabled.value) return;
215
+
216
+ const target = event.target as HTMLElement | null;
217
+ if (!target || !containerRef.value?.contains(target)) return;
218
+
219
+ const accept = configRef.value?.accept ?? "*/*";
220
+ const items = Array.from(event.clipboardData?.items ?? []);
221
+ const fileItems = items.filter((item) => {
222
+ if (item.kind !== "file") return false;
223
+ const file = item.getAsFile();
224
+ return file !== null && matchesAcceptFilter(file, accept);
225
+ });
226
+ if (fileItems.length === 0) return;
227
+
228
+ event.preventDefault();
229
+ const files = fileItems
230
+ .map((item) => item.getAsFile())
231
+ .filter((file): file is File => file !== null);
232
+ await processFiles(files);
233
+ }
234
+
235
+ onMounted(() => {
236
+ if (typeof document !== "undefined") {
237
+ document.addEventListener("paste", handlePaste);
238
+ }
239
+ });
240
+
241
+ onBeforeUnmount(() => {
242
+ if (typeof document !== "undefined") {
243
+ document.removeEventListener("paste", handlePaste);
244
+ }
245
+ });
246
+
247
+ return {
248
+ attachments,
249
+ enabled,
250
+ dragOver,
251
+ fileInputRef,
252
+ containerRef,
253
+ processFiles,
254
+ handleFileUpload,
255
+ handleDragOver,
256
+ handleDragLeave,
257
+ handleDrop,
258
+ removeAttachment,
259
+ consumeAttachments,
260
+ };
261
+ }
@@ -0,0 +1,30 @@
1
+ import type { AgentCapabilities } from "@ag-ui/core";
2
+ import { computed } from "vue";
3
+ import type { ComputedRef } from "vue";
4
+ import { useAgent } from "./use-agent";
5
+
6
+ /**
7
+ * Returns the capabilities declared by the given agent (or the default agent).
8
+ *
9
+ * Capabilities are populated from the runtime `/info` response at connection
10
+ * time. The composable reads them synchronously from the agent instance — there
11
+ * is no separate loading state, but the value will be `undefined` until the
12
+ * runtime handshake completes.
13
+ *
14
+ * @param agentId - Optional agent ID. If omitted, uses the default agent.
15
+ * @returns A computed ref containing the agent's capabilities, or `undefined`
16
+ * if the agent doesn't declare capabilities.
17
+ */
18
+ export function useCapabilities(
19
+ agentId?: string,
20
+ ): ComputedRef<AgentCapabilities | undefined> {
21
+ const { agent } = useAgent({ agentId });
22
+
23
+ return computed(() => {
24
+ const a = agent.value;
25
+ if (a && "capabilities" in a) {
26
+ return (a as { capabilities?: AgentCapabilities }).capabilities;
27
+ }
28
+ return undefined;
29
+ });
30
+ }
@@ -0,0 +1,46 @@
1
+ import type { StandardSchemaV1, InferSchemaOutput } from "@copilotkit/shared";
2
+ import type { Component } from "vue";
3
+ import { h } from "vue";
4
+ import type { WatchSource } from "vue";
5
+ import { useFrontendTool } from "./use-frontend-tool";
6
+
7
+ type InferRenderProps<T> = T extends StandardSchemaV1
8
+ ? InferSchemaOutput<T>
9
+ : any;
10
+
11
+ export function useComponent<
12
+ TSchema extends StandardSchemaV1 | undefined = undefined,
13
+ >(
14
+ config: {
15
+ name: string;
16
+ description?: string;
17
+ parameters?: TSchema;
18
+ render: Component<NoInfer<InferRenderProps<TSchema>>>;
19
+ agentId?: string;
20
+ },
21
+ deps?: WatchSource<unknown>[],
22
+ ): void {
23
+ const prefix = `Use this tool to display the "${config.name}" component in the chat. This tool renders a visual UI component for the user.`;
24
+ const fullDescription = config.description
25
+ ? `${prefix}\n\n${config.description}`
26
+ : prefix;
27
+
28
+ useFrontendTool(
29
+ {
30
+ name: config.name,
31
+ description: fullDescription,
32
+ parameters: config.parameters as
33
+ | StandardSchemaV1<any, Record<string, unknown>>
34
+ | undefined,
35
+ render: ({ args }: { args: unknown }) => {
36
+ const RenderComponent = config.render;
37
+ return h(
38
+ RenderComponent as Component,
39
+ args as InferRenderProps<TSchema>,
40
+ );
41
+ },
42
+ agentId: config.agentId,
43
+ },
44
+ deps,
45
+ );
46
+ }