@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
@@ -20,6 +20,11 @@ import type {
20
20
  import CopilotTooltip from "../ui/CopilotTooltip.vue";
21
21
  import { useCopilotId } from "../ui/use-id";
22
22
  import { hideInspectorShortcuts } from "./inspector-shortcuts";
23
+ import {
24
+ ɵHoverMenuController,
25
+ ɵinspectorKiteFill,
26
+ ɵinspectorKiteIcon,
27
+ } from "@copilotkit/core";
23
28
 
24
29
  defineOptions({ inheritAttrs: false });
25
30
 
@@ -37,32 +42,20 @@ const menuId = useCopilotId("cpk-inspector-menu");
37
42
  const triggerId = useCopilotId("cpk-inspector-button");
38
43
  const kiteId = useCopilotId("cpk-inspector-kite");
39
44
  const trigger = shallowRef<HTMLButtonElement | null>(null);
40
- const open = ref(false);
41
- const dark = ref(false);
42
45
  const initialFocus = ref<"first" | "none">("none");
43
- let closeTimer: ReturnType<typeof setTimeout> | null = null;
44
- // Hover opens it without moving focus, and leaving closes it again.
45
- let openedByHover = false;
46
-
47
- const cancelClose = () => {
48
- if (closeTimer !== null) clearTimeout(closeTimer);
49
- closeTimer = null;
50
- };
51
- onBeforeUnmount(cancelClose);
52
-
53
- const changeOpen = (next: boolean) => {
54
- cancelClose();
55
- if (next) dark.value = !!trigger.value?.closest(".dark");
56
- open.value = next;
57
- };
58
-
59
- const scheduleClose = () => {
60
- cancelClose();
61
- closeTimer = setTimeout(() => {
62
- // Keep the panel available while the keyboard is interacting with it.
63
- if (openedByHover) open.value = false;
64
- }, 180);
65
- };
46
+ const menu = new ɵHoverMenuController();
47
+ const menuState = shallowRef(menu.getSnapshot());
48
+ const unsubscribeMenu = menu.subscribe(() => {
49
+ menuState.value = menu.getSnapshot();
50
+ });
51
+ onBeforeUnmount(() => {
52
+ unsubscribeMenu();
53
+ menu.dispose();
54
+ });
55
+ const open = computed(() => menuState.value.open);
56
+ const dark = computed(() => menuState.value.dark);
57
+ const { cancelClose, scheduleClose, keyboardUsed } = menu;
58
+ const changeOpen = (next: boolean) => menu.setOpen(next, trigger.value);
66
59
 
67
60
  const items = computed<CopilotDropdownMenuEntry[]>(() => [
68
61
  {
@@ -82,9 +75,8 @@ const isInspectItem = (item: CopilotDropdownMenuItem) =>
82
75
 
83
76
  function onPointerEnter(event: PointerEvent) {
84
77
  if (props.disabled || event.pointerType === "touch") return;
85
- openedByHover = true;
86
78
  initialFocus.value = "none";
87
- changeOpen(true);
79
+ menu.pointerEnter({ pointerType: event.pointerType, trigger: trigger.value });
88
80
  }
89
81
 
90
82
  function onClick() {
@@ -93,7 +85,7 @@ function onClick() {
93
85
  }
94
86
 
95
87
  function onKeyDown(event: KeyboardEvent) {
96
- openedByHover = false;
88
+ keyboardUsed();
97
89
  if (event.key === "Enter" || event.key === " ") {
98
90
  // Enter and Space inspect, as a click does, instead of opening the menu.
99
91
  event.preventDefault();
@@ -103,7 +95,7 @@ function onKeyDown(event: KeyboardEvent) {
103
95
  initialFocus.value = "first";
104
96
  if (open.value) {
105
97
  // Open already from hover: move into it.
106
- open.value = false;
98
+ changeOpen(false);
107
99
  queueMicrotask(() => changeOpen(true));
108
100
  } else {
109
101
  changeOpen(true);
@@ -112,14 +104,14 @@ function onKeyDown(event: KeyboardEvent) {
112
104
  }
113
105
 
114
106
  function onSelect(item: CopilotDropdownMenuItem) {
115
- const returnFocus = !openedByHover;
107
+ const returnFocus = !menu.openedByHover;
116
108
  changeOpen(false);
117
109
  item.action?.();
118
110
  if (returnFocus && !isInspectItem(item)) trigger.value?.focus();
119
111
  }
120
112
 
121
113
  function onDismiss(reason: CopilotDropdownMenuDismissReason) {
122
- const returnFocus = !openedByHover && reason !== "outside";
114
+ const returnFocus = !menu.openedByHover && reason !== "outside";
123
115
  changeOpen(false);
124
116
  if (returnFocus) trigger.value?.focus();
125
117
  }
@@ -178,7 +170,7 @@ const descriptionFor = (item: CopilotDropdownMenuItem) =>
178
170
  @dismiss="onDismiss"
179
171
  @pointer-enter="cancelClose"
180
172
  @pointer-leave="scheduleClose"
181
- @keydown="openedByHover = false"
173
+ @keydown="keyboardUsed"
182
174
  >
183
175
  <template #header>
184
176
  <div
@@ -226,90 +218,35 @@ const descriptionFor = (item: CopilotDropdownMenuItem) =>
226
218
  v-if="isInspectItem(item)"
227
219
  aria-hidden="true"
228
220
  class="cpk-inspector-button-kite-icon cpk-inspector-button-menu-item-icon"
229
- viewBox="4.57 3.36 17.8 17.8"
221
+ :viewBox="ɵinspectorKiteIcon.viewBox"
230
222
  fill="none"
231
223
  >
232
224
  <path
233
- d="M6.36084 10.9855C8.34277 8.393 9.98843 5.82939 10.6204 3.75914C10.6382 3.70281 10.7043 3.67888 10.7534 3.7114C12.9536 5.16894 16.9635 6.12833 20.5086 6.15085C20.5703 6.15124 20.6124 6.2114 20.5895 6.26829C19.4109 9.25938 17.9705 14.6189 17.9148 20.7392C17.9148 20.8301 17.7873 20.8627 17.7419 20.7837C15.7236 17.2522 9.26021 12.2898 6.39414 11.1186C6.34112 11.0968 6.32556 11.0313 6.36084 10.9855Z"
234
- :fill="`url(#${kiteId}-paint0_linear)`"
235
- />
236
- <path
237
- d="M13.0475 9.39974C9.95016 10.3806 7.11935 10.9259 6.44331 11.0498C6.40027 11.0577 6.39115 11.1172 6.43152 11.134C9.3203 12.3347 15.7516 17.2826 17.7511 20.7998C17.7551 20.8075 17.7647 20.8103 17.7728 20.8068C17.7809 20.803 17.7853 20.793 17.7819 20.7844L13.0475 9.39974Z"
238
- :fill="`url(#${kiteId}-paint1_linear)`"
239
- />
240
- <path
241
- d="M10.762 3.705C13.4137 5.15161 16.4787 5.80132 20.545 6.14367C20.5703 6.14585 20.5787 6.18008 20.5557 6.19197C20.0359 6.45923 17.0574 7.97512 14.8455 8.78701C14.2524 9.00453 13.6564 9.20632 13.0692 9.39249C13.0562 9.39656 13.0419 9.39015 13.0369 9.37774L10.7005 3.75979C10.6849 3.72196 10.7257 3.68538 10.762 3.705Z"
242
- :fill="`url(#${kiteId}-paint2_linear)`"
243
- />
244
- <path
245
- d="M10.7145 3.79041L17.8305 20.7659"
246
- stroke="#513C9F"
247
- stroke-width="0.17284"
248
- stroke-linecap="round"
249
- />
250
- <path
251
- d="M6.44531 11.0476C6.44531 11.0476 10.375 10.3422 14.0686 9.06804C17.7623 7.7939 20.5122 6.23373 20.5122 6.23373"
252
- stroke="#513C9F"
253
- stroke-width="0.17284"
254
- stroke-linecap="round"
255
- />
256
- <path
257
- d="M11.6914 5.93518L9.05534 14.7068M9.05534 14.7068H15.3203M9.05534 14.7068L0.15625 26.3646"
258
- stroke="#ABABAB"
259
- stroke-width="0.302474"
260
- stroke-linecap="round"
261
- />
262
- <path
263
- d="M6.02539 23.9646L4.85806 24.1287C5.46272 25.7287 6.70381 26.4276 8.18528 26.4276C11.8147 26.4276 10.707 22.3227 12.8103 22.3227C14.3358 22.3227 13.7155 25.6498 16.9992 25.6498C19.0029 25.6498 19.2028 23.631 18.8607 22.7625C18.8589 22.7572 18.8568 22.7524 18.8538 22.7476L18.3166 21.9253C18.2817 21.8706 18.1968 21.8912 18.1907 21.9562L18.0908 22.9529C18.0838 23.0222 18.0857 23.0913 18.0936 23.1605C18.1764 23.8491 18.2291 25.5202 16.9992 25.5202C15.7015 25.5202 15.3895 22.2362 12.8103 22.2362C9.78393 22.2362 10.1726 26.298 8.31487 26.298C7.08938 26.298 6.15447 24.9153 6.02539 23.9646Z"
264
- :fill="`url(#${kiteId}-paint3_linear)`"
225
+ v-for="path in ɵinspectorKiteIcon.paths"
226
+ :key="path.d"
227
+ :d="path.d"
228
+ :fill="ɵinspectorKiteFill(kiteId, path)"
229
+ :stroke="path.stroke"
230
+ :stroke-width="path.strokeWidth"
231
+ :stroke-linecap="path.strokeLinecap"
265
232
  />
266
233
  <defs>
267
234
  <linearGradient
268
- :id="`${kiteId}-paint0_linear`"
269
- x1="15.5372"
270
- y1="5.0278"
271
- x2="12.0802"
272
- y2="14.534"
273
- gradientUnits="userSpaceOnUse"
274
- >
275
- <stop stop-color="#6430AB" />
276
- <stop offset="1" stop-color="#AA89D8" />
277
- </linearGradient>
278
- <linearGradient
279
- :id="`${kiteId}-paint1_linear`"
280
- x1="12.8583"
281
- y1="10.3858"
282
- x2="8.40764"
283
- y2="18.9846"
284
- gradientUnits="userSpaceOnUse"
285
- >
286
- <stop stop-color="#005DBB" />
287
- <stop offset="1" stop-color="#3D92E8" />
288
- </linearGradient>
289
- <linearGradient
290
- :id="`${kiteId}-paint2_linear`"
291
- x1="14.8452"
292
- y1="5.02774"
293
- x2="13.5047"
294
- y2="9.21911"
295
- gradientUnits="userSpaceOnUse"
296
- >
297
- <stop stop-color="#1B70C4" />
298
- <stop offset="1" stop-color="#54A4F2" />
299
- </linearGradient>
300
- <linearGradient
301
- :id="`${kiteId}-paint3_linear`"
302
- x1="4.85806"
303
- y1="24.2455"
304
- x2="18.9963"
305
- y2="24.2455"
235
+ v-for="gradient in ɵinspectorKiteIcon.gradients"
236
+ :id="`${kiteId}-${gradient.id}`"
237
+ :key="gradient.id"
238
+ :x1="gradient.x1"
239
+ :y1="gradient.y1"
240
+ :x2="gradient.x2"
241
+ :y2="gradient.y2"
306
242
  gradientUnits="userSpaceOnUse"
307
243
  >
308
- <stop stop-color="#4497EA" />
309
- <stop offset="0.254755" stop-color="#1463B2" />
310
- <stop offset="0.498725" stop-color="#0A437D" />
311
- <stop offset="0.666667" stop-color="#2476C8" />
312
- <stop offset="0.972542" stop-color="#0C549A" />
244
+ <stop
245
+ v-for="stop in gradient.stops"
246
+ :key="`${stop.offset ?? '0'}-${stop.color}`"
247
+ :offset="stop.offset"
248
+ :stop-color="stop.color"
249
+ />
313
250
  </linearGradient>
314
251
  </defs>
315
252
  </svg>
@@ -15,6 +15,27 @@ import {
15
15
  createRowKeyStore,
16
16
  resolveRowRenderKeysById,
17
17
  } from "@copilotkit/shared";
18
+ import {
19
+ ɵdeduplicateMessages,
20
+ ɵgetToolCallLayouts,
21
+ ɵgetToolCallRendererNames,
22
+ ɵgetTurnWork,
23
+ ɵgetWorkOpenState,
24
+ ɵisTurnWorkOpen,
25
+ ɵisTurnWorking,
26
+ ɵrecordWorkTime,
27
+ ɵresolveActivityRenderer,
28
+ ɵresolveCustomMessageRenderers,
29
+ ɵgetLatestTurnKey,
30
+ } from "@copilotkit/core";
31
+ import type {
32
+ CopilotChatToolCallDisplay,
33
+ ToolCallEntry,
34
+ ɵToolCallDisplayContextValue,
35
+ ɵToolCallLayout,
36
+ ɵTurnWork,
37
+ ɵWorkTime,
38
+ } from "@copilotkit/core";
18
39
  import type {
19
40
  InterruptRenderProps,
20
41
  VueCustomMessageRendererProps,
@@ -33,18 +54,6 @@ import {
33
54
  } from "./message-feedback";
34
55
  import type { MessageFeedbackScope } from "./message-feedback";
35
56
  import { ToolCallDisplayContextKey } from "./tool-call-display-context";
36
- import type { ToolCallDisplayContextValue } from "./tool-call-display-context";
37
- import {
38
- getToolCallLayouts,
39
- getToolCallRendererNames,
40
- getTurnWork,
41
- } from "./tool-call-layout";
42
- import type {
43
- CopilotChatToolCallDisplay,
44
- ToolCallEntry,
45
- ToolCallLayout,
46
- TurnWork,
47
- } from "./tool-call-layout";
48
57
  import type { CopilotChatWorkSummarySlotProps } from "./types";
49
58
 
50
59
  interface MessageMetaProps {
@@ -203,47 +212,22 @@ watch(
203
212
  { immediate: true },
204
213
  );
205
214
 
206
- function deduplicateMessages(messages: Message[]): Message[] {
207
- const byId = new Map<string, Message>();
208
- for (const message of messages) {
209
- const existing = byId.get(message.id);
210
- if (
211
- existing &&
212
- message.role === "assistant" &&
213
- existing.role === "assistant"
214
- ) {
215
- const content = message.content || existing.content;
216
- const toolCalls = message.toolCalls ?? existing.toolCalls;
217
- byId.set(message.id, {
218
- ...existing,
219
- ...message,
220
- content,
221
- toolCalls,
222
- } as AssistantMessage);
223
- } else {
224
- byId.set(message.id, message);
225
- }
226
- }
227
- return [...byId.values()];
228
- }
229
-
230
215
  const deduplicatedMessages = computed(() =>
231
- deduplicateMessages(props.messages),
216
+ ɵdeduplicateMessages(props.messages),
232
217
  );
233
218
 
234
219
  // Groups of calls can span messages (an agent often sends each call as its
235
220
  // own message), so they're laid out here for the whole list and handed to
236
221
  // each message's tool calls view through provide/inject.
237
- const toolCallLayouts = computed<ReadonlyMap<string, ToolCallLayout>>(() =>
222
+ const toolCallLayouts = computed<ReadonlyMap<string, ɵToolCallLayout>>(() =>
238
223
  props.toolCallDisplay === "separate"
239
224
  ? new Map()
240
- : getToolCallLayouts(
225
+ : ɵgetToolCallLayouts(
241
226
  deduplicatedMessages.value,
242
227
  props.messages,
243
- getToolCallRendererNames(
244
- copilotkit.value.renderToolCalls,
245
- forwardedSlotNames.value,
246
- ),
228
+ ɵgetToolCallRendererNames(copilotkit.value.renderToolCalls, {
229
+ slotNames: forwardedSlotNames.value,
230
+ }),
247
231
  ),
248
232
  );
249
233
  const learningFeedbackEnabled = useLearningFeedbackEnabled(copilotkit);
@@ -265,11 +249,11 @@ provide(
265
249
 
266
250
  const turnWork = computed(() =>
267
251
  props.toolCallDisplay === "turn"
268
- ? getTurnWork(deduplicatedMessages.value, toolCallLayouts.value)
252
+ ? ɵgetTurnWork(deduplicatedMessages.value, toolCallLayouts.value)
269
253
  : undefined,
270
254
  );
271
255
  const turnByFirstMessage = computed(() => {
272
- const byFirst = new Map<string, TurnWork>();
256
+ const byFirst = new Map<string, ɵTurnWork>();
273
257
  for (const turn of turnWork.value?.values() ?? []) {
274
258
  byFirst.set(turn.firstMessageId, turn);
275
259
  }
@@ -280,30 +264,23 @@ const lastRenderedMessage = computed(
280
264
  () => deduplicatedMessages.value[deduplicatedMessages.value.length - 1],
281
265
  );
282
266
  // The latest reply is keyed by the user message it answers (see getTurnWork).
283
- const latestTurnKey = computed(() => {
284
- const rendered = deduplicatedMessages.value;
285
- for (let i = rendered.length - 1; i >= 0; i--) {
286
- if (rendered[i]!.role === "user") return rendered[i]!.id;
287
- }
288
- return "start";
289
- });
290
- const isWorkingOn = (turnKey: string) =>
291
- props.isRunning && turnKey === latestTurnKey.value;
267
+ const latestTurnKey = computed(() =>
268
+ ɵgetLatestTurnKey(deduplicatedMessages.value),
269
+ );
292
270
 
293
271
  // Work shows while the agent is on it and folds once the reply is done,
294
272
  // unless the user has opened or closed it themselves.
295
273
  const toggledTurns = ref<ReadonlyMap<string, boolean>>(new Map());
296
- const isWorkOpen = (turnKey: string) =>
297
- toggledTurns.value.get(turnKey) ?? isWorkingOn(turnKey);
298
-
299
- // How long the agent worked, for "Worked for 9s": the sum of its runs on the
300
- // reply, so waiting between them (say, for an approval) doesn't count. Only
301
- // known for replies this client watched start from the user's message; a
302
- // restored thread shows the tool count instead.
303
- const workTimes = new Map<
304
- string,
305
- { elapsedMs: number; workingSince?: number }
306
- >();
274
+ const turnOpenState = computed(() => ({
275
+ toggledTurns: toggledTurns.value,
276
+ isRunning: props.isRunning,
277
+ latestTurnKey: latestTurnKey.value,
278
+ }));
279
+
280
+ // How long the agent worked, for "Worked for 9s". Only known for replies this
281
+ // client watched start from the user's message; a restored thread shows the
282
+ // tool count instead.
283
+ const workTimes = new Map<string, ɵWorkTime>();
307
284
  const workTimesVersion = ref(0);
308
285
  watch(
309
286
  [
@@ -314,42 +291,25 @@ watch(
314
291
  ],
315
292
  ([display, isRunning, turnKey, lastRole]) => {
316
293
  if (display !== "turn") return;
317
- const now = Date.now();
318
- if (isRunning) {
319
- const times = workTimes.get(turnKey);
320
- if (times) times.workingSince ??= now;
321
- else if (lastRole === "user")
322
- workTimes.set(turnKey, { elapsedMs: 0, workingSince: now });
323
- } else {
324
- for (const times of workTimes.values()) {
325
- if (times.workingSince === undefined) continue;
326
- times.elapsedMs += now - times.workingSince;
327
- times.workingSince = undefined;
328
- }
329
- }
294
+ ɵrecordWorkTime(workTimes, {
295
+ isRunning,
296
+ latestTurnKey: turnKey,
297
+ lastMessageRole: lastRole,
298
+ now: Date.now(),
299
+ });
330
300
  workTimesVersion.value++;
331
301
  },
332
302
  { immediate: true },
333
303
  );
334
304
 
335
- // Whether each working-phase message's work shows. Text that ends the reply
336
- // stays out even when its message also calls a tool: it's the answer.
337
- const workOpenState = computed(() => {
338
- const open = new Map<string, boolean>();
339
- const textOpen = new Map<string, boolean>();
340
- for (const turn of turnWork.value?.values() ?? []) {
341
- const turnOpen = isWorkOpen(turn.key);
342
- for (const id of turn.workMessageIds) {
343
- open.set(id, turnOpen);
344
- if (id !== turn.replyTextMessageId) textOpen.set(id, turnOpen);
345
- }
346
- }
347
- return { workOpen: open, workTextOpen: textOpen };
348
- });
305
+ // Whether each working-phase message's work, and its text, shows.
306
+ const workOpenState = computed(() =>
307
+ ɵgetWorkOpenState(turnWork.value?.values() ?? [], turnOpenState.value),
308
+ );
349
309
 
350
310
  provide(
351
311
  ToolCallDisplayContextKey,
352
- computed<ToolCallDisplayContextValue>(() => ({
312
+ computed<ɵToolCallDisplayContextValue>(() => ({
353
313
  display: props.toolCallDisplay,
354
314
  isRunning: props.isRunning,
355
315
  layouts: toolCallLayouts.value,
@@ -364,8 +324,8 @@ const WorkSummaryRow: FunctionalComponent<{
364
324
  calls: ToolCallEntry[];
365
325
  }> = ({ turnKey, calls }) => {
366
326
  void workTimesVersion.value;
367
- const isWorking = isWorkingOn(turnKey);
368
- const isOpen = isWorkOpen(turnKey);
327
+ const isWorking = ɵisTurnWorking(turnKey, turnOpenState.value);
328
+ const isOpen = ɵisTurnWorkOpen(turnKey, turnOpenState.value);
369
329
  const times = workTimes.get(turnKey);
370
330
  const summaryProps: CopilotChatWorkSummarySlotProps = {
371
331
  isWorking,
@@ -534,21 +494,12 @@ function resolveCustomMessageRenderer(
534
494
  return null;
535
495
  }
536
496
 
537
- const agentId = resolvedAgentId.value;
538
- const renderers = [...copilotkit.value.renderCustomMessages]
539
- .filter(
540
- (renderer) =>
541
- renderer.agentId === undefined || renderer.agentId === agentId,
542
- )
543
- .sort((a, b) => {
544
- const aHasAgent = a.agentId !== undefined;
545
- const bHasAgent = b.agentId !== undefined;
546
- if (aHasAgent === bHasAgent) return 0;
547
- return aHasAgent ? -1 : 1;
548
- });
549
-
550
- const selected = renderers[0];
551
- if (!selected?.render) {
497
+ // Try each renderer in order and use the first that has something to draw.
498
+ const selected = ɵresolveCustomMessageRenderers(
499
+ copilotkit.value.renderCustomMessages,
500
+ resolvedAgentId.value,
501
+ ).find((renderer) => renderer.render);
502
+ if (!selected) {
552
503
  return null;
553
504
  }
554
505
 
@@ -563,45 +514,26 @@ function resolveActivityRenderer(
563
514
  ): { renderer: Component; props: ActivitySlotProps } | null {
564
515
  stateTick.value += 0;
565
516
 
566
- const agentId = resolvedAgentId.value;
567
- const renderer = [...copilotkit.value.renderActivityMessages]
568
- .filter(
569
- (entry) =>
570
- entry.activityType === message.activityType &&
571
- (entry.agentId === undefined || entry.agentId === agentId),
572
- )
573
- .sort((a, b) => {
574
- const aScoped = a.agentId !== undefined;
575
- const bScoped = b.agentId !== undefined;
576
- if (aScoped === bScoped) return 0;
577
- return aScoped ? -1 : 1;
578
- })[0];
579
-
580
- if (!renderer) return null;
581
- const parsed = renderer.content.safeParse(message.content);
582
- if (!parsed.success) return null;
517
+ const match = ɵresolveActivityRenderer(
518
+ copilotkit.value.renderActivityMessages,
519
+ {
520
+ activityType: message.activityType,
521
+ agentId: resolvedAgentId.value,
522
+ content: message.content,
523
+ },
524
+ );
525
+ if (!match) return null;
583
526
 
584
527
  return {
585
- renderer: renderer.render as Component,
528
+ renderer: match.renderer.render as Component,
586
529
  props: {
587
530
  activityType: message.activityType,
588
- content: parsed.data,
531
+ content: match.content,
589
532
  message,
590
533
  agent: resolvedThreadAgent.value,
591
534
  },
592
535
  };
593
536
  }
594
-
595
- function resolveToolMessage(
596
- message: Message,
597
- toolCallId: string,
598
- ): ToolMessage | undefined {
599
- return props.messages.find(
600
- (candidate) =>
601
- candidate.role === "tool" &&
602
- (candidate as ToolMessage).toolCallId === toolCallId,
603
- ) as ToolMessage | undefined;
604
- }
605
537
  </script>
606
538
 
607
539
  <template>
@@ -3,8 +3,8 @@ import { computed, onBeforeUnmount, ref, watch } from "vue";
3
3
  import type { Message, ReasoningMessage } from "@ag-ui/core";
4
4
  import { IconChevronRight } from "../icons";
5
5
  import StreamingMarkdownDefault from "./StreamingMarkdownDefault.vue";
6
- import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
7
- import { CopilotChatDefaultLabels } from "../../providers/types";
6
+ import { ɵformatLabel, ɵformatReasoningDurationLabel } from "@copilotkit/core";
7
+ import { useChatLabels } from "./use-chat-labels";
8
8
 
9
9
  const props = withDefaults(
10
10
  defineProps<{
@@ -69,15 +69,6 @@ defineSlots<{
69
69
  }) => unknown;
70
70
  }>();
71
71
 
72
- function formatDuration(seconds: number): string {
73
- if (seconds < 1) return "a few seconds";
74
- if (seconds < 60) return `${Math.round(seconds)} seconds`;
75
- const mins = Math.floor(seconds / 60);
76
- const secs = Math.round(seconds % 60);
77
- if (secs === 0) return `${mins} minute${mins > 1 ? "s" : ""}`;
78
- return `${mins}m ${secs}s`;
79
- }
80
-
81
72
  const normalizedContent = computed(() =>
82
73
  typeof props.message.content === "string" ? props.message.content : "",
83
74
  );
@@ -133,13 +124,14 @@ onBeforeUnmount(() => {
133
124
  clearElapsedInterval();
134
125
  });
135
126
 
136
- const config = useCopilotChatConfiguration();
127
+ const labels = useChatLabels();
137
128
  /** `labels.reasoningMessageThinkingLabel` while streaming, then "Thought for …". */
138
129
  const label = computed(() =>
139
130
  isStreaming.value
140
- ? (config.value?.labels ?? CopilotChatDefaultLabels)
141
- .reasoningMessageThinkingLabel
142
- : `Thought for ${formatDuration(elapsed.value)}`,
131
+ ? labels.value.reasoningMessageThinkingLabel
132
+ : ɵformatLabel(labels.value.reasoningMessageThoughtForLabel, {
133
+ duration: ɵformatReasoningDurationLabel(elapsed.value, labels.value),
134
+ }),
143
135
  );
144
136
 
145
137
  function toggleOpen() {