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

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 (239) hide show
  1. package/PARITY.md +13 -12
  2. package/README.md +1 -2
  3. package/dist/components/copilot-provider/CopilotKit.vue.d.ts +3 -1
  4. package/dist/components/copilot-provider/CopilotKit.vue.d.ts.map +1 -1
  5. package/dist/index.cjs +43 -46
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.mjs +10170 -7506
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/v2/components/A2UIMessageRenderer.d.ts +7 -0
  10. package/dist/v2/components/A2UIMessageRenderer.d.ts.map +1 -1
  11. package/dist/v2/components/A2UISurfaceActivityRenderer.vue.d.ts.map +1 -1
  12. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts +11 -2
  13. package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts.map +1 -1
  14. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts +136 -0
  15. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts.map +1 -0
  16. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts.map +1 -1
  17. package/dist/v2/components/chat/CopilotChat.vue.d.ts +1 -0
  18. package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
  19. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts +3 -1
  20. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -1
  21. package/dist/v2/components/chat/CopilotChatAssistantToolbarButton.vue.d.ts +16 -0
  22. package/dist/v2/components/chat/CopilotChatAssistantToolbarButton.vue.d.ts.map +1 -0
  23. package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -1
  24. package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -1
  25. package/dist/v2/components/chat/CopilotChatAudioRecorder.vue.d.ts.map +1 -1
  26. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts +22 -0
  27. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts.map +1 -0
  28. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +69 -16
  29. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -1
  30. package/dist/v2/components/chat/CopilotChatInspectorButton.vue.d.ts +12 -0
  31. package/dist/v2/components/chat/CopilotChatInspectorButton.vue.d.ts.map +1 -0
  32. package/dist/v2/components/chat/CopilotChatLightbox.vue.d.ts +22 -0
  33. package/dist/v2/components/chat/CopilotChatLightbox.vue.d.ts.map +1 -0
  34. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +20 -0
  35. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -1
  36. package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -1
  37. package/dist/v2/components/chat/CopilotChatSuggestionPill.vue.d.ts.map +1 -1
  38. package/dist/v2/components/chat/CopilotChatSuggestionView.vue.d.ts.map +1 -1
  39. package/dist/v2/components/chat/CopilotChatToggleButton.vue.d.ts.map +1 -1
  40. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts +32 -0
  41. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts.map +1 -0
  42. package/dist/v2/components/chat/CopilotChatToolCallItem.vue.d.ts.map +1 -1
  43. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +11 -1
  44. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -1
  45. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -1
  46. package/dist/v2/components/chat/CopilotChatView.vue.d.ts +1 -0
  47. package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
  48. package/dist/v2/components/chat/CopilotChatWorkSummary.vue.d.ts +5 -0
  49. package/dist/v2/components/chat/CopilotChatWorkSummary.vue.d.ts.map +1 -0
  50. package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts.map +1 -1
  51. package/dist/v2/components/chat/CopilotModalHeaderCloseButton.d.ts.map +1 -1
  52. package/dist/v2/components/chat/CopilotModalHeaderTitle.d.ts.map +1 -1
  53. package/dist/v2/components/chat/CopilotPopup.vue.d.ts +1 -0
  54. package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -1
  55. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts +1 -0
  56. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -1
  57. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts +1 -0
  58. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -1
  59. package/dist/v2/components/chat/CopilotPopupWelcomeScreen.vue.d.ts.map +1 -1
  60. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts +2 -0
  61. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -1
  62. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +2 -0
  63. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -1
  64. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +2 -0
  65. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -1
  66. package/dist/v2/components/chat/CopilotSidebarWelcomeScreen.vue.d.ts.map +1 -1
  67. package/dist/v2/components/chat/StreamingMarkdownDefault.vue.d.ts.map +1 -1
  68. package/dist/v2/components/chat/index.d.ts +17 -0
  69. package/dist/v2/components/chat/index.d.ts.map +1 -1
  70. package/dist/v2/components/chat/inspector-shortcuts.d.ts +12 -0
  71. package/dist/v2/components/chat/inspector-shortcuts.d.ts.map +1 -0
  72. package/dist/v2/components/chat/message-feedback.d.ts +89 -0
  73. package/dist/v2/components/chat/message-feedback.d.ts.map +1 -0
  74. package/dist/v2/components/chat/tool-call-capture.d.ts +39 -0
  75. package/dist/v2/components/chat/tool-call-capture.d.ts.map +1 -0
  76. package/dist/v2/components/chat/tool-call-display-context.d.ts +39 -0
  77. package/dist/v2/components/chat/tool-call-display-context.d.ts.map +1 -0
  78. package/dist/v2/components/chat/tool-call-group-parts.d.ts +144 -0
  79. package/dist/v2/components/chat/tool-call-group-parts.d.ts.map +1 -0
  80. package/dist/v2/components/chat/tool-call-layout.d.ts +115 -0
  81. package/dist/v2/components/chat/tool-call-layout.d.ts.map +1 -0
  82. package/dist/v2/components/chat/turn-work.d.ts +35 -0
  83. package/dist/v2/components/chat/turn-work.d.ts.map +1 -0
  84. package/dist/v2/components/chat/types.d.ts +104 -4
  85. package/dist/v2/components/chat/types.d.ts.map +1 -1
  86. package/dist/v2/components/chat/use-lightbox.d.ts +18 -0
  87. package/dist/v2/components/chat/use-lightbox.d.ts.map +1 -0
  88. package/dist/v2/components/icons/index.d.ts +1 -1
  89. package/dist/v2/components/icons/index.d.ts.map +1 -1
  90. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts +55 -0
  91. package/dist/v2/components/ui/CopilotDropdownMenuContent.vue.d.ts.map +1 -0
  92. package/dist/v2/components/ui/CopilotPopover.vue.d.ts +40 -0
  93. package/dist/v2/components/ui/CopilotPopover.vue.d.ts.map +1 -0
  94. package/dist/v2/components/ui/CopilotTooltip.vue.d.ts +37 -0
  95. package/dist/v2/components/ui/CopilotTooltip.vue.d.ts.map +1 -0
  96. package/dist/v2/components/ui/dropdown-menu.d.ts +14 -0
  97. package/dist/v2/components/ui/dropdown-menu.d.ts.map +1 -0
  98. package/dist/v2/components/ui/floating.d.ts +84 -0
  99. package/dist/v2/components/ui/floating.d.ts.map +1 -0
  100. package/dist/v2/components/ui/presence.d.ts +9 -0
  101. package/dist/v2/components/ui/presence.d.ts.map +1 -0
  102. package/dist/v2/components/ui/use-id.d.ts +9 -0
  103. package/dist/v2/components/ui/use-id.d.ts.map +1 -0
  104. package/dist/v2/hooks/use-default-render-tool.d.ts +6 -0
  105. package/dist/v2/hooks/use-default-render-tool.d.ts.map +1 -1
  106. package/dist/v2/hooks/use-render-tool.d.ts +4 -0
  107. package/dist/v2/hooks/use-render-tool.d.ts.map +1 -1
  108. package/dist/v2/index.cjs +1 -1
  109. package/dist/v2/index.d.cts +3 -0
  110. package/dist/v2/index.d.mts +3 -0
  111. package/dist/v2/index.d.ts +3 -0
  112. package/dist/v2/index.d.ts.map +1 -1
  113. package/dist/v2/index.mjs +165 -162
  114. package/dist/v2/lib/message-feedback.d.ts +33 -0
  115. package/dist/v2/lib/message-feedback.d.ts.map +1 -0
  116. package/dist/v2/providers/CopilotChatConfigurationProvider.vue.d.ts.map +1 -1
  117. package/dist/v2/providers/CopilotKitProvider.types.d.ts +56 -1
  118. package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -1
  119. package/dist/v2/providers/CopilotKitProvider.vue.d.ts +5 -1
  120. package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
  121. package/dist/v2/providers/index.d.ts +1 -1
  122. package/dist/v2/providers/index.d.ts.map +1 -1
  123. package/dist/v2/providers/keys.d.ts +8 -0
  124. package/dist/v2/providers/keys.d.ts.map +1 -1
  125. package/dist/v2/providers/types.d.ts +9 -0
  126. package/dist/v2/providers/types.d.ts.map +1 -1
  127. package/dist/v2/styles/CopilotKitStyles.d.ts +18 -0
  128. package/dist/v2/styles/CopilotKitStyles.d.ts.map +1 -0
  129. package/dist/v2/types/defineToolCallRenderer.d.ts +2 -0
  130. package/dist/v2/types/defineToolCallRenderer.d.ts.map +1 -1
  131. package/dist/v2/types/vue-tool-call-renderer.d.ts +7 -0
  132. package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -1
  133. package/package.json +11 -23
  134. package/src/components/copilot-provider/CopilotKit.vue +4 -1
  135. package/src/v2/__tests__/exports.test.ts +4 -2
  136. package/src/v2/components/A2UIMessageRenderer.ts +55 -67
  137. package/src/v2/components/A2UISurfaceActivityRenderer.vue +11 -23
  138. package/src/v2/components/__tests__/A2UIBasicCatalogColors.test.ts +8 -9
  139. package/src/v2/components/__tests__/A2UIMessageRenderer.test.ts +63 -36
  140. package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +14 -257
  141. package/src/v2/components/a2ui/A2UIRecoveryStates.ts +444 -0
  142. package/src/v2/components/a2ui/__tests__/A2UIRecoveryStates.test.ts +175 -0
  143. package/src/v2/components/chat/BasicMarkdown.vue +8 -6
  144. package/src/v2/components/chat/CopilotChat.vue +7 -0
  145. package/src/v2/components/chat/CopilotChatAssistantMessage.vue +267 -67
  146. package/src/v2/components/chat/CopilotChatAssistantToolbarButton.vue +46 -0
  147. package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +141 -168
  148. package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +67 -18
  149. package/src/v2/components/chat/CopilotChatAudioRecorder.vue +2 -2
  150. package/src/v2/components/chat/CopilotChatFeedbackCommentPopover.vue +240 -0
  151. package/src/v2/components/chat/CopilotChatInput.vue +210 -161
  152. package/src/v2/components/chat/CopilotChatInspectorButton.vue +331 -0
  153. package/src/v2/components/chat/CopilotChatLightbox.vue +105 -0
  154. package/src/v2/components/chat/CopilotChatMessageView.vue +261 -18
  155. package/src/v2/components/chat/CopilotChatReasoningMessage.vue +21 -22
  156. package/src/v2/components/chat/CopilotChatSuggestionPill.vue +5 -14
  157. package/src/v2/components/chat/CopilotChatSuggestionView.vue +1 -4
  158. package/src/v2/components/chat/CopilotChatToggleButton.vue +3 -9
  159. package/src/v2/components/chat/CopilotChatToggleButtonCloseIcon.ts +1 -1
  160. package/src/v2/components/chat/CopilotChatToggleButtonOpenIcon.ts +1 -1
  161. package/src/v2/components/chat/CopilotChatToolCallGroup.vue +330 -0
  162. package/src/v2/components/chat/CopilotChatToolCallItem.vue +21 -11
  163. package/src/v2/components/chat/CopilotChatToolCallsView.vue +192 -21
  164. package/src/v2/components/chat/CopilotChatUserMessage.vue +105 -42
  165. package/src/v2/components/chat/CopilotChatView.vue +33 -38
  166. package/src/v2/components/chat/CopilotChatWorkSummary.vue +85 -0
  167. package/src/v2/components/chat/CopilotModalHeader.vue +10 -8
  168. package/src/v2/components/chat/CopilotModalHeaderCloseButton.ts +7 -6
  169. package/src/v2/components/chat/CopilotModalHeaderTitle.ts +1 -4
  170. package/src/v2/components/chat/CopilotPopup.vue +3 -0
  171. package/src/v2/components/chat/CopilotPopupView.vue +1 -0
  172. package/src/v2/components/chat/CopilotPopupViewInternal.vue +9 -19
  173. package/src/v2/components/chat/CopilotPopupWelcomeScreen.vue +5 -8
  174. package/src/v2/components/chat/CopilotSidebar.vue +5 -0
  175. package/src/v2/components/chat/CopilotSidebarView.vue +2 -0
  176. package/src/v2/components/chat/CopilotSidebarViewInternal.vue +24 -17
  177. package/src/v2/components/chat/CopilotSidebarWelcomeScreen.vue +7 -10
  178. package/src/v2/components/chat/StreamingMarkdownDefault.vue +3 -5
  179. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.inspector.test.ts +269 -0
  180. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.learningFeedback.test.ts +760 -0
  181. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.slots.e2e.test.ts +3 -5
  182. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.test.ts +2 -2
  183. package/src/v2/components/chat/__tests__/CopilotChatInput.addMenu.test.ts +328 -0
  184. package/src/v2/components/chat/__tests__/CopilotChatInput.slots.e2e.test.ts +6 -3
  185. package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +22 -13
  186. package/src/v2/components/chat/__tests__/CopilotChatLightbox.test.ts +160 -0
  187. package/src/v2/components/chat/__tests__/CopilotChatMessageView.toolCallDisplay.test.ts +735 -0
  188. package/src/v2/components/chat/__tests__/CopilotChatSuggestionPill.test.ts +1 -1
  189. package/src/v2/components/chat/__tests__/CopilotChatSuggestionView.slots.e2e.test.ts +3 -1
  190. package/src/v2/components/chat/__tests__/CopilotChatToolCallsView.learning.test.ts +75 -0
  191. package/src/v2/components/chat/__tests__/CopilotChatUserMessage.attachments.test.ts +143 -0
  192. package/src/v2/components/chat/__tests__/CopilotChatView.inputOverlay.test.ts +5 -4
  193. package/src/v2/components/chat/__tests__/CopilotChatView.rootWidth.test.ts +7 -33
  194. package/src/v2/components/chat/__tests__/CopilotModalHeader.slots.e2e.test.ts +1 -1
  195. package/src/v2/components/chat/__tests__/CopilotPopupView.slots.e2e.test.ts +3 -3
  196. package/src/v2/components/chat/__tests__/CopilotSidebarView.position.test.ts +126 -0
  197. package/src/v2/components/chat/__tests__/messageFeedbackDefaults.test.ts +33 -0
  198. package/src/v2/components/chat/__tests__/modalChatDisplayProps.test.ts +44 -0
  199. package/src/v2/components/chat/index.ts +2 -0
  200. package/src/v2/components/chat/inspector-shortcuts.ts +34 -0
  201. package/src/v2/components/chat/message-feedback.ts +291 -0
  202. package/src/v2/components/chat/tool-call-capture.ts +55 -0
  203. package/src/v2/components/chat/tool-call-display-context.ts +49 -0
  204. package/src/v2/components/chat/tool-call-group-parts.ts +292 -0
  205. package/src/v2/components/chat/tool-call-layout.ts +304 -0
  206. package/src/v2/components/chat/turn-work.ts +61 -0
  207. package/src/v2/components/chat/types.ts +113 -3
  208. package/src/v2/components/chat/use-lightbox.ts +64 -0
  209. package/src/v2/components/icons/index.ts +4 -0
  210. package/src/v2/components/ui/CopilotDropdownMenuContent.vue +465 -0
  211. package/src/v2/components/ui/CopilotPopover.vue +138 -0
  212. package/src/v2/components/ui/CopilotTooltip.vue +237 -0
  213. package/src/v2/components/ui/__tests__/CopilotTooltip.test.ts +168 -0
  214. package/src/v2/components/ui/dropdown-menu.ts +15 -0
  215. package/src/v2/components/ui/floating.ts +321 -0
  216. package/src/v2/components/ui/presence.ts +54 -0
  217. package/src/v2/components/ui/use-id.ts +16 -0
  218. package/src/v2/hooks/use-default-render-tool.ts +123 -62
  219. package/src/v2/hooks/use-render-tool.ts +8 -0
  220. package/src/v2/index.ts +3 -0
  221. package/src/v2/lib/__tests__/message-feedback.test.ts +152 -0
  222. package/src/v2/lib/message-feedback.ts +120 -0
  223. package/src/v2/providers/CopilotChatConfigurationProvider.vue +29 -2
  224. package/src/v2/providers/CopilotKitProvider.types.ts +57 -0
  225. package/src/v2/providers/CopilotKitProvider.vue +125 -3
  226. package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.openThread.test.ts +69 -0
  227. package/src/v2/providers/__tests__/CopilotKitProvider.learning.test.ts +534 -0
  228. package/src/v2/providers/index.ts +4 -1
  229. package/src/v2/providers/keys.ts +12 -0
  230. package/src/v2/providers/types.ts +11 -0
  231. package/src/v2/styles/CopilotKitStyles.ts +95 -0
  232. package/src/v2/styles/__tests__/CopilotKitStyles.client.test.ts +149 -0
  233. package/src/v2/styles/__tests__/CopilotKitStyles.ssr.test.ts +71 -0
  234. package/src/v2/types/defineToolCallRenderer.ts +4 -0
  235. package/src/v2/types/vue-tool-call-renderer.ts +7 -0
  236. package/vite.config.ts +2 -1
  237. package/dist/styles.css +0 -2
  238. package/scripts/scope-preflight.mjs +0 -100
  239. package/src/styles/globals.css +0 -233
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Renders the CSS for CopilotKit's UI, so apps never import a stylesheet.
3
+ * `CopilotChat` (and so `CopilotPopup` and `CopilotSidebar`) renders it for
4
+ * you. Render it yourself only when you build a layout from the chat parts
5
+ * without `CopilotChat`.
6
+ *
7
+ * The `<style>` tag renders in place, so it is in the server HTML and the page
8
+ * is styled before it hydrates. Only the first instance in the app renders the
9
+ * tag, so a page with many chats has one copy. When that instance unmounts, the
10
+ * next one renders the tag in the same update. The server and the client set
11
+ * up instances in the same order, so hydration matches.
12
+ *
13
+ * Renders nothing when `CopilotKitProvider` has `:inject-styles="false"`.
14
+ */
15
+ export declare const CopilotKitStyles: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
16
+ [key: string]: any;
17
+ }> | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
18
+ //# sourceMappingURL=CopilotKitStyles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CopilotKitStyles.d.ts","sourceRoot":"","sources":["../../../src/v2/styles/CopilotKitStyles.ts"],"names":[],"mappings":"AA2BA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB;;kPAqD3B,CAAC"}
@@ -5,11 +5,13 @@ export declare function defineToolCallRenderer(def: {
5
5
  name: "*";
6
6
  render: VueToolCallRendererRenderFn<unknown>;
7
7
  agentId?: string;
8
+ group?: boolean;
8
9
  }): VueToolCallRenderer<unknown>;
