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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (335) hide show
  1. package/PARITY.md +3 -3
  2. package/dist/hooks/use-copilot-action.d.ts.map +1 -1
  3. package/dist/hooks/use-frontend-tool.d.ts +1 -1
  4. package/dist/hooks/use-frontend-tool.d.ts.map +1 -1
  5. package/dist/hooks/zod-parameters.d.ts +14 -0
  6. package/dist/hooks/zod-parameters.d.ts.map +1 -0
  7. package/dist/index.cjs +1 -73
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.mjs +365 -16920
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/use-render-activity-message-BAhbpSDh.js +16200 -0
  12. package/dist/use-render-activity-message-BAhbpSDh.js.map +1 -0
  13. package/dist/use-render-activity-message-DJ6q1qHV.cjs +114 -0
  14. package/dist/use-render-activity-message-DJ6q1qHV.cjs.map +1 -0
  15. package/dist/v2/components/A2UIMessageRenderer.d.ts +14 -0
  16. package/dist/v2/components/A2UIMessageRenderer.d.ts.map +1 -1
  17. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts +10 -3
  18. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts.map +1 -1
  19. package/dist/v2/components/CopilotKitInspector.vue.d.ts +5 -1
  20. package/dist/v2/components/CopilotKitInspector.vue.d.ts.map +1 -1
  21. package/dist/v2/components/InlineFeatureWarning.vue.d.ts.map +1 -1
  22. package/dist/v2/components/LicenseWarningBanner.vue.d.ts +2 -2
  23. package/dist/v2/components/LicenseWarningBanner.vue.d.ts.map +1 -1
  24. package/dist/v2/components/MCPAppsActivityRenderer.d.ts.map +1 -1
  25. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts +13 -59
  26. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts.map +1 -1
  27. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts +0 -5
  28. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts.map +1 -1
  29. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts +10 -15
  30. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts.map +1 -1
  31. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts +14 -130
  32. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts.map +1 -1
  33. package/dist/v2/components/a2ui/catalog.d.ts.map +1 -1
  34. package/dist/v2/components/a2ui/utils.d.ts +3 -15
  35. package/dist/v2/components/a2ui/utils.d.ts.map +1 -1
  36. package/dist/v2/components/a2ui.d.ts +9 -8
  37. package/dist/v2/components/a2ui.d.ts.map +1 -1
  38. package/dist/v2/components/chat/CopilotChat.vue.d.ts +2 -2
  39. package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
  40. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -1
  41. package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -1
  42. package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -1
  43. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts +4 -8
  44. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts.map +1 -1
  45. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts +1 -1
  46. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts.map +1 -1
  47. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +6 -270
  48. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -1
  49. package/dist/v2/components/chat/CopilotChatInspectorButton.vue.d.ts.map +1 -1
  50. package/dist/v2/components/chat/CopilotChatLightbox.vue.d.ts.map +1 -1
  51. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +1 -1
  52. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -1
  53. package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -1
  54. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts +1 -1
  55. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts.map +1 -1
  56. package/dist/v2/components/chat/CopilotChatToolCallItem.vue.d.ts.map +1 -1
  57. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +1 -1
  58. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -1
  59. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -1
  60. package/dist/v2/components/chat/CopilotChatView.vue.d.ts +3 -3
  61. package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
  62. package/dist/v2/components/chat/CopilotChatWorkSummary.vue.d.ts.map +1 -1
  63. package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts.map +1 -1
  64. package/dist/v2/components/chat/CopilotPopup.vue.d.ts +8 -3
  65. package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -1
  66. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts +5 -3
  67. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -1
  68. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts +5 -3
  69. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -1
  70. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts +8 -3
  71. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -1
  72. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +6 -4
  73. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -1
  74. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +6 -4
  75. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -1
  76. package/dist/v2/components/chat/CopilotThreadsDrawer.vue.d.ts.map +1 -1
  77. package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts +1 -0
  78. package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts.map +1 -1
  79. package/dist/v2/components/chat/audioRecorder.d.ts +3 -4
  80. package/dist/v2/components/chat/audioRecorder.d.ts.map +1 -1
  81. package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts +3 -3
  82. package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts.map +1 -1
  83. package/dist/v2/components/chat/forwarded-slots.d.ts +12 -0
  84. package/dist/v2/components/chat/forwarded-slots.d.ts.map +1 -0
  85. package/dist/v2/components/chat/index.d.ts +34 -31
  86. package/dist/v2/components/chat/index.d.ts.map +1 -1
  87. package/dist/v2/components/chat/inspector-shortcuts.d.ts +2 -1
  88. package/dist/v2/components/chat/inspector-shortcuts.d.ts.map +1 -1
  89. package/dist/v2/components/chat/message-feedback.d.ts +18 -49
  90. package/dist/v2/components/chat/message-feedback.d.ts.map +1 -1
  91. package/dist/v2/components/chat/tool-call-display-context.d.ts +4 -19
  92. package/dist/v2/components/chat/tool-call-display-context.d.ts.map +1 -1
  93. package/dist/v2/components/chat/tool-call-group-parts.d.ts +7 -20
  94. package/dist/v2/components/chat/tool-call-group-parts.d.ts.map +1 -1
  95. package/dist/v2/components/chat/turn-work.d.ts +0 -2
  96. package/dist/v2/components/chat/turn-work.d.ts.map +1 -1
  97. package/dist/v2/components/chat/types.d.ts +9 -4
  98. package/dist/v2/components/chat/types.d.ts.map +1 -1
  99. package/dist/v2/components/chat/use-chat-labels.d.ts +8 -0
  100. package/dist/v2/components/chat/use-chat-labels.d.ts.map +1 -0
  101. package/dist/v2/components/chat/use-copy-feedback.d.ts +11 -0
  102. package/dist/v2/components/chat/use-copy-feedback.d.ts.map +1 -0
  103. package/dist/v2/components/chat/use-lightbox.d.ts.map +1 -1
  104. package/dist/v2/components/icons/index.d.ts +968 -1
  105. package/dist/v2/components/icons/index.d.ts.map +1 -1
  106. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts +1 -1
  107. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts.map +1 -1
  108. package/dist/v2/hooks/use-agent-context.d.ts +2 -3
  109. package/dist/v2/hooks/use-agent-context.d.ts.map +1 -1
  110. package/dist/v2/hooks/use-agent.d.ts +4 -1
  111. package/dist/v2/hooks/use-agent.d.ts.map +1 -1
  112. package/dist/v2/hooks/use-attachments.d.ts +7 -0
  113. package/dist/v2/hooks/use-attachments.d.ts.map +1 -1
  114. package/dist/v2/hooks/use-capabilities.d.ts.map +1 -1
  115. package/dist/v2/hooks/use-component.d.ts +1 -0
  116. package/dist/v2/hooks/use-component.d.ts.map +1 -1
  117. package/dist/v2/hooks/use-configure-suggestions.d.ts +4 -9
  118. package/dist/v2/hooks/use-configure-suggestions.d.ts.map +1 -1
  119. package/dist/v2/hooks/use-default-render-tool.d.ts.map +1 -1
  120. package/dist/v2/hooks/use-frontend-tool.d.ts +5 -0
  121. package/dist/v2/hooks/use-frontend-tool.d.ts.map +1 -1
  122. package/dist/v2/hooks/use-human-in-the-loop.d.ts +2 -1
  123. package/dist/v2/hooks/use-human-in-the-loop.d.ts.map +1 -1
  124. package/dist/v2/hooks/use-interrupt.d.ts +0 -1
  125. package/dist/v2/hooks/use-interrupt.d.ts.map +1 -1
  126. package/dist/v2/hooks/use-keyboard-height.d.ts +1 -1
  127. package/dist/v2/hooks/use-keyboard-height.d.ts.map +1 -1
  128. package/dist/v2/hooks/use-pin-to-send.d.ts +4 -12
  129. package/dist/v2/hooks/use-pin-to-send.d.ts.map +1 -1
  130. package/dist/v2/hooks/use-render-activity-message.d.ts +13 -9
  131. package/dist/v2/hooks/use-render-activity-message.d.ts.map +1 -1
  132. package/dist/v2/hooks/use-render-custom-messages.d.ts +5 -7
  133. package/dist/v2/hooks/use-render-custom-messages.d.ts.map +1 -1
  134. package/dist/v2/hooks/use-suggestions.d.ts.map +1 -1
  135. package/dist/v2/hooks/use-threads.d.ts +0 -8
  136. package/dist/v2/hooks/use-threads.d.ts.map +1 -1
  137. package/dist/v2/index.cjs +1 -1
  138. package/dist/v2/index.mjs +197 -200
  139. package/dist/v2/index.mjs.map +1 -1
  140. package/dist/v2/lib/processPartialHtml.d.ts +1 -2
  141. package/dist/v2/lib/processPartialHtml.d.ts.map +1 -1
  142. package/dist/v2/lib/shallow-stable.d.ts.map +1 -1
  143. package/dist/v2/lib/vue-core.d.ts +12 -12
  144. package/dist/v2/lib/vue-core.d.ts.map +1 -1
  145. package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts.map +1 -1
  146. package/dist/v2/providers/CopilotKitProvider.types.d.ts +9 -129
  147. package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -1
  148. package/dist/v2/providers/CopilotKitProvider.vue.d.ts +9 -10
  149. package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
  150. package/dist/v2/providers/chat-configuration-store-key.d.ts +8 -0
  151. package/dist/v2/providers/chat-configuration-store-key.d.ts.map +1 -0
  152. package/dist/v2/providers/markdown-renderer.d.ts +4 -2
  153. package/dist/v2/providers/markdown-renderer.d.ts.map +1 -1
  154. package/dist/v2/providers/types.d.ts +3 -46
  155. package/dist/v2/providers/types.d.ts.map +1 -1
  156. package/dist/v2/providers/use-inspector-thread-override.d.ts +5 -0
  157. package/dist/v2/providers/use-inspector-thread-override.d.ts.map +1 -1
  158. package/dist/v2/types/human-in-the-loop.d.ts +8 -29
  159. package/dist/v2/types/human-in-the-loop.d.ts.map +1 -1
  160. package/dist/v2/types/interrupt.d.ts +1 -22
  161. package/dist/v2/types/interrupt.d.ts.map +1 -1
  162. package/dist/v2/types/vue-activity-message-renderer.d.ts +16 -15
  163. package/dist/v2/types/vue-activity-message-renderer.d.ts.map +1 -1
  164. package/dist/v2/types/vue-custom-message-renderer.d.ts +7 -16
  165. package/dist/v2/types/vue-custom-message-renderer.d.ts.map +1 -1
  166. package/dist/v2/types/vue-tool-call-renderer.d.ts +16 -35
  167. package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -1
  168. package/package.json +10 -11
  169. package/src/__tests__/build-entries.test.ts +27 -0
  170. package/src/hooks/__tests__/zod-parameters.test.ts +520 -0
  171. package/src/hooks/use-copilot-action.ts +2 -1
  172. package/src/hooks/use-frontend-tool.ts +3 -6
  173. package/src/hooks/zod-parameters.ts +162 -0
  174. package/src/v2/__tests__/exports.test.ts +10 -0
  175. package/src/v2/__tests__/mocks/web-inspector.ts +6 -0
  176. package/src/v2/__tests__/utils/test-helpers.ts +34 -4
  177. package/src/v2/components/A2UIMessageRenderer.ts +98 -68
  178. package/src/v2/components/A2UISurfaceActivityRenderer.vue +68 -103
  179. package/src/v2/components/CopilotKitInspector.vue +104 -51
  180. package/src/v2/components/InlineFeatureWarning.vue +20 -21
  181. package/src/v2/components/LicenseWarningBanner.vue +27 -135
  182. package/src/v2/components/MCPAppsActivityRenderer.ts +75 -201
  183. package/src/v2/components/OpenGenerativeUIRenderer.ts +122 -446
  184. package/src/v2/components/__tests__/A2UIMessageRenderer.test.ts +171 -8
  185. package/src/v2/components/__tests__/CopilotKitInspector.test.ts +42 -0
  186. package/src/v2/components/__tests__/LicenseWarningBanner.test.ts +60 -0
  187. package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.ts +64 -8
  188. package/src/v2/components/__tests__/OpenGenerativeUIToolRenderer.test.ts +38 -0
  189. package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +2 -7
  190. package/src/v2/components/a2ui/A2UICatalogContext.ts +27 -185
  191. package/src/v2/components/a2ui/A2UIRecoveryStates.ts +127 -327
  192. package/src/v2/components/a2ui/catalog.ts +3 -3
  193. package/src/v2/components/a2ui/utils.ts +13 -65
  194. package/src/v2/components/a2ui.ts +15 -22
  195. package/src/v2/components/chat/CopilotChat.vue +147 -356
  196. package/src/v2/components/chat/CopilotChatAssistantMessage.vue +19 -43
  197. package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +36 -55
  198. package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +14 -6
  199. package/src/v2/components/chat/CopilotChatAudioRecorder.vue +19 -246
  200. package/src/v2/components/chat/CopilotChatFeedbackCommentPopover.vue +2 -2
  201. package/src/v2/components/chat/CopilotChatInput.vue +108 -436
  202. package/src/v2/components/chat/CopilotChatInspectorButton.vue +45 -108
  203. package/src/v2/components/chat/CopilotChatLightbox.vue +10 -31
  204. package/src/v2/components/chat/CopilotChatMessageView.vue +82 -210
  205. package/src/v2/components/chat/CopilotChatReasoningMessage.vue +7 -15
  206. package/src/v2/components/chat/CopilotChatToolCallGroup.vue +63 -71
  207. package/src/v2/components/chat/CopilotChatToolCallItem.vue +8 -6
  208. package/src/v2/components/chat/CopilotChatToolCallsView.vue +31 -32
  209. package/src/v2/components/chat/CopilotChatUserMessage.vue +24 -112
  210. package/src/v2/components/chat/CopilotChatView.vue +33 -28
  211. package/src/v2/components/chat/CopilotChatWorkSummary.vue +26 -36
  212. package/src/v2/components/chat/CopilotModalHeader.vue +11 -23
  213. package/src/v2/components/chat/CopilotPopup.vue +23 -25
  214. package/src/v2/components/chat/CopilotPopupView.vue +10 -39
  215. package/src/v2/components/chat/CopilotPopupViewInternal.vue +35 -131
  216. package/src/v2/components/chat/CopilotSidebar.vue +23 -25
  217. package/src/v2/components/chat/CopilotSidebarView.vue +10 -39
  218. package/src/v2/components/chat/CopilotSidebarViewInternal.vue +38 -59
  219. package/src/v2/components/chat/CopilotThreadsDrawer.vue +37 -102
  220. package/src/v2/components/chat/StreamingMarkdownDefault.vue +15 -28
  221. package/src/v2/components/chat/__tests__/CopilotChat.labels.test.ts +19 -4
  222. package/src/v2/components/chat/__tests__/CopilotChat.test.ts +12 -10
  223. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.ts +26 -9
  224. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.learningFeedback.test.ts +5 -5
  225. package/src/v2/components/chat/__tests__/CopilotChatAttachmentQueue.test.ts +28 -0
  226. package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +89 -1
  227. package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.ts +247 -403
  228. package/src/v2/components/chat/__tests__/CopilotChatMessageView.toolCallDisplay.test.ts +1 -99
  229. package/src/v2/components/chat/__tests__/CopilotPopup.test.ts +90 -1
  230. package/src/v2/components/chat/__tests__/CopilotPopupView.test.ts +19 -0
  231. package/src/v2/components/chat/__tests__/CopilotSidebar.test.ts +90 -1
  232. package/src/v2/components/chat/__tests__/CopilotSidebarView.position.test.ts +32 -8
  233. package/src/v2/components/chat/__tests__/CopilotSidebarView.test.ts +2 -1
  234. package/src/v2/components/chat/__tests__/StreamingMarkdownDefault.test.ts +54 -0
  235. package/src/v2/components/chat/audioRecorder.ts +4 -7
  236. package/src/v2/components/chat/copilotChatToolCallItemRender.ts +24 -89
  237. package/src/v2/components/chat/forwarded-slots.ts +17 -0
  238. package/src/v2/components/chat/index.ts +0 -1
  239. package/src/v2/components/chat/inspector-shortcuts.ts +10 -16
  240. package/src/v2/components/chat/message-feedback.ts +62 -197
  241. package/src/v2/components/chat/tool-call-display-context.ts +6 -22
  242. package/src/v2/components/chat/tool-call-group-parts.ts +47 -108
  243. package/src/v2/components/chat/turn-work.ts +0 -9
  244. package/src/v2/components/chat/types.ts +12 -4
  245. package/src/v2/components/chat/use-chat-labels.ts +16 -0
  246. package/src/v2/components/chat/use-copy-feedback.ts +21 -0
  247. package/src/v2/components/chat/use-lightbox.ts +15 -33
  248. package/src/v2/components/icons/__tests__/icons.test.ts +72 -68
  249. package/src/v2/components/icons/index.ts +109 -27
  250. package/src/v2/hooks/__tests__/use-agent-error-state.test.ts +5 -3
  251. package/src/v2/hooks/__tests__/use-agent-stability.test.ts +25 -4
  252. package/src/v2/hooks/__tests__/use-agent-throttle.test.ts +5 -1
  253. package/src/v2/hooks/__tests__/use-agent.test.ts +6 -3
  254. package/src/v2/hooks/__tests__/use-component.test.ts +21 -0
  255. package/src/v2/hooks/__tests__/use-configure-suggestions.test.ts +30 -1
  256. package/src/v2/hooks/__tests__/use-default-render-tool.test.ts +10 -10
  257. package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.ts +66 -1
  258. package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.ts +6 -1
  259. package/src/v2/hooks/__tests__/use-human-in-the-loop.test.ts +187 -12
  260. package/src/v2/hooks/__tests__/use-interrupt.test.ts +97 -0
  261. package/src/v2/hooks/__tests__/use-render-activity-message.test.ts +106 -0
  262. package/src/v2/hooks/__tests__/use-render-tool.test.ts +3 -6
  263. package/src/v2/hooks/__tests__/use-threads.test.ts +48 -6
  264. package/src/v2/hooks/__tests__/zod-regression.test.ts +5 -4
  265. package/src/v2/hooks/use-agent-context.ts +4 -10
  266. package/src/v2/hooks/use-agent.ts +86 -290
  267. package/src/v2/hooks/use-attachments.ts +48 -168
  268. package/src/v2/hooks/use-capabilities.ts +2 -7
  269. package/src/v2/hooks/use-component.ts +7 -4
  270. package/src/v2/hooks/use-configure-suggestions.ts +28 -218
  271. package/src/v2/hooks/use-default-render-tool.ts +34 -94
  272. package/src/v2/hooks/use-frontend-tool.ts +10 -10
  273. package/src/v2/hooks/use-human-in-the-loop.ts +11 -80
  274. package/src/v2/hooks/use-interrupt.ts +29 -308
  275. package/src/v2/hooks/use-keyboard-height.ts +17 -40
  276. package/src/v2/hooks/use-pin-to-send.ts +15 -99
  277. package/src/v2/hooks/use-render-activity-message.ts +31 -55
  278. package/src/v2/hooks/use-render-custom-messages.ts +24 -88
  279. package/src/v2/hooks/use-suggestions.ts +9 -33
  280. package/src/v2/hooks/use-threads.ts +43 -273
  281. package/src/v2/lib/__tests__/shallow-stable.test.ts +54 -0
  282. package/src/v2/lib/__tests__/vue-core-renderers.test.ts +42 -0
  283. package/src/v2/lib/processPartialHtml.ts +6 -21
  284. package/src/v2/lib/shallow-stable.ts +2 -16
  285. package/src/v2/lib/vue-core.ts +69 -78
  286. package/src/v2/providers/CopilotChatConfigurationProvider.vue +48 -186
  287. package/src/v2/providers/CopilotKitProvider.types.ts +12 -132
  288. package/src/v2/providers/CopilotKitProvider.vue +237 -510
  289. package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.ts +22 -2
  290. package/src/v2/providers/__tests__/CopilotKitProvider.a2ui.test.ts +20 -2
  291. package/src/v2/providers/__tests__/CopilotKitProvider.config.test.ts +124 -0
  292. package/src/v2/providers/__tests__/CopilotKitProvider.headersAtSendTime.test.ts +3 -3
  293. package/src/v2/providers/__tests__/CopilotKitProvider.learning.test.ts +3 -1
  294. package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.ts +4 -1
  295. package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +53 -26
  296. package/src/v2/providers/chat-configuration-store-key.ts +9 -0
  297. package/src/v2/providers/markdown-renderer.ts +8 -2
  298. package/src/v2/providers/types.ts +3 -49
  299. package/src/v2/providers/use-inspector-thread-override.ts +22 -80
  300. package/src/v2/types/__tests__/defineToolCallRenderer.test.ts +28 -33
  301. package/src/v2/types/defineToolCallRenderer.ts +5 -4
  302. package/src/v2/types/human-in-the-loop.ts +8 -32
  303. package/src/v2/types/interrupt.ts +7 -31
  304. package/src/v2/types/vue-activity-message-renderer.ts +24 -15
  305. package/src/v2/types/vue-custom-message-renderer.ts +12 -16
  306. package/src/v2/types/vue-tool-call-renderer.ts +23 -38
  307. package/tsconfig.json +0 -1
  308. package/vite.config.ts +8 -5
  309. package/vitest.config.ts +12 -7
  310. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts +0 -9
  311. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts.map +0 -1
  312. package/dist/v2/components/chat/normalize-auto-scroll.d.ts +0 -3
  313. package/dist/v2/components/chat/normalize-auto-scroll.d.ts.map +0 -1
  314. package/dist/v2/components/chat/tool-call-layout.d.ts +0 -115
  315. package/dist/v2/components/chat/tool-call-layout.d.ts.map +0 -1
  316. package/dist/v2/lib/is-mobile-viewport.d.ts +0 -15
  317. package/dist/v2/lib/is-mobile-viewport.d.ts.map +0 -1
  318. package/dist/v2/lib/message-feedback.d.ts +0 -33
  319. package/dist/v2/lib/message-feedback.d.ts.map +0 -1
  320. package/dist/v2/lib/transcription-client.d.ts +0 -19
  321. package/dist/v2/lib/transcription-client.d.ts.map +0 -1
  322. package/src/v2/components/__tests__/A2UICatalogContext.test.ts +0 -63
  323. package/src/v2/components/a2ui/__tests__/A2UIRecoveryStates.test.ts +0 -175
  324. package/src/v2/components/chat/BasicMarkdown.vue +0 -160
  325. package/src/v2/components/chat/__tests__/BasicMarkdown.test.ts +0 -69
  326. package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +0 -39
  327. package/src/v2/components/chat/normalize-auto-scroll.ts +0 -17
  328. package/src/v2/components/chat/tool-call-layout.ts +0 -304
  329. package/src/v2/lib/__tests__/is-mobile-viewport.test.ts +0 -48
  330. package/src/v2/lib/__tests__/message-feedback.test.ts +0 -152
  331. package/src/v2/lib/__tests__/processPartialHtml.test.ts +0 -84
  332. package/src/v2/lib/__tests__/transcription-client.test.ts +0 -67
  333. package/src/v2/lib/is-mobile-viewport.ts +0 -23
  334. package/src/v2/lib/message-feedback.ts +0 -120
  335. package/src/v2/lib/transcription-client.ts +0 -151
