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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/CONTRIBUTOR_GUIDE.md +1 -1
  2. package/PARITY.md +3 -3
  3. package/dist/hooks/use-copilot-action.d.ts.map +1 -1
  4. package/dist/hooks/use-frontend-tool.d.ts +1 -1
  5. package/dist/hooks/use-frontend-tool.d.ts.map +1 -1
  6. package/dist/hooks/zod-parameters.d.ts +14 -0
  7. package/dist/hooks/zod-parameters.d.ts.map +1 -0
  8. package/dist/index.cjs +1 -73
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.mjs +365 -16920
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/use-render-activity-message-BZJ33B_r.cjs +113 -0
  13. package/dist/use-render-activity-message-BZJ33B_r.cjs.map +1 -0
  14. package/dist/use-render-activity-message-DrR407LQ.js +15901 -0
  15. package/dist/use-render-activity-message-DrR407LQ.js.map +1 -0
  16. package/dist/v2/components/A2UIMessageRenderer.d.ts +14 -0
  17. package/dist/v2/components/A2UIMessageRenderer.d.ts.map +1 -1
  18. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts +10 -3
  19. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts.map +1 -1
  20. package/dist/v2/components/CopilotKitInspector.vue.d.ts +5 -1
  21. package/dist/v2/components/CopilotKitInspector.vue.d.ts.map +1 -1
  22. package/dist/v2/components/InlineFeatureWarning.vue.d.ts.map +1 -1
  23. package/dist/v2/components/LicenseWarningBanner.vue.d.ts +2 -2
  24. package/dist/v2/components/LicenseWarningBanner.vue.d.ts.map +1 -1
  25. package/dist/v2/components/MCPAppsActivityRenderer.d.ts.map +1 -1
  26. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts +13 -59
  27. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts.map +1 -1
  28. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts +3 -11
  29. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts.map +1 -1
  30. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts +10 -15
  31. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts.map +1 -1
  32. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts +14 -130
  33. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts.map +1 -1
  34. package/dist/v2/components/a2ui/catalog.d.ts.map +1 -1
  35. package/dist/v2/components/a2ui/utils.d.ts +3 -15
  36. package/dist/v2/components/a2ui/utils.d.ts.map +1 -1
  37. package/dist/v2/components/a2ui.d.ts +9 -8
  38. package/dist/v2/components/a2ui.d.ts.map +1 -1
  39. package/dist/v2/components/chat/CopilotChat.vue.d.ts +2 -2
  40. package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
  41. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -1
  42. package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -1
  43. package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -1
  44. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts +4 -8
  45. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts.map +1 -1
  46. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts +1 -1
  47. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts.map +1 -1
  48. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +7 -286
  49. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -1
  50. package/dist/v2/components/chat/CopilotChatInspectorButton.vue.d.ts.map +1 -1
  51. package/dist/v2/components/chat/CopilotChatLightbox.vue.d.ts.map +1 -1
  52. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +1 -1
  53. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -1
  54. package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -1
  55. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts +1 -1
  56. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts.map +1 -1
  57. package/dist/v2/components/chat/CopilotChatToolCallItem.vue.d.ts.map +1 -1
  58. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +1 -1
  59. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -1
  60. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -1
  61. package/dist/v2/components/chat/CopilotChatView.vue.d.ts +3 -3
  62. package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
  63. package/dist/v2/components/chat/CopilotChatWorkSummary.vue.d.ts.map +1 -1
  64. package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts.map +1 -1
  65. package/dist/v2/components/chat/CopilotPopup.vue.d.ts +8 -3
  66. package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -1
  67. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts +5 -3
  68. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -1
  69. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts +5 -3
  70. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -1
  71. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts +8 -3
  72. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -1
  73. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +6 -4
  74. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -1
  75. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +6 -4
  76. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -1
  77. package/dist/v2/components/chat/CopilotThreadsDrawer.vue.d.ts.map +1 -1
  78. package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts +1 -0
  79. package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts.map +1 -1
  80. package/dist/v2/components/chat/audioRecorder.d.ts +3 -4
  81. package/dist/v2/components/chat/audioRecorder.d.ts.map +1 -1
  82. package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts +4 -4
  83. package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts.map +1 -1
  84. package/dist/v2/components/chat/forwarded-slots.d.ts +12 -0
  85. package/dist/v2/components/chat/forwarded-slots.d.ts.map +1 -0
  86. package/dist/v2/components/chat/index.d.ts +34 -31
  87. package/dist/v2/components/chat/index.d.ts.map +1 -1
  88. package/dist/v2/components/chat/inspector-shortcuts.d.ts +2 -1
  89. package/dist/v2/components/chat/inspector-shortcuts.d.ts.map +1 -1
  90. package/dist/v2/components/chat/message-feedback.d.ts +38 -49
  91. package/dist/v2/components/chat/message-feedback.d.ts.map +1 -1
  92. package/dist/v2/components/chat/tool-call-display-context.d.ts +4 -19
  93. package/dist/v2/components/chat/tool-call-display-context.d.ts.map +1 -1
  94. package/dist/v2/components/chat/tool-call-group-parts.d.ts +7 -20
  95. package/dist/v2/components/chat/tool-call-group-parts.d.ts.map +1 -1
  96. package/dist/v2/components/chat/turn-work.d.ts +0 -2
  97. package/dist/v2/components/chat/turn-work.d.ts.map +1 -1
  98. package/dist/v2/components/chat/types.d.ts +9 -4
  99. package/dist/v2/components/chat/types.d.ts.map +1 -1
  100. package/dist/v2/components/chat/use-chat-labels.d.ts +8 -0
  101. package/dist/v2/components/chat/use-chat-labels.d.ts.map +1 -0
  102. package/dist/v2/components/chat/use-copy-feedback.d.ts +11 -0
  103. package/dist/v2/components/chat/use-copy-feedback.d.ts.map +1 -0
  104. package/dist/v2/components/chat/use-lightbox.d.ts.map +1 -1
  105. package/dist/v2/components/icons/index.d.ts +968 -1
  106. package/dist/v2/components/icons/index.d.ts.map +1 -1
  107. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts +1 -1
  108. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts.map +1 -1
  109. package/dist/v2/hooks/use-agent-context.d.ts +2 -3
  110. package/dist/v2/hooks/use-agent-context.d.ts.map +1 -1
  111. package/dist/v2/hooks/use-agent.d.ts +4 -1
  112. package/dist/v2/hooks/use-agent.d.ts.map +1 -1
  113. package/dist/v2/hooks/use-attachments.d.ts +7 -0
  114. package/dist/v2/hooks/use-attachments.d.ts.map +1 -1
  115. package/dist/v2/hooks/use-capabilities.d.ts.map +1 -1
  116. package/dist/v2/hooks/use-component.d.ts +1 -0
  117. package/dist/v2/hooks/use-component.d.ts.map +1 -1
  118. package/dist/v2/hooks/use-configure-suggestions.d.ts +4 -9
  119. package/dist/v2/hooks/use-configure-suggestions.d.ts.map +1 -1
  120. package/dist/v2/hooks/use-default-render-tool.d.ts +2 -7
  121. package/dist/v2/hooks/use-default-render-tool.d.ts.map +1 -1
  122. package/dist/v2/hooks/use-frontend-tool.d.ts +5 -0
  123. package/dist/v2/hooks/use-frontend-tool.d.ts.map +1 -1
  124. package/dist/v2/hooks/use-human-in-the-loop.d.ts +2 -1
  125. package/dist/v2/hooks/use-human-in-the-loop.d.ts.map +1 -1
  126. package/dist/v2/hooks/use-interrupt.d.ts +0 -1
  127. package/dist/v2/hooks/use-interrupt.d.ts.map +1 -1
  128. package/dist/v2/hooks/use-keyboard-height.d.ts +1 -1
  129. package/dist/v2/hooks/use-keyboard-height.d.ts.map +1 -1
  130. package/dist/v2/hooks/use-pin-to-send.d.ts +4 -12
  131. package/dist/v2/hooks/use-pin-to-send.d.ts.map +1 -1
  132. package/dist/v2/hooks/use-render-activity-message.d.ts +13 -9
  133. package/dist/v2/hooks/use-render-activity-message.d.ts.map +1 -1
  134. package/dist/v2/hooks/use-render-custom-messages.d.ts +5 -7
  135. package/dist/v2/hooks/use-render-custom-messages.d.ts.map +1 -1
  136. package/dist/v2/hooks/use-render-tool.d.ts +1 -1
  137. package/dist/v2/hooks/use-render-tool.d.ts.map +1 -1
  138. package/dist/v2/hooks/use-suggestions.d.ts.map +1 -1
  139. package/dist/v2/hooks/use-threads.d.ts +6 -23
  140. package/dist/v2/hooks/use-threads.d.ts.map +1 -1
  141. package/dist/v2/index.cjs +1 -1
  142. package/dist/v2/index.mjs +197 -200
  143. package/dist/v2/index.mjs.map +1 -1
  144. package/dist/v2/lib/processPartialHtml.d.ts +1 -2
  145. package/dist/v2/lib/processPartialHtml.d.ts.map +1 -1
  146. package/dist/v2/lib/shallow-stable.d.ts.map +1 -1
  147. package/dist/v2/lib/vue-core.d.ts +33 -19
  148. package/dist/v2/lib/vue-core.d.ts.map +1 -1
  149. package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts.map +1 -1
  150. package/dist/v2/providers/CopilotKitProvider.types.d.ts +9 -129
  151. package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -1
  152. package/dist/v2/providers/CopilotKitProvider.vue.d.ts +9 -10
  153. package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
  154. package/dist/v2/providers/chat-configuration-store-key.d.ts +8 -0
  155. package/dist/v2/providers/chat-configuration-store-key.d.ts.map +1 -0
  156. package/dist/v2/providers/markdown-renderer.d.ts +4 -2
  157. package/dist/v2/providers/markdown-renderer.d.ts.map +1 -1
  158. package/dist/v2/providers/types.d.ts +3 -46
  159. package/dist/v2/providers/types.d.ts.map +1 -1
  160. package/dist/v2/providers/use-inspector-thread-override.d.ts +5 -0
  161. package/dist/v2/providers/use-inspector-thread-override.d.ts.map +1 -1
  162. package/dist/v2/types/defineToolCallRenderer.d.ts +1 -1
  163. package/dist/v2/types/defineToolCallRenderer.d.ts.map +1 -1
  164. package/dist/v2/types/human-in-the-loop.d.ts +8 -29
  165. package/dist/v2/types/human-in-the-loop.d.ts.map +1 -1
  166. package/dist/v2/types/interrupt.d.ts +1 -22
  167. package/dist/v2/types/interrupt.d.ts.map +1 -1
  168. package/dist/v2/types/vue-activity-message-renderer.d.ts +16 -15
  169. package/dist/v2/types/vue-activity-message-renderer.d.ts.map +1 -1
  170. package/dist/v2/types/vue-custom-message-renderer.d.ts +7 -16
  171. package/dist/v2/types/vue-custom-message-renderer.d.ts.map +1 -1
  172. package/dist/v2/types/vue-tool-call-renderer.d.ts +16 -35
  173. package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -1
  174. package/package.json +12 -13
  175. package/src/__tests__/build-entries.test.ts +29 -0
  176. package/src/hooks/__tests__/zod-parameters.test.ts +520 -0
  177. package/src/hooks/use-copilot-action.ts +2 -1
  178. package/src/hooks/use-frontend-tool.ts +3 -6
  179. package/src/hooks/zod-parameters.ts +162 -0
  180. package/src/v2/__tests__/exports.test.ts +10 -0
  181. package/src/v2/__tests__/mocks/web-inspector.ts +6 -0
  182. package/src/v2/__tests__/utils/test-helpers.ts +34 -4
  183. package/src/v2/components/A2UIMessageRenderer.ts +98 -68
  184. package/src/v2/components/A2UISurfaceActivityRenderer.vue +68 -103
  185. package/src/v2/components/CopilotKitInspector.vue +104 -51
  186. package/src/v2/components/InlineFeatureWarning.vue +20 -21
  187. package/src/v2/components/LicenseWarningBanner.vue +27 -135
  188. package/src/v2/components/MCPAppsActivityRenderer.ts +75 -201
  189. package/src/v2/components/OpenGenerativeUIRenderer.ts +122 -446
  190. package/src/v2/components/__tests__/A2UIMessageRenderer.test.ts +171 -8
  191. package/src/v2/components/__tests__/CopilotKitInspector.test.ts +42 -0
  192. package/src/v2/components/__tests__/LicenseWarningBanner.test.ts +60 -0
  193. package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.ts +64 -8
  194. package/src/v2/components/__tests__/OpenGenerativeUIToolRenderer.test.ts +38 -0
  195. package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +6 -26
  196. package/src/v2/components/a2ui/A2UICatalogContext.ts +27 -185
  197. package/src/v2/components/a2ui/A2UIRecoveryStates.ts +127 -327
  198. package/src/v2/components/a2ui/catalog.ts +3 -3
  199. package/src/v2/components/a2ui/utils.ts +13 -65
  200. package/src/v2/components/a2ui.ts +15 -22
  201. package/src/v2/components/chat/CopilotChat.vue +121 -498
  202. package/src/v2/components/chat/CopilotChatAssistantMessage.vue +47 -184
  203. package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +36 -55
  204. package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +14 -6
  205. package/src/v2/components/chat/CopilotChatAudioRecorder.vue +19 -246
  206. package/src/v2/components/chat/CopilotChatFeedbackCommentPopover.vue +12 -77
  207. package/src/v2/components/chat/CopilotChatInput.vue +139 -654
  208. package/src/v2/components/chat/CopilotChatInspectorButton.vue +45 -108
  209. package/src/v2/components/chat/CopilotChatLightbox.vue +10 -31
  210. package/src/v2/components/chat/CopilotChatMessageView.vue +96 -274
  211. package/src/v2/components/chat/CopilotChatReasoningMessage.vue +27 -62
  212. package/src/v2/components/chat/CopilotChatToolCallGroup.vue +63 -71
  213. package/src/v2/components/chat/CopilotChatToolCallItem.vue +8 -6
  214. package/src/v2/components/chat/CopilotChatToolCallsView.vue +31 -32
  215. package/src/v2/components/chat/CopilotChatUserMessage.vue +24 -112
  216. package/src/v2/components/chat/CopilotChatView.vue +123 -161
  217. package/src/v2/components/chat/CopilotChatWorkSummary.vue +26 -36
  218. package/src/v2/components/chat/CopilotModalHeader.vue +11 -23
  219. package/src/v2/components/chat/CopilotPopup.vue +23 -25
  220. package/src/v2/components/chat/CopilotPopupView.vue +10 -39
  221. package/src/v2/components/chat/CopilotPopupViewInternal.vue +49 -185
  222. package/src/v2/components/chat/CopilotSidebar.vue +23 -25
  223. package/src/v2/components/chat/CopilotSidebarView.vue +10 -39
  224. package/src/v2/components/chat/CopilotSidebarViewInternal.vue +56 -100
  225. package/src/v2/components/chat/CopilotThreadsDrawer.vue +43 -105
  226. package/src/v2/components/chat/StreamingMarkdownDefault.vue +15 -28
  227. package/src/v2/components/chat/__tests__/CopilotChat.labels.test.ts +19 -4
  228. package/src/v2/components/chat/__tests__/CopilotChat.test.ts +12 -10
  229. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.ts +26 -9
  230. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.learningFeedback.test.ts +5 -5
  231. package/src/v2/components/chat/__tests__/CopilotChatAttachmentQueue.test.ts +28 -0
  232. package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +132 -1
  233. package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.ts +247 -403
  234. package/src/v2/components/chat/__tests__/CopilotChatMessageView.toolCallDisplay.test.ts +1 -99
  235. package/src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.ts +43 -1
  236. package/src/v2/components/chat/__tests__/CopilotPopup.test.ts +90 -1
  237. package/src/v2/components/chat/__tests__/CopilotPopupView.test.ts +19 -0
  238. package/src/v2/components/chat/__tests__/CopilotSidebar.test.ts +90 -1
  239. package/src/v2/components/chat/__tests__/CopilotSidebarView.position.test.ts +32 -8
  240. package/src/v2/components/chat/__tests__/CopilotSidebarView.test.ts +2 -1
  241. package/src/v2/components/chat/__tests__/StreamingMarkdownDefault.test.ts +54 -0
  242. package/src/v2/components/chat/audioRecorder.ts +4 -7
  243. package/src/v2/components/chat/copilotChatToolCallItemRender.ts +25 -90
  244. package/src/v2/components/chat/forwarded-slots.ts +17 -0
  245. package/src/v2/components/chat/index.ts +0 -1
  246. package/src/v2/components/chat/inspector-shortcuts.ts +10 -16
  247. package/src/v2/components/chat/message-feedback.ts +92 -195
  248. package/src/v2/components/chat/tool-call-display-context.ts +6 -22
  249. package/src/v2/components/chat/tool-call-group-parts.ts +47 -108
  250. package/src/v2/components/chat/turn-work.ts +0 -9
  251. package/src/v2/components/chat/types.ts +12 -4
  252. package/src/v2/components/chat/use-chat-labels.ts +16 -0
  253. package/src/v2/components/chat/use-copy-feedback.ts +21 -0
  254. package/src/v2/components/chat/use-lightbox.ts +15 -33
  255. package/src/v2/components/icons/__tests__/icons.test.ts +72 -68
  256. package/src/v2/components/icons/index.ts +109 -27
  257. package/src/v2/hooks/__tests__/use-agent-error-state.test.ts +5 -3
  258. package/src/v2/hooks/__tests__/use-agent-stability.test.ts +25 -4
  259. package/src/v2/hooks/__tests__/use-agent-throttle.test.ts +5 -1
  260. package/src/v2/hooks/__tests__/use-agent.test.ts +6 -3
  261. package/src/v2/hooks/__tests__/use-component.test.ts +21 -0
  262. package/src/v2/hooks/__tests__/use-configure-suggestions.test.ts +30 -1
  263. package/src/v2/hooks/__tests__/use-default-render-tool.test.ts +10 -10
  264. package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.ts +66 -1
  265. package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.ts +6 -1
  266. package/src/v2/hooks/__tests__/use-human-in-the-loop.test.ts +187 -12
  267. package/src/v2/hooks/__tests__/use-interrupt.test.ts +97 -0
  268. package/src/v2/hooks/__tests__/use-render-activity-message.test.ts +106 -0
  269. package/src/v2/hooks/__tests__/use-render-tool.test.ts +3 -6
  270. package/src/v2/hooks/__tests__/use-threads.test.ts +48 -6
  271. package/src/v2/hooks/__tests__/zod-regression.test.ts +5 -4
  272. package/src/v2/hooks/use-agent-context.ts +4 -10
  273. package/src/v2/hooks/use-agent.ts +86 -290
  274. package/src/v2/hooks/use-attachments.ts +48 -168
  275. package/src/v2/hooks/use-capabilities.ts +2 -7
  276. package/src/v2/hooks/use-component.ts +7 -4
  277. package/src/v2/hooks/use-configure-suggestions.ts +29 -220
  278. package/src/v2/hooks/use-default-render-tool.ts +31 -152
  279. package/src/v2/hooks/use-frontend-tool.ts +15 -25
  280. package/src/v2/hooks/use-human-in-the-loop.ts +11 -80
  281. package/src/v2/hooks/use-interrupt.ts +29 -308
  282. package/src/v2/hooks/use-keyboard-height.ts +17 -40
  283. package/src/v2/hooks/use-pin-to-send.ts +15 -99
  284. package/src/v2/hooks/use-render-activity-message.ts +35 -57
  285. package/src/v2/hooks/use-render-custom-messages.ts +24 -88
  286. package/src/v2/hooks/use-render-tool.ts +2 -4
  287. package/src/v2/hooks/use-suggestions.ts +17 -36
  288. package/src/v2/hooks/use-threads.ts +49 -288
  289. package/src/v2/lib/__tests__/shallow-stable.test.ts +54 -0
  290. package/src/v2/lib/__tests__/vue-core-renderers.test.ts +42 -0
  291. package/src/v2/lib/processPartialHtml.ts +6 -21
  292. package/src/v2/lib/shallow-stable.ts +2 -16
  293. package/src/v2/lib/vue-core.ts +90 -85
  294. package/src/v2/providers/CopilotChatConfigurationProvider.vue +48 -186
  295. package/src/v2/providers/CopilotKitProvider.types.ts +12 -132
  296. package/src/v2/providers/CopilotKitProvider.vue +291 -641
  297. package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.ts +22 -2
  298. package/src/v2/providers/__tests__/CopilotKitProvider.a2ui.test.ts +38 -2
  299. package/src/v2/providers/__tests__/CopilotKitProvider.config.test.ts +124 -0
  300. package/src/v2/providers/__tests__/CopilotKitProvider.headersAtSendTime.test.ts +3 -3
  301. package/src/v2/providers/__tests__/CopilotKitProvider.learning.test.ts +3 -1
  302. package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.ts +4 -1
  303. package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +88 -28
  304. package/src/v2/providers/chat-configuration-store-key.ts +9 -0
  305. package/src/v2/providers/markdown-renderer.ts +8 -2
  306. package/src/v2/providers/types.ts +3 -49
  307. package/src/v2/providers/use-inspector-thread-override.ts +22 -80
  308. package/src/v2/types/__tests__/defineToolCallRenderer.test.ts +28 -33
  309. package/src/v2/types/defineToolCallRenderer.ts +7 -6
  310. package/src/v2/types/human-in-the-loop.ts +8 -32
  311. package/src/v2/types/interrupt.ts +7 -31
  312. package/src/v2/types/vue-activity-message-renderer.ts +24 -15
  313. package/src/v2/types/vue-custom-message-renderer.ts +12 -16
  314. package/src/v2/types/vue-tool-call-renderer.ts +23 -38
  315. package/tsconfig.json +0 -1
  316. package/vite.config.ts +8 -5
  317. package/vitest.config.ts +12 -7
  318. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts +0 -9
  319. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts.map +0 -1
  320. package/dist/v2/components/chat/normalize-auto-scroll.d.ts +0 -3
  321. package/dist/v2/components/chat/normalize-auto-scroll.d.ts.map +0 -1
  322. package/dist/v2/components/chat/tool-call-layout.d.ts +0 -115
  323. package/dist/v2/components/chat/tool-call-layout.d.ts.map +0 -1
  324. package/dist/v2/lib/is-mobile-viewport.d.ts +0 -15
  325. package/dist/v2/lib/is-mobile-viewport.d.ts.map +0 -1
  326. package/dist/v2/lib/message-feedback.d.ts +0 -33
  327. package/dist/v2/lib/message-feedback.d.ts.map +0 -1
  328. package/dist/v2/lib/transcription-client.d.ts +0 -19
  329. package/dist/v2/lib/transcription-client.d.ts.map +0 -1
  330. package/src/v2/components/__tests__/A2UICatalogContext.test.ts +0 -63
  331. package/src/v2/components/a2ui/__tests__/A2UIRecoveryStates.test.ts +0 -175
  332. package/src/v2/components/chat/BasicMarkdown.vue +0 -160
  333. package/src/v2/components/chat/__tests__/BasicMarkdown.test.ts +0 -69
  334. package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +0 -39
  335. package/src/v2/components/chat/normalize-auto-scroll.ts +0 -17
  336. package/src/v2/components/chat/tool-call-layout.ts +0 -304
  337. package/src/v2/lib/__tests__/is-mobile-viewport.test.ts +0 -48
  338. package/src/v2/lib/__tests__/message-feedback.test.ts +0 -152
  339. package/src/v2/lib/__tests__/processPartialHtml.test.ts +0 -84
  340. package/src/v2/lib/__tests__/transcription-client.test.ts +0 -67
  341. package/src/v2/lib/is-mobile-viewport.ts +0 -23
  342. package/src/v2/lib/message-feedback.ts +0 -120
  343. package/src/v2/lib/transcription-client.ts +0 -151