9
10
  export declare function defineToolCallRenderer<S extends StandardSchemaV1>(def: {
10
11
  name: string;
11
12
  args: S;
12
13
  render: VueToolCallRendererRenderFn<InferSchemaOutput<S>>;
13
14
  agentId?: string;
15
+ group?: boolean;
14
16
  }): VueToolCallRenderer<InferSchemaOutput<S>>;
15
17
  //# sourceMappingURL=defineToolCallRenderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"defineToolCallRenderer.d.ts","sourceRoot":"","sources":["../../../src/v2/types/defineToolCallRenderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAE5E,wBAAgB,sBAAsB,CAAC,GAAG,EAAE;IAC1C,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,EAAE,2BAA2B,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAEjC,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,gBAAgB,EAAE,GAAG,EAAE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,2BAA2B,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"defineToolCallRenderer.d.ts","sourceRoot":"","sources":["../../../src/v2/types/defineToolCallRenderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAE5E,wBAAgB,sBAAsB,CAAC,GAAG,EAAE;IAC1C,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,EAAE,2BAA2B,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAEjC,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,gBAAgB,EAAE,GAAG,EAAE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,2BAA2B,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -32,6 +32,13 @@ export interface VueToolCallRenderer<T = unknown> {
32
32
  name: string;
33
33
  args: StandardSchemaV1<any, T>;
