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

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 (241) 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 +353 -16908
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/use-render-activity-message-CsWYyd6r.cjs +91 -0
  12. package/dist/use-render-activity-message-CsWYyd6r.cjs.map +1 -0
  13. package/dist/use-render-activity-message-DntKKNdd.js +17418 -0
  14. package/dist/use-render-activity-message-DntKKNdd.js.map +1 -0
  15. package/dist/v2/components/InlineFeatureWarning.vue.d.ts.map +1 -1
  16. package/dist/v2/components/LicenseWarningBanner.vue.d.ts +2 -2
  17. package/dist/v2/components/LicenseWarningBanner.vue.d.ts.map +1 -1
  18. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts +13 -45
  19. package/dist/v2/components/OpenGenerativeUIRenderer.d.ts.map +1 -1
  20. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts +1 -1
  21. package/dist/v2/components/a2ui/A2UICatalogContext.d.ts.map +1 -1
  22. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts +13 -5
  23. package/dist/v2/components/a2ui/A2UIRecoveryStates.d.ts.map +1 -1
  24. package/dist/v2/components/a2ui/catalog.d.ts.map +1 -1
  25. package/dist/v2/components/a2ui/utils.d.ts.map +1 -1
  26. package/dist/v2/components/a2ui.d.ts +3 -7
  27. package/dist/v2/components/a2ui.d.ts.map +1 -1
  28. package/dist/v2/components/chat/CopilotChat.vue.d.ts +2 -2
  29. package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
  30. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -1
  31. package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -1
  32. package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -1
  33. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts +1 -1
  34. package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts.map +1 -1
  35. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +6 -270
  36. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -1
  37. package/dist/v2/components/chat/CopilotChatInspectorButton.vue.d.ts.map +1 -1
  38. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +1 -1
  39. package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -1
  40. package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -1
  41. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts +1 -1
  42. package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts.map +1 -1
  43. package/dist/v2/components/chat/CopilotChatToolCallItem.vue.d.ts.map +1 -1
  44. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +1 -1
  45. package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -1
  46. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -1
  47. package/dist/v2/components/chat/CopilotChatView.vue.d.ts +2 -2
  48. package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
  49. package/dist/v2/components/chat/CopilotChatWorkSummary.vue.d.ts.map +1 -1
  50. package/dist/v2/components/chat/CopilotModalHeader.vue.d.ts.map +1 -1
  51. package/dist/v2/components/chat/CopilotPopup.vue.d.ts +8 -3
  52. package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -1
  53. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts +5 -3
  54. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -1
  55. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts +5 -3
  56. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -1
  57. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts +8 -3
  58. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -1
  59. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts +5 -3
  60. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -1
  61. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts +5 -3
  62. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -1
  63. package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts +0 -1
  64. package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts.map +1 -1
  65. package/dist/v2/components/chat/forwarded-slots.d.ts +12 -0
  66. package/dist/v2/components/chat/forwarded-slots.d.ts.map +1 -0
  67. package/dist/v2/components/chat/index.d.ts +28 -25
  68. package/dist/v2/components/chat/index.d.ts.map +1 -1
  69. package/dist/v2/components/chat/inspector-shortcuts.d.ts +2 -1
  70. package/dist/v2/components/chat/inspector-shortcuts.d.ts.map +1 -1
  71. package/dist/v2/components/chat/message-feedback.d.ts +18 -49
  72. package/dist/v2/components/chat/message-feedback.d.ts.map +1 -1
  73. package/dist/v2/components/chat/normalize-auto-scroll.d.ts +2 -2
  74. package/dist/v2/components/chat/normalize-auto-scroll.d.ts.map +1 -1
  75. package/dist/v2/components/chat/tool-call-display-context.d.ts +2 -19
  76. package/dist/v2/components/chat/tool-call-display-context.d.ts.map +1 -1
  77. package/dist/v2/components/chat/tool-call-group-parts.d.ts +7 -20
  78. package/dist/v2/components/chat/tool-call-group-parts.d.ts.map +1 -1
  79. package/dist/v2/components/chat/turn-work.d.ts +0 -2
  80. package/dist/v2/components/chat/turn-work.d.ts.map +1 -1
  81. package/dist/v2/components/chat/types.d.ts +8 -3
  82. package/dist/v2/components/chat/types.d.ts.map +1 -1
  83. package/dist/v2/components/chat/use-chat-labels.d.ts +8 -0
  84. package/dist/v2/components/chat/use-chat-labels.d.ts.map +1 -0
  85. package/dist/v2/components/chat/use-copy-feedback.d.ts +11 -0
  86. package/dist/v2/components/chat/use-copy-feedback.d.ts.map +1 -0
  87. package/dist/v2/components/icons/index.d.ts +968 -1
  88. package/dist/v2/components/icons/index.d.ts.map +1 -1
  89. package/dist/v2/hooks/use-attachments.d.ts.map +1 -1
  90. package/dist/v2/hooks/use-frontend-tool.d.ts +5 -0
  91. package/dist/v2/hooks/use-frontend-tool.d.ts.map +1 -1
  92. package/dist/v2/hooks/use-keyboard-height.d.ts +1 -1
  93. package/dist/v2/hooks/use-keyboard-height.d.ts.map +1 -1
  94. package/dist/v2/hooks/use-pin-to-send.d.ts +4 -12
  95. package/dist/v2/hooks/use-pin-to-send.d.ts.map +1 -1
  96. package/dist/v2/hooks/use-render-activity-message.d.ts +13 -9
  97. package/dist/v2/hooks/use-render-activity-message.d.ts.map +1 -1
  98. package/dist/v2/hooks/use-render-custom-messages.d.ts +5 -7
  99. package/dist/v2/hooks/use-render-custom-messages.d.ts.map +1 -1
  100. package/dist/v2/index.cjs +1 -1
  101. package/dist/v2/index.mjs +197 -200
  102. package/dist/v2/index.mjs.map +1 -1
  103. package/dist/v2/lib/is-mobile-viewport.d.ts +1 -14
  104. package/dist/v2/lib/is-mobile-viewport.d.ts.map +1 -1
  105. package/dist/v2/lib/processPartialHtml.d.ts +1 -2
  106. package/dist/v2/lib/processPartialHtml.d.ts.map +1 -1
  107. package/dist/v2/lib/shallow-stable.d.ts.map +1 -1
  108. package/dist/v2/lib/vue-core.d.ts +0 -1
  109. package/dist/v2/lib/vue-core.d.ts.map +1 -1
  110. package/dist/v2/providers/CopilotKitProvider.types.d.ts +0 -5
  111. package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -1
  112. package/dist/v2/providers/CopilotKitProvider.vue.d.ts +1 -1
  113. package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
  114. package/dist/v2/providers/markdown-renderer.d.ts +2 -2
  115. package/dist/v2/providers/markdown-renderer.d.ts.map +1 -1
  116. package/dist/v2/providers/types.d.ts +3 -46
  117. package/dist/v2/providers/types.d.ts.map +1 -1
  118. package/dist/v2/types/human-in-the-loop.d.ts +8 -29
  119. package/dist/v2/types/human-in-the-loop.d.ts.map +1 -1
  120. package/dist/v2/types/interrupt.d.ts +1 -22
  121. package/dist/v2/types/interrupt.d.ts.map +1 -1
  122. package/dist/v2/types/vue-activity-message-renderer.d.ts +16 -15
  123. package/dist/v2/types/vue-activity-message-renderer.d.ts.map +1 -1
  124. package/dist/v2/types/vue-custom-message-renderer.d.ts +7 -16
  125. package/dist/v2/types/vue-custom-message-renderer.d.ts.map +1 -1
  126. package/dist/v2/types/vue-tool-call-renderer.d.ts +16 -35
  127. package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -1
  128. package/package.json +10 -11
  129. package/src/__tests__/build-entries.test.ts +27 -0
  130. package/src/hooks/__tests__/zod-parameters.test.ts +520 -0
  131. package/src/hooks/use-copilot-action.ts +2 -1
  132. package/src/hooks/use-frontend-tool.ts +3 -6
  133. package/src/hooks/zod-parameters.ts +162 -0
  134. package/src/v2/components/A2UIMessageRenderer.ts +3 -3
  135. package/src/v2/components/InlineFeatureWarning.vue +20 -21
  136. package/src/v2/components/LicenseWarningBanner.vue +27 -135
  137. package/src/v2/components/OpenGenerativeUIRenderer.ts +51 -373
  138. package/src/v2/components/__tests__/A2UICatalogContext.test.ts +1 -1
  139. package/src/v2/components/__tests__/LicenseWarningBanner.test.ts +60 -0
  140. package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.ts +55 -6
  141. package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +1 -1
  142. package/src/v2/components/a2ui/A2UICatalogContext.ts +10 -102
  143. package/src/v2/components/a2ui/A2UIRecoveryStates.ts +1 -1
  144. package/src/v2/components/a2ui/catalog.ts +1 -0
  145. package/src/v2/components/a2ui/utils.ts +2 -0
  146. package/src/v2/components/a2ui.ts +1 -1
  147. package/src/v2/components/chat/CopilotChat.vue +19 -40
  148. package/src/v2/components/chat/CopilotChatAssistantMessage.vue +19 -43
  149. package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +14 -10
  150. package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +14 -6
  151. package/src/v2/components/chat/CopilotChatFeedbackCommentPopover.vue +2 -2
  152. package/src/v2/components/chat/CopilotChatInput.vue +40 -30
  153. package/src/v2/components/chat/CopilotChatInspectorButton.vue +45 -108
  154. package/src/v2/components/chat/CopilotChatMessageView.vue +72 -140
  155. package/src/v2/components/chat/CopilotChatReasoningMessage.vue +7 -15
  156. package/src/v2/components/chat/CopilotChatToolCallGroup.vue +60 -37
  157. package/src/v2/components/chat/CopilotChatToolCallItem.vue +3 -3
  158. package/src/v2/components/chat/CopilotChatToolCallsView.vue +15 -13
  159. package/src/v2/components/chat/CopilotChatUserMessage.vue +24 -112
  160. package/src/v2/components/chat/CopilotChatView.vue +5 -5
  161. package/src/v2/components/chat/CopilotChatWorkSummary.vue +26 -36
  162. package/src/v2/components/chat/CopilotModalHeader.vue +11 -23
  163. package/src/v2/components/chat/CopilotPopup.vue +23 -25
  164. package/src/v2/components/chat/CopilotPopupView.vue +10 -39
  165. package/src/v2/components/chat/CopilotPopupViewInternal.vue +14 -34
  166. package/src/v2/components/chat/CopilotSidebar.vue +23 -25
  167. package/src/v2/components/chat/CopilotSidebarView.vue +10 -39
  168. package/src/v2/components/chat/CopilotSidebarViewInternal.vue +14 -34
  169. package/src/v2/components/chat/StreamingMarkdownDefault.vue +4 -4
  170. package/src/v2/components/chat/__tests__/CopilotChat.labels.test.ts +19 -4
  171. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.ts +26 -9
  172. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.learningFeedback.test.ts +5 -5
  173. package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +33 -1
  174. package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.ts +247 -403
  175. package/src/v2/components/chat/__tests__/CopilotChatMessageView.toolCallDisplay.test.ts +1 -99
  176. package/src/v2/components/chat/__tests__/CopilotPopup.test.ts +90 -1
  177. package/src/v2/components/chat/__tests__/CopilotSidebar.test.ts +90 -1
  178. package/src/v2/components/chat/copilotChatToolCallItemRender.ts +3 -19
  179. package/src/v2/components/chat/forwarded-slots.ts +17 -0
  180. package/src/v2/components/chat/index.ts +0 -1
  181. package/src/v2/components/chat/inspector-shortcuts.ts +10 -16
  182. package/src/v2/components/chat/message-feedback.ts +62 -197
  183. package/src/v2/components/chat/normalize-auto-scroll.ts +3 -17
  184. package/src/v2/components/chat/tool-call-display-context.ts +2 -23
  185. package/src/v2/components/chat/tool-call-group-parts.ts +44 -85
  186. package/src/v2/components/chat/turn-work.ts +0 -9
  187. package/src/v2/components/chat/types.ts +12 -4
  188. package/src/v2/components/chat/use-chat-labels.ts +16 -0
  189. package/src/v2/components/chat/use-copy-feedback.ts +21 -0
  190. package/src/v2/components/icons/__tests__/icons.test.ts +72 -68
  191. package/src/v2/components/icons/index.ts +109 -27
  192. package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.ts +62 -1
  193. package/src/v2/hooks/__tests__/use-render-activity-message.test.ts +105 -0
  194. package/src/v2/hooks/__tests__/use-render-tool.test.ts +3 -6
  195. package/src/v2/hooks/__tests__/zod-regression.test.ts +5 -4
  196. package/src/v2/hooks/use-attachments.ts +6 -2
  197. package/src/v2/hooks/use-frontend-tool.ts +10 -10
  198. package/src/v2/hooks/use-keyboard-height.ts +17 -40
  199. package/src/v2/hooks/use-pin-to-send.ts +15 -99
  200. package/src/v2/hooks/use-render-activity-message.ts +27 -48
  201. package/src/v2/hooks/use-render-custom-messages.ts +14 -35
  202. package/src/v2/lib/__tests__/shallow-stable.test.ts +54 -0
  203. package/src/v2/lib/is-mobile-viewport.ts +5 -23
  204. package/src/v2/lib/processPartialHtml.ts +6 -21
  205. package/src/v2/lib/shallow-stable.ts +2 -16
  206. package/src/v2/lib/vue-core.ts +9 -13
  207. package/src/v2/providers/CopilotKitProvider.types.ts +0 -5
  208. package/src/v2/providers/CopilotKitProvider.vue +53 -112
  209. package/src/v2/providers/__tests__/CopilotKitProvider.a2ui.test.ts +1 -1
  210. package/src/v2/providers/__tests__/CopilotKitProvider.headersAtSendTime.test.ts +3 -3
  211. package/src/v2/providers/__tests__/CopilotKitProvider.learning.test.ts +3 -1
  212. package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +17 -33
  213. package/src/v2/providers/markdown-renderer.ts +2 -2
  214. package/src/v2/providers/types.ts +3 -49
  215. package/src/v2/types/__tests__/defineToolCallRenderer.test.ts +28 -33
  216. package/src/v2/types/defineToolCallRenderer.ts +5 -4
  217. package/src/v2/types/human-in-the-loop.ts +8 -32
  218. package/src/v2/types/interrupt.ts +7 -31
  219. package/src/v2/types/vue-activity-message-renderer.ts +24 -15
  220. package/src/v2/types/vue-custom-message-renderer.ts +12 -16
  221. package/src/v2/types/vue-tool-call-renderer.ts +23 -38
  222. package/tsconfig.json +0 -1
  223. package/vite.config.ts +3 -4
  224. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts +0 -9
  225. package/dist/v2/components/chat/BasicMarkdown.vue.d.ts.map +0 -1
  226. package/dist/v2/components/chat/tool-call-layout.d.ts +0 -115
  227. package/dist/v2/components/chat/tool-call-layout.d.ts.map +0 -1
  228. package/dist/v2/lib/message-feedback.d.ts +0 -33
  229. package/dist/v2/lib/message-feedback.d.ts.map +0 -1
  230. package/dist/v2/lib/transcription-client.d.ts +0 -19
  231. package/dist/v2/lib/transcription-client.d.ts.map +0 -1
  232. package/src/v2/components/chat/BasicMarkdown.vue +0 -160
  233. package/src/v2/components/chat/__tests__/BasicMarkdown.test.ts +0 -69
  234. package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +0 -39
  235. package/src/v2/components/chat/tool-call-layout.ts +0 -304
  236. package/src/v2/lib/__tests__/is-mobile-viewport.test.ts +0 -48
  237. package/src/v2/lib/__tests__/message-feedback.test.ts +0 -152
  238. package/src/v2/lib/__tests__/processPartialHtml.test.ts +0 -84
  239. package/src/v2/lib/__tests__/transcription-client.test.ts +0 -67
  240. package/src/v2/lib/message-feedback.ts +0 -120
  241. package/src/v2/lib/transcription-client.ts +0 -151
