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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/CONTRIBUTOR_GUIDE.md +1 -1
  2. package/PARITY.md +3 -3
  3. package/dist/hooks/use-copilot-action.d.ts.map +1 -1
  4. package/dist/hooks/use-frontend-tool.d.ts +1 -1
  5. package/dist/hooks/use-frontend-tool.d.ts.map +1 -1
  6. package/dist/hooks/zod-parameters.d.ts +14 -0
  7. package/dist/hooks/zod-parameters.d.ts.map +1 -0
  8. package/dist/index.cjs +1 -73
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.mjs +365 -16920
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/use-render-activity-message-BZJ33B_r.cjs +113 -0
  13. package/dist/use-render-activity-message-BZJ33B_r.cjs.map +1 -0
  14. package/dist/use-render-activity-message-DrR407LQ.js +15901 -0
  15. package/dist/use-render-activity-message-DrR407LQ.js.map +1 -0
  16. package/dist/v2/components/A2UIMessageRenderer.d.ts +14 -0
  17. package/dist/v2/components/A2UIMessageRenderer.d.ts.map +1 -1
  18. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts +10 -3
  19. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts.map +1 -1
  20. package/dist/v2/components/CopilotKitInspector.vue.d.ts +5 -1
  21. package/dist/v2/components/CopilotKitInspector.vue.d.ts.map +1 -1
  22. package/dist/v2/components/InlineFeatureWarning.vue.d.ts.map +1 -1
  23. package/dist/v2/components/LicenseWarningBanner.vue.d.ts +2 -2
  24. package/dist/v2/components/LicenseWarningBanner.vue.d.ts.map +1 -1
  25. package/dist/v2/components/MCPAppsActivityRenderer.d.ts.map +1 -1
  26. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts +13 -59
  27. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts.map +1 -1
  28. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts +3 -11
  29. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts.map +1 -1
  30. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts +10 -15
  31. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts.map +1 -1
  32. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts +14 -130
  33. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts.map +1 -1
  34. package/dist/v2/components/a2ui/catalog.d.ts.map +1 -1
  35. package/dist/v2/components/a2ui/utils.d.ts +3 -15
  36. package/dist/v2/components/a2ui/utils.d.ts.map +1 -1
  37. package/dist/v2/components/a2ui.d.ts +9 -8
  38. package/dist/v2/components/a2ui.d.ts.map +1 -1
  39. package/dist/v2/components/chat/CopilotChat.vue.d.ts +2 -2
  40. package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
  41. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -1
  42. package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -1
  43. package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -1
  44. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts +4 -8
  45. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts.map +1 -1
  46. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts +1 -1
  47. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts.map +1 -1
  48. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +7 -286
  49. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -1
  50. package/dist/v2/components/chat/CopilotChatInspectorButton.vue.d.ts.map +1 -1
  51. package/dist/v2/components/chat/CopilotChatLightbox.vue.d.ts.map +1 -1
  52. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +1 -1
  53. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -1
  54. package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -1
  55. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts +1 -1
  56. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts.map +1 -1
  57. package/dist/v2/components/chat/CopilotChatToolCallItem.vue.d.ts.map +1 -1
  58. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +1 -1
  59. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -1
  60. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -1
  61. package/dist/v2/components/chat/CopilotChatView.vue.d.ts +3 -3
  62. package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
  63. package/dist/v2/components/chat/CopilotChatWorkSummary.vue.d.ts.map +1 -1
  64. package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts.map +1 -1
  65. package/dist/v2/components/chat/CopilotPopup.vue.d.ts +8 -3
  66. package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -1
  67. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts +5 -3
  68. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -1
  69. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts +5 -3
  70. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -1
  71. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts +8 -3
  72. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -1
  73. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +6 -4
  74. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -1
  75. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +6 -4
  76. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -1
  77. package/dist/v2/components/chat/CopilotThreadsDrawer.vue.d.ts.map +1 -1
  78. package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts +1 -0
  79. package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts.map +1 -1
  80. package/dist/v2/components/chat/audioRecorder.d.ts +3 -4
  81. package/dist/v2/components/chat/audioRecorder.d.ts.map +1 -1
  82. package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts +4 -4
  83. package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts.map +1 -1
  84. package/dist/v2/components/chat/forwarded-slots.d.ts +12 -0
  85. package/dist/v2/components/chat/forwarded-slots.d.ts.map +1 -0
  86. package/dist/v2/components/chat/index.d.ts +34 -31
  87. package/dist/v2/components/chat/index.d.ts.map +1 -1
  88. package/dist/v2/components/chat/inspector-shortcuts.d.ts +2 -1
  89. package/dist/v2/components/chat/inspector-shortcuts.d.ts.map +1 -1
  90. package/dist/v2/components/chat/message-feedback.d.ts +38 -49
  91. package/dist/v2/components/chat/message-feedback.d.ts.map +1 -1
  92. package/dist/v2/components/chat/tool-call-display-context.d.ts +4 -19
  93. package/dist/v2/components/chat/tool-call-display-context.d.ts.map +1 -1
  94. package/dist/v2/components/chat/tool-call-group-parts.d.ts +7 -20
  95. package/dist/v2/components/chat/tool-call-group-parts.d.ts.map +1 -1
  96. package/dist/v2/components/chat/turn-work.d.ts +0 -2
  97. package/dist/v2/components/chat/turn-work.d.ts.map +1 -1
  98. package/dist/v2/components/chat/types.d.ts +9 -4
  99. package/dist/v2/components/chat/types.d.ts.map +1 -1
  100. package/dist/v2/components/chat/use-chat-labels.d.ts +8 -0
  101. package/dist/v2/components/chat/use-chat-labels.d.ts.map +1 -0
  102. package/dist/v2/components/chat/use-copy-feedback.d.ts +11 -0
  103. package/dist/v2/components/chat/use-copy-feedback.d.ts.map +1 -0
  104. package/dist/v2/components/chat/use-lightbox.d.ts.map +1 -1
  105. package/dist/v2/components/icons/index.d.ts +968 -1
  106. package/dist/v2/components/icons/index.d.ts.map +1 -1
  107. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts +1 -1
  108. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts.map +1 -1
  109. package/dist/v2/hooks/use-agent-context.d.ts +2 -3
  110. package/dist/v2/hooks/use-agent-context.d.ts.map +1 -1
  111. package/dist/v2/hooks/use-agent.d.ts +4 -1
  112. package/dist/v2/hooks/use-agent.d.ts.map +1 -1
  113. package/dist/v2/hooks/use-attachments.d.ts +7 -0
  114. package/dist/v2/hooks/use-attachments.d.ts.map +1 -1
  115. package/dist/v2/hooks/use-capabilities.d.ts.map +1 -1
  116. package/dist/v2/hooks/use-component.d.ts +1 -0
  117. package/dist/v2/hooks/use-component.d.ts.map +1 -1
  118. package/dist/v2/hooks/use-configure-suggestions.d.ts +4 -9
  119. package/dist/v2/hooks/use-configure-suggestions.d.ts.map +1 -1
  120. package/dist/v2/hooks/use-default-render-tool.d.ts +2 -7
  121. package/dist/v2/hooks/use-default-render-tool.d.ts.map +1 -1
  122. package/dist/v2/hooks/use-frontend-tool.d.ts +5 -0
  123. package/dist/v2/hooks/use-frontend-tool.d.ts.map +1 -1
  124. package/dist/v2/hooks/use-human-in-the-loop.d.ts +2 -1
  125. package/dist/v2/hooks/use-human-in-the-loop.d.ts.map +1 -1
  126. package/dist/v2/hooks/use-interrupt.d.ts +0 -1
  127. package/dist/v2/hooks/use-interrupt.d.ts.map +1 -1
  128. package/dist/v2/hooks/use-keyboard-height.d.ts +1 -1
  129. package/dist/v2/hooks/use-keyboard-height.d.ts.map +1 -1
  130. package/dist/v2/hooks/use-pin-to-send.d.ts +4 -12
  131. package/dist/v2/hooks/use-pin-to-send.d.ts.map +1 -1
  132. package/dist/v2/hooks/use-render-activity-message.d.ts +13 -9
  133. package/dist/v2/hooks/use-render-activity-message.d.ts.map +1 -1
  134. package/dist/v2/hooks/use-render-custom-messages.d.ts +5 -7
  135. package/dist/v2/hooks/use-render-custom-messages.d.ts.map +1 -1
  136. package/dist/v2/hooks/use-render-tool.d.ts +1 -1
  137. package/dist/v2/hooks/use-render-tool.d.ts.map +1 -1
  138. package/dist/v2/hooks/use-suggestions.d.ts.map +1 -1
  139. package/dist/v2/hooks/use-threads.d.ts +6 -23
  140. package/dist/v2/hooks/use-threads.d.ts.map +1 -1
  141. package/dist/v2/index.cjs +1 -1
  142. package/dist/v2/index.mjs +197 -200
  143. package/dist/v2/index.mjs.map +1 -1
  144. package/dist/v2/lib/processPartialHtml.d.ts +1 -2
  145. package/dist/v2/lib/processPartialHtml.d.ts.map +1 -1
  146. package/dist/v2/lib/shallow-stable.d.ts.map +1 -1
  147. package/dist/v2/lib/vue-core.d.ts +33 -19
  148. package/dist/v2/lib/vue-core.d.ts.map +1 -1
  149. package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts.map +1 -1
  150. package/dist/v2/providers/CopilotKitProvider.types.d.ts +9 -129
  151. package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -1
  152. package/dist/v2/providers/CopilotKitProvider.vue.d.ts +9 -10
  153. package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
  154. package/dist/v2/providers/chat-configuration-store-key.d.ts +8 -0
  155. package/dist/v2/providers/chat-configuration-store-key.d.ts.map +1 -0
  156. package/dist/v2/providers/markdown-renderer.d.ts +4 -2
  157. package/dist/v2/providers/markdown-renderer.d.ts.map +1 -1
  158. package/dist/v2/providers/types.d.ts +3 -46
  159. package/dist/v2/providers/types.d.ts.map +1 -1
  160. package/dist/v2/providers/use-inspector-thread-override.d.ts +5 -0
  161. package/dist/v2/providers/use-inspector-thread-override.d.ts.map +1 -1
  162. package/dist/v2/types/defineToolCallRenderer.d.ts +1 -1
  163. package/dist/v2/types/defineToolCallRenderer.d.ts.map +1 -1
  164. package/dist/v2/types/human-in-the-loop.d.ts +8 -29
  165. package/dist/v2/types/human-in-the-loop.d.ts.map +1 -1
  166. package/dist/v2/types/interrupt.d.ts +1 -22
  167. package/dist/v2/types/interrupt.d.ts.map +1 -1
  168. package/dist/v2/types/vue-activity-message-renderer.d.ts +16 -15
  169. package/dist/v2/types/vue-activity-message-renderer.d.ts.map +1 -1
  170. package/dist/v2/types/vue-custom-message-renderer.d.ts +7 -16
  171. package/dist/v2/types/vue-custom-message-renderer.d.ts.map +1 -1
  172. package/dist/v2/types/vue-tool-call-renderer.d.ts +16 -35
  173. package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -1
  174. package/package.json +12 -13
  175. package/src/__tests__/build-entries.test.ts +29 -0
  176. package/src/hooks/__tests__/zod-parameters.test.ts +520 -0
  177. package/src/hooks/use-copilot-action.ts +2 -1
  178. package/src/hooks/use-frontend-tool.ts +3 -6
  179. package/src/hooks/zod-parameters.ts +162 -0
  180. package/src/v2/__tests__/exports.test.ts +10 -0
  181. package/src/v2/__tests__/mocks/web-inspector.ts +6 -0
  182. package/src/v2/__tests__/utils/test-helpers.ts +34 -4
  183. package/src/v2/components/A2UIMessageRenderer.ts +98 -68
  184. package/src/v2/components/A2UISurfaceActivityRenderer.vue +68 -103
  185. package/src/v2/components/CopilotKitInspector.vue +104 -51
  186. package/src/v2/components/InlineFeatureWarning.vue +20 -21
  187. package/src/v2/components/LicenseWarningBanner.vue +27 -135
  188. package/src/v2/components/MCPAppsActivityRenderer.ts +75 -201
  189. package/src/v2/components/OpenGenerativeUIRenderer.ts +122 -446
  190. package/src/v2/components/__tests__/A2UIMessageRenderer.test.ts +171 -8
  191. package/src/v2/components/__tests__/CopilotKitInspector.test.ts +42 -0
  192. package/src/v2/components/__tests__/LicenseWarningBanner.test.ts +60 -0
  193. package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.ts +64 -8
  194. package/src/v2/components/__tests__/OpenGenerativeUIToolRenderer.test.ts +38 -0
  195. package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +6 -26
  196. package/src/v2/components/a2ui/A2UICatalogContext.ts +27 -185
  197. package/src/v2/components/a2ui/A2UIRecoveryStates.ts +127 -327
  198. package/src/v2/components/a2ui/catalog.ts +3 -3
  199. package/src/v2/components/a2ui/utils.ts +13 -65
  200. package/src/v2/components/a2ui.ts +15 -22
  201. package/src/v2/components/chat/CopilotChat.vue +121 -498
  202. package/src/v2/components/chat/CopilotChatAssistantMessage.vue +47 -184
  203. package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +36 -55
  204. package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +14 -6
  205. package/src/v2/components/chat/CopilotChatAudioRecorder.vue +19 -246
  206. package/src/v2/components/chat/CopilotChatFeedbackCommentPopover.vue +12 -77
  207. package/src/v2/components/chat/CopilotChatInput.vue +139 -654
  208. package/src/v2/components/chat/CopilotChatInspectorButton.vue +45 -108
  209. package/src/v2/components/chat/CopilotChatLightbox.vue +10 -31
  210. package/src/v2/components/chat/CopilotChatMessageView.vue +96 -274
  211. package/src/v2/components/chat/CopilotChatReasoningMessage.vue +27 -62
  212. package/src/v2/components/chat/CopilotChatToolCallGroup.vue +63 -71
  213. package/src/v2/components/chat/CopilotChatToolCallItem.vue +8 -6
  214. package/src/v2/components/chat/CopilotChatToolCallsView.vue +31 -32
  215. package/src/v2/components/chat/CopilotChatUserMessage.vue +24 -112
  216. package/src/v2/components/chat/CopilotChatView.vue +123 -161
  217. package/src/v2/components/chat/CopilotChatWorkSummary.vue +26 -36
  218. package/src/v2/components/chat/CopilotModalHeader.vue +11 -23
  219. package/src/v2/components/chat/CopilotPopup.vue +23 -25
  220. package/src/v2/components/chat/CopilotPopupView.vue +10 -39
  221. package/src/v2/components/chat/CopilotPopupViewInternal.vue +49 -185
  222. package/src/v2/components/chat/CopilotSidebar.vue +23 -25
  223. package/src/v2/components/chat/CopilotSidebarView.vue +10 -39
  224. package/src/v2/components/chat/CopilotSidebarViewInternal.vue +56 -100
  225. package/src/v2/components/chat/CopilotThreadsDrawer.vue +43 -105
  226. package/src/v2/components/chat/StreamingMarkdownDefault.vue +15 -28
  227. package/src/v2/components/chat/__tests__/CopilotChat.labels.test.ts +19 -4
  228. package/src/v2/components/chat/__tests__/CopilotChat.test.ts +12 -10
  229. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.ts +26 -9
  230. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.learningFeedback.test.ts +5 -5
  231. package/src/v2/components/chat/__tests__/CopilotChatAttachmentQueue.test.ts +28 -0
  232. package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +132 -1
  233. package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.ts +247 -403
  234. package/src/v2/components/chat/__tests__/CopilotChatMessageView.toolCallDisplay.test.ts +1 -99
  235. package/src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.ts +43 -1
  236. package/src/v2/components/chat/__tests__/CopilotPopup.test.ts +90 -1
  237. package/src/v2/components/chat/__tests__/CopilotPopupView.test.ts +19 -0
  238. package/src/v2/components/chat/__tests__/CopilotSidebar.test.ts +90 -1
  239. package/src/v2/components/chat/__tests__/CopilotSidebarView.position.test.ts +32 -8
  240. package/src/v2/components/chat/__tests__/CopilotSidebarView.test.ts +2 -1
  241. package/src/v2/components/chat/__tests__/StreamingMarkdownDefault.test.ts +54 -0
  242. package/src/v2/components/chat/audioRecorder.ts +4 -7
  243. package/src/v2/components/chat/copilotChatToolCallItemRender.ts +25 -90
  244. package/src/v2/components/chat/forwarded-slots.ts +17 -0
  245. package/src/v2/components/chat/index.ts +0 -1
  246. package/src/v2/components/chat/inspector-shortcuts.ts +10 -16
  247. package/src/v2/components/chat/message-feedback.ts +92 -195
  248. package/src/v2/components/chat/tool-call-display-context.ts +6 -22
  249. package/src/v2/components/chat/tool-call-group-parts.ts +47 -108
  250. package/src/v2/components/chat/turn-work.ts +0 -9
  251. package/src/v2/components/chat/types.ts +12 -4
  252. package/src/v2/components/chat/use-chat-labels.ts +16 -0
  253. package/src/v2/components/chat/use-copy-feedback.ts +21 -0
  254. package/src/v2/components/chat/use-lightbox.ts +15 -33
  255. package/src/v2/components/icons/__tests__/icons.test.ts +72 -68
  256. package/src/v2/components/icons/index.ts +109 -27
  257. package/src/v2/hooks/__tests__/use-agent-error-state.test.ts +5 -3
  258. package/src/v2/hooks/__tests__/use-agent-stability.test.ts +25 -4
  259. package/src/v2/hooks/__tests__/use-agent-throttle.test.ts +5 -1
  260. package/src/v2/hooks/__tests__/use-agent.test.ts +6 -3
  261. package/src/v2/hooks/__tests__/use-component.test.ts +21 -0
  262. package/src/v2/hooks/__tests__/use-configure-suggestions.test.ts +30 -1
  263. package/src/v2/hooks/__tests__/use-default-render-tool.test.ts +10 -10
  264. package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.ts +66 -1
  265. package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.ts +6 -1
  266. package/src/v2/hooks/__tests__/use-human-in-the-loop.test.ts +187 -12
  267. package/src/v2/hooks/__tests__/use-interrupt.test.ts +97 -0
  268. package/src/v2/hooks/__tests__/use-render-activity-message.test.ts +106 -0
  269. package/src/v2/hooks/__tests__/use-render-tool.test.ts +3 -6
  270. package/src/v2/hooks/__tests__/use-threads.test.ts +48 -6
  271. package/src/v2/hooks/__tests__/zod-regression.test.ts +5 -4
  272. package/src/v2/hooks/use-agent-context.ts +4 -10
  273. package/src/v2/hooks/use-agent.ts +86 -290
  274. package/src/v2/hooks/use-attachments.ts +48 -168
  275. package/src/v2/hooks/use-capabilities.ts +2 -7
  276. package/src/v2/hooks/use-component.ts +7 -4
  277. package/src/v2/hooks/use-configure-suggestions.ts +29 -220
  278. package/src/v2/hooks/use-default-render-tool.ts +31 -152
  279. package/src/v2/hooks/use-frontend-tool.ts +15 -25
  280. package/src/v2/hooks/use-human-in-the-loop.ts +11 -80
  281. package/src/v2/hooks/use-interrupt.ts +29 -308
  282. package/src/v2/hooks/use-keyboard-height.ts +17 -40
  283. package/src/v2/hooks/use-pin-to-send.ts +15 -99
  284. package/src/v2/hooks/use-render-activity-message.ts +35 -57
  285. package/src/v2/hooks/use-render-custom-messages.ts +24 -88
  286. package/src/v2/hooks/use-render-tool.ts +2 -4
  287. package/src/v2/hooks/use-suggestions.ts +17 -36
  288. package/src/v2/hooks/use-threads.ts +49 -288
  289. package/src/v2/lib/__tests__/shallow-stable.test.ts +54 -0
  290. package/src/v2/lib/__tests__/vue-core-renderers.test.ts +42 -0
  291. package/src/v2/lib/processPartialHtml.ts +6 -21
  292. package/src/v2/lib/shallow-stable.ts +2 -16
  293. package/src/v2/lib/vue-core.ts +90 -85
  294. package/src/v2/providers/CopilotChatConfigurationProvider.vue +48 -186
  295. package/src/v2/providers/CopilotKitProvider.types.ts +12 -132
  296. package/src/v2/providers/CopilotKitProvider.vue +291 -641
  297. package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.ts +22 -2
  298. package/src/v2/providers/__tests__/CopilotKitProvider.a2ui.test.ts +38 -2
  299. package/src/v2/providers/__tests__/CopilotKitProvider.config.test.ts +124 -0
  300. package/src/v2/providers/__tests__/CopilotKitProvider.headersAtSendTime.test.ts +3 -3
  301. package/src/v2/providers/__tests__/CopilotKitProvider.learning.test.ts +3 -1
  302. package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.ts +4 -1
  303. package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +88 -28
  304. package/src/v2/providers/chat-configuration-store-key.ts +9 -0
  305. package/src/v2/providers/markdown-renderer.ts +8 -2
  306. package/src/v2/providers/types.ts +3 -49
  307. package/src/v2/providers/use-inspector-thread-override.ts +22 -80
  308. package/src/v2/types/__tests__/defineToolCallRenderer.test.ts +28 -33
  309. package/src/v2/types/defineToolCallRenderer.ts +7 -6
  310. package/src/v2/types/human-in-the-loop.ts +8 -32
  311. package/src/v2/types/interrupt.ts +7 -31
  312. package/src/v2/types/vue-activity-message-renderer.ts +24 -15
  313. package/src/v2/types/vue-custom-message-renderer.ts +12 -16
  314. package/src/v2/types/vue-tool-call-renderer.ts +23 -38
  315. package/tsconfig.json +0 -1
  316. package/vite.config.ts +8 -5
  317. package/vitest.config.ts +12 -7
  318. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts +0 -9
  319. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts.map +0 -1
  320. package/dist/v2/components/chat/normalize-auto-scroll.d.ts +0 -3
  321. package/dist/v2/components/chat/normalize-auto-scroll.d.ts.map +0 -1
  322. package/dist/v2/components/chat/tool-call-layout.d.ts +0 -115
  323. package/dist/v2/components/chat/tool-call-layout.d.ts.map +0 -1
  324. package/dist/v2/lib/is-mobile-viewport.d.ts +0 -15
  325. package/dist/v2/lib/is-mobile-viewport.d.ts.map +0 -1
  326. package/dist/v2/lib/message-feedback.d.ts +0 -33
  327. package/dist/v2/lib/message-feedback.d.ts.map +0 -1
  328. package/dist/v2/lib/transcription-client.d.ts +0 -19
  329. package/dist/v2/lib/transcription-client.d.ts.map +0 -1
  330. package/src/v2/components/__tests__/A2UICatalogContext.test.ts +0 -63
  331. package/src/v2/components/a2ui/__tests__/A2UIRecoveryStates.test.ts +0 -175
  332. package/src/v2/components/chat/BasicMarkdown.vue +0 -160
  333. package/src/v2/components/chat/__tests__/BasicMarkdown.test.ts +0 -69
  334. package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +0 -39
  335. package/src/v2/components/chat/normalize-auto-scroll.ts +0 -17
  336. package/src/v2/components/chat/tool-call-layout.ts +0 -304
  337. package/src/v2/lib/__tests__/is-mobile-viewport.test.ts +0 -48
  338. package/src/v2/lib/__tests__/message-feedback.test.ts +0 -152
  339. package/src/v2/lib/__tests__/processPartialHtml.test.ts +0 -84
  340. package/src/v2/lib/__tests__/transcription-client.test.ts +0 -67
  341. package/src/v2/lib/is-mobile-viewport.ts +0 -23
  342. package/src/v2/lib/message-feedback.ts +0 -120
  343. package/src/v2/lib/transcription-client.ts +0 -151