34
34
  agentId?: string;
35
+ /**
36
+ * Whether calls this renderer draws join the chat's tool-call groups (see
37
+ * `toolCallDisplay` on `CopilotChatMessageView`). CopilotKit's built-in card
38
+ * sets it; a renderer that leaves it unset always shows its calls on their
39
+ * own, since the chat can't tell what it draws (it may even draw nothing).
40
+ */
41
+ group?: boolean;
35
42
  render: VueToolCallRendererRenderFn<T>;
36
43
  }
37
44
  //# sourceMappingURL=vue-tool-call-renderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vue-tool-call-renderer.d.ts","sourceRoot":"","sources":["../../../src/v2/types/vue-tool-call-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,8BAA8B,CAAC,CAAC,IACxC;IACE,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC;IAClC,MAAM,EAAE,SAAS,CAAC;CACnB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,cAAc,CAAC,SAAS,CAAC;IACjC,MAAM,EAAE,SAAS,CAAC;CACnB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN;;;GAGG;AACH,MAAM,MAAM,2BAA2B,CAAC,CAAC,IACrC,CAAC,CAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,GAC1D,SAAS,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAAC,CAAC;AAEjD,MAAM,WAAW,mBAAmB,CAAC,CAAC,GAAG,OAAO;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,2BAA2B,CAAC,CAAC,CAAC,CAAC;CACxC"}