@@ -1,41 +1,48 @@
1
1
  <script setup lang="ts">
2
- import {
3
- GENERATE_SANDBOXED_UI_DESCRIPTION,
4
- randomUUID,
5
- } from "@copilotkit/shared";
2
+ import { ɵanySchema } from "@copilotkit/shared";
6
3
  import {
7
4
  computed,
8
5
  h,
9
6
  onMounted,
7
+ onUnmounted,
10
8
  provide,
11
9
  ref,
12
10
  shallowRef,
11
+ toRaw,
13
12
  triggerRef,
14
13
  watch,
15
14
  } from "vue";
16
15
  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";
16
+ import type { Catalog, ComponentApi } from "@a2ui/web_core/v0_9";
17
+ import {
18
+ ɵLearningAutoStarter,
19
+ ɵbuildHumanInTheLoopTool,
20
+ ɵhitlRenderProps,
21
+ ɵtoLearningConfig,
22
+ } from "@copilotkit/core";
20
23
  import type {
21
- CopilotKitCoreErrorCode,
22
- CopilotKitCoreSubscriber,
23
24
  CopilotKitHeadersSource,
24
25
  FrontendTool,
26
+ ɵRuntimeInfo,
25
27
  } 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";
28
+ import {
29
+ ɵSTABLE_ARRAY_WARNINGS,
30
+ ɵbuildOpenGenerativeUIContexts,
31
+ ɵcreateOpenGenerativeUITool,
32
+ ɵisOpenGenerativeUIActive,
33
+ ɵpublicKeyHeaderDefaults,
34
+ ɵreportProviderConfigDiagnostics,
35
+ ɵresolveLicenseState,
36
+ ɵresolveProviderConfig,
37
+ ɵtoolRendererShapeChanged,
38
+ ɵwithHeaderDefaults,
39
+ } from "@copilotkit/core";
40
+ import { shouldEnableInspector } from "@copilotkit/shared";
33
41
  import { CopilotKitCoreVue } from "../lib/vue-core";