@@ -5,23 +5,10 @@ import {
5
5
  ref,
6
6
  shallowRef,
7
7
  toValue,
8
- watch,
9
8
  } from "vue";
10
9
  import type { MaybeRefOrGetter, Ref } from "vue";
11
- import {
12
- randomUUID,
13
- getModalityFromMimeType,
14
- exceedsMaxSize,
15
- readFileAsBase64,
16
- generateVideoThumbnail,
17
- matchesAcceptFilter,
18
- formatFileSize,
19
- } from "@copilotkit/shared";
20
- import type {
21
- Attachment,
22
- AttachmentUploadResult,
23
- AttachmentsConfig,
24
- } from "@copilotkit/shared";
10
+ import { ɵAttachmentQueue } from "@copilotkit/core";
11
+ import type { Attachment, AttachmentsConfig } from "@copilotkit/shared";
25
12
 
26
13
  export interface UseAttachmentsProps {
27
14
  config?: MaybeRefOrGetter<AttachmentsConfig | undefined>;
@@ -33,6 +20,7 @@ export interface UseAttachmentsReturn {
33
20
  dragOver: Ref<boolean>;
34
21
  fileInputRef: Ref<HTMLInputElement | null>;
35
22
  containerRef: Ref<HTMLElement | null>;
23
+ /** Process files (validate, upload, add to state). No-op while attachments are disabled. */
36
24
  processFiles: (files: File[]) => Promise<void>;
37
25
  handleFileUpload: (event: Event) => Promise<void>;
38
26
  handleDragOver: (event: DragEvent) => void;
@@ -42,133 +30,43 @@ export interface UseAttachmentsReturn {
42
30
  consumeAttachments: () => Attachment[];
43
31
  }
44
32
 
33
+ /**
34
+ * Manages file attachment state — uploads, drag-and-drop, paste. The queue
35
+ * itself (validation, uploads, ready state) lives in `@copilotkit/core`'s
36
+ * `ɵAttachmentQueue`; this composable adds the DOM wiring and projects the
37
+ * queue into a `shallowRef`.
38
+ */
45
39
  export function useAttachments(
46
40
  props: UseAttachmentsProps,
47
41
  ): UseAttachmentsReturn {
48
- const attachments = shallowRef<Attachment[]>([]);
42
+ const queue = new ɵAttachmentQueue(() => toValue(props.config));
43
+ const attachments = shallowRef<Attachment[]>(queue.getSnapshot());
44
+ const unsubscribe = queue.subscribe(() => {
45
+ attachments.value = queue.getSnapshot();
46
+ });
49
47
  const dragOver = ref(false);
50
48
  const fileInputRef = ref<HTMLInputElement | null>(null);
51
49
  const containerRef = ref<HTMLElement | null>(null);
52
- const configRef = ref<AttachmentsConfig | undefined>(toValue(props.config));
53
- const attachmentsRef = shallowRef<Attachment[]>(attachments.value);
54
- const enabled = computed(() => configRef.value?.enabled ?? false);
55
-
56
- watch(
57
- () => toValue(props.config),
58
- (next) => {
59
- configRef.value = next;
60
- },
61
- { immediate: true },
62
- );
63
-
64
- const setAttachments = (next: Attachment[]) => {
65
- attachments.value = next;
66
- attachmentsRef.value = next;
67
- };
68
-
69
- const updateAttachments = (
70
- updater: (previous: Attachment[]) => Attachment[],
71
- ) => {
72
- setAttachments(updater(attachmentsRef.value));
73
- };
74
-
75
- async function processFiles(files: File[]) {
76
- const config = configRef.value;
77
- const accept = config?.accept ?? "*/*";
78
- const maxSize = config?.maxSize ?? 20 * 1024 * 1024;
79
-
80
- const rejectedFiles = files.filter(
81
- (file) => !matchesAcceptFilter(file, accept),
82
- );
83
- for (const file of rejectedFiles) {
84
- config?.onUploadFailed?.({
85
- reason: "invalid-type",
86
- file,
87
- message: `File "${file.name}" is not accepted. Supported types: ${accept}`,
88
- });
89
- }
90
-
91
- const validFiles = files.filter((file) =>
92
- matchesAcceptFilter(file, accept),
93
- );
94
- for (const file of validFiles) {
95
- if (exceedsMaxSize(file, maxSize)) {
96
- config?.onUploadFailed?.({
97
- reason: "file-too-large",
98
- file,
99
- message: `File "${file.name}" exceeds the maximum size of ${formatFileSize(maxSize)}`,
100
- });
101
- continue;
102
- }
103
-
104
- const modality = getModalityFromMimeType(file.type);
105
- const placeholderId = randomUUID();
106
- updateAttachments((previous) => [
107
- ...previous,
108
- {
109
- id: placeholderId,
110
- type: modality,
111
- source: { type: "data", value: "", mimeType: file.type },
112
- filename: file.name,
113
- size: file.size,
114
- status: "uploading",
115
- },
116
- ]);
117
-
118
- try {
119
- let source: Attachment["source"];
120
- let uploadMetadata: Record<string, unknown> | undefined;
121
- if (config?.onUpload) {
122
- const uploadResult: AttachmentUploadResult =
123
- await config.onUpload(file);
124
- const { metadata, ...uploadSource } = uploadResult;
125
- source = uploadSource;
126
- uploadMetadata = metadata;
127
- } else {
128
- const base64 = await readFileAsBase64(file);
129
- source = { type: "data", value: base64, mimeType: file.type };
130
- }
50
+ const enabled = computed(() => toValue(props.config)?.enabled ?? false);
131
51
 
132
- let thumbnail: string | undefined;
133
- if (modality === "video") {
134
- thumbnail = await generateVideoThumbnail(file);
135
- }
52
+ function processFiles(files: File[]) {
53
+ return queue.processFiles(files);
54
+ }
136
55
 
137
- updateAttachments((previous) =>
138
- previous.map((attachment) =>
139
- attachment.id === placeholderId
140
- ? {
141
- ...attachment,
142
- source,
143
- status: "ready",
144
- thumbnail,
145
- metadata: uploadMetadata,
146
- }
147
- : attachment,
148
- ),
149
- );
150
- } catch (error) {
151
- updateAttachments((previous) =>
152
- previous.filter((attachment) => attachment.id !== placeholderId),
153
- );
154
- console.error(`[CopilotKit] Failed to upload "${file.name}":`, error);
155
- config?.onUploadFailed?.({
156
- reason: "upload-failed",
157
- file,
158
- message:
159
- error instanceof Error
160
- ? error.message
161
- : `Failed to upload "${file.name}"`,
162
- });
163
- }
56
+ async function processSafely(files: File[], label: string) {
57
+ try {
58
+ await queue.processFiles(files);
59
+ } catch (error) {
60
+ console.error(`[CopilotKit] ${label}:`, error);
164
61
  }
165
62
  }
166
63
 
167
64
  async function handleFileUpload(event: Event) {
168
- const target = event.target as HTMLInputElement | null;
169
- if (!target?.files?.length) return;
170
- await processFiles(Array.from(target.files));
171
- if (target) target.value = "";
65
+ const target = event.target;
66
+ if (!(target instanceof HTMLInputElement) || !target.files?.length) return;
67
+ await processSafely(Array.from(target.files), "Upload error");
68
+ // Clear the picker so choosing the same file again fires `change`.
69
+ target.value = "";
172
70
  }
173
71
 
174
72
  function handleDragOver(event: DragEvent) {
@@ -188,68 +86,50 @@ export function useAttachments(
188
86
  event.preventDefault();
189
87
  event.stopPropagation();
190
88
  dragOver.value = false;
191
- if (!enabled.value) return;
192
-
193
89
  const files = Array.from(event.dataTransfer?.files ?? []);
194
- if (files.length > 0) {
195
- await processFiles(files);
196
- }
90
+ if (files.length > 0) await processSafely(files, "Drop error");
197
91
  }
198
92
 
199
93
  function removeAttachment(id: string) {
200
- updateAttachments((previous) =>
201
- previous.filter((attachment) => attachment.id !== id),
202
- );
94
+ queue.remove(id);
203
95
  }
204
96
 
205
97
  function consumeAttachments() {
206
- const ready = attachmentsRef.value.filter(
207
- (attachment) => attachment.status === "ready",
208
- );
209
- if (ready.length === 0) {
210
- return ready;
211
- }
212
- updateAttachments((previous) =>
213
- previous.filter((attachment) => attachment.status !== "ready"),
214
- );
215
- if (fileInputRef.value) {
98
+ const ready = queue.consumeReady();
99
+ if (ready.length > 0 && fileInputRef.value) {
216
100
  fileInputRef.value.value = "";
217
101
  }
218
102
  return ready;
219
103
  }
220
104
 
221
105
  async function handlePaste(event: ClipboardEvent) {
222
- if (!enabled.value) return;
223
-
224
- const target = event.target as HTMLElement | null;
225
- if (!target || !containerRef.value?.contains(target)) return;
226
-
227
- const accept = configRef.value?.accept ?? "*/*";
228
- const items = Array.from(event.clipboardData?.items ?? []);
229
- const fileItems = items.filter((item) => {
230
- if (item.kind !== "file") return false;
231
- const file = item.getAsFile();
232
- return file !== null && matchesAcceptFilter(file, accept);
233
- });
234
- if (fileItems.length === 0) return;
235
-
106
+ const target = event.target;
107
+ if (!(target instanceof Node) || !containerRef.value?.contains(target))
108
+ return;
109
+ const files = queue.filterPastedFiles(
110
+ Array.from(event.clipboardData?.items ?? []),
111
+ );
112
+ if (files.length === 0) return;
236
113
  event.preventDefault();
237
- const files = fileItems
238
- .map((item) => item.getAsFile())
239
- .filter((file): file is File => file !== null);
240
- await processFiles(files);
114
+ await processSafely(files, "Paste error");
115
+ }
116
+
117
+ function onPaste(event: ClipboardEvent) {
118
+ void handlePaste(event);
241
119
  }
242
120
 
243
121
  onMounted(() => {
244
122
  if (typeof document !== "undefined") {
245
- document.addEventListener("paste", handlePaste);
123
+ document.addEventListener("paste", onPaste);
246
124
  }
247
125
  });
248
126
 
249
127
  onBeforeUnmount(() => {
250
128
  if (typeof document !== "undefined") {
251
- document.removeEventListener("paste", handlePaste);
129
+ document.removeEventListener("paste", onPaste);
252
130
  }
131
+ unsubscribe();
132
+ queue.dispose();
253
133
  });
254
134
 
255
135
  return {
@@ -1,6 +1,7 @@
1
1
  import type { AgentCapabilities } from "@ag-ui/core";
2
2
  import { computed } from "vue";
3
3
  import type { ComputedRef } from "vue";
4
+ import { ɵgetAgentCapabilities } from "@copilotkit/core";
4
5
  import { useAgent } from "./use-agent";
5
6
 
6
7
  /**
@@ -20,11 +21,5 @@ export function useCapabilities(
20
21
  ): ComputedRef<AgentCapabilities | undefined> {
21
22
  const { agent } = useAgent({ agentId });
22
23
 
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
- });
24
+ return computed(() => ɵgetAgentCapabilities(agent.value));
30
25
  }
@@ -2,6 +2,7 @@ import type { StandardSchemaV1, InferSchemaOutput } from "@copilotkit/shared";
2
2
  import type { Component } from "vue";
3
3
  import { h } from "vue";
4
4
  import type { WatchSource } from "vue";
5
+ import { ɵcomponentToolDescription } from "@copilotkit/core";
5
6
  import { useFrontendTool } from "./use-frontend-tool";
6
7
 
7
8
  type InferRenderProps<T> = T extends StandardSchemaV1
@@ -17,13 +18,14 @@ export function useComponent<
17
18
  parameters?: TSchema;
18
19
  render: Component<NoInfer<InferRenderProps<TSchema>>>;
19
20
  agentId?: string;
21
+ followUp?: boolean;
20
22
  },
21
23
  deps?: WatchSource<unknown>[],
22
24
  ): 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;
25
+ const fullDescription = ɵcomponentToolDescription(
26
+ config.name,
27
+ config.description,
28
+ );
27
29
 
28
30
  useFrontendTool(
29
31
  {
@@ -40,6 +42,7 @@ export function useComponent<
40
42
  );
41
43
  },
42
44
  agentId: config.agentId,
45
+ followUp: config.followUp,
43
46
  },
44
47
  deps,
45
48
  );
@@ -1,49 +1,16 @@
1
- import { computed, ref, watch } from "vue";
1
+ import { computed, watch } from "vue";
2
2
  import type { WatchSource } from "vue";
3
3
  import { useCopilotKit } from "../providers/useCopilotKit";
4
4
  import { useCopilotChatConfiguration } from "../providers/useCopilotChatConfiguration";
5
- import { DEFAULT_AGENT_ID } from "@copilotkit/shared";
6
- import type {
7
- DynamicSuggestionsConfig,
8
- Suggestion,
9
- StaticSuggestionsConfig,
10
- SuggestionsConfig,
11
- } from "@copilotkit/core";
12
-
13
- type StaticSuggestionInput = Omit<Suggestion, "isLoading"> &
14
- Partial<Pick<Suggestion, "isLoading">>;
15
-
16
- type StaticSuggestionsConfigInput = Omit<
17
- StaticSuggestionsConfig,
18
- "suggestions"
19
- > & {
20
- suggestions: StaticSuggestionInput[];
21
- };
22
-
23
- type SuggestionsConfigInput =
24
- | DynamicSuggestionsConfig
25
- | StaticSuggestionsConfigInput;
26
-
27
- function isDynamicConfig(
28
- config: SuggestionsConfigInput,
29
- ): config is DynamicSuggestionsConfig {
30
- return "instructions" in config;
31
- }
32
-
33
- function normalizeStaticSuggestions(
34
- suggestions: StaticSuggestionInput[],
35
- ): Suggestion[] {
36
- return suggestions.map((s) => ({
37
- ...s,
38
- isLoading: s.isLoading ?? false,
39
- }));
40
- }
5
+ import { ɵbindSuggestionsConfig, ɵresolveAgentId } from "@copilotkit/core";
6
+ import type { ɵSuggestionsConfigInput } from "@copilotkit/core";
41
7
 
42
8
  /**
43
9
  * Registers a suggestions configuration (dynamic or static) for the current
44
10
  * chat context.
45
11
  *
46
- * Configuration is kept in sync reactively and removed on scope cleanup.
12
+ * Configuration is kept in sync reactively and removed on scope cleanup. Pass
13
+ * `deps` to reload suggestions when values the config reads change.
47
14
  *
48
15
  * @example
49
16
  * ```ts
@@ -54,197 +21,39 @@ function normalizeStaticSuggestions(
54
21
  * ```
55
22
  */
56
23
  export function useConfigureSuggestions(
57
- config: SuggestionsConfigInput | null | undefined,
24
+ config: ɵSuggestionsConfigInput | null | undefined,
58
25
  deps?: WatchSource<unknown>[],
59
26
  ): void {
60
27
  const { copilotkit } = useCopilotKit();
61
28
  const chatConfig = useCopilotChatConfiguration();
62
- const extraDeps = deps ?? [];
63
-
64
- const resolvedConsumerAgentId = computed(
65
- () => chatConfig.value?.agentId ?? DEFAULT_AGENT_ID,
66
- );
67
- const rawConsumerAgentId = computed(() =>
68
- config ? (config as SuggestionsConfigInput).consumerAgentId : undefined,
69
- );
70
-
71
- const normalizedConfig = computed<SuggestionsConfig | null>(() => {
72
- if (
73
- !config ||
74
- (config as { available?: string }).available === "disabled"
75
- ) {
76
- return null;
77
- }
78
- if (isDynamicConfig(config)) {
79
- return { ...config };
80
- }
81
- const normalizedSuggestions = normalizeStaticSuggestions(
82
- config.suggestions,
83
- );
84
- return { ...config, suggestions: normalizedSuggestions };
85
- });
86
- const serializedConfig = computed(() =>
87
- normalizedConfig.value ? JSON.stringify(normalizedConfig.value) : null,
88
- );
89
-
90
- const targetAgentId = computed(() => {
91
- if (!normalizedConfig.value) return resolvedConsumerAgentId.value;
92
- const consumer = (
93
- normalizedConfig.value as
94
- | StaticSuggestionsConfig
95
- | DynamicSuggestionsConfig
96
- ).consumerAgentId;
97
- if (!consumer || consumer === "*") return resolvedConsumerAgentId.value;
98
- return consumer;
99
- });
100
-
101
- const isGlobalConfig = computed(
102
- () =>
103
- rawConsumerAgentId.value === undefined ||
104
- rawConsumerAgentId.value === "*",
105
- );
106
- const pendingGlobalReload = ref(false);
107
- const pendingReloadTimer = ref<ReturnType<typeof setTimeout> | null>(null);
108
- const previousSerializedConfig = ref<string | null>(null);
109
-
110
- const flushPendingGlobalReload = () => {
111
- if (!pendingGlobalReload.value || !isGlobalConfig.value) {
112
- return;
113
- }
114
- const hasRunning = Object.values(copilotkit.value.agents ?? {}).some(
115
- (entry) => !!entry.agentId && entry.isRunning,
116
- );
117
- if (hasRunning) {
118
- pendingReloadTimer.value = setTimeout(() => {
119
- pendingReloadTimer.value = null;
120
- flushPendingGlobalReload();
121
- }, 0);
122
- return;
123
- }
124
-
125
- pendingGlobalReload.value = false;
126
- requestReload();
127
- };
128
-
129
- const requestReload = () => {
130
- if (!normalizedConfig.value) {
131
- return;
132
- }
133
-
134
- if (isGlobalConfig.value) {
135
- let skippedBecauseRunning = false;
136
- const agents = Object.values(copilotkit.value.agents ?? {});
137
- for (const entry of agents) {
138
- const aid = entry.agentId;
139
- if (!aid) {
140
- continue;
141
- }
142
- if (!entry.isRunning) {
143
- copilotkit.value.reloadSuggestions(aid);
144
- } else {
145
- skippedBecauseRunning = true;
146
- }
147
- }
148
- pendingGlobalReload.value = skippedBecauseRunning;
149
- if (skippedBecauseRunning && pendingReloadTimer.value === null) {
150
- pendingReloadTimer.value = setTimeout(() => {
151
- pendingReloadTimer.value = null;
152
- flushPendingGlobalReload();
153
- }, 0);
154
- }
155
- return;
156
- }
157
-
158
- if (targetAgentId.value) {
159
- copilotkit.value.reloadSuggestions(targetAgentId.value);
160
- }
161
- };
162
-
163
- watch(
164
- [() => copilotkit.value, serializedConfig],
165
- ([_core, serialized], _old, onCleanup) => {
166
- if (!serialized || !normalizedConfig.value) {
167
- return;
168
- }
169
-
170
- const core = copilotkit.value;
171
- const cfg = normalizedConfig.value;
172
- const id = core.addSuggestionsConfig(cfg);
173
- requestReload();
174
-
175
- onCleanup(() => core.removeSuggestionsConfig(id));
176
- },
177
- { immediate: true },
178
- );
179
-
180
- watch(
181
- [normalizedConfig, serializedConfig],
182
- ([cfg, serialized]) => {
183
- if (!cfg) {
184
- previousSerializedConfig.value = null;
185
- return;
186
- }
187
-
188
- if (serialized && previousSerializedConfig.value === serialized) {
189
- return;
190
- }
191
-
192
- if (serialized) {
193
- previousSerializedConfig.value = serialized;
194
- }
195
-
196
- requestReload();
197
- },
198
- { immediate: false },
199
- );
200
-
201
- watch(
202
- [normalizedConfig, () => extraDeps.length, ...extraDeps],
203
- ([cfg]) => {
204
- if (!cfg || extraDeps.length === 0) {
205
- return;
206
- }
207
- requestReload();
208
- },
209
- { immediate: true },
29
+ const chatAgentId = computed(() =>
30
+ ɵresolveAgentId({ chatAgentId: chatConfig.value?.agentId }),
210
31
  );
32
+ const extraDeps = deps ?? [];
211
33
 
212
34
  watch(
213
- [() => copilotkit.value, pendingGlobalReload],
214
- (_vals, _old, onCleanup) => {
215
- onCleanup(() => {
216
- if (pendingReloadTimer.value !== null) {
217
- clearTimeout(pendingReloadTimer.value);
218
- pendingReloadTimer.value = null;
219
- }
35
+ () => copilotkit.value,
36
+ (core, _old, onCleanup) => {
37
+ const binding = ɵbindSuggestionsConfig(core, config, {
38
+ chatAgentId: chatAgentId.value,
220
39
  });
221
- },
222
- { immediate: true },
223
- );
224
-
225
- watch(
226
- [() => copilotkit.value, isGlobalConfig],
227
- ([core, global], _old, onCleanup) => {
228
- if (!global) {
229
- return;
230
- }
231
-
232
- const agentSubscriptions = Object.values(core.agents ?? {})
233
- .filter((agent): agent is NonNullable<typeof agent> => !!agent)
234
- .map((agent) =>
235
- agent.subscribe({
236
- onRunStartedEvent: flushPendingGlobalReload,
237
- onRunFinishedEvent: flushPendingGlobalReload,
238
- onRunFinalized: flushPendingGlobalReload,
239
- onRunFailed: flushPendingGlobalReload,
240
- onRunErrorEvent: flushPendingGlobalReload,
241
- }),
242
- );
243
-
40
+ // Deep, so a `reactive()` config that changes in place is applied. The
41
+ // binding compares configs by content, so other re-runs are no-ops.
42
+ const stopConfig = watch(
43
+ [() => config, chatAgentId],
44
+ ([nextConfig, nextChatAgentId]) => {
45
+ binding.update(nextConfig, { chatAgentId: nextChatAgentId });
46
+ },
47
+ { deep: true },
48
+ );
49
+ const stopDeps =
50
+ extraDeps.length > 0
51
+ ? watch(extraDeps, () => binding.reload())
52
+ : undefined;
244
53
  onCleanup(() => {
245
- for (const sub of agentSubscriptions) {
246
- sub.unsubscribe();
247
- }
54
+ stopConfig();
55
+ stopDeps?.();
56
+ binding.dispose();
248
57
  });
249
58
  },
250
59
  { immediate: true },