1
+ {"version":3,"file":"vue-tool-call-renderer.d.ts","sourceRoot":"","sources":["../../../src/v2/types/vue-tool-call-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,8BAA8B,CAAC,CAAC,IACxC;IACE,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC;IAClC,MAAM,EAAE,SAAS,CAAC;CACnB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,cAAc,CAAC,SAAS,CAAC;IACjC,MAAM,EAAE,SAAS,CAAC;CACnB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN;;;GAGG;AACH,MAAM,MAAM,2BAA2B,CAAC,CAAC,IACrC,CAAC,CAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,GAC1D,SAAS,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAAC,CAAC;AAEjD,MAAM,WAAW,mBAAmB,CAAC,CAAC,GAAG,OAAO;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,2BAA2B,CAAC,CAAC,CAAC,CAAC;CACxC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@copilotkit/vue",
3
- "version": "2.0.0-rc.1",
3
+ "version": "2.0.0-rc.3",
4
4
  "private": false,
5
5
  "description": "Vue 3 components and composables for CopilotKit",
6
6
  "keywords": [
@@ -20,9 +20,7 @@
20
20
  "url": "https://github.com/CopilotKit/CopilotKit.git"
21
21
  },
22
22
  "type": "module",
23
- "sideEffects": [
24
- "**/*.css"
25
- ],
23
+ "sideEffects": false,
26
24
  "main": "./dist/index.cjs",
27
25
  "module": "./dist/index.mjs",
28
26
  "types": "./dist/index.d.cts",
@@ -54,7 +52,6 @@
54
52
  "default": "./dist/v2/index.cjs"
55
53
  }
56
54
  },
57
- "./styles.css": "./dist/styles.css",
58
55
  "./package.json": "./package.json"
59
56
  },