@@ -1,41 +1,52 @@
1
1
  <script setup lang="ts">
2
- import {
3
- GENERATE_SANDBOXED_UI_DESCRIPTION,
4
- randomUUID,
5
- } from "@copilotkit/shared";
6
2
  import {
7
3
  computed,
8
4
  h,
9
5
  onMounted,
6
+ onUnmounted,
10
7
  provide,
11
8
  ref,
12
9
  shallowRef,
10
+ toRaw,
13
11
  triggerRef,
14
12
  watch,
15
13
  } from "vue";
16
14
  import type { Component, FunctionalComponent } from "vue";
17
- import { z } from "zod";
18
- import type { AbstractAgent } from "@ag-ui/client";
19
- import { ToolCallStatus } from "@copilotkit/core";
15
+ import type { Catalog, ComponentApi } from "@a2ui/web_core/v0_9";
16
+ import {
17
+ ɵLearningAutoStarter,
18
+ ɵassembleActivityRenderers,
19
+ ɵassembleHumanInTheLoop,
20
+ ɵassembleProviderToolRenderers,
21
+ ɵassembleProviderTools,
22
+ ɵhitlRenderProps,
23
+ ɵresolveA2UIActivation,
24
+ ɵstableArrayPropWarning,
25
+ ɵtoLearningConfig,
26
+ } from "@copilotkit/core";
20
27
  import type {
21
- CopilotKitCoreErrorCode,
22
- CopilotKitCoreSubscriber,
23
28
  CopilotKitHeadersSource,
24
29
  FrontendTool,
30
+ ɵHumanInTheLoopRegistry,
31
+ ɵRuntimeInfo,
32
+ ɵStableArrayProp,
25
33
  } from "@copilotkit/core";