@@ -1,7 +1,11 @@
1
1
  import { computed, watch } from "vue";
2
2
  import type { ShallowRef } from "vue";
3
3
  import type { Catalog, ComponentApi } from "@a2ui/web_core/v0_9";
4
- import { zodToJsonSchema } from "zod-to-json-schema";
4
+ import {
5
+ A2UI_SCHEMA_CONTEXT_DESCRIPTION,
6
+ buildCatalogContextValue as buildContextValue,
7
+ extractCatalogComponentSchemas,
8
+ } from "@copilotkit/a2ui-renderer/catalog-schema";
5
9
  import {
6
10
  A2UI_DEFAULT_GENERATION_GUIDELINES,
7
11
  A2UI_DEFAULT_DESIGN_GUIDELINES,
@@ -9,22 +13,9 @@ import {
9
13
  import type { CopilotKitCoreVue } from "../../lib/vue-core";
10
14
  import { vueBasicCatalog } from "./catalog";
11
15
 
12
- /**
13
- * Context description used to identify the A2UI component schema in
14
- * RunAgentInput.context. Must match the constant in @ag-ui/a2ui-middleware
15
- * so the middleware can overwrite a frontend-provided schema with a
16
- * server-side one.
17
- *
18
- * Duplicated from @copilotkit/a2ui-renderer/catalog-utils to avoid pulling
19
- * in React dependencies.
20
- */
21
- const A2UI_SCHEMA_CONTEXT_DESCRIPTION =
22
- "A2UI Component Schema — available components for generating UI surfaces. " +
23
- "Use these component names and properties when creating A2UI operations.";
24
-
25
16
  /**
26
17
  * Build a context string describing the available A2UI catalog.
27
- * Vue-native equivalent of buildCatalogContextValue from a2ui-renderer.
18
+ * Defaults to the Vue basic catalog.
28
19
  *
29
20
  * When `options.includeSchema` is `false`, custom components are listed by name
30
21
  * only and their JSON schemas are omitted.
@@ -33,92 +24,7 @@ export function buildCatalogContextValue(
33
24
  catalog?: Catalog<ComponentApi>,
34
25
  options?: { includeSchema?: boolean },
35
26
  ): string {
36
- const resolved = catalog ?? vueBasicCatalog;
37
- const BASIC_CATALOG_ID =
38
- "https://a2ui.org/specification/v0_9/basic_catalog.json";
39
- const lines: string[] = [];
40
- lines.push("Available A2UI catalog:");
41
-
42
- if (resolved.id === BASIC_CATALOG_ID) {
43
- lines.push(`- ${resolved.id} (basic catalog)`);
44
- return lines.join("\n");
45
- }
46
-
47
- // Check if the resolved catalog extends the basic catalog
48
- let isSuperset = true;
49
- for (const name of vueBasicCatalog.components.keys()) {
50
- if (!resolved.components.has(name)) {
51
- isSuperset = false;
52
- break;
53
- }
54
- }
55
-
56
- // Identify custom components (not in basic catalog)
57
- const customNames: string[] = [];
58
- for (const name of resolved.components.keys()) {
59
- if (!vueBasicCatalog.components.has(name)) {
60
- customNames.push(name);
61
- }
62
- }
63
-
64
- lines.push(`- ${resolved.id}`);
65
- if (isSuperset) {
66
- lines.push(
67
- " Extends the basic catalog with all standard components plus:",
68
- );
69
- } else {
70
- lines.push(" Custom catalog (does NOT include all basic components).");
71
- lines.push(" Custom components:");
72
- }
73
-
74
- for (const name of customNames) {
75
- const comp = resolved.components.get(name);
76
- if (!comp) continue;
77
- if (options?.includeSchema === false) {
78
- lines.push(` - ${name}`);
79
- continue;
80
- }
81
- const jsonSchema = zodToJsonSchema(comp.schema);
82
- lines.push(` - ${name}:`);
83
- lines.push(
84
- ` ${JSON.stringify(jsonSchema, null, 2).split("\n").join("\n ")}`,
85
- );
86
- }
87
-
88
- return lines.join("\n");
89
- }
90
-
91
- /**
92
- * Extract component schemas from a catalog in A2UI v0.9 inline format.
93
- * Vue-native equivalent of extractCatalogComponentSchemas.
94
- */
95
- function extractCatalogComponentSchemas(catalog?: Catalog<ComponentApi>): {
96
- catalogId: string;
97
- components: Record<string, Record<string, unknown>>;
98
- } {
99
- const resolved = catalog ?? vueBasicCatalog;
100
- const components: Record<string, Record<string, unknown>> = {};
101
-
102
- for (const [name, comp] of resolved.components) {
103
- const zodSchema = zodToJsonSchema(comp.schema, {
104
- target: "jsonSchema2019-09",
105
- }) as { properties?: Record<string, unknown>; required?: string[] };
106
-
107
- components[name] = {
108
- allOf: [
109
- { $ref: "common_types.json#/$defs/ComponentCommon" },
110
- {
111
- properties: {
112
- component: { const: name },
113
- ...zodSchema.properties,
114
- },
115
- required: ["component", ...(zodSchema.required ?? [])],
116
- },
117
- ],
118
- };
119
- }
120
-
121
- return { catalogId: resolved.id, components };
27
+ return buildContextValue(catalog ?? vueBasicCatalog, options);
122
28
  }
123
29
 
124
30
  /**
@@ -165,7 +71,9 @@ export function registerA2UICatalogContext(
165
71
  // Register schema + generation/design guidelines
166
72
  const schemaValue = computed(() => {
167
73
  if (!options.includeSchema()) return null;
168
- return JSON.stringify(extractCatalogComponentSchemas(options.catalog()));
74
+ return JSON.stringify(
75
+ extractCatalogComponentSchemas(options.catalog() ?? vueBasicCatalog),
76
+ );
169
77
  });
170
78
 
171
79
  watch(
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, h, onBeforeUnmount, ref, watch } from "vue";
2
2
  import type { PropType, VNodeChild } from "vue";
3
- import { z } from "zod";
3
+ import * as z from "zod";
4
4
 
5
5
  /**
6
6
  * Shared pre-paint lifecycle states for the A2UI surface renderer, ported from
@@ -100,6 +100,7 @@ const Text = createVueComponent(TextApi, ({ props }) => {
100
100
  text,
101
101
  );
102
102
  case "body":
103
+ case undefined:
103
104
  default:
104
105
  return h("span", { style }, text);
105
106
  }
@@ -33,6 +33,7 @@ export const mapJustify = (j?: string): string => {
33
33
  return "flex-start";
34
34
  case "stretch":
35
35
  return "stretch";
36
+ case undefined:
36
37
  default:
37
38
  return "flex-start";
38
39
  }
@@ -48,6 +49,7 @@ export const mapAlign = (a?: string): string => {
48
49
  return "flex-end";
49
50
  case "stretch":
50
51
  return "stretch";
52
+ case undefined:
51
53
  default:
52
54
  return "stretch";
53
55
  }
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import * as z from "zod";
2
2
 
3
3
  export type A2UIOperation = Record<string, unknown>;
4
4
 
@@ -4,7 +4,6 @@ import {
4
4
  createAttachmentContent,
5
5
  DEFAULT_AGENT_ID,
6
6
  randomUUID,
7
- TranscriptionErrorCode,
8
7
  } from "@copilotkit/shared";
9
8
  import {
10
9
  computed,
@@ -17,7 +16,14 @@ import {
17
16
  useSlots,
18
17
  watch,
19
18
  } from "vue";
20
- import { CopilotKitCoreErrorCode, ɵisHttpAgent } from "@copilotkit/core";
19
+ import {
20
+ CopilotChatDefaultLabels,
21
+ CopilotKitCoreErrorCode,
22
+ TranscriptionError,
23
+ ɵisHttpAgent,
24
+ ɵtranscribeAudio,
25
+ ɵtranscriptionErrorMessageKey,
26
+ } from "@copilotkit/core";
21
27
  import type { Suggestion } from "@copilotkit/core";
22
28
  import CopilotChatConfigurationProvider from "../../providers/CopilotChatConfigurationProvider.vue";
23
29
  import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
@@ -28,10 +34,6 @@ import { useAgent } from "../../hooks/use-agent";
28
34
  import { useSuggestions } from "../../hooks/use-suggestions";
29
35
  import { useAttachments } from "../../hooks/use-attachments";
30
36
  import { useShallowStableRef } from "../../lib/shallow-stable";
31
- import {
32
- transcribeAudio,
33
- TranscriptionError,
34
- } from "../../lib/transcription-client";
35
37
  import CopilotChatView from "./CopilotChatView.vue";
36
38
  import { LastUserMessageKey } from "./last-user-message-context";
37
39
  import type { LastUserMessageState } from "./last-user-message-context";
@@ -159,6 +161,12 @@ const isConnecting = computed(
159
161
  );
160
162
  const stableLabels = useShallowStableRef(computed(() => props.labels));
161
163
  const resolvedLabels = computed(() => stableLabels.value);
164
+ // The labels this chat shows, the same merge its configuration provider makes.
165
+ const chatLabels = computed(() => ({
166
+ ...CopilotChatDefaultLabels,
167
+ ...existingConfig.value?.labels,
168
+ ...resolvedLabels.value,
169
+ }));
162
170
 
163
171
  // `useAgent` takes no threadId: it pins one only from a surrounding chat
164
172
  // configuration, and this call sits outside the provider rendered in this
@@ -771,48 +779,19 @@ async function handleFinishTranscribeWithAudio(audioBlob: Blob) {
771
779
  isTranscribing.value = true;
772
780
  try {
773
781
  transcriptionError.value = null;
774
- const result = await transcribeAudio(copilotkit.value, audioBlob);
782
+ const result = await ɵtranscribeAudio(copilotkit.value, audioBlob);
775
783
  const trimmedPrevious = inputValue.value.trim();
776
784
  inputValue.value = trimmedPrevious
777
785
  ? `${trimmedPrevious} ${result.text}`
778
786
  : result.text;
779
787
  } catch (error) {
780
788
  console.error("CopilotChat: Transcription failed", error);
789
+ const labels = chatLabels.value;
781
790
  if (error instanceof TranscriptionError) {
782
- const { code, retryable, message } = error.info;
783
- switch (code) {
784
- case TranscriptionErrorCode.RATE_LIMITED:
785
- transcriptionError.value = "Too many requests. Please wait a moment.";
786
- break;
787
- case TranscriptionErrorCode.AUTH_FAILED:
788
- transcriptionError.value =
789
- "Authentication error. Please check your configuration.";
790
- break;
791
- case TranscriptionErrorCode.AUDIO_TOO_LONG:
792
- transcriptionError.value =
793
- "Recording is too long. Please try a shorter recording.";
794
- break;
795
- case TranscriptionErrorCode.AUDIO_TOO_SHORT:
796
- transcriptionError.value =
797
- "Recording is too short. Please try again.";
798
- break;
799
- case TranscriptionErrorCode.INVALID_AUDIO_FORMAT:
800
- transcriptionError.value = "Audio format not supported.";
801
- break;
802
- case TranscriptionErrorCode.SERVICE_NOT_CONFIGURED:
803
- transcriptionError.value = "Transcription service is not available.";
804
- break;
805
- case TranscriptionErrorCode.NETWORK_ERROR:
806
- transcriptionError.value =
807
- "Network error. Please check your connection.";
808
- break;
809
- default:
810
- transcriptionError.value = retryable
811
- ? "Transcription failed. Please try again."
812
- : message;
813
- }
791
+ const key = ɵtranscriptionErrorMessageKey(error.info);
792
+ transcriptionError.value = key ? labels[key] : error.info.message;
814
793
  } else {
815
- transcriptionError.value = "Transcription failed. Please try again.";
794
+ transcriptionError.value = labels.transcriptionErrorGenericText;
816
795
  }
817
796
  } finally {
818
797
  isTranscribing.value = false;
@@ -2,7 +2,6 @@
2
2
  import {
3
3
  computed,
4
4
  inject,
5
- onBeforeUnmount,
6
5
  onUpdated,
7
6
  ref,
8
7
  shallowRef,
@@ -34,7 +33,12 @@ import CopilotChatInspectorButton from "./CopilotChatInspectorButton.vue";
34
33
  import { useInspectorShortcutsHidden } from "./inspector-shortcuts";
35
34
  import { InspectorKey } from "../../providers/keys";
36
35
  import { useFeedbackComment, useMessageFeedback } from "./message-feedback";
37
- import type { MessageFeedbackRating } from "../../lib/message-feedback";
36
+ import {
37
+ ɵhasAssistantMessageText,
38
+ ɵshouldShowAssistantToolbar,
39
+ } from "@copilotkit/core";
40
+ import type { ɵMessageFeedbackRating as MessageFeedbackRating } from "@copilotkit/core";
41
+ import { useCopyFeedback } from "./use-copy-feedback";
38
42
  import type {
39
43
  CopilotChatAssistantMessageCopyButtonSlotProps,
40
44
  CopilotChatAssistantMessageFeedbackCommentSlotProps,
@@ -109,8 +113,7 @@ const emit = defineEmits<{
109
113
 
110
114
  const config = useCopilotChatConfiguration();
111
115
  const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
112
- const copied = ref(false);
113
- let copiedResetTimeout: ReturnType<typeof setTimeout> | null = null;
116
+ const { copied, copy } = useCopyFeedback();
114
117
 
115
118
  function normalizeContent(content: unknown): string {
116
119
  if (!content) {
@@ -146,7 +149,9 @@ function normalizeContent(content: unknown): string {
146
149
  const normalizedContent = computed(() =>
147
150
  normalizeContent(props.message.content),
148
151
  );
149
- const hasContent = computed(() => normalizedContent.value.trim().length > 0);
152
+ const hasContent = computed(() =>
153
+ ɵhasAssistantMessageText(normalizedContent.value),
154
+ );
150
155
 
151
156
  const providerMarkdownRenderer = useMarkdownRenderer();
152
157
  const providerIsComponent = computed(() =>
@@ -190,11 +195,14 @@ const hasRegenerate = computed(() => typeof props.onRegenerate === "function");
190
195
  const isLatestAssistantMessage = computed(
191
196
  () => props.messages[props.messages.length - 1]?.id === props.message.id,
192
197
  );
193
- const shouldShowToolbar = computed(
194
- () =>
195
- props.toolbarVisible &&
196
- (hasContent.value || showInspectorShortcut.value) &&
197
- !(props.isRunning && isLatestAssistantMessage.value),
198
+ const shouldShowToolbar = computed(() =>
199
+ ɵshouldShowAssistantToolbar({
200
+ toolbarVisible: props.toolbarVisible,
201
+ hasContent: hasContent.value,
202
+ showInspectorShortcut: showInspectorShortcut.value,
203
+ isRunning: props.isRunning,
204
+ isLatest: isLatestAssistantMessage.value,
205
+ }),
198
206
  );
199
207
 
200
208
  // A custom thumb that calls its handler without an event gives no element:
@@ -325,34 +333,8 @@ function handleInspect() {
325
333
  });
326
334
  }
327
335
 
328
- function resetCopiedStateWithDelay() {
329
- if (copiedResetTimeout) {
330
- clearTimeout(copiedResetTimeout);
331
- }
332
- copied.value = true;
333
- copiedResetTimeout = setTimeout(() => {
334
- copied.value = false;
335
- copiedResetTimeout = null;
336
- }, 2000);
337
- }
338
-
339
336
  async function handleCopyMessage() {
340
- const content = normalizedContent.value;
341
- if (!content) return;
342
-
343
- if (
344
- typeof navigator === "undefined" ||
345
- typeof navigator.clipboard?.writeText !== "function"
346
- ) {
347
- return;
348
- }
349
-
350
- try {
351
- await navigator.clipboard.writeText(content);
352
- resetCopiedStateWithDelay();
353
- } catch (error) {
354
- console.error("Failed to copy to clipboard:", error);
355
- }
337
+ await copy(normalizedContent.value);
356
338
  }
357
339
 
358
340
  function handleThumbsUp(event?: MouseEvent) {
@@ -371,12 +353,6 @@ function handleReadAloud() {
371
353
  function handleRegenerate() {
372
354
  emit("regenerate", props.message);
373
355
  }
374
-
375
- onBeforeUnmount(() => {
376
- if (copiedResetTimeout) {
377
- clearTimeout(copiedResetTimeout);
378
- }
379
- });
380
356
  </script>
381
357
 
382
358
  <template>
@@ -9,8 +9,7 @@ import type { Attachment } from "@copilotkit/shared";
9
9
  import type { CopilotChatAttachmentQueueProps } from "./types";
10
10
  import { IconPlay } from "../icons";
11
11
  import CopilotChatLightbox from "./CopilotChatLightbox.vue";
12
- import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
13
- import { CopilotChatDefaultLabels } from "../../providers/types";
12
+ import { useChatLabels } from "./use-chat-labels";
14
13
 
15
14
  const props = withDefaults(defineProps<CopilotChatAttachmentQueueProps>(), {
16
15
  attachments: () => [],
@@ -21,8 +20,7 @@ const emit = defineEmits<{
21
20
  "remove-attachment": [id: string];
22
21
  }>();
23
22
 
24
- const config = useCopilotChatConfiguration();
25
- const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
23
+ const labels = useChatLabels();
26
24
 
27
25
  const activeLightboxAttachment = ref<Attachment | null>(null);
28
26
  const documentBlobUrl = ref<string | null>(null);
@@ -32,10 +30,10 @@ const lightboxLabel = computed(() => {
32
30
  if (!attachment) return undefined;
33
31
  if (attachment.filename) return attachment.filename;
34
32
  return attachment.type === "image"
35
- ? "Image attachment"
33
+ ? labels.value.attachmentImageAltText
36
34
  : attachment.type === "video"
37
35
  ? "Video attachment"
38
- : "Document";
36
+ : labels.value.attachmentDocumentLabel;
39
37
  });
40
38
  const isPreviewableDocument = computed(() => {
41
39
  const attachment = activeLightboxAttachment.value;
@@ -267,7 +265,7 @@ function createBlobUrl(
267
265
  class="cpk-attachment-queue-document-name"
268
266
  data-testid="copilot-chat-attachment-document-filename"
269
267
  >
270
- {{ attachment.filename || "Document" }}
268
+ {{ attachment.filename || labels.attachmentDocumentLabel }}
271
269
  </span>
272
270
  <span
273
271
  v-if="attachment.size != null"
@@ -369,10 +367,16 @@ function createBlobUrl(
369
367
  </div>
370
368
  <div class="cpk-attachment-queue-document-card-details">
371
369
  <div class="cpk-attachment-queue-document-card-name">
372
- {{ activeLightboxAttachment.filename || "Document" }}
370
+ {{
371
+ activeLightboxAttachment.filename ||
372
+ labels.attachmentDocumentLabel
373
+ }}
373
374
  </div>
374
375
  <div class="cpk-attachment-queue-document-card-meta">
375
- {{ activeLightboxAttachment.source.mimeType || "Unknown type" }}
376
+ {{
377
+ activeLightboxAttachment.source.mimeType ||
378
+ labels.attachmentUnknownTypeText
379
+ }}
376
380
  {{
377
381
  activeLightboxAttachment.size != null
378
382
  ? ` · ${formatFileSize(activeLightboxAttachment.size)}`
@@ -381,7 +385,7 @@ function createBlobUrl(
381
385
  </div>
382
386
  </div>
383
387
  <div class="cpk-attachment-queue-document-card-note">
384
- No preview available for this file type
388
+ {{ labels.attachmentNoPreviewText }}
385
389
  </div>
386
390
  </div>
387
391
  </template>
@@ -4,19 +4,27 @@ import { getDocumentIcon, getSourceUrl } from "@copilotkit/shared";
4
4
  import type { CopilotChatAttachmentRendererProps } from "./types";
5
5
  import CopilotChatLightbox from "./CopilotChatLightbox.vue";
6
6
  import { useLightbox } from "./use-lightbox";
7
+ import { useChatLabels } from "./use-chat-labels";
7
8
 
8
9
  const props = withDefaults(defineProps<CopilotChatAttachmentRendererProps>(), {
9
10
  filename: undefined,
10
11
  className: "",
11
12
  });
12
13
 
14
+ const labels = useChatLabels();
13
15
  const imageLoadFailed = ref(false);
14
16
  const sourceUrl = computed(() => getSourceUrl(props.source));
15
17
  const documentLabel = computed(
16
- () => props.filename || props.source.mimeType || "Unknown type",
18
+ () =>
19
+ props.filename ||
20
+ props.source.mimeType ||
21
+ labels.value.attachmentUnknownTypeText,
17
22
  );
18
23
  const documentAriaLabel = computed(
19
- () => props.filename || props.source.mimeType || "Document attachment",
24
+ () =>
25
+ props.filename ||
26
+ props.source.mimeType ||
27
+ labels.value.attachmentDocumentAltText,
20
28
  );
21
29
 
22
30
  const imageButton = ref<HTMLButtonElement | null>(null);
@@ -43,7 +51,7 @@ const {
43
51
  <img
44
52
  ref="thumbnailRef"
45
53
  :src="sourceUrl"
46
- alt="Image attachment"
54
+ :alt="labels.attachmentImageAltText"
47
55
  class="cpk-attachment-renderer cpk-attachment-renderer-image"
48
56
  :class="props.className"
49
57
  data-testid="copilot-chat-attachment-renderer-image"
@@ -52,14 +60,14 @@ const {
52
60
  <!-- Teleported to the body; inside the button only to keep one root. -->
53
61
  <CopilotChatLightbox
54
62
  v-if="lightboxOpen"
55
- label="Image attachment"
63
+ :label="labels.attachmentImageAltText"
56
64
  :return-focus-to="imageButton"
57
65
  @close="closeLightbox"
58
66
  >
59
67
  <img
60
68
  :style="{ viewTransitionName: vtName }"
61
69
  :src="sourceUrl"
62
- alt="Image attachment"
70
+ :alt="labels.attachmentImageAltText"
63
71
  class="cpk-attachment-renderer-lightbox-image"
64
72
  data-testid="copilot-chat-attachment-renderer-lightbox-image"
65
73
  />
@@ -71,7 +79,7 @@ const {
71
79
  :class="props.className"
72
80
  data-testid="copilot-chat-attachment-renderer-image-fallback"
73
81
  >
74
- <span>Failed to load image</span>
82
+ <span>{{ labels.attachmentImageLoadErrorText }}</span>
75
83
  </div>
76
84
 
77
85
  <div
@@ -12,8 +12,8 @@
12
12
  import { computed, nextTick, ref, watch } from "vue";
13
13
  import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
14
14
  import { CopilotChatDefaultLabels } from "../../providers/types";
15
- import { MESSAGE_FEEDBACK_MAX_COMMENT_LENGTH } from "../../lib/message-feedback";
16
- import type { MessageFeedbackRating } from "../../lib/message-feedback";
15
+ import { ɵMESSAGE_FEEDBACK_MAX_COMMENT_LENGTH as MESSAGE_FEEDBACK_MAX_COMMENT_LENGTH } from "@copilotkit/core";
16
+ import type { ɵMessageFeedbackRating as MessageFeedbackRating } from "@copilotkit/core";
17
17
  import CopilotPopover from "../ui/CopilotPopover.vue";
18
18
  import { IconArrowUp } from "../icons";
19
19
  import type { FeedbackComment } from "./message-feedback";
@@ -8,8 +8,7 @@ import {
8
8
  useAttrs,
9
9
  watch,
10
10
  } from "vue";
11
- import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
12
- import { CopilotChatDefaultLabels } from "../../providers/types";
11
+ import { ɵcomposerButtonState, ɵresolveComposerKey } from "@copilotkit/core";
13
12
  import {
14
13
  IconArrowUp,
15
14
  IconCheck,
@@ -29,6 +28,7 @@ import type {
29
28
  import { useCopilotId } from "../ui/use-id";
30
29
  import type { CopilotChatAudioRecorderRef } from "./audioRecorder";
31
30
  import type { CopilotChatInputMode, ToolsMenuItem } from "./types";
31
+ import { useChatLabels } from "./use-chat-labels";
32
32
 
33
33
  defineOptions({ inheritAttrs: false });
34
34
 
@@ -107,7 +107,6 @@ const emit = defineEmits<{
107
107
  }>();
108
108
 
109
109
  const attrs = useAttrs();
110
- const config = useCopilotChatConfiguration();
111
110
  const shellRef = ref<HTMLElement | null>(null);
112
111
  const textareaRef = ref<HTMLTextAreaElement | null>(null);
113
112
  const gridRef = ref<HTMLElement | null>(null);
@@ -148,16 +147,13 @@ const isControlled = computed(() => props.modelValue !== undefined);
148
147
  const inputValue = computed(() =>
149
148
  isControlled.value ? (props.modelValue ?? "") : localValue.value,
150
149
  );
151
- const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
150
+ const labels = useChatLabels();
152
151
  const resolvedPlaceholder = computed(
153
152
  () => props.placeholder ?? labels.value.chatInputPlaceholder,
154
153
  );
155
154
  const isExpanded = computed(
156
155
  () => props.mode === "input" && layout.value === "expanded",
157
156
  );
158
- const isProcessing = computed(
159
- () => props.mode !== "transcribe" && props.isRunning,
160
- );
161
157
  const shouldShowDisclaimer = computed(
162
158
  () => props.showDisclaimer ?? props.positioning === "absolute",
163
159
  );
@@ -177,16 +173,20 @@ const hasFinishTranscribeAction = computed(
177
173
  typeof props.onFinishTranscribe === "function" ||
178
174
  typeof props.onFinishTranscribeWithAudio === "function",
179
175
  );
180
- const canSend = computed(
181
- () =>
182
- props.mode === "input" &&
183
- !props.disabled &&
184
- hasSubmitAction.value &&
185
- inputValue.value.trim().length > 0,
186
- );
187
- const sendDisabled = computed(() =>
188
- isProcessing.value ? !hasStopAction.value : !canSend.value,
176
+ const composerInput = computed(() => ({
177
+ mode: props.mode,
178
+ isRunning: props.isRunning,
179
+ value: inputValue.value,
180
+ canSubmit: hasSubmitAction.value,
181
+ canStop: hasStopAction.value,
182
+ disabled: props.disabled,
183
+ }));
184
+ const composerButton = computed(() =>
185
+ ɵcomposerButtonState(composerInput.value),
189
186
  );
187
+ const isProcessing = computed(() => composerButton.value.isProcessing);
188
+ const sendDisabled = computed(() => composerButton.value.disabled);
189
+ const showsStop = computed(() => composerButton.value.action === "stop");
190
190
 
191
191
  const containerClass = computed(() => [
192
192
  "cpk-chat-input",
@@ -408,14 +408,16 @@ function handleInput(event: Event) {
408
408
  updateSlashState(nextValue);
409
409
  }
410
410
 
411
+ // The button stops a run whatever the input holds. Enter differs: see
412
+ // handleKeydown.
411
413
  function handleSendButtonClick() {
412
- if (isProcessing.value) {
413
- if (hasStopAction.value) {
414
- emit("stop");
415
- }
414
+ if (showsStop.value) {
415
+ emit("stop");
416
416
  return;
417
417
  }
418
- submit();
418
+ if (!isProcessing.value) {
419
+ submit();
420
+ }
419
421
  }
420
422
 
421
423
  function handleKeydown(event: KeyboardEvent) {
@@ -473,15 +475,23 @@ function handleKeydown(event: KeyboardEvent) {
473
475
  }
474
476
  }
475
477
 
476
- if (event.key === "Enter" && !event.shiftKey && props.mode === "input") {
478
+ if (props.mode !== "input") {
479
+ return;
480
+ }
481
+
482
+ // Enter with text sends, also while a run is going. Enter in an empty input
483
+ // stops the run. Read the textarea: a controlled modelValue can lag a tick.
484
+ const action = ɵresolveComposerKey(event, {
485
+ ...composerInput.value,
486
+ value: textareaRef.value?.value ?? inputValue.value,
487
+ });
488
+ if (event.key === "Enter" && !event.shiftKey) {
477
489
  event.preventDefault();
478
- if (isProcessing.value) {
479
- if (hasStopAction.value) {
480
- emit("stop");
481
- }
482
- return;
483
- }
490
+ }
491
+ if (action === "send") {
484
492
  submit();
493
+ } else if (action === "stop") {
494
+ emit("stop");
485
495
  }
486
496
  }
487
497
 
@@ -1295,7 +1305,7 @@ onBeforeUnmount(() => {
1295
1305
  type="button"
1296
1306
  data-testid="copilot-chat-input-send"
1297
1307
  :aria-label="
1298
- isProcessing && hasStopAction
1308
+ showsStop
1299
1309
  ? labels.chatInputToolbarStopButtonLabel
1300
1310
  : labels.chatInputToolbarSendButtonLabel
1301
1311
  "
@@ -1304,7 +1314,7 @@ onBeforeUnmount(() => {
1304
1314
  @click="handleSendButtonClick"
1305
1315
  >
1306
1316
  <IconSquare
1307
- v-if="isProcessing && hasStopAction"
1317
+ v-if="showsStop"
1308
1318
  class="cpk-chat-input-stop-icon"
1309
1319
  />
1310
1320
  <IconArrowUp v-else class="cpk-chat-input-send-icon" />