60
57
  "publishConfig": {
@@ -64,12 +61,12 @@
64
61
  "@a2ui/web_core": "0.10.4",
65
62
  "@ag-ui/client": "1.0.2",
66
63
  "@ag-ui/core": "1.0.2",
67
- "@copilotkit/core": "2.0.0-rc.1",
68
- "@copilotkit/markdown-renderer": "2.0.0-rc.1",
69
- "@copilotkit/mcp-apps-renderer": "2.0.0-rc.1",
70
- "@copilotkit/shared": "2.0.0-rc.1",
71
- "@copilotkit/web-components": "2.0.0-rc.1",
72
- "@copilotkit/web-inspector": "2.0.0-rc.1",
64
+ "@copilotkit/core": "2.0.0-rc.3",
65
+ "@copilotkit/markdown-renderer": "2.0.0-rc.3",
66
+ "@copilotkit/mcp-apps-renderer": "2.0.0-rc.3",
67
+ "@copilotkit/shared": "2.0.0-rc.3",
68
+ "@copilotkit/web-components": "2.0.0-rc.3",
69
+ "@copilotkit/web-inspector": "2.0.0-rc.3",
73
70
  "@jetbrains/websandbox": "^1.1.3",
74
71
  "lucide-vue-next": "^0.525.0",
75
72
  "zod": "^3.25.75",
@@ -77,25 +74,18 @@
77
74
  },
78
75
  "devDependencies": {
79
76
  "@eslint/js": "^9.39.2",
80
- "@tailwindcss/cli": "^4.1.11",
81
- "@tailwindcss/postcss": "^4.1.11",
82
- "@tailwindcss/typography": "^0.5.16",
83
77
  "@testing-library/vue": "^8.1.0",
84
78
  "@types/node": "^22.15.3",
85
79
  "@vitejs/plugin-vue": "^5.2.1",
86
80
  "@vue/compiler-sfc": "^3.5.14",
87
81
  "@vue/test-utils": "^2.4.6",
88
82
  "arktype": "^2.1.29",
89
- "concurrently": "^9.1.0",
90
83
  "eslint": "^9.30.0",
91
84
  "eslint-plugin-vue": "^10.8.0",
92
85
  "globals": "^16.5.0",
93
86
  "jsdom": "^26.1.0",
94
87
  "phoenix": "^1.8.4",
95
- "postcss": "^8.5.6",
96
88
  "rxjs": "7.8.1",
97
- "tailwindcss": "^4.0.8",
98
- "tw-animate-css": "^1.3.5",
99
89
  "typescript": "5.8.2",
100
90
  "typescript-eslint": "^8.52.0",
101
91
  "valibot": "^1.3.0",
@@ -113,11 +103,9 @@
113
103
  "node": ">=20"
114
104
  },
115
105
  "scripts": {
116
- "build": "vite build && pnpm build:css && pnpm build:types",
117
- "build:css": "npx @tailwindcss/cli -i ./src/styles/globals.css -o ./dist/styles.css -m && node scripts/scope-preflight.mjs ./dist/styles.css",
106
+ "build": "vite build && pnpm build:types",
118
107
  "build:types": "vue-tsc -p tsconfig.json --declaration --emitDeclarationOnly --outDir dist --skipLibCheck && node -e \"const fs=require('fs');fs.cpSync('./dist/index.d.ts','./dist/index.d.mts');fs.cpSync('./dist/index.d.ts','./dist/index.d.cts');fs.cpSync('./dist/v2/index.d.ts','./dist/v2/index.d.mts');fs.cpSync('./dist/v2/index.d.ts','./dist/v2/index.d.cts')\"",
119
- "dev:css": "npx @tailwindcss/cli -i ./src/styles/globals.css -o ./dist/styles.css --watch --minify",
120
- "dev": "concurrently \"pnpm dev:css\" \"vite build --watch\"",
108
+ "dev": "vite build --watch",
121
109
  "test": "vitest run",
122
110
  "test:watch": "vitest",
123
111
  "test:coverage": "vitest run --coverage",
@@ -125,7 +113,7 @@
125
113
  "lint": "eslint .",
126
114
  "check-types": "vue-tsc --noEmit",
127
115
  "publint": "publint .",
128
- "attw": "attw --pack . --profile node16 --exclude-entrypoints ./styles.css --ignore-rules internal-resolution-error",
116
+ "attw": "attw --pack . --profile node16 --ignore-rules internal-resolution-error",
129
117
  "clean": "node -e \"const fs=require('fs');fs.rmSync('dist',{recursive:true,force:true})\""
130
118
  }
131
119
  }
@@ -8,7 +8,10 @@
8
8
  import type { CopilotKitProps } from "./types";
9
9
  import CopilotKitProvider from "../../v2/providers/CopilotKitProvider.vue";
10
10
 
11
- const props = defineProps<CopilotKitProps>();
11
+ // Vue casts an absent boolean prop to `false`, so keep the provider's default.
12
+ const props = withDefaults(defineProps<CopilotKitProps>(), {
13
+ injectStyles: true,
14
+ });
12
15
  </script>
13
16
 
14
17
  <template>