26
- import { ɵwithHeaderDefaults } from "@copilotkit/core";
27
- import { schemaToJsonSchema, shouldEnableInspector } from "@copilotkit/shared";
28
- import type {
29
- RuntimeEntitlementResponse,
30
- RuntimeLicenseStatus,
31
- } from "@copilotkit/shared";
32
- import { zodToJsonSchema } from "zod-to-json-schema";
34
+ import {
35
+ ɵaddOpenGenerativeUIContexts,
36
+ ɵcreateOpenGenerativeUITool,
37
+ ɵisOpenGenerativeUIActive,
38
+ ɵpublicKeyHeaderDefaults,
39
+ ɵreportProviderConfigDiagnostics,
40
+ ɵresolveLicenseState,
41
+ ɵresolveProviderConfig,
42
+ ɵwithHeaderDefaults,
43
+ } from "@copilotkit/core";
44
+ import { shouldEnableInspector } from "@copilotkit/shared";
33
45
  import { CopilotKitCoreVue } from "../lib/vue-core";
34
46
  import { createA2UIMessageRenderer } from "../components/A2UIMessageRenderer";
35
47
  import { registerA2UIBuiltInToolCallRenderer } from "../components/a2ui/A2UIBuiltInToolCallRenderer";
36
- import { registerA2UICatalogContext } from "../components/a2ui/A2UICatalogContext";
48
+ import { registerA2UICatalog } from "../components/a2ui/A2UICatalogContext";
37
49
  import {
38
- GenerateSandboxedUiArgsSchema,
39
50
  OpenGenerativeUIActivityRenderer,
40
51
  OpenGenerativeUIActivityType,
41
52
  OpenGenerativeUIContentSchema,
@@ -54,17 +65,10 @@ import {
54
65
  } from "./keys";
55
66
  import type { VueInspectorOpenRequest } from "./keys";
56
67
  import { MARKDOWN_RENDERER_KEY } from "./markdown-renderer";
57
- import {
58
- LicenseContextKey,
59
- createLicenseContextValue,
60
- } from "./license-context";
61
- import type { LicenseContextValue } from "./license-context";
68
+ import { LicenseContextKey } from "./license-context";
62
69
  import CopilotKitInspector from "../components/CopilotKitInspector.vue";
63
70
  import LicenseWarningBanner from "../components/LicenseWarningBanner.vue";
64
- import type {
65
- CopilotKitLearningOptions,
66
- CopilotKitProviderProps,
67
- } from "./CopilotKitProvider.types";
71
+ import type { CopilotKitProviderProps } from "./CopilotKitProvider.types";
68
72
  import type {
69
73
  SandboxFunction,
70
74
  VueActivityMessageRenderer,
@@ -73,37 +77,6 @@ import type {
73
77
  VueToolCallRendererRenderProps,
74
78
  } from "../types";
75
79
 
76
- const HEADER_NAME = "X-CopilotCloud-Public-Api-Key";
77
- const COPILOT_CLOUD_CHAT_URL = "https://api.cloud.copilotkit.ai/copilotkit/v1";
78
- // Canonical A2UI viewer theme default (matches @copilotkit/a2ui-renderer).
79
- // Defined locally to avoid pulling React dependencies from a2ui-renderer.
80
- const viewerTheme: Record<string, unknown> = {};
81
-
82
- const FRONTEND_TOOLS_STABLE_WARNING =
83
- "frontendTools must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.";
84
- const HUMAN_IN_THE_LOOP_STABLE_WARNING =
85
- "humanInTheLoop must be a stable array. If you want to dynamically add or remove human-in-the-loop tools, use `useHumanInTheLoop` instead.";
86
- const RENDER_CUSTOM_MESSAGES_STABLE_WARNING =
87
- "renderCustomMessages must be a stable array.";
88
- const RENDER_ACTIVITY_MESSAGES_STABLE_WARNING =
89
- "renderActivityMessages must be a stable array.";
90
- const SANDBOX_FUNCTIONS_STABLE_WARNING =
91
- "openGenerativeUI.sandboxFunctions must be a stable array.";
92
- // Matches the message React's `useHumanInTheLoop` rejects with, so an aborted
93
- // interrupt reads the same across frameworks (see #5554).
94
- const HUMAN_IN_THE_LOOP_ABORTED_MESSAGE =
95
- "Human-in-the-loop interaction aborted";
96
- const DEFAULT_DESIGN_SKILL = `When generating UI with generateSandboxedUi, follow these design principles inspired by shadcn/ui:
97
-
98
- - Use a minimal, flat aesthetic. Avoid drop shadows and gradients — rely on subtle borders (1px solid, light gray like #e5e7eb) to define surfaces.
99
- - Neutral base palette: white backgrounds, zinc/slate gray text (#09090b for headings, #71717a for secondary text). One accent color for interactive elements.
100
- - Use system font stacks (system-ui, -apple-system, sans-serif) at readable sizes (14px body, 600 weight for headings). Tight line-heights.
101
- - Small, consistent border-radius (6–8px). Cards and containers use border, not shadow, for separation.
102
- - Buttons: solid fill for primary (dark bg, white text), outline for secondary (border + transparent bg). Subtle hover state (slight opacity or background shift).
103
- - Use CSS Grid or Flexbox for layout. Ensure the UI looks good at any width.
104
- - Minimal transitions (150ms) for hover/focus states only. No decorative animations.
105
- - Keep the UI focused and dense — avoid excessive padding. Use compact spacing (8–12px gaps, 10–14px padding in controls).`;
106
-
107
80
  /** The MCP Apps renderer with `mcpApps.allowSameOriginFallback` applied. */
108
81
  const SameOriginMCPAppsActivityRenderer: FunctionalComponent = (_, { attrs }) =>
109
82
  h(MCPAppsActivityRenderer as Component, {
@@ -137,12 +110,16 @@ provide(
137
110
  );
138
111
 
139
112
  const shouldRenderInspector = ref(false);
113
+ // Follows the Inspector's own show/hide, so message actions that open it are
114
+ // hidden while a temporary dismissal hides it.
115
+ const inspectorVisible = ref(false);
140
116
 
141
117
  function updateInspectorVisibility(): void {
142
118
  shouldRenderInspector.value = shouldEnableInspector({
143
119
  enableInspector: props.enableInspector,
144
120
  isBrowser: true,
145
121
  isDevelopment: process.env.NODE_ENV === "development",
122
+ hostname: window.location?.hostname,
146
123
  });
147
124
  }
148
125
 
@@ -150,7 +127,9 @@ onMounted(updateInspectorVisibility);
150
127
  watch(() => props.enableInspector, updateInspectorVisibility);
151
128
 
152
129
  const inspectorOpenRequest = ref<VueInspectorOpenRequest | null>(null);
153
- const isInspectorEnabled = computed(() => shouldRenderInspector.value);
130
+ const isInspectorEnabled = computed(
131
+ () => shouldRenderInspector.value && inspectorVisible.value,
132
+ );
154
133
 
155
134
  function openInspector(request: VueInspectorOpenRequest) {
156
135
  inspectorOpenRequest.value = { ...request };
@@ -161,67 +140,56 @@ provide(InspectorKey, {
161
140
  openInspector,
162
141
  });
163
142
 
164
- const initialFrontendTools = props.frontendTools;
165
- const initialHumanInTheLoop = props.humanInTheLoop;
166
- const initialRenderCustomMessages = props.renderCustomMessages;
167
- const initialRenderActivityMessages = props.renderActivityMessages;
168
- const initialSandboxFunctions = props.openGenerativeUI?.sandboxFunctions;
169
-
170
- watch(
171
- () => props.frontendTools,
172
- (next) => {
173
- if (next !== initialFrontendTools) {
174
- console.error(FRONTEND_TOOLS_STABLE_WARNING);
175
- }
176
- },
177
- );
178
-
179
- watch(
180
- () => props.humanInTheLoop,
181
- (next) => {
182
- if (next !== initialHumanInTheLoop) {
183
- console.error(HUMAN_IN_THE_LOOP_STABLE_WARNING);
184
- }
185
- },
186
- );
187
-
188
- watch(
189
- () => props.renderCustomMessages,
190
- (next) => {
191
- if (next !== initialRenderCustomMessages) {
192
- console.error(RENDER_CUSTOM_MESSAGES_STABLE_WARNING);
193
- }
194
- },
195
- );
196
-
197
- watch(
198
- () => props.renderActivityMessages,
199
- (next) => {
200
- if (next !== initialRenderActivityMessages) {
201
- console.error(RENDER_ACTIVITY_MESSAGES_STABLE_WARNING);
202
- }
203
- },
204
- );
205
-
206
- watch(
207
- () => props.openGenerativeUI?.sandboxFunctions,
208
- (next) => {
209
- if (next !== initialSandboxFunctions) {
210
- console.error(SANDBOX_FUNCTIONS_STABLE_WARNING);
211
- }
212
- },
213
- );
143
+ // Props that come from reactive state arrive as deep proxies. Zod 4 schemas
144
+ // break behind a Vue proxy (their `_zod` property is read-only and
145
+ // non-configurable), so read tools and renderers through their raw objects.
146
+ const rawEntries = <T>(entries: readonly T[] | undefined): T[] =>
147
+ [...toRaw(entries ?? [])].map((entry) => toRaw(entry));
148
+
149
+ // Array props must keep their identity; core decides when a change warns
150
+ // (for `renderToolCalls`, only a change of the agentId:name pairs).
151
+ const stableArrayProps: Record<
152
+ ɵStableArrayProp,
153
+ () => readonly unknown[] | undefined
154
+ > = {
155
+ renderToolCalls: () => props.renderToolCalls,
156
+ frontendTools: () => props.frontendTools,
157
+ humanInTheLoop: () => props.humanInTheLoop,
158
+ renderCustomMessages: () => props.renderCustomMessages,
159
+ renderActivityMessages: () => props.renderActivityMessages,
160
+ sandboxFunctions: () => props.openGenerativeUI?.sandboxFunctions,
161
+ };
162
+ for (const [name, read] of Object.entries(stableArrayProps)) {
163
+ const initial = read();
164
+ watch(read, (next) => {
165
+ const warning = ɵstableArrayPropWarning(
166
+ name as ɵStableArrayProp,
167
+ initial,
168
+ next,
169
+ );
170
+ if (warning) console.error(warning);
171
+ });
172
+ }
214
173
 
215
- const resolvedPublicKey = computed(
216
- () => props.publicApiKey ?? props.publicLicenseKey,
217
- );
218
- const mergedAgents = computed(() => ({
219
- ...props.agents__unsafe_dev_only,
220
- ...props.selfManagedAgents,
221
- }));
222
- const hasLocalAgents = computed(
223
- () => Object.keys(mergedAgents.value).length > 0,
224
- );
174
+ // Key fallback, Copilot Cloud URL, transport, agent merge and the catalog
175
+ // property all come from core.
176
+ const resolvedConfig = computed(() =>
177
+ ɵresolveProviderConfig({
178
+ runtimeUrl: props.runtimeUrl,
179
+ publicApiKey: props.publicApiKey,
180
+ publicLicenseKey: props.publicLicenseKey,
181
+ useSingleEndpoint: props.useSingleEndpoint,
182
+ agents__unsafe_dev_only: props.agents__unsafe_dev_only,
183
+ selfManagedAgents: props.selfManagedAgents,
184
+ properties: props.properties,
185
+ a2uiCatalog: props.a2ui?.catalog,
186
+ }),
187
+ );
188
+ // Strings, so dependents only re-run when the value really changes.
189
+ const resolvedPublicKey = computed(() => resolvedConfig.value.publicKey);
190
+ const chatApiEndpoint = computed(() => resolvedConfig.value.runtimeUrl);
191
+ const runtimeTransport = computed(() => resolvedConfig.value.runtimeTransport);
192
+ const mergedAgents = computed(() => resolvedConfig.value.agents);
225
193
 
226
194
  // Whether `headers` is a builder, as its own computed so that a re-render
227
195
  // merely passing a NEW function of the same kind (e.g. a fresh inline arrow)
@@ -250,294 +218,158 @@ const latestHeaders = (() =>
250
218
  const headersSource = computed<CopilotKitHeadersSource>(() =>
251
219
  ɵwithHeaderDefaults(
252
220
  isHeadersBuilder.value ? latestHeaders : props.headers,
253
- resolvedPublicKey.value ? { [HEADER_NAME]: resolvedPublicKey.value } : {},
221
+ ɵpublicKeyHeaderDefaults(resolvedPublicKey.value),
254
222
  ),
255
223
  );
256
224
 
257
- const chatApiEndpoint = computed(
258
- () =>
259
- props.runtimeUrl ??
260
- (resolvedPublicKey.value ? COPILOT_CLOUD_CHAT_URL : undefined),
261
- );
262
-
225
+ // Throws in production for a missing runtime config; otherwise warns, once
226
+ // per provider for each message.
227
+ const loggedDiagnostics = new Set<string>();
263
228
  watch(
264
- [chatApiEndpoint, resolvedPublicKey, hasLocalAgents],
265
- ([endpoint, publicKey, localAgents]) => {
266
- if (endpoint || publicKey || localAgents) return;
267
- const msg =
268
- "Missing required prop: 'runtimeUrl' or 'publicApiKey' or 'publicLicenseKey'";
269
- if (process.env.NODE_ENV === "production") {
270
- throw new Error(msg);
271
- }
272
- console.warn(msg);
229
+ () => resolvedConfig.value.diagnostics,
230
+ (diagnostics) => {
231
+ ɵreportProviderConfigDiagnostics(diagnostics, {
232
+ isProduction: process.env.NODE_ENV === "production",
233
+ logged: loggedDiagnostics,
234
+ });
273
235
  },
274
236
  { immediate: true },
275
237
  );
276
238
 
277
- /**
278
- * A human-in-the-loop tool call from the `humanInTheLoop` prop that is waiting
279
- * on the user. Keyed by tool call id so parallel interrupts on the same tool
280
- * stay independent.
281
- */
282
- type PendingHumanInTheLoop = {
283
- resolve: (result: unknown) => void;
284
- detachAbort?: () => void;
285
- };
286
-
287
- const pendingHumanInTheLoop = new Map<string, PendingHumanInTheLoop>();
288
-
289
- /** Removes a pending interaction and detaches its abort listener. */
290
- const takePendingHumanInTheLoop = (key: string) => {
291
- const pending = pendingHumanInTheLoop.get(key);
292
- if (!pending) return undefined;
293
- pending.detachAbort?.();
294
- pendingHumanInTheLoop.delete(key);
295
- return pending;
296
- };
297
-
298
- const processedHumanInTheLoop = computed(() => {
299
- const tools: FrontendTool[] = [];
300
- const renderToolCalls: VueToolCallRenderer<unknown>[] = [];
301
-
302
- for (const tool of props.humanInTheLoop) {
303
- tools.push({
304
- type: "human-in-the-loop",
305
- name: tool.name,
306
- description: tool.description,
307
- parameters: tool.parameters,
308
- followUp: tool.followUp,
309
- ...(tool.agentId && { agentId: tool.agentId }),
310
- // Keep the tool call pending until the render calls `respond`, matching
311
- // the `useHumanInTheLoop` composable. Resolving immediately made the HITL
312
- // UI flash and disappear without ever waiting for the user.
313
- handler: async (_args, context) => {
314
- const signal = context?.signal;
315
- const key = context?.toolCall?.id ?? tool.name;
316
-
317
- return new Promise((resolve, reject) => {
318
- // Already aborted before the handler ran — reject so core records an
319
- // explicit error tool result rather than silently resolving empty.
320
- if (signal?.aborted) {
321
- reject(new Error(HUMAN_IN_THE_LOOP_ABORTED_MESSAGE));
322
- return;
323
- }
324
-
325
- const pending: PendingHumanInTheLoop = { resolve };
326
- pendingHumanInTheLoop.set(key, pending);
327
-
328
- if (signal) {
329
- const onAbort = () => {
330
- pendingHumanInTheLoop.delete(key);
331
- reject(new Error(HUMAN_IN_THE_LOOP_ABORTED_MESSAGE));
332
- };
333
- signal.addEventListener("abort", onAbort, { once: true });
334
- pending.detachAbort = () => {
335
- signal.removeEventListener("abort", onAbort);
336
- };
337
- }
338
- });
339
- },
340
- });
341
- if (tool.render) {
342
- const ToolComponent = tool.render;
343
- const render: VueToolCallRenderer<unknown>["render"] = (
344
- renderProps: VueToolCallRendererRenderProps<unknown>,
345
- ) => {
346
- const key = renderProps.toolCallId ?? tool.name;
347
- return h(ToolComponent as Parameters<typeof h>[0], {
348
- ...renderProps,
349
- // `renderProps.name` is the tool that was actually invoked. It equals
350
- // `tool.name` for a named registration; for a wildcard (`"*"`) it is
351
- // the only place the real name exists.
352
- name: tool.name === "*" ? renderProps.name : tool.name,
353
- description: tool.description || "",
354
- agentId: tool.agentId,
355
- // `respond` is live only while the tool is executing — the one phase
356
- // with a promise waiting on the user.
357
- respond:
358
- renderProps.status === ToolCallStatus.Executing
359
- ? async (result: unknown) => {
360
- takePendingHumanInTheLoop(key)?.resolve(result);
361
- }
362
- : undefined,
363
- });
364
- };
365
-
366
- renderToolCalls.push({
367
- name: tool.name,
368
- args: tool.parameters ?? z.any(),
369
- render,
370
- ...(tool.agentId && { agentId: tool.agentId }),
371
- } as VueToolCallRenderer<unknown>);
372
- }
373
- }
374
- return { tools, renderToolCalls };
375
- });
376
-
377
- const allTools = computed(() => {
378
- const tools: FrontendTool[] = [];
379
- for (const t of props.frontendTools) {
380
- tools.push(t as FrontendTool);
381
- }
382
- for (const t of builtInFrontendTools.value) {
383
- tools.push(t as FrontendTool);
384
- }
385
- tools.push(...processedHumanInTheLoop.value.tools);
386
- return tools;
387
- });
388
-
389
- const allRenderToolCalls = computed(() => {
390
- const combined: VueToolCallRenderer<unknown>[] = [
391
- ...(props.renderToolCalls ?? []),
392
- ];
393
- for (const tool of [...props.frontendTools, ...builtInFrontendTools.value]) {
394
- if (tool.render) {
395
- const args = tool.parameters ?? (tool.name === "*" ? z.any() : undefined);
396
- if (args) {
397
- combined.push({
398
- name: tool.name,
399
- args,
400
- render: tool.render,
401
- } as VueToolCallRenderer<unknown>);
402
- }
403
- }
404
- }
405
- combined.push(...processedHumanInTheLoop.value.renderToolCalls);
406
- return combined;
407
- });
239
+ type FrontendToolRender = NonNullable<VueFrontendTool["render"]>;
240
+
241
+ // The tools and tool-call renderers for core (assembly rules from core).
242
+ // Human-in-the-loop renders are wrapped once per `humanInTheLoop` change: a
243
+ // new wrapper is a new component type, so Vue would remount the card.
244
+ const humanInTheLoopAssembly = computed(() =>
245
+ ɵassembleHumanInTheLoop<FrontendToolRender, unknown>({
246
+ humanInTheLoop: rawEntries(props.humanInTheLoop),
247
+ // Core parks each call by tool call id until the render responds. The core
248
+ // is created further down, so read its registry lazily.
249
+ humanInTheLoopRegistry: (): ɵHumanInTheLoopRegistry =>
250
+ copilotkit.value.ɵhumanInTheLoop,
251
+ wrapHumanInTheLoopRender: (ToolComponent, tool, registry) =>
252
+ ((renderProps: VueToolCallRendererRenderProps<unknown>) =>
253
+ h(
254
+ ToolComponent as Parameters<typeof h>[0],
255
+ ɵhitlRenderProps(renderProps, tool, registry()),
256
+ )) as FrontendToolRender,
257
+ }),
258
+ );
259
+ const allTools = computed<FrontendTool[]>(() =>
260
+ ɵassembleProviderTools({
261
+ frontendTools: rawEntries(props.frontendTools),
262
+ builtInFrontendTools: builtInFrontendTools.value,
263
+ humanInTheLoop: humanInTheLoopAssembly.value,
264
+ }),
265
+ );
266
+ const allRenderToolCalls = computed(
267
+ () =>
268
+ ɵassembleProviderToolRenderers({
269
+ renderToolCalls: rawEntries(props.renderToolCalls),
270
+ frontendTools: rawEntries(props.frontendTools),
271
+ builtInFrontendTools: builtInFrontendTools.value,
272
+ humanInTheLoop: humanInTheLoopAssembly.value,
273
+ }) as VueToolCallRenderer<unknown>[],
274
+ );
408
275
 
409
276
  const allRenderCustomMessages = computed(
410
277
  () => props.renderCustomMessages ?? [],
411
278
  );
412
- const runtimeA2UIEnabled = ref(false);
413
- const runtimeOpenGenerativeUIEnabled = ref(false);
414
- const runtimeLicenseStatus = ref<RuntimeLicenseStatus | undefined>(undefined);
415
- const runtimeEntitlements = ref<RuntimeEntitlementResponse | undefined>(
416
- undefined,
279
+ // Core's runtime info snapshot, projected from the core watcher below.
280
+ const runtimeInfo = shallowRef<ɵRuntimeInfo | null>(null);
281
+ const runtimeA2UIEnabled = computed(
282
+ () => runtimeInfo.value?.a2uiEnabled ?? false,
283
+ );
284
+ const runtimeOpenGenerativeUIEnabled = computed(
285
+ () => runtimeInfo.value?.openGenerativeUIEnabled ?? false,
286
+ );
287
+ const runtimeLicenseStatus = computed(() => runtimeInfo.value?.licenseStatus);
288
+ const runtimeEntitlements = computed(
289
+ () => runtimeInfo.value?.runtimeEntitlements,
290
+ );
291
+ const runtimeEntitlementRetryPending = computed(
292
+ () => runtimeInfo.value?.runtimeEntitlementRetryPending ?? false,
417
293
  );
418
- const runtimeEntitlementRetryPending = ref(false);
419
- const openGenerativeUIActive = computed(
420
- () => runtimeOpenGenerativeUIEnabled.value || !!props.openGenerativeUI,
294
+ const openGenerativeUIActive = computed(() =>
295
+ ɵisOpenGenerativeUIActive({
296
+ runtimeEnabled: runtimeOpenGenerativeUIEnabled.value,
297
+ configured: !!props.openGenerativeUI,
298
+ }),
421
299
  );
422
300
  // A catalog passed to the provider is enough to turn A2UI on: render the
423
301
  // surfaces locally and forward the catalog signal so the runtime injects the
424
302
  // render tool — no runtime-side `a2ui` config required.
425
- const a2uiCatalogProvided = computed(() => !!props.a2ui?.catalog);
426
303
  const a2uiActive = computed(
427
- () => runtimeA2UIEnabled.value || a2uiCatalogProvided.value,
304
+ () =>
305
+ ɵresolveA2UIActivation({
306
+ runtimeEnabled: runtimeA2UIEnabled.value,
307
+ hasCatalog: !!props.a2ui?.catalog,
308
+ }).active,
309
+ );
310
+ // The catalog with components disabled in the Inspector removed; set by
311
+ // `registerA2UICatalog` below once the core exists.
312
+ const a2uiFilteredCatalog = shallowRef<Catalog<ComponentApi> | undefined>(
313
+ undefined,
428
314
  );
429
315
  // Forward a per-run signal when the provider has an A2UI catalog so the
430
316
  // runtime can turn A2UI on (and inject the render tool) without a separate
431
317
  // `a2ui.injectA2UITool` flag on the runtime.
432
- const resolvedProperties = computed(() =>
433
- a2uiCatalogProvided.value
434
- ? { ...props.properties, a2uiCatalogAvailable: true }
435
- : props.properties,
318
+ const resolvedProperties = computed(() => resolvedConfig.value.properties);
319
+ const sandboxFunctions = computed<readonly SandboxFunction[]>(() =>
320
+ rawEntries(props.openGenerativeUI?.sandboxFunctions),
436
321
  );
437
- const sandboxFunctions = computed<readonly SandboxFunction[]>(
438
- () => props.openGenerativeUI?.sandboxFunctions ?? [],
439
- );
440
- const zodToJsonSchemaCompat = (
441
- schema: unknown,
442
- options?: { $refStrategy?: string },
443
- ): Record<string, unknown> =>
444
- zodToJsonSchema(
445
- schema as z.ZodTypeAny,
446
- options as { $refStrategy?: "none" | "relative" | "root" | "seen" },
447
- ) as Record<string, unknown>;
448
-
449
322
  const builtInFrontendTools = computed<VueFrontendTool[]>(() => {
450
323
  if (!openGenerativeUIActive.value) return [];
451
324
  return [
452
325
  {
453
- name: "generateSandboxedUi",
454
- description: GENERATE_SANDBOXED_UI_DESCRIPTION,
455
- parameters: GenerateSandboxedUiArgsSchema,
456
- handler: async () => "UI generated",
457
- // This acknowledgement has no side effects and is safe to reconstruct.
458
- reconnectBehavior: "resume-pending",
459
- followUp: true,
326
+ ...ɵcreateOpenGenerativeUITool(),
460
327
  render:
461
328
  OpenGenerativeUIToolRenderer as unknown as VueFrontendTool["render"],
462
329
  } as VueFrontendTool,
463
330
  ];
464
331
  });
465
332
 
466
- const builtInActivityRenderers = computed<
467
- VueActivityMessageRenderer<unknown>[]
468
- >(() => {
469
- const renderers: VueActivityMessageRenderer<unknown>[] = [
470
- {
471
- activityType: MCPAppsActivityType,
472
- content: MCPAppsActivityContentSchema as unknown as z.ZodSchema<unknown>,
473
- render: (props.mcpApps?.allowSameOriginFallback
474
- ? SameOriginMCPAppsActivityRenderer
475
- : MCPAppsActivityRenderer) as unknown as VueActivityMessageRenderer<unknown>["render"],
476
- },
477
- ];
478
-
479
- if (openGenerativeUIActive.value) {
480
- renderers.push({
481
- activityType: OpenGenerativeUIActivityType,
482
- content: OpenGenerativeUIContentSchema as unknown as z.ZodSchema<unknown>,
483
- render:
484
- OpenGenerativeUIActivityRenderer as unknown as VueActivityMessageRenderer<unknown>["render"],
485
- });
486
- }
487
-
488
- if (a2uiActive.value) {
489
- renderers.unshift(
490
- createA2UIMessageRenderer({
491
- theme: props.a2ui?.theme ?? viewerTheme,
492
- catalog: props.a2ui?.catalog,
493
- loadingComponent: props.a2ui?.loadingComponent,
494
- recovery: props.a2ui?.recovery,
495
- }),
496
- );
497
- }
498
-
499
- return renderers;
500
- });
501
-
502
- const allRenderActivityMessages = computed(() => [
503
- ...(props.renderActivityMessages ?? []),
504
- ...builtInActivityRenderers.value,
505
- ]);
506
-
507
- const applyDefaultThrottleMs = (core: CopilotKitCoreVue) => {
508
- if (
509
- props.defaultThrottleMs !== undefined &&
510
- (!Number.isFinite(props.defaultThrottleMs) || props.defaultThrottleMs < 0)
511
- ) {
512
- console.error(
513
- `CopilotKitProvider: defaultThrottleMs must be a non-negative finite number, got ${props.defaultThrottleMs}. useAgent hooks without an explicit throttleMs will fall back to unthrottled.`,
514
- );
515
- }
516
- core.setDefaultThrottleMs(props.defaultThrottleMs);
517
- };
518
-
519
- function toLearningConfig(
520
- learning: boolean | CopilotKitLearningOptions | undefined,
521
- ): CopilotKitLearningOptions | undefined {
522
- // `true` uses the default authenticated capture options.
523
- if (learning === true) return {};
524
- if (learning === false || learning === undefined) return undefined;
525
- // `autoStart` only controls the provider; Core never receives it.
526
- const { autoStart: _autoStart, ...config } = learning;
527
- return config;
528
- }
333
+ // The app's activity renderers, then the built-in ones (order from core).
334
+ const allRenderActivityMessages = computed(() =>
335
+ ɵassembleActivityRenderers<VueActivityMessageRenderer<unknown>>({
336
+ app: rawEntries(props.renderActivityMessages),
337
+ a2ui: a2uiActive.value
338
+ ? createA2UIMessageRenderer({
339
+ theme: props.a2ui?.theme ?? {},
340
+ catalog: a2uiFilteredCatalog.value ?? props.a2ui?.catalog,
341
+ loadingComponent: props.a2ui?.loadingComponent,
342
+ recovery: props.a2ui?.recovery,
343
+ onAction: props.a2ui?.onAction,
344
+ })
345
+ : undefined,
346
+ builtIns: [
347
+ {
348
+ activityType: MCPAppsActivityType,
349
+ content: MCPAppsActivityContentSchema,
350
+ render: (props.mcpApps?.allowSameOriginFallback
351
+ ? SameOriginMCPAppsActivityRenderer
352
+ : MCPAppsActivityRenderer) as unknown as VueActivityMessageRenderer<unknown>["render"],
353
+ },
354
+ openGenerativeUIActive.value && {
355
+ activityType: OpenGenerativeUIActivityType,
356
+ content: OpenGenerativeUIContentSchema,
357
+ render:
358
+ OpenGenerativeUIActivityRenderer as unknown as VueActivityMessageRenderer<unknown>["render"],
359
+ },
360
+ ],
361
+ }),
362
+ );
529
363
 
530
- const learningConfig = computed(() => toLearningConfig(props.learning));
364
+ const learningConfig = computed(() => ɵtoLearningConfig(props.learning));
531
365
 
532
- const createCopilotKit = () => {
533
- const core = new CopilotKitCoreVue({
366
+ const createCopilotKit = () =>
367
+ new CopilotKitCoreVue({
534
368
  runtimeUrl: chatApiEndpoint.value,
535
- runtimeTransport:
536
- props.useSingleEndpoint === true
537
- ? "single"
538
- : props.useSingleEndpoint === false
539
- ? "rest"
540
- : "auto",
369
+ // `/info` starts from `onMounted` (`connect()` below), so server-side
370
+ // setup never fetches it.
371
+ deferInitialConnection: true,
372
+ runtimeTransport: runtimeTransport.value,
541
373
  headers: headersSource.value,
542
374
  credentials: props.credentials,
543
375
  messageFilter: props.messageFilter,
@@ -548,12 +380,12 @@ const createCopilotKit = () => {
548
380
  renderActivityMessages: allRenderActivityMessages.value,
549
381
  renderCustomMessages: allRenderCustomMessages.value,
550
382
  debug: props.debug,
383
+ // Set at construction so child hooks can read it on first render. Core
384
+ // validates it.
385
+ defaultThrottleMs: props.defaultThrottleMs,
386
+ onError: props.onError,
551
387
  learning: learningConfig.value,
552
388
  });
553
- // Initialize synchronously so child hooks can read the value on first render.
554
- applyDefaultThrottleMs(core);
555
- return core;
556
- };
557
389
 
558
390
  const copilotkit = shallowRef<CopilotKitCoreVue>(createCopilotKit());
559
391
  const didMountRef = ref(false);
@@ -563,27 +395,17 @@ const executingToolCallIds = ref<ReadonlySet<string>>(new Set());
563
395
  watch(
564
396
  copilotkit,
565
397
  (core, _, onCleanup) => {
398
+ // Core keeps a call executing until its result is in the messages, so
399
+ // the status never drops back to in-progress between the two.
400
+ executingToolCallIds.value = core.executingToolCallIds;
566
401
  const sub1 = core.subscribe({
567
- onToolExecutionStart: ({
568
- toolCallId,
569
- }: Parameters<
570
- NonNullable<CopilotKitCoreSubscriber["onToolExecutionStart"]>
571
- >[0]) => {
572
- executingToolCallIds.value = new Set(executingToolCallIds.value).add(
573
- toolCallId,
574
- );
575
- },
576
- onToolExecutionEnd: ({
577
- toolCallId,
578
- }: Parameters<
579
- NonNullable<CopilotKitCoreSubscriber["onToolExecutionEnd"]>
580
- >[0]) => {
581
- setTimeout(() => {
582
- const next = new Set(executingToolCallIds.value);
583
- next.delete(toolCallId);
584
- executingToolCallIds.value = next;
585
- triggerRef(copilotkit);
586
- }, 0);
402
+ onExecutingToolCallsChanged: ({ executingToolCallIds: ids }) => {
403
+ const hasFinishedCall = ids.size < executingToolCallIds.value.size;
404
+ executingToolCallIds.value = ids;
405
+ // Core adds the result to `agent.messages` without a messages event,
406
+ // so re-read the agents once a call finishes. Not on start: that
407
+ // re-runs the agent subscriptions mid-run and drops a pending update.
408
+ if (hasFinishedCall) triggerRef(copilotkit);
587
409
  },
588
410
  });
589
411
  const sub2 = core.subscribe({
@@ -595,27 +417,21 @@ watch(
595
417
  onRenderCustomMessagesChanged: () => {
596
418
  triggerRef(copilotkit);
597
419
  },
420
+ onRenderActivityMessagesChanged: () => {
421
+ triggerRef(copilotkit);
422
+ },
423
+ });
424
+ runtimeInfo.value = core.ɵruntimeInfo;
425
+ const unsubscribeRuntimeInfo = core.ɵsubscribeToRuntimeInfo(() => {
426
+ runtimeInfo.value = core.ɵruntimeInfo;
598
427
  });
428
+ // Consumers read runtime getters off `copilotkit` directly, so every
429
+ // status event invalidates them.
599
430
  const sub4 = core.subscribe({
600
431
  onRuntimeConnectionStatusChanged: () => {
601
- runtimeA2UIEnabled.value = core.a2uiEnabled;
602
- runtimeOpenGenerativeUIEnabled.value = core.openGenerativeUIEnabled;
603
- runtimeLicenseStatus.value = core.licenseStatus;
604
- runtimeEntitlements.value = core.runtimeEntitlements;
605
- runtimeEntitlementRetryPending.value =
606
- core.runtimeEntitlementRetryPending;
607
432
  triggerRef(copilotkit);
608
433
  },
609
434
  });
610
- const sub5 = core.subscribe({
611
- onError: (event) => {
612
- void props.onError?.({
613
- error: event.error,
614
- code: event.code,
615
- context: event.context,
616
- });
617
- },
618
- });
619
435
  // `onHeadersChanged` fires only from a real `setHeaders()` call (a new
620
436
  // source), never from a builder resolving a new token — same generation
621
437
  // core bumps. Without this, nothing pokes Vue's reactivity when a source
@@ -633,7 +449,7 @@ watch(
633
449
  sub2.unsubscribe();
634
450
  sub3.unsubscribe();
635
451
  sub4.unsubscribe();
636
- sub5.unsubscribe();
452
+ unsubscribeRuntimeInfo();
637
453
  sub6.unsubscribe();
638
454
  });
639
455
  },
@@ -653,48 +469,34 @@ watch([allRenderToolCalls], ([renderToolCalls]) => {
653
469
  watch([allRenderCustomMessages], ([renderCustomMessages]) => {
654
470
  if (!didMountRef.value) return;
655
471
  copilotkit.value.setRenderCustomMessages(renderCustomMessages);
656
- triggerRef(copilotkit);
657
472
  });
658
473
 
659
474
  watch([allRenderActivityMessages], ([renderActivityMessages]) => {
660
475
  if (!didMountRef.value) return;
661
476
  copilotkit.value.setRenderActivityMessages(renderActivityMessages);
662
- triggerRef(copilotkit);
663
477
  });
664
478
 
665
- // The last `headersSource` reference actually handed to `core.setHeaders`.
666
- // `syncRuntimeConfig` runs once (unconditionally) from `onMounted` in
667
- // addition to the constructor already having applied this same value.
668
- // `HeaderSourceResolver.setSource` itself is a no-op both for an identical
669
- // function reference and for a record whose normalized values equal the
670
- // currently applied record's (see #1937), so this reference
671
- // check is now a cheap pre-filter rather than the only thing preventing a
672
- // spurious `onHeadersChanged`. It still avoids the `setHeaders` call (and
673
- // its normalize + shallow-equal work) entirely on the common path where
674
- // nothing changed.
675
- let lastAppliedHeadersSource: CopilotKitHeadersSource = headersSource.value;
676
-
479
+ // Every setter is a no-op when its value did not change (`setHeaders` too, for
480
+ // the same builder or an equal record, see #1937), so this can pass every key.
677
481
  function syncRuntimeConfig() {
678
- copilotkit.value.setRuntimeUrl(chatApiEndpoint.value);
679
- copilotkit.value.setRuntimeTransport(
680
- props.useSingleEndpoint === true
681
- ? "single"
682
- : props.useSingleEndpoint === false
683
- ? "rest"
684
- : "auto",
685
- );
686
- if (headersSource.value !== lastAppliedHeadersSource) {
687
- lastAppliedHeadersSource = headersSource.value;
688
- copilotkit.value.setHeaders(headersSource.value);
689
- }
690
- copilotkit.value.setCredentials(props.credentials);
691
- copilotkit.value.setMessageFilter(props.messageFilter);
692
- copilotkit.value.setProperties(resolvedProperties.value);
693
- copilotkit.value.setAgents__unsafe_dev_only(mergedAgents.value);
694
- copilotkit.value.setDebug(props.debug);
695
- applyDefaultThrottleMs(copilotkit.value);
482
+ copilotkit.value.ɵupdateConfig({
483
+ messageFilter: props.messageFilter,
484
+ runtimeUrl: chatApiEndpoint.value,
485
+ runtimeTransport: runtimeTransport.value,
486
+ headers: headersSource.value,
487
+ credentials: props.credentials,
488
+ properties: resolvedProperties.value,
489
+ agents__unsafe_dev_only: mergedAgents.value,
490
+ debug: props.debug,
491
+ defaultThrottleMs: props.defaultThrottleMs,
492
+ });
696
493
  }
697
494
 
495
+ watch(
496
+ () => props.onError,
497
+ (onError) => copilotkit.value.setErrorHandler(onError),
498
+ );
499
+
698
500
  watch(
699
501
  [
700
502
  () => chatApiEndpoint.value,
@@ -703,7 +505,7 @@ watch(
703
505
  () => props.messageFilter,
704
506
  () => resolvedProperties.value,
705
507
  () => mergedAgents.value,
706
- () => props.useSingleEndpoint,
508
+ () => runtimeTransport.value,
707
509
  () => props.debug,
708
510
  ],
709
511
  () => {
@@ -714,111 +516,32 @@ watch(
714
516
 
715
517
  watch(
716
518
  () => props.defaultThrottleMs,
717
- () => {
519
+ (defaultThrottleMs) => {
718
520
  if (!didMountRef.value) return;
719
- applyDefaultThrottleMs(copilotkit.value);
521
+ copilotkit.value.ɵupdateConfig({ defaultThrottleMs });
720
522
  triggerRef(copilotkit);
721
523
  },
722
524
  );
723
525
 
724
526
  onMounted(() => {
725
527
  syncRuntimeConfig();
726
- runtimeA2UIEnabled.value = copilotkit.value.a2uiEnabled;
727
- runtimeOpenGenerativeUIEnabled.value =
728
- copilotkit.value.openGenerativeUIEnabled;
729
- runtimeLicenseStatus.value = copilotkit.value.licenseStatus;
730
- runtimeEntitlements.value = copilotkit.value.runtimeEntitlements;
731
- runtimeEntitlementRetryPending.value =
732
- copilotkit.value.runtimeEntitlementRetryPending;
528
+ // The constructor deferred `/info`; start it now that we are in the browser
529
+ // (`onMounted` never runs during SSR). Idempotent.
530
+ copilotkit.value.connect();
531
+ runtimeInfo.value = copilotkit.value.ɵruntimeInfo;
733
532
  didMountRef.value = true;
734
533
  // After the runtime URL is set, so CopilotKit's own runtime traffic is never
735
- // captured. Created here, the watchers stop (and stop capture) on unmount.
736
- watchLearning();
737
- });
738
-
739
- const learningEnabled = computed(() => learningConfig.value !== undefined);
740
- // `true` is the options-free form, so only an object can opt out.
741
- const learningAutoStart = computed(
742
- () =>
743
- learningEnabled.value &&
744
- (typeof props.learning !== "object" || props.learning.autoStart !== false),
745
- );
746
- const suppliedTrajectoryId = computed(() =>
747
- learningAutoStart.value ? learningConfig.value?.trajectoryId : undefined,
748
- );
749
- const generatesTrajectoryId = computed(
750
- () => learningAutoStart.value && suppliedTrajectoryId.value === undefined,
751
- );
752
-
753
- function watchLearning() {
754
- let learningContainerIds = learningConfig.value?.learningContainerIds;
755
-
534
+ // captured. The provider's onUnmounted disposes the starter (stops capture).
756
535
  watch(
757
- [learningConfig, learningAutoStart],
758
- ([config, autoStart]) => {
759
- copilotkit.value.setLearningConfig(config);
760
- learningContainerIds = config?.learningContainerIds;
761
- // Automatic starts report unsupported options in Core. With manual
762
- // starts, the provider's container option is not part of
763
- // startTrajectory() options.
764
- if (
765
- config?.sink === undefined &&
766
- !autoStart &&
767
- config?.learningContainerIds !== undefined
768
- ) {
769
- console.warn(
770
- "[CopilotKit] learningContainerIds is supported only with a custom sink. Authenticated Trajectory capture ignores it; assign Learning Spaces on the server with getTrajectoryLearningContainerIds on CopilotKitIntelligence, and remove learningContainerIds from the capture options.",
771
- );
772
- }
773
- },
774
- { immediate: true },
775
- );
776
-
777
- // Watched as a boolean so a new inline `learning` object warns once.
778
- watch(
779
- () =>
780
- !learningAutoStart.value &&
781
- learningConfig.value?.trajectoryId !== undefined,
782
- (ignoresTrajectoryId) => {
783
- if (!ignoresTrajectoryId) return;
784
- console.warn(
785
- "[CopilotKit] learning.trajectoryId is ignored when autoStart is false; pass the ID to startTrajectory() instead.",
786
- );
536
+ () => props.learning,
537
+ (learning) => learningStarter.update(learning),
538
+ {
539
+ immediate: true,
787
540
  },
788
- { immediate: true },
789
541
  );
542
+ });
790
543
 
791
- // Runs only when these change, so option changes that keep generating keep
792
- // the generated Trajectory; generating again starts one with a new ID.
793
- watch(
794
- [learningEnabled, generatesTrajectoryId, suppliedTrajectoryId],
795
- ([enabled, generates, supplied], _previous, onCleanup) => {
796
- if (!enabled) return;
797
- let disposed = false;
798
- const core = copilotkit.value;
799
- const trajectoryId = generates ? randomUUID() : supplied;
800
- if (trajectoryId !== undefined) {
801
- void core
802
- .startTrajectory({ trajectoryId, learningContainerIds })
803
- .catch(() => {
804
- // Expected authentication/connection failures resolve with an
805
- // error result; Core reports them to LearningConfig.onError or
806
- // warns once. Consume unexpected rejections without logging
807
- // credentials or errors from a previous start after a new
808
- // Trajectory has already started.
809
- if (!disposed) {
810
- console.warn("[CopilotKit] Failed to start interaction capture.");
811
- }
812
- });
813
- }
814
- onCleanup(() => {
815
- disposed = true;
816
- core.stopTrajectory();
817
- });
818
- },
819
- { immediate: true },
820
- );
821
- }
544
+ const learningStarter = new ɵLearningAutoStarter(copilotkit.value);
822
545
 
823
546
  const a2uiTheme = computed(() => props.a2ui?.theme);
824
547
  const a2uiCatalog = computed(() => props.a2ui?.catalog);
@@ -828,14 +551,17 @@ const a2uiIncludeSchema = computed(() => props.a2ui?.includeSchema ?? true);
828
551
  // A2UI tool call renderer (progress indicator) — auto-registered when A2UI enabled
829
552
  registerA2UIBuiltInToolCallRenderer(copilotkit, () => a2uiActive.value);
830
553
 
831
- // A2UI catalog context, schema, and generation/design guidelines
832
- registerA2UICatalogContext(copilotkit, {
554
+ // A2UI catalog: component registration for the Inspector, the filtered
555
+ // catalog, and the agent context (schema, generation/design guidelines).
556
+ registerA2UICatalog(copilotkit, {
833
557
  enabled: () => a2uiActive.value,
834
558
  catalog: () => props.a2ui?.catalog,
835
559
  includeSchema: () => props.a2ui?.includeSchema ?? true,
560
+ onFilteredCatalog: (catalog) => {
561
+ a2uiFilteredCatalog.value = catalog;
562
+ },
836
563
  });
837
564
 
838
- const providerContextIds = ref<string[]>([]);
839
565
  watch(
840
566
  [
841
567
  openGenerativeUIActive,
@@ -845,40 +571,12 @@ watch(
845
571
  ([active, functions, designSkill], _previous, onCleanup) => {
846
572
  if (!active) return;
847
573
 
848
- const ids: string[] = [];
849
- ids.push(
850
- copilotkit.value.addContext({
851
- description:
852
- "Design guidelines for the generateSandboxedUi tool. Follow these when building UI.",
853
- value: designSkill ?? DEFAULT_DESIGN_SKILL,
574
+ onCleanup(
575
+ ɵaddOpenGenerativeUIContexts(copilotkit.value, {
576
+ designSkill,
577
+ sandboxFunctions: functions,
854
578
  }),
855
579
  );
856
-
857
- if (functions.length > 0) {
858
- const descriptors = JSON.stringify(
859
- functions.map((fn) => ({
860
- name: fn.name,
861
- description: fn.description,
862
- parameters: schemaToJsonSchema(fn.parameters, {
863
- zodToJsonSchema: zodToJsonSchemaCompat,
864
- }),
865
- })),
866
- );
867
- ids.push(
868
- copilotkit.value.addContext({
869
- description:
870
- "Sandbox functions available in generated sandboxed UI code. Call via Websandbox.connection.remote.<functionName>(args).",
871
- value: descriptors,
872
- }),
873
- );
874
- }
875
-
876
- providerContextIds.value = ids;
877
- onCleanup(() => {
878
- for (const id of ids) {
879
- copilotkit.value.removeContext(id);
880
- }
881
- });
882
580
  },
883
581
  { immediate: true },
884
582
  );
@@ -894,73 +592,27 @@ provide(CopilotKitKey, {
894
592
  provide(SandboxFunctionsKey, sandboxFunctions);
895
593
  provide(MARKDOWN_RENDERER_KEY, props.markdownRenderer);
896
594
 
897
- // License context — driven by structured and legacy Runtime authority.
898
- const retryableRuntimeEntitlementFailure = computed(
899
- () =>
900
- runtimeEntitlements.value?.status !== "ready" &&
901
- runtimeEntitlements.value?.error.retryable === true,
902
- );
903
- const hasNonReadyRuntimeEntitlement = computed(
904
- () =>
905
- runtimeEntitlements.value !== undefined &&
906
- runtimeEntitlements.value.status !== "ready",
907
- );
908
- const hasLegacyRuntimeEntitlementFallback = computed(
909
- () =>
910
- runtimeLicenseStatus.value === "valid" ||
911
- runtimeLicenseStatus.value === "expiring",
912
- );
913
- const runtimeEntitlementRetryInProgress = computed(
914
- () =>
915
- retryableRuntimeEntitlementFailure.value &&
916
- runtimeEntitlementRetryPending.value &&
917
- !hasLegacyRuntimeEntitlementFallback.value,
918
- );
919
- // Only a terminal failure denies features. A retryable failure (a timeout,
920
- // a network error, a 5xx) says nothing about what the project may use.
921
- const terminalRuntimeEntitlementFailure = computed(
922
- () =>
923
- hasNonReadyRuntimeEntitlement.value &&
924
- !retryableRuntimeEntitlementFailure.value &&
925
- !hasLegacyRuntimeEntitlementFallback.value,
926
- );
927
- const licenseContextValue = computed<LicenseContextValue>(() => {
928
- const runtimeLicenseContext = createLicenseContextValue(
929
- runtimeEntitlementRetryInProgress.value
930
- ? undefined
931
- : runtimeLicenseStatus.value,
932
- runtimeEntitlements.value,
933
- );
934
- if (!terminalRuntimeEntitlementFailure.value) {
935
- return runtimeLicenseContext;
936
- }
937
-
938
- return {
939
- ...runtimeLicenseContext,
940
- checkFeature: () => false,
941
- getLimit: () => null,
942
- };
943
- });
595
+ // License context and banner, from the runtime license status and the
596
+ // structured entitlement response.
597
+ const licenseState = computed(() =>
598
+ ɵresolveLicenseState({
599
+ status: runtimeLicenseStatus.value,
600
+ entitlements: runtimeEntitlements.value,
601
+ retryPending: runtimeEntitlementRetryPending.value,
602
+ publicKey: resolvedPublicKey.value,
603
+ }),
604
+ );
605
+ const licenseContextValue = computed(() => licenseState.value.context);
944
606
  provide(LicenseContextKey, licenseContextValue);
945
-
946
- const runtimeLicenseWarningStatus = computed(() =>
947
- runtimeEntitlementRetryInProgress.value
948
- ? undefined
949
- : (licenseContextValue.value.status ?? undefined),
950
- );
951
- const showNoLicenseBanner = computed(
952
- () =>
953
- runtimeLicenseWarningStatus.value === "none" && !resolvedPublicKey.value,
954
- );
955
- const showExpiredBanner = computed(
956
- () => runtimeLicenseWarningStatus.value === "expired",
957
- );
958
- const showInvalidBanner = computed(
959
- () => runtimeLicenseWarningStatus.value === "invalid",
960
- );
961
- const showExpiringBanner = computed(
962
- () => runtimeLicenseWarningStatus.value === "expiring",
963
- );
607
+ const licenseBannerType = computed(() => licenseState.value.bannerType);
608
+
609
+ // The provider created this core, so it stops the core's runs, timers and
610
+ // subscriptions. `onUnmounted` runs after the children unmount, so their
611
+ // cleanup still reaches a live core.
612
+ onUnmounted(() => {
613
+ learningStarter.dispose();
614
+ copilotkit.value.dispose();
615
+ });
964
616
  </script>
965
617
 
966
618
  <template>
@@ -969,10 +621,8 @@ const showExpiringBanner = computed(
969
621
  v-if="shouldRenderInspector"
970
622
  :core="copilotkit"
971
623
  :open-request="inspectorOpenRequest"
624
+ @visibility-change="inspectorVisible = $event"
972
625
  />
973
626
  <!-- License warnings — driven by server-reported status -->
974
- <LicenseWarningBanner v-if="showNoLicenseBanner" type="no_license" />
975
- <LicenseWarningBanner v-if="showExpiredBanner" type="expired" />
976
- <LicenseWarningBanner v-if="showInvalidBanner" type="invalid" />
977
- <LicenseWarningBanner v-if="showExpiringBanner" type="expiring" />
627
+ <LicenseWarningBanner v-if="licenseBannerType" :type="licenseBannerType" />
978
628
  </template>