@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
@@ -10,8 +10,15 @@
10
10
  * a custom wildcard renderer draws whatever it draws.
11
11
  */
12
12
  import { computed, provide, ref } from "vue";
13
+ import {
14
+ ɵformatLabel,
15
+ ɵformatToolNames,
16
+ ɵgetToolCallPreview,
17
+ ɵgetToolCallRowStatus,
18
+ ɵformatCountLabel,
19
+ } from "@copilotkit/core";
20
+ import type { ToolCallEntry, ɵToolCallRowStatus } from "@copilotkit/core";
13
21
  import { useCopilotId } from "../ui/use-id";
14
- import type { ToolCallEntry } from "./tool-call-layout";
15
22
  import { ToolCallGroupContextKey } from "./tool-call-display-context";
16
23
  import type { ToolCallGroupContextValue } from "./tool-call-display-context";
17
24
  import {
@@ -19,13 +26,9 @@ import {
19
26
  ToolCallChevron,
20
27
  ToolCallFailedCount,
21
28
  ToolCallStatusIcon,
22
- entryPreview,
23
- entryStatus,
24
- pluralize,
25
- statusLabels,
26
- toolNames,
29
+ toolCallStatusLabel,
27
30
  } from "./tool-call-group-parts";
28
- import type { ToolCallStatusName } from "./tool-call-group-parts";
31
+ import { useChatLabels } from "./use-chat-labels";
29
32
  import type { CopilotChatToolCallGroupAppearance } from "./types";
30
33
 
31
34
  const props = withDefaults(
@@ -49,6 +52,7 @@ defineSlots<{
49
52
  call(props: { call: ToolCallEntry }): unknown;
50
53
  }>();
51
54
 
55
+ const labels = useChatLabels();
52
56
  const open = ref(false);
53
57
  const bodyId = useCopilotId("cpk-tool-call-group");
54
58
  const toggle = () => {
@@ -64,13 +68,13 @@ const current = computed(() =>
64
68
  : undefined,
65
69
  );
66
70
  const preview = computed(() =>
67
- current.value ? entryPreview(current.value) : undefined,
71
+ current.value ? ɵgetToolCallPreview(current.value) : undefined,
68
72
  );
69
73
  const done = computed(
70
74
  () => props.calls.filter((call) => call.toolMessage).length,
71
75
  );
72
76
  const statuses = computed(() =>
73
- props.calls.map((call) => entryStatus(call, props.isActive)),
77
+ props.calls.map((call) => ɵgetToolCallRowStatus(call, props.isActive)),
74
78
  );
75
79
  const failedIds = computed(
76
80
  () =>
@@ -80,7 +84,7 @@ const failedIds = computed(
80
84
  .map((call) => call.toolCall.id),
81
85
  ),
82
86
  );
83
- const status = computed<ToolCallStatusName>(() =>
87
+ const status = computed<ɵToolCallRowStatus>(() =>
84
88
  current.value
85
89
  ? "running"
86
90
  : failedIds.value.size > 0
@@ -108,10 +112,27 @@ const behind = computed(() =>
108
112
  open.value ? 0 : Math.min(props.calls.length - 1, 2),
109
113
  );
110
114
  const latestStatus = computed(() =>
111
- latest.value ? entryStatus(latest.value, props.isActive) : "done",
115
+ latest.value ? ɵgetToolCallRowStatus(latest.value, props.isActive) : "done",
112
116
  );
113
117
  const latestPreview = computed(() =>
114
- latest.value ? entryPreview(latest.value) : undefined,
118
+ latest.value ? ɵgetToolCallPreview(latest.value) : undefined,
119
+ );
120
+ const runningLabel = computed(() =>
121
+ current.value
122
+ ? ɵformatLabel(labels.value.toolCallRunningLabel, {
123
+ name: current.value.toolCall.function.name,
124
+ })
125
+ : "",
126
+ );
127
+ const usedToolsLabel = computed(() =>
128
+ ɵformatCountLabel(props.calls.length, {
129
+ one: labels.value.toolCallUsedToolsOne,
130
+ other: labels.value.toolCallUsedToolsOther,
131
+ }),
132
+ );
133
+ const toolNames = computed(() => ɵformatToolNames(props.calls));
134
+ const latestStatusLabel = computed(() =>
135
+ toolCallStatusLabel(labels.value, latestStatus.value),
115
136
  );
116
137
  const layer = "cpk-tool-call-group-stack-layer";
117
138
  </script>
@@ -144,20 +165,18 @@ const layer = "cpk-tool-call-group-stack-layer";
144
165
  @click="toggle"
145
166
  >
146
167
  <template v-if="current">
147
- <span class="cpk-tool-call-group-running cpk-shimmer"
148
- >Running {{ current.toolCall.function.name }}</span
149
- >
168
+ <span class="cpk-tool-call-group-running cpk-shimmer">{{
169
+ runningLabel
170
+ }}</span>
150
171
  <span v-if="preview" class="cpk-tool-call-group-preview">{{
151
172
  preview
152
173
  }}</span>
153
174
  </template>
154
175
  <template v-else>
155
- <span class="cpk-tool-call-group-line-summary"
156
- >Used {{ pluralize(calls.length, "tool") }}</span
157
- >
158
- <span class="cpk-tool-call-group-line-names">{{
159
- toolNames(calls)
176
+ <span class="cpk-tool-call-group-line-summary">{{
177
+ usedToolsLabel
160
178
  }}</span>
179
+ <span class="cpk-tool-call-group-line-names">{{ toolNames }}</span>
161
180
  <ToolCallFailedCount :calls="calls" />
162
181
  </template>
163
182
  <ToolCallChevron :open="open" />
@@ -206,10 +225,15 @@ const layer = "cpk-tool-call-group-stack-layer";
206
225
  @click="toggle"
207
226
  >
208
227
  <template v-if="open">
209
- {{ pluralize(calls.length, "tool call") }}
228
+ {{
229
+ ɵformatCountLabel(calls.length, {
230
+ one: labels.toolCallToolCallCountOne,
231
+ other: labels.toolCallToolCallCountOther,
232
+ })
233
+ }}
210
234
  <ToolCallFailedCount :calls="calls" />
211
235
  <span class="cpk-tool-call-group-stack-collapse">
212
- Collapse
236
+ {{ labels.toolCallCollapseLabel }}
213
237
  <ToolCallChevron
214
238
  :open="true"
215
239
  class="cpk-tool-call-group-stack-collapse-icon"
@@ -236,13 +260,16 @@ const layer = "cpk-tool-call-group-stack-layer";
236
260
  >
237
261
  <!-- The status icon is decorative, so say the status. -->
238
262
  <span class="cpk-tool-call-group-stack-status">{{
239
- statusLabels[latestStatus]
263
+ latestStatusLabel
240
264
  }}</span>
241
265
  </span>
242
266
  <span class="cpk-tool-call-group-stack-meta">
243
267
  <ToolCallFailedCount :calls="calls" />
244
268
  <span class="cpk-tool-call-group-stack-count">{{
245
- pluralize(calls.length, "call")
269
+ ɵformatCountLabel(calls.length, {
270
+ one: labels.toolCallCallCountOne,
271
+ other: labels.toolCallCallCountOther,
272
+ })
246
273
  }}</span>
247
274
  <ToolCallChevron
248
275
  :open="false"
@@ -255,9 +282,7 @@ const layer = "cpk-tool-call-group-stack-layer";
255
282
  call change ("read_file: Running", then "read_file: Done"); the
256
283
  button only names it. -->
257
284
  <span aria-live="polite" class="cpk-tool-call-group-stack-live">{{
258
- open
259
- ? ""
260
- : `${latest.toolCall.function.name}: ${statusLabels[latestStatus]}`
285
+ open ? "" : `${latest.toolCall.function.name}: ${latestStatusLabel}`
261
286
  }}</span>
262
287
  </div>
263
288
  <!-- Each call gets the collapsed stack's card, easing out of the stack. -->
@@ -292,28 +317,26 @@ const layer = "cpk-tool-call-group-stack-layer";
292
317
  >
293
318
  <ToolCallStatusIcon :status="status" />
294
319
  <template v-if="current">
295
- <span class="cpk-tool-call-group-running cpk-shimmer"
296
- >Running {{ current.toolCall.function.name }}</span
297
- >
320
+ <span class="cpk-tool-call-group-running cpk-shimmer">{{
321
+ runningLabel
322
+ }}</span>
298
323
  <span v-if="preview" class="cpk-tool-call-group-preview">{{
299
324
  preview
300
325
  }}</span>
301
326
  </template>
302
327
  <template v-else>
303
- <span class="cpk-tool-call-group-card-summary"
304
- >Used {{ pluralize(calls.length, "tool") }}</span
305
- >
306
- <span class="cpk-tool-call-group-card-names">{{
307
- toolNames(calls)
328
+ <span class="cpk-tool-call-group-card-summary">{{
329
+ usedToolsLabel
308
330
  }}</span>
331
+ <span class="cpk-tool-call-group-card-names">{{ toolNames }}</span>
309
332
  </template>
310
333
  <span class="cpk-tool-call-group-card-meta">
311
334
  <ToolCallFailedCount v-if="status === 'failed'" :calls="calls" />
312
335
  <span v-else class="cpk-tool-call-group-card-status">{{
313
336
  status !== "running"
314
- ? statusLabels[status]
337
+ ? toolCallStatusLabel(labels, status)
315
338
  : done > 0
316
- ? `${done} done`
339
+ ? ɵformatLabel(labels.toolCallDoneCountLabel, { count: done })
317
340
  : ""
318
341
  }}</span>
319
342
  <ToolCallChevron :open="open" />
@@ -1,11 +1,11 @@
1
1
  <script setup lang="ts">
2
2
  import type { Message, ToolCall } from "@ag-ui/core";
3
3
  import { DEFAULT_AGENT_ID } from "@copilotkit/shared";
4
+ import { ɵresolveToolCallRenderer } from "@copilotkit/core";
4
5
  import { useCopilotKit } from "../../providers/useCopilotKit";
5
6
  import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
6
7
  import type { CopilotChatToolCallRenderSlotProps } from "./types";
7
8
  import {
8
- getCoreRenderConfig,
9
9
  getCoreRenderProps,
10
10
  getToolCallMemoDeps,
11
11
  getToolCallRenderProps,
@@ -55,9 +55,9 @@ function getCoreProps() {
55
55
 
56
56
  function getRenderConfig() {
57
57
  const agentId = config.value?.agentId ?? DEFAULT_AGENT_ID;
58
- return getCoreRenderConfig(
59
- props.toolCall,
58
+ return ɵresolveToolCallRenderer(
60
59
  copilotkit.value.renderToolCalls,
60
+ props.toolCall.function.name,
61
61
  agentId,
62
62
  );
63
63
  }
@@ -3,6 +3,14 @@ import { computed, defineComponent, h, inject, provide, useSlots } from "vue";
3
3
  import type { PropType } from "vue";
4
4
  import type { Slots, VNode } from "vue";
5
5
  import type { AssistantMessage, Message } from "@ag-ui/core";
6
+ import {
7
+ ɵgetToolCallLayouts,
8
+ ɵgetToolCallRendererNames,
9
+ } from "@copilotkit/core";
10
+ import type {
11
+ CopilotChatToolCallDisplay,
12
+ ToolCallEntry,
13
+ } from "@copilotkit/core";
6
14
  import { useCopilotKit } from "../../providers/useCopilotKit";
7
15
  import type {
8
16
  CopilotChatToolCallGroupAppearance,
@@ -17,14 +25,6 @@ import {
17
25
  ToolCallGroupContextKey,
18
26
  } from "./tool-call-display-context";
19
27
  import type { ToolCallGroupContextValue } from "./tool-call-display-context";
20
- import {
21
- getToolCallLayouts,
22
- getToolCallRendererNames,
23
- } from "./tool-call-layout";
24
- import type {
25
- CopilotChatToolCallDisplay,
26
- ToolCallEntry,
27
- } from "./tool-call-layout";
28
28
 
29
29
  const props = withDefaults(
30
30
  defineProps<{
@@ -84,13 +84,15 @@ const layout = computed(() => {
84
84
  if (display.value === "separate") return undefined;
85
85
  const viewLayout = context?.value.layouts.get(props.message.id);
86
86
  if (viewLayout) return viewLayout;
87
- const rendererNames = getToolCallRendererNames(
87
+ const rendererNames = ɵgetToolCallRendererNames(
88
88
  copilotkit.value.renderToolCalls,
89
- getToolCallSlotNames(),
90
- );
91
- return getToolCallLayouts([props.message], props.messages, rendererNames).get(
92
- props.message.id,
89
+ { slotNames: getToolCallSlotNames() },
93
90
  );
91
+ return ɵgetToolCallLayouts(
92
+ [props.message],
93
+ props.messages,
94
+ rendererNames,
95
+ ).get(props.message.id);
94
96
  });
95
97
 
96
98
  // Whether the agent may still finish a trailing group's calls. Without a
@@ -1,12 +1,12 @@
1
1
  <script setup lang="ts">
2
- import { computed, onBeforeUnmount, ref } from "vue";
2
+ import { computed } from "vue";
3
3
  import type { UserMessage } from "@ag-ui/core";
4
- import type {
5
- AudioInputPart,
6
- DocumentInputPart,
7
- ImageInputPart,
8
- VideoInputPart,
9
- } from "@copilotkit/shared";
4
+ import {
5
+ ɵflattenUserMessageContent,
6
+ ɵgetBranchNavState,
7
+ ɵgetUserMessageMediaFilename,
8
+ ɵgetUserMessageMediaParts,
9
+ } from "@copilotkit/core";
10
10
  import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
11
11
  import { CopilotChatDefaultLabels } from "../../providers/types";
12
12
  import {
@@ -18,6 +18,7 @@ import {
18
18
  } from "../icons";
19
19
  import CopilotTooltip from "../ui/CopilotTooltip.vue";
20
20
  import CopilotChatAttachmentRenderer from "./CopilotChatAttachmentRenderer.vue";
21
+ import { useCopyFeedback } from "./use-copy-feedback";
21
22
  import type {
22
23
  CopilotChatUserMessageBranchNavigationSlotProps,
23
24
  CopilotChatUserMessageCopyButtonSlotProps,
@@ -66,117 +67,34 @@ const emit = defineEmits<{
66
67
 
67
68
  const config = useCopilotChatConfiguration();
68
69
  const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
69
- const copied = ref(false);
70
- let copiedResetTimeout: ReturnType<typeof setTimeout> | null = null;
70
+ const { copied, copy } = useCopyFeedback();
71
71
 
72
72
  // Styles live in @copilotkit/core (ui/button.css, user-message.css).
73
73
  const toolbarButtonClass =
74
74
  "cpk-button cpk-button-assistant-message-toolbar cpk-button-size-default";
75
75
 
76
- function flattenUserMessageContent(content?: UserMessage["content"]): string {
77
- if (!content) {
78
- return "";
79
- }
80
-
81
- if (typeof content === "string") {
82
- return content;
83
- }
84
-
85
- return content
86
- .map((part) => {
87
- if (
88
- part &&
89
- typeof part === "object" &&
90
- "type" in part &&
91
- (part as { type?: unknown }).type === "text" &&
92
- typeof (part as { text?: unknown }).text === "string"
93
- ) {
94
- return (part as { text: string }).text;
95
- }
96
- return "";
97
- })
98
- .filter((text) => text.length > 0)
99
- .join("\n");
100
- }
101
-
102
- type MediaPart =
103
- | ImageInputPart
104
- | AudioInputPart
105
- | VideoInputPart
106
- | DocumentInputPart;
107
-
108
- function getMediaParts(content: UserMessage["content"]): MediaPart[] {
109
- if (!content || typeof content === "string") return [];
110
- return content.filter(
111
- (part): part is MediaPart =>
112
- part.type === "image" ||
113
- part.type === "audio" ||
114
- part.type === "video" ||
115
- part.type === "document",
116
- );
117
- }
118
-
119
- function getFilename(part: MediaPart): string | undefined {
120
- const meta = part.metadata;
121
- if (
122
- meta != null &&
123
- typeof meta === "object" &&
124
- "filename" in meta &&
125
- typeof meta.filename === "string"
126
- ) {
127
- return meta.filename;
128
- }
129
- return undefined;
130
- }
131
-
132
- const mediaParts = computed(() => getMediaParts(props.message.content));
76
+ const mediaParts = computed(() =>
77
+ ɵgetUserMessageMediaParts(props.message.content),
78
+ );
133
79
 
134
80
  const flattenedContent = computed(() =>
135
- flattenUserMessageContent(props.message.content),
81
+ ɵflattenUserMessageContent(props.message.content),
136
82
  );
137
83
  const isMultiline = computed(() => flattenedContent.value.includes("\n"));
138
84
  const hasEditAction = computed(() => typeof props.onEditMessage === "function");
139
- const showBranchNavigation = computed(
140
- () =>
141
- props.numberOfBranches > 1 && typeof props.onSwitchToBranch === "function",
142
- );
143
-
144
- const canGoPrev = computed(
145
- () => showBranchNavigation.value && props.branchIndex > 0,
146
- );
147
- const canGoNext = computed(
148
- () =>
149
- showBranchNavigation.value &&
150
- props.branchIndex < props.numberOfBranches - 1,
85
+ const branchNav = computed(() =>
86
+ ɵgetBranchNavState({
87
+ branchIndex: props.branchIndex,
88
+ numberOfBranches: props.numberOfBranches,
89
+ canSwitch: typeof props.onSwitchToBranch === "function",
90
+ }),
151
91
  );
152
-
153
- function resetCopiedStateWithDelay() {
154
- if (copiedResetTimeout) {
155
- clearTimeout(copiedResetTimeout);
156
- }
157
- copied.value = true;
158
- copiedResetTimeout = setTimeout(() => {
159
- copied.value = false;
160
- copiedResetTimeout = null;
161
- }, 2000);
162
- }
92
+ const showBranchNavigation = computed(() => branchNav.value.show);
93
+ const canGoPrev = computed(() => branchNav.value.canGoPrev);
94
+ const canGoNext = computed(() => branchNav.value.canGoNext);
163
95
 
164
96
  async function handleCopyMessage() {
165
- if (!flattenedContent.value) return;
166
-
167
- if (
168
- typeof navigator === "undefined" ||
169
- typeof navigator.clipboard?.writeText !== "function"
170
- ) {
171
- return;
172
- }
173
-
174
- try {
175
- await navigator.clipboard.writeText(flattenedContent.value);
176
- resetCopiedStateWithDelay();
177
- } catch (error) {
178
- console.error("Failed to copy to clipboard:", error);
179
- }
97
+ await copy(flattenedContent.value);
180
98
  }
181
99
 
182
100
  function handleEditMessage() {
@@ -212,12 +130,6 @@ function goNext() {
212
130
  }
213
131
  switchToBranch(props.branchIndex + 1);
214
132
  }
215
-
216
- onBeforeUnmount(() => {
217
- if (copiedResetTimeout) {
218
- clearTimeout(copiedResetTimeout);
219
- }
220
- });
221
133
  </script>
222
134
 
223
135
  <template>
@@ -255,7 +167,7 @@ onBeforeUnmount(() => {
255
167
  :key="index"
256
168
  :type="part.type"
257
169
  :source="part.source"
258
- :filename="getFilename(part)"
170
+ :filename="ɵgetUserMessageMediaFilename(part)"
259
171
  />
260
172
  </div>
261
173
 
@@ -11,8 +11,7 @@ import {
11
11
  import type { Message } from "@ag-ui/core";
12
12
  import type { Suggestion } from "@copilotkit/core";
13
13
  import type { Attachment } from "@copilotkit/shared";
14
- import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
15
- import { CopilotChatDefaultLabels } from "../../providers/types";
14
+ import { useChatLabels } from "./use-chat-labels";
16
15
  import { useKeyboardHeight } from "../../hooks/use-keyboard-height";
17
16
  import { usePinToSend } from "../../hooks/use-pin-to-send";
18
17
  import { IconChevronDown, IconUpload } from "../icons";
@@ -127,8 +126,7 @@ const emit = defineEmits<{
127
126
  "finish-transcribe": [];
128
127
  }>();
129
128
 
130
- const config = useCopilotChatConfiguration();
131
- const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
129
+ const labels = useChatLabels();
132
130
  const componentSlots = useSlots();
133
131
 
134
132
  const scrollContainerRef = ref<HTMLElement | null>(null);
@@ -457,7 +455,9 @@ onBeforeUnmount(() => {
457
455
  >
458
456
  <div class="cpk-chat-view-drop-overlay-content">
459
457
  <IconUpload class="cpk-chat-view-drop-overlay-icon" />
460
- <span class="cpk-chat-view-drop-overlay-label">Drop files here</span>
458
+ <span class="cpk-chat-view-drop-overlay-label">{{
459
+ labels.chatDropFilesLabel
460
+ }}</span>
461
461
  </div>
462
462
  </div>
463
463
  <slot
@@ -5,10 +5,10 @@
5
5
  * for 9s · 7 tools" and toggles the work it folded away.
6
6
  */
7
7
  import { computed, ref, watch } from "vue";
8
+ import { ɵgetWorkSummaryText } from "@copilotkit/core";
8
9
  import { IconChevronRight } from "../icons";
9
10
  import type { CopilotChatWorkSummarySlotProps } from "./types";
10
- import { pluralize } from "./tool-call-group-parts";
11
- import { formatDuration } from "./turn-work";
11
+ import { useChatLabels } from "./use-chat-labels";
12
12
 
13
13
  // `onClick` falls through to the button.
14
14
  const props = defineProps<Omit<CopilotChatWorkSummarySlotProps, "onClick">>();
@@ -28,19 +28,16 @@ watch(
28
28
  { immediate: true },
29
29
  );
30
30
 
31
- const failed = computed(
32
- () => props.calls.filter((call) => call.toolMessage?.error).length,
33
- );
34
- const liveMs = computed(() =>
35
- props.elapsedMs !== undefined && props.workingSince !== undefined
36
- ? props.elapsedMs + Math.max(0, now.value - props.workingSince)
37
- : undefined,
38
- );
39
- // A finished reply worked for at least a second.
40
- const duration = computed(() =>
41
- props.elapsedMs !== undefined
42
- ? formatDuration(Math.max(1000, props.elapsedMs))
43
- : undefined,
31
+ const labels = useChatLabels();
32
+ const text = computed(() =>
33
+ ɵgetWorkSummaryText({
34
+ isWorking: props.isWorking,
35
+ calls: props.calls,
36
+ elapsedMs: props.elapsedMs,
37
+ workingSince: props.workingSince,
38
+ now: now.value,
39
+ labels: labels.value,
40
+ }),
44
41
  );
45
42
  </script>
46
43
 
@@ -53,27 +50,20 @@ const duration = computed(() =>
53
50
  :aria-expanded="isOpen ? 'true' : 'false'"
54
51
  class="cpk-work-summary"
55
52
  >
56
- <template v-if="isWorking">
57
- <span class="cpk-work-summary-label cpk-shimmer">Working</span>
58
- <span
59
- v-if="liveMs !== undefined"
60
- class="cpk-work-summary-detail cpk-work-summary-timer"
61
- >{{ formatDuration(liveMs) }}</span
62
- >
63
- </template>
64
- <template v-else>
65
- <span class="cpk-work-summary-label">{{
66
- duration
67
- ? `Worked for ${duration}`
68
- : `Used ${pluralize(calls.length, "tool")}`
69
- }}</span>
70
- <span v-if="duration" class="cpk-work-summary-detail">{{
71
- pluralize(calls.length, "tool")
72
- }}</span>
73
- <span v-if="failed > 0" class="cpk-work-summary-failed"
74
- >{{ failed }} failed</span
75
- >
76
- </template>
53
+ <span :class="['cpk-work-summary-label', isWorking && 'cpk-shimmer']">{{
54
+ text.label
55
+ }}</span>
56
+ <span
57
+ v-if="text.detail !== null"
58
+ :class="[
59
+ 'cpk-work-summary-detail',
60
+ isWorking && 'cpk-work-summary-timer',
61
+ ]"
62
+ >{{ text.detail }}</span
63
+ >
64
+ <span v-if="text.failed !== null" class="cpk-work-summary-failed">{{
65
+ text.failed
66
+ }}</span>
77
67
  <IconChevronRight
78
68
  aria-hidden="true"
79
69
  :class="[
@@ -2,7 +2,7 @@
2
2
  import { computed, onBeforeUnmount, onMounted, ref, useAttrs } from "vue";
3
3
  import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
4
4
  import { CopilotChatDefaultLabels } from "../../providers/types";
5
- import { MOBILE_MAX_WIDTH_QUERY } from "../../lib/is-mobile-viewport";
5
+ import { ɵwatchMobileViewport } from "@copilotkit/core";
6
6
  import CopilotModalHeaderCloseButton from "./CopilotModalHeaderCloseButton";
7
7
  import CopilotModalHeaderTitle from "./CopilotModalHeaderTitle";
8
8
  import { IconPanelLeftOpen } from "../icons";
@@ -45,34 +45,22 @@ function handleClose() {
45
45
  config.value?.setModalOpen?.(false);
46
46
  }
47
47
 
48
- // Tracks whether the viewport is in the mobile range (MOBILE_MAX_WIDTH_QUERY) — the same
49
- // breakpoint the drawer + chat coordination use. SSR-safe: starts `false`
50
- // (desktop) so the server render and first client render agree, then syncs
51
- // on mount and on viewport changes.
48
+ // Tracks whether the viewport is in the mobile range — the same breakpoint
49
+ // the drawer + chat coordination use. SSR-safe: starts `false` (desktop) so
50
+ // the server render and first client render agree, then syncs on mount and
51
+ // on viewport changes.
52
52
  const isMobile = ref(false);
53
- let mobileMediaQuery: MediaQueryList | null = null;
54
-
55
- function syncIsMobile() {
56
- if (mobileMediaQuery) {
57
- isMobile.value = mobileMediaQuery.matches;
58
- }
59
- }
53
+ let stopWatchingMobile: (() => void) | undefined;
60
54
 
61
55
  onMounted(() => {
62
- if (
63
- typeof window === "undefined" ||
64
- typeof window.matchMedia !== "function"
65
- ) {
66
- return;
67
- }
68
- mobileMediaQuery = window.matchMedia(MOBILE_MAX_WIDTH_QUERY);
69
- mobileMediaQuery.addEventListener("change", syncIsMobile);
70
- syncIsMobile();
56
+ stopWatchingMobile = ɵwatchMobileViewport((mobile) => {
57
+ isMobile.value = mobile;
58
+ });
71
59
  });
72
60
 
73
61
  onBeforeUnmount(() => {
74
- mobileMediaQuery?.removeEventListener("change", syncIsMobile);
75
- mobileMediaQuery = null;
62
+ stopWatchingMobile?.();
63
+ stopWatchingMobile = undefined;
76
64
  });
77
65
 
78
66
  // The thread-list launcher renders ONLY when a <CopilotThreadsDrawer> wrapper