@@ -8,6 +8,7 @@ describe("package exports", () => {
8
8
  expect(typeof VuePackage.CopilotChat.View).toBe("object");
9
9
  expect(typeof VuePackage.CopilotChatMessageView).toBe("object");
10
10
  expect(typeof VuePackage.CopilotChatToolCallsView).toBe("object");
11
+ expect(typeof VuePackage.CopilotChatToolCallGroup).toBe("object");
11
12
  expect(typeof VuePackage.CopilotChatInput).toBe("object");
12
13
  expect(typeof VuePackage.CopilotChatAssistantMessage).toBe("object");
13
14
  expect(typeof VuePackage.CopilotChatUserMessage).toBe("object");
@@ -32,11 +33,12 @@ describe("package exports", () => {
32
33
  expect(VuePackage.vueBasicCatalog.components.size).toBeGreaterThan(0);
33
34
  });
34
35
 
35
- it("exports the vue stylesheet entrypoint", () => {
36
+ it("exports CopilotKitStyles and no stylesheet, since the CSS is injected", () => {
36
37
  const packageJson = JSON.parse(readFileSync("package.json", "utf8")) as {
37
38
  exports?: Record<string, unknown>;
38
39
  };
39
40
 
40
- expect(packageJson.exports?.["./styles.css"]).toBe("./dist/styles.css");
41
+ expect(typeof VuePackage.CopilotKitStyles).toBe("object");
42
+ expect(packageJson.exports?.["./styles.css"]).toBeUndefined();
41
43
  });
42
44
  });
@@ -4,86 +4,74 @@ import { z } from "zod";
4
4
  import type { VueActivityMessageRenderer } from "../types";
5
5
  import type { A2UITheme } from "../types";
6
6
  import A2UISurfaceActivityRenderer from "./A2UISurfaceActivityRenderer.vue";
7
+ import {
8
+ A2UIBuildingState,
9
+ A2UILifecycleFields,
10
+ A2UIRecoveryFailure,
11
+ A2UIRetryingState,
12
+ resolveDebugExposure,
13
+ } from "./a2ui/A2UIRecoveryStates";
14
+ import type { A2UIRecoveryRendererOptions } from "./a2ui/A2UIRecoveryStates";
7
15
 
8
16
  const A2UI_OPERATIONS_KEY = "a2ui_operations";
9
17
 
10
18
  export type A2UIMessageRendererOptions = {
11
19
  theme: A2UITheme;
12
20
  catalog?: any;
21
+ /** Optional custom loading component shown while the A2UI surface is building. */
13
22
  loadingComponent?: unknown;
23
+ /**
24
+ * Pre-paint recovery/loading UX options: timing before the "Retrying…"
25
+ * sub-label appears, and how much retry/debug detail to surface.
26
+ */
27
+ recovery?: A2UIRecoveryRendererOptions;
14
28
  };
15
29
 
16
30
  /**
17
- * Default loading component shown while an A2UI surface is generating.
18
- * Mirrors React's `DefaultA2UILoading` in
19
- * `packages/react-core/src/a2ui/A2UIMessageRenderer.tsx`:
20
- * an animated dot + "Generating UI..." label + three shimmer bars
21
- * (80% / 60% / 40% widths) with staggered `cpk-a2ui-pulse` opacity animation.
31
+ * The `a2ui-surface` activity carries the WHOLE generative-UI lifecycle on one
32
+ * stable messageId: pre-paint `status` ("building" | "retrying" | "failed")
33
+ * with recovery detail, then `a2ui_operations` on paint. The states swap in
34
+ * place, so the painted surface replaces the skeleton. `.passthrough()` keeps
35
+ * the operations and any future fields.
22
36
  */
23
- const DefaultA2UILoading = defineComponent({
24
- name: "DefaultA2UILoading",
25
- setup() {
26
- const barWidths = [0.8, 0.6, 0.4] as const;
27
- return () =>
28
- h(
29
- "div",
30
- {
31
- class:
32
- "cpk:flex cpk:flex-col cpk:gap-3 cpk:rounded-xl cpk:border cpk:border-gray-100 cpk:bg-gray-50/50 cpk:p-5",
33
- style: { minHeight: "120px" },
34
- "data-testid": "a2ui-loading",
35
- },
36
- [
37
- h("div", { class: "cpk:flex cpk:items-center cpk:gap-2" }, [
38
- h("div", {
39
- class: "cpk:h-3 cpk:w-3 cpk:rounded-full cpk:bg-gray-200",
40
- style: {
41
- animation: "cpk-a2ui-pulse 1.5s ease-in-out infinite",
42
- },
43
- "data-testid": "a2ui-loading-dot",
44
- }),
45
- h(
46
- "span",
47
- {
48
- class: "cpk:text-xs cpk:font-medium cpk:text-gray-400",
49
- },
50
- "Generating UI...",
51
- ),
52
- ]),
53
- h(
54
- "div",
55
- { class: "cpk:flex cpk:flex-col cpk:gap-2" },
56
- barWidths.map((width, i) =>
57
- h("div", {
58
- key: i,
59
- class: "cpk:h-3 cpk:rounded cpk:bg-gray-200/70",
60
- style: {
61
- width: `${width * 100}%`,
62
- animation: `cpk-a2ui-pulse 1.5s ease-in-out ${i * 0.15}s infinite`,
63
- },
64
- "data-testid": "a2ui-loading-bar",
65
- }),
66
- ),
67
- ),
68
- h(
69
- "style",
70
- {},
71
- `@keyframes cpk-a2ui-pulse {
72
- 0%, 100% { opacity: 0.4; }
73
- 50% { opacity: 1; }
74
- }`,
75
- ),
76
- ],
77
- );
78
- },
79
- });
37
+ const A2UISurfaceContentSchema = z
38
+ .object({
39
+ a2ui_operations: z.array(z.any()).optional(),
40
+ ...A2UILifecycleFields,
41
+ })
42
+ .passthrough();
80
43
 
81
44
  export function createA2UIMessageRenderer(
82
45
  options: A2UIMessageRendererOptions,
83
46
  ): VueActivityMessageRenderer<any> {
47
+ const showAfterMs = options.recovery?.showAfterMs ?? 2000;
48
+ const showAfterAttempts = options.recovery?.showAfterAttempts ?? 2;
49
+ const optionDebugExposure = options.recovery?.debugExposure ?? "collapsed";
50
+
51
+ // Renders the pre-paint lifecycle state for a content snapshot.
52
+ const renderLifecycle = (content: any) => {
53
+ const debugExposure = resolveDebugExposure(content, optionDebugExposure);
54
+ if (content?.status === "failed") {
55
+ return h(A2UIRecoveryFailure, { content, debugExposure });
56
+ }
57
+ if (content?.status === "retrying") {
58
+ return h(A2UIRetryingState, {
59
+ content,
60
+ showAfterMs,
61
+ showAfterAttempts,
62
+ debugExposure,
63
+ });
64
+ }
65
+ // "building" / default: a host-supplied loader wins; else the skeleton.
66
+ if (options.loadingComponent) {
67
+ return h(options.loadingComponent as any);
68
+ }
69
+ return h(A2UIBuildingState, { content });
70
+ };
71
+
84
72
  return {
85
73
  activityType: "a2ui-surface",
86
- content: z.any(),
74
+ content: A2UISurfaceContentSchema,
87
75
  render: defineComponent({
88
76
  name: "A2UIMessageRendererHost",
89
77
  props: {
@@ -104,11 +92,11 @@ export function createA2UIMessageRenderer(
104
92
  );
105
93
 
106
94
  return () => {
95
+ // No painted surface yet → the pre-paint lifecycle state. It shares
96
+ // this activity's messageId, so the painted surface below replaces
97
+ // it in place once operations arrive.
107
98
  if (operations.value.length === 0) {
108
- if (options.loadingComponent) {
109
- return h(options.loadingComponent as any);
110
- }
111
- return h(DefaultA2UILoading);
99
+ return renderLifecycle(props.content);
112
100
  }
113
101
 
114
102
  return h(A2UISurfaceActivityRenderer, {
@@ -1,24 +1,15 @@
1
1
  <script setup lang="ts">
2
- import {
3
- computed,
4
- h,
5
- onBeforeUnmount,
6
- shallowRef,
7
- ref,
8
- watch,
9
- type VNode,
10
- } from "vue";
2
+ import { computed, h, onBeforeUnmount, shallowRef, ref, watch } from "vue";
3
+ import type { VNode } from "vue";
11
4
  import type { ActivityMessage } from "@ag-ui/core";
12
5
  import type { A2UITheme } from "../types";
13
6
  import type { A2UIOperation } from "./a2ui";
14
7
  import { getOperationSurfaceId } from "./a2ui";
15
8
  import { useCopilotKit } from "../providers";
16
- import { MessageProcessor, type SurfaceModel } from "@a2ui/web_core/v0_9";
17
- import {
18
- vueBasicCatalog,
19
- A2uiSurface,
20
- type VueComponentImplementation,
21
- } from "./a2ui/index";
9
+ import { MessageProcessor } from "@a2ui/web_core/v0_9";
10
+ import type { SurfaceModel } from "@a2ui/web_core/v0_9";
11
+ import { vueBasicCatalog, A2uiSurface } from "./a2ui/index";
12
+ import type { VueComponentImplementation } from "./a2ui/index";
22
13
 
23
14
  const DEFAULT_SURFACE_ID = "default";
24
15
 
@@ -61,7 +52,7 @@ async function handleAction(message: unknown) {
61
52
  if (!props.agent) return;
62
53
  try {
63
54
  copilotkit.value.setProperties({
64
- ...(copilotkit.value.properties ?? {}),
55
+ ...copilotkit.value.properties,
65
56
  a2uiAction: message,
66
57
  });
67
58
  await copilotkit.value.runAgent({ agent: props.agent as any });
@@ -160,24 +151,21 @@ const surfaceEntries = computed(() => {
160
151
  :data-activity-type="activityType"
161
152
  :data-message-id="message.id"
162
153
  >
163
- <div
164
- v-if="error"
165
- class="cpk:rounded-lg cpk:border cpk:border-red-200 cpk:bg-red-50 cpk:p-3 cpk:text-sm cpk:text-red-700"
166
- >
154
+ <div v-if="error" class="cpk-a2ui-message-error">
167
155
  A2UI render error: {{ error }}
168
156
  </div>
169
157
  <div
170
158
  v-else
171
- class="cpk:flex cpk:min-h-0 cpk:flex-1 cpk:flex-col cpk:gap-6 cpk:overflow-auto cpk:py-6"
159
+ class="cpk-a2ui-message-surfaces"
172
160
  data-testid="a2ui-activity-renderer"
173
161
  >
174
162
  <div
175
163
  v-for="entry in surfaceEntries"
176
164
  :key="entry.surfaceId"
177
- class="cpk:flex cpk:w-full cpk:flex-none cpk:flex-col cpk:gap-4"
165
+ class="cpk-a2ui-message-surface-host"
178
166
  :data-surface-id="entry.surfaceId"
179
167
  >
180
- <div class="a2ui-surface cpk:flex cpk:flex-1">
168
+ <div class="a2ui-surface cpk-a2ui-message-surface">
181
169
  <A2uiSurface :surface="entry.surface" />
182
170
  </div>
183
171
  </div>
@@ -1,7 +1,7 @@
1
- import { readFileSync } from "node:fs";
2
1
  import { describe, expect, it } from "vitest";
3
2
  import { ref } from "vue";
4
3
  import { render, waitFor } from "@testing-library/vue";
4
+ import { stylesheet } from "@copilotkit/core/styles";
5
5
  import { createA2UIMessageRenderer } from "../A2UIMessageRenderer";
6
6
  import { CopilotKitKey } from "../../providers/keys";
7
7
 
@@ -173,16 +173,15 @@ describe("A2UI basic catalog colours", () => {
173
173
  );
174
174
  });
175
175
 
176
- it("sets the variables from the dark theme in the chat stylesheet", () => {
177
- const globalsCss = readFileSync("src/styles/globals.css", "utf8");
176
+ it("sets the variables from the dark theme in the injected stylesheet", () => {
178
177
  const darkBlock =
179
- globalsCss.match(
180
- /\.dark \[data-copilotkit\],\s*\[data-copilotkit\]\.dark \{([^}]*)\}/,
178
+ stylesheet.match(
179
+ /:where\(\.dark \[data-copilotkit\],\[data-copilotkit\]\.dark\)\{([^}]*)\}/,
181
180
  )?.[1] ?? "";
182
181
 
183
- expect(darkBlock).toContain("--a2ui-color-surface: var(--card);");
184
- expect(darkBlock).toContain("--a2ui-color-border: oklch(0.371 0 0);");
185
- expect(darkBlock).toContain("--a2ui-color-muted: var(--muted-foreground);");
186
- expect(darkBlock).toContain("--a2ui-color-error: #f87171;");
182
+ expect(darkBlock).toContain("--a2ui-color-surface: var(--card)");
183
+ expect(darkBlock).toContain("--a2ui-color-border: oklch(.371 0 0)");
184
+ expect(darkBlock).toContain("--a2ui-color-muted: var(--muted-foreground)");
185
+ expect(darkBlock).toContain("--a2ui-color-error: #f87171");
187
186
  });
188
187
  });
@@ -22,52 +22,79 @@ function copilotKitProvide() {
22
22
  }
23
23
 
24
24
  describe("createA2UIMessageRenderer", () => {
25
- it("returns loading state when no operations exist", () => {
26
- const renderer = createA2UIMessageRenderer({ theme: {} });
27
- const { getByTestId } = render(renderer.render, {
28
- props: {
29
- activityType: "a2ui-surface",
30
- content: {},
31
- message: {},
32
- agent: {},
33
- },
25
+ const renderLifecycle = (
26
+ content: Record<string, unknown>,
27
+ options: Partial<Parameters<typeof createA2UIMessageRenderer>[0]> = {},
28
+ ) => {
29
+ const renderer = createA2UIMessageRenderer({ theme: {}, ...options });
30
+ return render(renderer.render, {
31
+ props: { activityType: "a2ui-surface", content, message: {}, agent: {} },
34
32
  });
35
- expect(getByTestId("a2ui-loading")).not.toBeNull();
33
+ };
34
+
35
+ it("shows the 'Building interface' skeleton while there are no operations", () => {
36
+ const { container } = renderLifecycle({});
37
+ expect(container.textContent).toContain("Building interface");
38
+ expect(container.textContent).not.toContain("Generating UI");
36
39
  });
37
40
 
38
- it("default loading fallback renders header dot, 'Generating UI...' label, and three pulsing skeleton bars", () => {
39
- const renderer = createA2UIMessageRenderer({ theme: {} });
40
- const { getByTestId, getAllByTestId, container } = render(renderer.render, {
41
- props: {
42
- activityType: "a2ui-surface",
43
- content: {},
44
- message: {},
45
- agent: {},
46
- },
41
+ it("shows the live token count while building", () => {
42
+ const { container } = renderLifecycle({
43
+ status: "building",
44
+ progressTokens: 97,
47
45
  });
46
+ expect(container.textContent).toContain("~97 tokens");
47
+ });
48
48
 
49
- const root = getByTestId("a2ui-loading");
50
- expect(root).not.toBeNull();
51
- expect((root as HTMLElement).textContent ?? "").toContain(
52
- "Generating UI...",
49
+ it("shows the retry state for status 'retrying'", () => {
50
+ const { container } = renderLifecycle({
51
+ status: "retrying",
52
+ attempt: 2,
53
+ maxAttempts: 3,
54
+ });
55
+ expect(container.textContent).toContain(
56
+ "Retrying generation… (2/3 attempts)",
53
57
  );
58
+ });
54
59
 
55
- const dot = getByTestId("a2ui-loading-dot") as HTMLElement;
56
- expect(dot.getAttribute("style") ?? "").toMatch(/cpk-a2ui-pulse/);
60
+ it("honours recovery.showAfterAttempts", () => {
61
+ const { container } = renderLifecycle(
62
+ { status: "retrying", attempt: 2, maxAttempts: 3 },
63
+ { recovery: { showAfterAttempts: 5, showAfterMs: 999999 } },
64
+ );
65
+ expect(container.textContent).toContain("Building interface");
66
+ expect(container.textContent).not.toContain("Retrying");
67
+ });
57
68
 
58
- const bars = getAllByTestId("a2ui-loading-bar") as HTMLElement[];
59
- expect(bars).toHaveLength(3);
69
+ it("shows the failure card for status 'failed', with details per recovery.debugExposure", () => {
70
+ const { container } = renderLifecycle(
71
+ { status: "failed", error: "boom", attempts: [] },
72
+ { recovery: { debugExposure: "hidden" } },
73
+ );
74
+ expect(
75
+ container.querySelector(".cpk-a2ui-recovery-failure")?.textContent,
76
+ ).toContain("Couldn't generate the UI");
77
+ expect(container.querySelector("details")).toBeNull();
78
+ });
60
79
 
61
- const widthMatches = bars.map((bar) => {
62
- const style = bar.getAttribute("style") ?? "";
63
- const match = style.match(/width:\s*([\d.]+)%/);
64
- expect(style).toMatch(/cpk-a2ui-pulse/);
65
- return match ? Number(match[1]) : null;
66
- });
67
- expect(widthMatches).toEqual([80, 60, 40]);
80
+ it("lets a server-stamped debugExposure win over the option", () => {
81
+ const { container } = renderLifecycle(
82
+ { status: "failed", error: "boom", debugExposure: "verbose" },
83
+ { recovery: { debugExposure: "hidden" } },
84
+ );
85
+ expect(container.querySelector("details")?.hasAttribute("open")).toBe(true);
86
+ });
68
87
 
69
- const styleTag = container.querySelector("style");
70
- expect(styleTag?.textContent ?? "").toContain("@keyframes cpk-a2ui-pulse");
88
+ it("shows the failure card instead of a custom loading component", () => {
89
+ const CustomLoading = defineComponent({
90
+ setup: () => () => h("div", { "data-testid": "custom-loading" }),
91
+ });
92
+ const { container, queryByTestId } = renderLifecycle(
93
+ { status: "failed" },
94
+ { loadingComponent: CustomLoading },
95
+ );
96
+ expect(queryByTestId("custom-loading")).toBeNull();
97
+ expect(container.textContent).toContain("Couldn't generate the UI");
71
98
  });
72
99
 
73
100
  it("renders custom loading component when provided", () => {