34
42
  import { createA2UIMessageRenderer } from "../components/A2UIMessageRenderer";
35
43
  import { registerA2UIBuiltInToolCallRenderer } from "../components/a2ui/A2UIBuiltInToolCallRenderer";
36
- import { registerA2UICatalogContext } from "../components/a2ui/A2UICatalogContext";
44
+ import { registerA2UICatalog } from "../components/a2ui/A2UICatalogContext";
37
45
  import {
38
- GenerateSandboxedUiArgsSchema,
39
46
  OpenGenerativeUIActivityRenderer,
40
47
  OpenGenerativeUIActivityType,
41
48
  OpenGenerativeUIContentSchema,
@@ -54,17 +61,10 @@ import {
54
61
  } from "./keys";
55
62
  import type { VueInspectorOpenRequest } from "./keys";
56
63
  import { MARKDOWN_RENDERER_KEY } from "./markdown-renderer";
57
- import {
58
- LicenseContextKey,
59
- createLicenseContextValue,
60
- } from "./license-context";
61
- import type { LicenseContextValue } from "./license-context";
64
+ import { LicenseContextKey } from "./license-context";
62
65
  import CopilotKitInspector from "../components/CopilotKitInspector.vue";
63
66
  import LicenseWarningBanner from "../components/LicenseWarningBanner.vue";
64
- import type {
65
- CopilotKitLearningOptions,
66
- CopilotKitProviderProps,
67
- } from "./CopilotKitProvider.types";
67
+ import type { CopilotKitProviderProps } from "./CopilotKitProvider.types";
68
68
  import type {
69
69
  SandboxFunction,
70
70
  VueActivityMessageRenderer,
@@ -73,37 +73,6 @@ import type {
73
73
  VueToolCallRendererRenderProps,
74
74
  } from "../types";
75
75
 
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
76
  /** The MCP Apps renderer with `mcpApps.allowSameOriginFallback` applied. */
108
77
  const SameOriginMCPAppsActivityRenderer: FunctionalComponent = (_, { attrs }) =>
109
78
  h(MCPAppsActivityRenderer as Component, {
@@ -137,12 +106,16 @@ provide(
137
106
  );
138
107
 
139
108
  const shouldRenderInspector = ref(false);
109
+ // Follows the Inspector's own show/hide, so message actions that open it are
110
+ // hidden while a temporary dismissal hides it.
111
+ const inspectorVisible = ref(false);
140
112
 
141
113
  function updateInspectorVisibility(): void {
142
114
  shouldRenderInspector.value = shouldEnableInspector({
143
115
  enableInspector: props.enableInspector,
144
116
  isBrowser: true,
145
117
  isDevelopment: process.env.NODE_ENV === "development",
118
+ hostname: window.location?.hostname,
146
119
  });
147
120
  }
148
121
 
@@ -150,7 +123,9 @@ onMounted(updateInspectorVisibility);
150
123
  watch(() => props.enableInspector, updateInspectorVisibility);
151
124
 
152
125
  const inspectorOpenRequest = ref<VueInspectorOpenRequest | null>(null);
153
- const isInspectorEnabled = computed(() => shouldRenderInspector.value);
126
+ const isInspectorEnabled = computed(
127
+ () => shouldRenderInspector.value && inspectorVisible.value,
128
+ );
154
129
 
155
130
  function openInspector(request: VueInspectorOpenRequest) {
156
131
  inspectorOpenRequest.value = { ...request };
@@ -161,17 +136,35 @@ provide(InspectorKey, {
161
136
  openInspector,
162
137
  });
163
138
 
139
+ const initialRenderToolCalls = props.renderToolCalls ?? [];
164
140
  const initialFrontendTools = props.frontendTools;
165
141
  const initialHumanInTheLoop = props.humanInTheLoop;
166
142
  const initialRenderCustomMessages = props.renderCustomMessages;
167
143
  const initialRenderActivityMessages = props.renderActivityMessages;
168
144
  const initialSandboxFunctions = props.openGenerativeUI?.sandboxFunctions;
169
145
 
146
+ // Props that come from reactive state arrive as deep proxies. Zod 4 schemas
147
+ // break behind a Vue proxy (their `_zod` property is read-only and
148
+ // non-configurable), so read tools and renderers through their raw objects.
149
+ const rawEntries = <T>(entries: readonly T[] | undefined): T[] =>
150
+ [...toRaw(entries ?? [])].map((entry) => toRaw(entry));
151
+
152
+ // Only the shape (agentId:name pairs) counts, so new render closures for the
153
+ // same tools do not warn.
154
+ watch(
155
+ () => props.renderToolCalls,
156
+ (next) => {
157
+ if (ɵtoolRendererShapeChanged(initialRenderToolCalls, next ?? [])) {
158
+ console.error(ɵSTABLE_ARRAY_WARNINGS.renderToolCalls);
159
+ }
160
+ },
161
+ );
162
+
170
163
  watch(
171
164
  () => props.frontendTools,
172
165
  (next) => {
173
166
  if (next !== initialFrontendTools) {
174
- console.error(FRONTEND_TOOLS_STABLE_WARNING);
167
+ console.error(ɵSTABLE_ARRAY_WARNINGS.frontendTools);
175
168
  }
176
169
  },
177
170
  );
@@ -180,7 +173,7 @@ watch(
180
173
  () => props.humanInTheLoop,
181
174
  (next) => {
182
175
  if (next !== initialHumanInTheLoop) {
183
- console.error(HUMAN_IN_THE_LOOP_STABLE_WARNING);
176
+ console.error(ɵSTABLE_ARRAY_WARNINGS.humanInTheLoop);
184
177
  }
185
178
  },
186
179
  );
@@ -189,7 +182,7 @@ watch(
189
182
  () => props.renderCustomMessages,
190
183
  (next) => {
191
184
  if (next !== initialRenderCustomMessages) {
192
- console.error(RENDER_CUSTOM_MESSAGES_STABLE_WARNING);
185
+ console.error(ɵSTABLE_ARRAY_WARNINGS.renderCustomMessages);
193
186
  }
194
187
  },
195
188
  );
@@ -198,7 +191,7 @@ watch(
198
191
  () => props.renderActivityMessages,
199
192
  (next) => {
200
193
  if (next !== initialRenderActivityMessages) {
201
- console.error(RENDER_ACTIVITY_MESSAGES_STABLE_WARNING);
194
+ console.error(ɵSTABLE_ARRAY_WARNINGS.renderActivityMessages);
202
195
  }
203
196
  },
204
197
  );
@@ -207,21 +200,30 @@ watch(
207
200
  () => props.openGenerativeUI?.sandboxFunctions,
208
201
  (next) => {
209
202
  if (next !== initialSandboxFunctions) {
210
- console.error(SANDBOX_FUNCTIONS_STABLE_WARNING);
203
+ console.error(ɵSTABLE_ARRAY_WARNINGS.sandboxFunctions);
211
204
  }
212
205
  },
213
206
  );
214
207
 
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
- );
208
+ // Key fallback, Copilot Cloud URL, transport, agent merge and the catalog
209
+ // property all come from core.
210
+ const resolvedConfig = computed(() =>
211
+ ɵresolveProviderConfig({
212
+ runtimeUrl: props.runtimeUrl,
213
+ publicApiKey: props.publicApiKey,
214
+ publicLicenseKey: props.publicLicenseKey,
215
+ useSingleEndpoint: props.useSingleEndpoint,
216
+ agents__unsafe_dev_only: props.agents__unsafe_dev_only,
217
+ selfManagedAgents: props.selfManagedAgents,
218
+ properties: props.properties,
219
+ a2uiCatalog: props.a2ui?.catalog,
220
+ }),
221
+ );
222
+ // Strings, so dependents only re-run when the value really changes.
223
+ const resolvedPublicKey = computed(() => resolvedConfig.value.publicKey);
224
+ const chatApiEndpoint = computed(() => resolvedConfig.value.runtimeUrl);
225
+ const runtimeTransport = computed(() => resolvedConfig.value.runtimeTransport);
226
+ const mergedAgents = computed(() => resolvedConfig.value.agents);
225
227
 
226
228
  // Whether `headers` is a builder, as its own computed so that a re-render
227
229
  // merely passing a NEW function of the same kind (e.g. a fresh inline arrow)
@@ -250,122 +252,46 @@ const latestHeaders = (() =>
250
252
  const headersSource = computed<CopilotKitHeadersSource>(() =>
251
253
  ɵwithHeaderDefaults(
252
254
  isHeadersBuilder.value ? latestHeaders : props.headers,
253
- resolvedPublicKey.value ? { [HEADER_NAME]: resolvedPublicKey.value } : {},
255
+ ɵpublicKeyHeaderDefaults(resolvedPublicKey.value),
254
256
  ),
255
257
  );
256
258
 
257
- const chatApiEndpoint = computed(
258
- () =>
259
- props.runtimeUrl ??
260
- (resolvedPublicKey.value ? COPILOT_CLOUD_CHAT_URL : undefined),
261
- );
262
-
259
+ // Throws in production for a missing runtime config; otherwise warns, once
260
+ // per provider for each message.
261
+ const loggedDiagnostics = new Set<string>();
263
262
  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);
263
+ () => resolvedConfig.value.diagnostics,
264
+ (diagnostics) => {
265
+ ɵreportProviderConfigDiagnostics(diagnostics, {
266
+ isProduction: process.env.NODE_ENV === "production",
267
+ logged: loggedDiagnostics,
268
+ });
273
269
  },
274
270
  { immediate: true },
275
271
  );
276
272
 
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
273
  const processedHumanInTheLoop = computed(() => {
299
274
  const tools: FrontendTool[] = [];
300
275
  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;
276
+ // Core parks each call by tool call id until the render responds. The core
277
+ // is created further down, so read its registry lazily.
278
+ const registry = () => copilotkit.value.ɵhumanInTheLoop;
279
+
280
+ for (const tool of rawEntries(props.humanInTheLoop)) {
281
+ const { render: ToolComponent, ...config } = tool;
282
+ tools.push(ɵbuildHumanInTheLoopTool(config, registry) as FrontendTool);
283
+ if (ToolComponent) {
343
284
  const render: VueToolCallRenderer<unknown>["render"] = (
344
285
  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
- };
286
+ ) =>
287
+ h(
288
+ ToolComponent as Parameters<typeof h>[0],
289
+ ɵhitlRenderProps(renderProps, tool, registry()),
290
+ );
365
291
 
366
292
  renderToolCalls.push({
367
293
  name: tool.name,
368
- args: tool.parameters ?? z.any(),
294
+ args: tool.parameters,
369
295
  render,
370
296
  ...(tool.agentId && { agentId: tool.agentId }),
371
297
  } as VueToolCallRenderer<unknown>);
@@ -376,7 +302,7 @@ const processedHumanInTheLoop = computed(() => {
376
302
 
377
303
  const allTools = computed(() => {
378
304
  const tools: FrontendTool[] = [];
379
- for (const t of props.frontendTools) {
305
+ for (const t of rawEntries(props.frontendTools)) {
380
306
  tools.push(t as FrontendTool);
381
307
  }
382
308
  for (const t of builtInFrontendTools.value) {
@@ -388,11 +314,15 @@ const allTools = computed(() => {
388
314
 
389
315
  const allRenderToolCalls = computed(() => {
390
316
  const combined: VueToolCallRenderer<unknown>[] = [
391
- ...(props.renderToolCalls ?? []),
317
+ ...rawEntries(props.renderToolCalls),
392
318
  ];
393
- for (const tool of [...props.frontendTools, ...builtInFrontendTools.value]) {
319
+ for (const tool of [
320
+ ...rawEntries(props.frontendTools),
321
+ ...builtInFrontendTools.value,
322
+ ]) {
394
323
  if (tool.render) {
395
- const args = tool.parameters ?? (tool.name === "*" ? z.any() : undefined);
324
+ const args =
325
+ tool.parameters ?? (tool.name === "*" ? ɵanySchema : undefined);
396
326
  if (args) {
397
327
  combined.push({
398
328
  name: tool.name,
@@ -409,15 +339,26 @@ const allRenderToolCalls = computed(() => {
409
339
  const allRenderCustomMessages = computed(
410
340
  () => props.renderCustomMessages ?? [],
411
341
  );
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,
342
+ // Core's runtime info snapshot, projected from the core watcher below.
343
+ const runtimeInfo = shallowRef<ɵRuntimeInfo | null>(null);
344
+ const runtimeA2UIEnabled = computed(
345
+ () => runtimeInfo.value?.a2uiEnabled ?? false,
346
+ );
347
+ const runtimeOpenGenerativeUIEnabled = computed(
348
+ () => runtimeInfo.value?.openGenerativeUIEnabled ?? false,
349
+ );
350
+ const runtimeLicenseStatus = computed(() => runtimeInfo.value?.licenseStatus);
351
+ const runtimeEntitlements = computed(
352
+ () => runtimeInfo.value?.runtimeEntitlements,
353
+ );
354
+ const runtimeEntitlementRetryPending = computed(
355
+ () => runtimeInfo.value?.runtimeEntitlementRetryPending ?? false,
417
356
  );
418
- const runtimeEntitlementRetryPending = ref(false);
419
- const openGenerativeUIActive = computed(
420
- () => runtimeOpenGenerativeUIEnabled.value || !!props.openGenerativeUI,
357
+ const openGenerativeUIActive = computed(() =>
358
+ ɵisOpenGenerativeUIActive({
359
+ runtimeEnabled: runtimeOpenGenerativeUIEnabled.value,
360
+ configured: !!props.openGenerativeUI,
361
+ }),
421
362
  );
422
363
  // A catalog passed to the provider is enough to turn A2UI on: render the
423
364
  // surfaces locally and forward the catalog signal so the runtime injects the
@@ -426,37 +367,23 @@ const a2uiCatalogProvided = computed(() => !!props.a2ui?.catalog);
426
367
  const a2uiActive = computed(
427
368
  () => runtimeA2UIEnabled.value || a2uiCatalogProvided.value,
428
369
  );
370
+ // The catalog with components disabled in the Inspector removed; set by
371
+ // `registerA2UICatalog` below once the core exists.
372
+ const a2uiFilteredCatalog = shallowRef<Catalog<ComponentApi> | undefined>(
373
+ undefined,
374
+ );
429
375
  // Forward a per-run signal when the provider has an A2UI catalog so the
430
376
  // runtime can turn A2UI on (and inject the render tool) without a separate
431
377
  // `a2ui.injectA2UITool` flag on the runtime.
432
- const resolvedProperties = computed(() =>
433
- a2uiCatalogProvided.value
434
- ? { ...props.properties, a2uiCatalogAvailable: true }
435
- : props.properties,
436
- );
437
- const sandboxFunctions = computed<readonly SandboxFunction[]>(
438
- () => props.openGenerativeUI?.sandboxFunctions ?? [],
378
+ const resolvedProperties = computed(() => resolvedConfig.value.properties);
379
+ const sandboxFunctions = computed<readonly SandboxFunction[]>(() =>
380
+ rawEntries(props.openGenerativeUI?.sandboxFunctions),
439
381
  );
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
382
  const builtInFrontendTools = computed<VueFrontendTool[]>(() => {
450
383
  if (!openGenerativeUIActive.value) return [];
451
384
  return [
452
385
  {
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,
386
+ ...ɵcreateOpenGenerativeUITool(),
460
387
  render:
461
388
  OpenGenerativeUIToolRenderer as unknown as VueFrontendTool["render"],
462
389
  } as VueFrontendTool,
@@ -469,7 +396,7 @@ const builtInActivityRenderers = computed<
469
396
  const renderers: VueActivityMessageRenderer<unknown>[] = [
470
397
  {
471
398
  activityType: MCPAppsActivityType,
472
- content: MCPAppsActivityContentSchema as unknown as z.ZodSchema<unknown>,
399
+ content: MCPAppsActivityContentSchema,
473
400
  render: (props.mcpApps?.allowSameOriginFallback
474
401
  ? SameOriginMCPAppsActivityRenderer
475
402
  : MCPAppsActivityRenderer) as unknown as VueActivityMessageRenderer<unknown>["render"],
@@ -479,7 +406,7 @@ const builtInActivityRenderers = computed<
479
406
  if (openGenerativeUIActive.value) {
480
407
  renderers.push({
481
408
  activityType: OpenGenerativeUIActivityType,
482
- content: OpenGenerativeUIContentSchema as unknown as z.ZodSchema<unknown>,
409
+ content: OpenGenerativeUIContentSchema,
483
410
  render:
484
411
  OpenGenerativeUIActivityRenderer as unknown as VueActivityMessageRenderer<unknown>["render"],
485
412
  });
@@ -488,10 +415,11 @@ const builtInActivityRenderers = computed<
488
415
  if (a2uiActive.value) {
489
416
  renderers.unshift(
490
417
  createA2UIMessageRenderer({
491
- theme: props.a2ui?.theme ?? viewerTheme,
492
- catalog: props.a2ui?.catalog,
418
+ theme: props.a2ui?.theme ?? {},
419
+ catalog: a2uiFilteredCatalog.value ?? props.a2ui?.catalog,
493
420
  loadingComponent: props.a2ui?.loadingComponent,
494
421
  recovery: props.a2ui?.recovery,
422
+ onAction: props.a2ui?.onAction,
495
423
  }),
496
424
  );
497
425
  }
@@ -500,44 +428,19 @@ const builtInActivityRenderers = computed<
500
428
  });
501
429
 
502
430
  const allRenderActivityMessages = computed(() => [
503
- ...(props.renderActivityMessages ?? []),
431
+ ...rawEntries(props.renderActivityMessages),
504
432
  ...builtInActivityRenderers.value,
505
433
  ]);
506
434
 
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
- }
529
-
530
- const learningConfig = computed(() => toLearningConfig(props.learning));
435
+ const learningConfig = computed(() => ɵtoLearningConfig(props.learning));
531
436
 
532
- const createCopilotKit = () => {
533
- const core = new CopilotKitCoreVue({
437
+ const createCopilotKit = () =>
438
+ new CopilotKitCoreVue({
534
439
  runtimeUrl: chatApiEndpoint.value,
535
- runtimeTransport:
536
- props.useSingleEndpoint === true
537
- ? "single"
538
- : props.useSingleEndpoint === false
539
- ? "rest"
540
- : "auto",
440
+ // `/info` starts from `onMounted` (`connect()` below), so server-side
441
+ // setup never fetches it.
442
+ deferInitialConnection: true,
443
+ runtimeTransport: runtimeTransport.value,
541
444
  headers: headersSource.value,
542
445
  credentials: props.credentials,
543
446
  messageFilter: props.messageFilter,
@@ -548,12 +451,12 @@ const createCopilotKit = () => {
548
451
  renderActivityMessages: allRenderActivityMessages.value,
549
452
  renderCustomMessages: allRenderCustomMessages.value,
550
453
  debug: props.debug,
454
+ // Set at construction so child hooks can read it on first render. Core
455
+ // validates it.
456
+ defaultThrottleMs: props.defaultThrottleMs,
457
+ onError: props.onError,
551
458
  learning: learningConfig.value,
552
459
  });
553
- // Initialize synchronously so child hooks can read the value on first render.
554
- applyDefaultThrottleMs(core);
555
- return core;
556
- };
557
460
 
558
461
  const copilotkit = shallowRef<CopilotKitCoreVue>(createCopilotKit());
559
462
  const didMountRef = ref(false);
@@ -563,27 +466,17 @@ const executingToolCallIds = ref<ReadonlySet<string>>(new Set());
563
466
  watch(
564
467
  copilotkit,
565
468
  (core, _, onCleanup) => {
469
+ // Core keeps a call executing until its result is in the messages, so
470
+ // the status never drops back to in-progress between the two.
471
+ executingToolCallIds.value = core.executingToolCallIds;
566
472
  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);
473
+ onExecutingToolCallsChanged: ({ executingToolCallIds: ids }) => {
474
+ const hasFinishedCall = ids.size < executingToolCallIds.value.size;
475
+ executingToolCallIds.value = ids;
476
+ // Core adds the result to `agent.messages` without a messages event,
477
+ // so re-read the agents once a call finishes. Not on start: that
478
+ // re-runs the agent subscriptions mid-run and drops a pending update.
479
+ if (hasFinishedCall) triggerRef(copilotkit);
587
480
  },
588
481
  });
589
482
  const sub2 = core.subscribe({
@@ -595,27 +488,21 @@ watch(
595
488
  onRenderCustomMessagesChanged: () => {
596
489
  triggerRef(copilotkit);
597
490
  },
491
+ onRenderActivityMessagesChanged: () => {
492
+ triggerRef(copilotkit);
493
+ },
494
+ });
495
+ runtimeInfo.value = core.ɵruntimeInfo;
496
+ const unsubscribeRuntimeInfo = core.ɵsubscribeToRuntimeInfo(() => {
497
+ runtimeInfo.value = core.ɵruntimeInfo;
598
498
  });
499
+ // Consumers read runtime getters off `copilotkit` directly, so every
500
+ // status event invalidates them.
599
501
  const sub4 = core.subscribe({
600
502
  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
503
  triggerRef(copilotkit);
608
504
  },
609
505
  });
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
506
  // `onHeadersChanged` fires only from a real `setHeaders()` call (a new
620
507
  // source), never from a builder resolving a new token — same generation
621
508
  // core bumps. Without this, nothing pokes Vue's reactivity when a source
@@ -633,7 +520,7 @@ watch(
633
520
  sub2.unsubscribe();
634
521
  sub3.unsubscribe();
635
522
  sub4.unsubscribe();
636
- sub5.unsubscribe();
523
+ unsubscribeRuntimeInfo();
637
524
  sub6.unsubscribe();
638
525
  });
639
526
  },
@@ -653,48 +540,34 @@ watch([allRenderToolCalls], ([renderToolCalls]) => {
653
540
  watch([allRenderCustomMessages], ([renderCustomMessages]) => {
654
541
  if (!didMountRef.value) return;
655
542
  copilotkit.value.setRenderCustomMessages(renderCustomMessages);
656
- triggerRef(copilotkit);
657
543
  });
658
544
 
659
545
  watch([allRenderActivityMessages], ([renderActivityMessages]) => {
660
546
  if (!didMountRef.value) return;
661
547
  copilotkit.value.setRenderActivityMessages(renderActivityMessages);
662
- triggerRef(copilotkit);
663
548
  });
664
549
 
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
-
550
+ // Every setter is a no-op when its value did not change (`setHeaders` too, for
551
+ // the same builder or an equal record, see #1937), so this can pass every key.
677
552
  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);
553
+ copilotkit.value.ɵupdateConfig({
554
+ messageFilter: props.messageFilter,
555
+ runtimeUrl: chatApiEndpoint.value,
556
+ runtimeTransport: runtimeTransport.value,
557
+ headers: headersSource.value,
558
+ credentials: props.credentials,
559
+ properties: resolvedProperties.value,
560
+ agents__unsafe_dev_only: mergedAgents.value,
561
+ debug: props.debug,
562
+ defaultThrottleMs: props.defaultThrottleMs,
563
+ });
696
564
  }
697
565
 
566
+ watch(
567
+ () => props.onError,
568
+ (onError) => copilotkit.value.setErrorHandler(onError),
569
+ );
570
+
698
571
  watch(
699
572
  [
700
573
  () => chatApiEndpoint.value,
@@ -703,7 +576,7 @@ watch(
703
576
  () => props.messageFilter,
704
577
  () => resolvedProperties.value,
705
578
  () => mergedAgents.value,
706
- () => props.useSingleEndpoint,
579
+ () => runtimeTransport.value,
707
580
  () => props.debug,
708
581
  ],
709
582
  () => {
@@ -714,111 +587,32 @@ watch(
714
587
 
715
588
  watch(
716
589
  () => props.defaultThrottleMs,
717
- () => {
590
+ (defaultThrottleMs) => {
718
591
  if (!didMountRef.value) return;
719
- applyDefaultThrottleMs(copilotkit.value);
592
+ copilotkit.value.ɵupdateConfig({ defaultThrottleMs });
720
593
  triggerRef(copilotkit);
721
594
  },
722
595
  );
723
596
 
724
597
  onMounted(() => {
725
598
  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;
599
+ // The constructor deferred `/info`; start it now that we are in the browser
600
+ // (`onMounted` never runs during SSR). Idempotent.
601
+ copilotkit.value.connect();
602
+ runtimeInfo.value = copilotkit.value.ɵruntimeInfo;
733
603
  didMountRef.value = true;
734
604
  // 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
-
605
+ // captured. The provider's onUnmounted disposes the starter (stops capture).
756
606
  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
- );
607
+ () => props.learning,
608
+ (learning) => learningStarter.update(learning),
609
+ {
610
+ immediate: true,
787
611
  },
788
- { immediate: true },
789
612
  );
613
+ });
790
614
 
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
- }
615
+ const learningStarter = new ɵLearningAutoStarter(copilotkit.value);
822
616
 
823
617
  const a2uiTheme = computed(() => props.a2ui?.theme);
824
618
  const a2uiCatalog = computed(() => props.a2ui?.catalog);
@@ -828,11 +622,15 @@ const a2uiIncludeSchema = computed(() => props.a2ui?.includeSchema ?? true);
828
622
  // A2UI tool call renderer (progress indicator) — auto-registered when A2UI enabled
829
623
  registerA2UIBuiltInToolCallRenderer(copilotkit, () => a2uiActive.value);
830
624
 
831
- // A2UI catalog context, schema, and generation/design guidelines
832
- registerA2UICatalogContext(copilotkit, {
625
+ // A2UI catalog: component registration for the Inspector, the filtered
626
+ // catalog, and the agent context (schema, generation/design guidelines).
627
+ registerA2UICatalog(copilotkit, {
833
628
  enabled: () => a2uiActive.value,
834
629
  catalog: () => props.a2ui?.catalog,
835
630
  includeSchema: () => props.a2ui?.includeSchema ?? true,
631
+ onFilteredCatalog: (catalog) => {
632
+ a2uiFilteredCatalog.value = catalog;
633
+ },
836
634
  });
837
635
 
838
636
  const providerContextIds = ref<string[]>([]);
@@ -845,33 +643,10 @@ watch(
845
643
  ([active, functions, designSkill], _previous, onCleanup) => {
846
644
  if (!active) return;
847
645
 
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,
854
- }),
855
- );
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
- }
646
+ const ids = ɵbuildOpenGenerativeUIContexts({
647
+ designSkill,
648
+ sandboxFunctions: functions,
649
+ }).map((entry) => copilotkit.value.addContext(entry));
875
650
 
876
651
  providerContextIds.value = ids;
877
652
  onCleanup(() => {
@@ -894,73 +669,27 @@ provide(CopilotKitKey, {
894
669
  provide(SandboxFunctionsKey, sandboxFunctions);
895
670
  provide(MARKDOWN_RENDERER_KEY, props.markdownRenderer);
896
671
 
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
- });
672
+ // License context and banner, from the runtime license status and the
673
+ // structured entitlement response.
674
+ const licenseState = computed(() =>
675
+ ɵresolveLicenseState({
676
+ status: runtimeLicenseStatus.value,
677
+ entitlements: runtimeEntitlements.value,
678
+ retryPending: runtimeEntitlementRetryPending.value,
679
+ publicKey: resolvedPublicKey.value,
680
+ }),
681
+ );
682
+ const licenseContextValue = computed(() => licenseState.value.context);
944
683
  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
- );
684
+ const licenseBannerType = computed(() => licenseState.value.bannerType);
685
+
686
+ // The provider created this core, so it stops the core's runs, timers and
687
+ // subscriptions. `onUnmounted` runs after the children unmount, so their
688
+ // cleanup still reaches a live core.
689
+ onUnmounted(() => {
690
+ learningStarter.dispose();
691
+ copilotkit.value.dispose();
692
+ });
964
693
  </script>
965
694
 
966
695
  <template>
@@ -969,10 +698,8 @@ const showExpiringBanner = computed(
969
698
  v-if="shouldRenderInspector"
970
699
  :core="copilotkit"
971
700
  :open-request="inspectorOpenRequest"
701
+ @visibility-change="inspectorVisible = $event"
972
702
  />
973
703
  <!-- 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" />
704
+ <LicenseWarningBanner v-if="licenseBannerType" :type="licenseBannerType" />
978
705
  </template>