@copilotkit/react-core 1.54.1 → 1.55.0-next.8

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 (183) hide show
  1. package/CHANGELOG.md +127 -116
  2. package/dist/copilotkit-B3Mb1yVE.cjs +7975 -0
  3. package/dist/copilotkit-B3Mb1yVE.cjs.map +1 -0
  4. package/dist/copilotkit-DBzgOMby.d.cts +2182 -0
  5. package/dist/copilotkit-DBzgOMby.d.cts.map +1 -0
  6. package/dist/copilotkit-DNYSFuz5.mjs +7562 -0
  7. package/dist/copilotkit-DNYSFuz5.mjs.map +1 -0
  8. package/dist/copilotkit-Dy5w3qEV.d.mts +2182 -0
  9. package/dist/copilotkit-Dy5w3qEV.d.mts.map +1 -0
  10. package/dist/index.cjs +27 -28
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.cts +3 -3
  13. package/dist/index.d.cts.map +1 -1
  14. package/dist/index.d.mts +3 -3
  15. package/dist/index.d.mts.map +1 -1
  16. package/dist/index.mjs +4 -5
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/index.umd.js +1941 -35
  19. package/dist/index.umd.js.map +1 -1
  20. package/dist/v2/index.cjs +77 -7
  21. package/dist/v2/index.css +1 -2
  22. package/dist/v2/index.d.cts +6 -4
  23. package/dist/v2/index.d.mts +6 -4
  24. package/dist/v2/index.mjs +7 -4
  25. package/dist/v2/index.umd.js +5725 -24
  26. package/dist/v2/index.umd.js.map +1 -1
  27. package/package.json +37 -9
  28. package/scripts/scope-preflight.mjs +101 -0
  29. package/src/components/CopilotListeners.tsx +2 -6
  30. package/src/components/copilot-provider/copilot-messages.tsx +1 -1
  31. package/src/components/copilot-provider/copilotkit-props.tsx +1 -1
  32. package/src/components/copilot-provider/copilotkit.tsx +4 -4
  33. package/src/context/copilot-messages-context.tsx +1 -1
  34. package/src/hooks/__tests__/use-coagent-config.test.ts +2 -2
  35. package/src/hooks/__tests__/use-coagent-state-render.e2e.test.tsx +2 -2
  36. package/src/hooks/__tests__/use-copilot-chat-internal-connect.test.tsx +3 -7
  37. package/src/hooks/__tests__/use-frontend-tool-available.test.tsx +1 -1
  38. package/src/hooks/__tests__/use-frontend-tool-remount.e2e.test.tsx +4 -4
  39. package/src/hooks/use-agent-nodename.ts +1 -1
  40. package/src/hooks/use-coagent-state-render-bridge.tsx +1 -4
  41. package/src/hooks/use-coagent.ts +1 -1
  42. package/src/hooks/use-configure-chat-suggestions.tsx +2 -2
  43. package/src/hooks/use-copilot-chat-suggestions.tsx +2 -2
  44. package/src/hooks/use-copilot-chat_internal.ts +2 -2
  45. package/src/hooks/use-copilot-readable.ts +1 -1
  46. package/src/hooks/use-frontend-tool.ts +2 -2
  47. package/src/hooks/use-human-in-the-loop.ts +2 -2
  48. package/src/hooks/use-langgraph-interrupt.ts +2 -5
  49. package/src/hooks/use-lazy-tool-renderer.tsx +1 -1
  50. package/src/hooks/use-render-tool-call.ts +1 -1
  51. package/src/lib/copilot-task.ts +1 -1
  52. package/src/setupTests.ts +18 -14
  53. package/src/v2/__tests__/A2UIMessageRenderer.test.tsx +176 -0
  54. package/src/v2/__tests__/globalSetup.ts +14 -0
  55. package/src/v2/__tests__/setup.ts +93 -0
  56. package/src/v2/__tests__/utils/test-helpers.tsx +470 -0
  57. package/src/v2/a2ui/A2UIMessageRenderer.tsx +206 -0
  58. package/src/v2/components/CopilotKitInspector.tsx +50 -0
  59. package/src/v2/components/MCPAppsActivityRenderer.tsx +785 -0
  60. package/src/v2/components/WildcardToolCallRender.tsx +86 -0
  61. package/src/v2/components/__tests__/license-warning-banner.test.tsx +46 -0
  62. package/src/v2/components/chat/CopilotChat.tsx +431 -0
  63. package/src/v2/components/chat/CopilotChatAssistantMessage.tsx +375 -0
  64. package/src/v2/components/chat/CopilotChatAudioRecorder.tsx +350 -0
  65. package/src/v2/components/chat/CopilotChatInput.tsx +1302 -0
  66. package/src/v2/components/chat/CopilotChatMessageView.tsx +556 -0
  67. package/src/v2/components/chat/CopilotChatReasoningMessage.tsx +252 -0
  68. package/src/v2/components/chat/CopilotChatSuggestionPill.tsx +59 -0
  69. package/src/v2/components/chat/CopilotChatSuggestionView.tsx +133 -0
  70. package/src/v2/components/chat/CopilotChatToggleButton.tsx +171 -0
  71. package/src/v2/components/chat/CopilotChatToolCallsView.tsx +40 -0
  72. package/src/v2/components/chat/CopilotChatUserMessage.tsx +388 -0
  73. package/src/v2/components/chat/CopilotChatView.tsx +598 -0
  74. package/src/v2/components/chat/CopilotModalHeader.tsx +129 -0
  75. package/src/v2/components/chat/CopilotPopup.tsx +81 -0
  76. package/src/v2/components/chat/CopilotPopupView.tsx +317 -0
  77. package/src/v2/components/chat/CopilotSidebar.tsx +76 -0
  78. package/src/v2/components/chat/CopilotSidebarView.tsx +255 -0
  79. package/src/v2/components/chat/__tests__/CopilotChat.e2e.test.tsx +1113 -0
  80. package/src/v2/components/chat/__tests__/CopilotChat.onError.test.tsx +73 -0
  81. package/src/v2/components/chat/__tests__/CopilotChat.slots.e2e.test.tsx +432 -0
  82. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +150 -0
  83. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.slots.e2e.test.tsx +624 -0
  84. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.test.tsx +702 -0
  85. package/src/v2/components/chat/__tests__/CopilotChatCssClasses.test.tsx +107 -0
  86. package/src/v2/components/chat/__tests__/CopilotChatInput.slots.e2e.test.tsx +929 -0
  87. package/src/v2/components/chat/__tests__/CopilotChatInput.test.tsx +986 -0
  88. package/src/v2/components/chat/__tests__/CopilotChatMessageView.slots.e2e.test.tsx +1004 -0
  89. package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.tsx +169 -0
  90. package/src/v2/components/chat/__tests__/CopilotChatSuggestionView.slots.e2e.test.tsx +530 -0
  91. package/src/v2/components/chat/__tests__/CopilotChatToolRendering.e2e.test.tsx +782 -0
  92. package/src/v2/components/chat/__tests__/CopilotChatToolRerenders.e2e.test.tsx +2413 -0
  93. package/src/v2/components/chat/__tests__/CopilotChatUserMessage.slots.e2e.test.tsx +621 -0
  94. package/src/v2/components/chat/__tests__/CopilotChatView.onClick.e2e.test.tsx +853 -0
  95. package/src/v2/components/chat/__tests__/CopilotChatView.slots.e2e.test.tsx +1050 -0
  96. package/src/v2/components/chat/__tests__/CopilotModalHeader.slots.e2e.test.tsx +484 -0
  97. package/src/v2/components/chat/__tests__/CopilotPopupView.slots.e2e.test.tsx +612 -0
  98. package/src/v2/components/chat/__tests__/CopilotSidebarView.slots.e2e.test.tsx +502 -0
  99. package/src/v2/components/chat/__tests__/MCPAppsActivityRenderer.e2e.test.tsx +1011 -0
  100. package/src/v2/components/chat/__tests__/setup.ts +1 -0
  101. package/src/v2/components/chat/index.ts +79 -0
  102. package/src/v2/components/index.ts +7 -0
  103. package/src/v2/components/license-warning-banner.tsx +198 -0
  104. package/src/v2/components/ui/button.tsx +123 -0
  105. package/src/v2/components/ui/dropdown-menu.tsx +258 -0
  106. package/src/v2/components/ui/tooltip.tsx +60 -0
  107. package/src/v2/hooks/__tests__/standard-schema-types.test.tsx +152 -0
  108. package/src/v2/hooks/__tests__/standard-schema.test.tsx +282 -0
  109. package/src/v2/hooks/__tests__/use-agent-context-timing.e2e.test.tsx +132 -0
  110. package/src/v2/hooks/__tests__/use-agent-context.test.tsx +401 -0
  111. package/src/v2/hooks/__tests__/use-agent-error-state.test.tsx +44 -0
  112. package/src/v2/hooks/__tests__/use-agent-stability.test.tsx +205 -0
  113. package/src/v2/hooks/__tests__/use-agent.e2e.test.tsx +148 -0
  114. package/src/v2/hooks/__tests__/use-component.test.tsx +123 -0
  115. package/src/v2/hooks/__tests__/use-configure-suggestions.e2e.test.tsx +696 -0
  116. package/src/v2/hooks/__tests__/use-default-render-tool.test.tsx +153 -0
  117. package/src/v2/hooks/__tests__/use-frontend-tool-available.test.tsx +167 -0
  118. package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.tsx +2129 -0
  119. package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.tsx +1261 -0
  120. package/src/v2/hooks/__tests__/use-interrupt.test.tsx +397 -0
  121. package/src/v2/hooks/__tests__/use-katex-styles.test.tsx +56 -0
  122. package/src/v2/hooks/__tests__/use-keyboard-height.test.tsx +192 -0
  123. package/src/v2/hooks/__tests__/use-render-tool.test.tsx +259 -0
  124. package/src/v2/hooks/__tests__/use-suggestions.e2e.test.tsx +524 -0
  125. package/src/v2/hooks/__tests__/use-threads.test.tsx +433 -0
  126. package/src/v2/hooks/__tests__/zod-regression.test.tsx +311 -0
  127. package/src/v2/hooks/index.ts +18 -0
  128. package/src/v2/hooks/use-agent-context.tsx +45 -0
  129. package/src/v2/hooks/use-agent.tsx +155 -0
  130. package/src/v2/hooks/use-component.tsx +89 -0
  131. package/src/v2/hooks/use-configure-suggestions.tsx +187 -0
  132. package/src/v2/hooks/use-default-render-tool.tsx +254 -0
  133. package/src/v2/hooks/use-frontend-tool.tsx +43 -0
  134. package/src/v2/hooks/use-human-in-the-loop.tsx +81 -0
  135. package/src/v2/hooks/use-interrupt.tsx +305 -0
  136. package/src/v2/hooks/use-keyboard-height.tsx +67 -0
  137. package/src/v2/hooks/use-render-activity-message.tsx +73 -0
  138. package/src/v2/hooks/use-render-custom-messages.tsx +93 -0
  139. package/src/v2/hooks/use-render-tool-call.tsx +175 -0
  140. package/src/v2/hooks/use-render-tool.tsx +181 -0
  141. package/src/v2/hooks/use-suggestions.tsx +91 -0
  142. package/src/v2/hooks/use-threads.tsx +256 -0
  143. package/src/v2/hooks/useKatexStyles.ts +27 -0
  144. package/src/v2/index.css +1 -1
  145. package/src/v2/index.ts +18 -2
  146. package/src/v2/lib/__tests__/completePartialMarkdown.test.ts +495 -0
  147. package/src/v2/lib/__tests__/renderSlot.test.tsx +588 -0
  148. package/src/v2/lib/react-core.ts +156 -0
  149. package/src/v2/lib/slots.tsx +143 -0
  150. package/src/v2/lib/transcription-client.ts +184 -0
  151. package/src/v2/lib/utils.ts +8 -0
  152. package/src/v2/providers/CopilotChatConfigurationProvider.tsx +162 -0
  153. package/src/v2/providers/CopilotKitProvider.tsx +600 -0
  154. package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.tsx +546 -0
  155. package/src/v2/providers/__tests__/CopilotKitProvider.license.test.tsx +101 -0
  156. package/src/v2/providers/__tests__/CopilotKitProvider.onError.test.tsx +69 -0
  157. package/src/v2/providers/__tests__/CopilotKitProvider.renderCustomMessages.e2e.test.tsx +881 -0
  158. package/src/v2/providers/__tests__/CopilotKitProvider.stability.test.tsx +740 -0
  159. package/src/v2/providers/__tests__/CopilotKitProvider.test.tsx +642 -0
  160. package/src/v2/providers/__tests__/CopilotKitProvider.wildcard.test.tsx +294 -0
  161. package/src/v2/providers/index.ts +14 -0
  162. package/src/v2/styles/globals.css +230 -0
  163. package/src/v2/types/__tests__/defineToolCallRenderer.test.tsx +525 -0
  164. package/src/v2/types/defineToolCallRenderer.ts +65 -0
  165. package/src/v2/types/frontend-tool.ts +8 -0
  166. package/src/v2/types/human-in-the-loop.ts +33 -0
  167. package/src/v2/types/index.ts +7 -0
  168. package/src/v2/types/interrupt.ts +15 -0
  169. package/src/v2/types/react-activity-message-renderer.ts +27 -0
  170. package/src/v2/types/react-custom-message-renderer.ts +17 -0
  171. package/src/v2/types/react-tool-call-renderer.ts +32 -0
  172. package/tsdown.config.ts +34 -10
  173. package/vitest.config.mjs +4 -3
  174. package/LICENSE +0 -21
  175. package/dist/copilotkit-BRPQ2sqS.d.cts +0 -670
  176. package/dist/copilotkit-BRPQ2sqS.d.cts.map +0 -1
  177. package/dist/copilotkit-C94ayZbs.cjs +0 -2161
  178. package/dist/copilotkit-C94ayZbs.cjs.map +0 -1
  179. package/dist/copilotkit-CwZMFmSK.d.mts +0 -670
  180. package/dist/copilotkit-CwZMFmSK.d.mts.map +0 -1
  181. package/dist/copilotkit-Yh_Ld_FX.mjs +0 -2031
  182. package/dist/copilotkit-Yh_Ld_FX.mjs.map +0 -1
  183. package/dist/v2/index.css.map +0 -1
@@ -0,0 +1,375 @@
1
+ import { AssistantMessage, Message } from "@ag-ui/core";
2
+ import { useState } from "react";
3
+ import {
4
+ Copy,
5
+ Check,
6
+ ThumbsUp,
7
+ ThumbsDown,
8
+ Volume2,
9
+ RefreshCw,
10
+ } from "lucide-react";
11
+ import {
12
+ useCopilotChatConfiguration,
13
+ CopilotChatDefaultLabels,
14
+ } from "../../providers/CopilotChatConfigurationProvider";
15
+ import { twMerge } from "tailwind-merge";
16
+ import { Button } from "../../components/ui/button";
17
+ import {
18
+ Tooltip,
19
+ TooltipContent,
20
+ TooltipTrigger,
21
+ } from "../../components/ui/tooltip";
22
+ import { useKatexStyles } from "../../hooks/useKatexStyles";
23
+ import { WithSlots, renderSlot } from "../../lib/slots";
24
+ import { Streamdown } from "streamdown";
25
+ import CopilotChatToolCallsView from "./CopilotChatToolCallsView";
26
+
27
+ export type CopilotChatAssistantMessageProps = WithSlots<
28
+ {
29
+ markdownRenderer: typeof CopilotChatAssistantMessage.MarkdownRenderer;
30
+ toolbar: typeof CopilotChatAssistantMessage.Toolbar;
31
+ copyButton: typeof CopilotChatAssistantMessage.CopyButton;
32
+ thumbsUpButton: typeof CopilotChatAssistantMessage.ThumbsUpButton;
33
+ thumbsDownButton: typeof CopilotChatAssistantMessage.ThumbsDownButton;
34
+ readAloudButton: typeof CopilotChatAssistantMessage.ReadAloudButton;
35
+ regenerateButton: typeof CopilotChatAssistantMessage.RegenerateButton;
36
+ toolCallsView: typeof CopilotChatToolCallsView;
37
+ },
38
+ {
39
+ onThumbsUp?: (message: AssistantMessage) => void;
40
+ onThumbsDown?: (message: AssistantMessage) => void;
41
+ onReadAloud?: (message: AssistantMessage) => void;
42
+ onRegenerate?: (message: AssistantMessage) => void;
43
+ message: AssistantMessage;
44
+ messages?: Message[];
45
+ isRunning?: boolean;
46
+ additionalToolbarItems?: React.ReactNode;
47
+ toolbarVisible?: boolean;
48
+ } & React.HTMLAttributes<HTMLDivElement>
49
+ >;
50
+
51
+ export function CopilotChatAssistantMessage({
52
+ message,
53
+ messages,
54
+ isRunning,
55
+ onThumbsUp,
56
+ onThumbsDown,
57
+ onReadAloud,
58
+ onRegenerate,
59
+ additionalToolbarItems,
60
+ toolbarVisible = true,
61
+ markdownRenderer,
62
+ toolbar,
63
+ copyButton,
64
+ thumbsUpButton,
65
+ thumbsDownButton,
66
+ readAloudButton,
67
+ regenerateButton,
68
+ toolCallsView,
69
+ children,
70
+ className,
71
+ ...props
72
+ }: CopilotChatAssistantMessageProps) {
73
+ useKatexStyles();
74
+
75
+ const boundMarkdownRenderer = renderSlot(
76
+ markdownRenderer,
77
+ CopilotChatAssistantMessage.MarkdownRenderer,
78
+ {
79
+ content: message.content || "",
80
+ },
81
+ );
82
+
83
+ const boundCopyButton = renderSlot(
84
+ copyButton,
85
+ CopilotChatAssistantMessage.CopyButton,
86
+ {
87
+ onClick: async () => {
88
+ if (message.content) {
89
+ try {
90
+ await navigator.clipboard.writeText(message.content);
91
+ } catch (err) {
92
+ console.error("Failed to copy message:", err);
93
+ }
94
+ }
95
+ },
96
+ },
97
+ );
98
+
99
+ const boundThumbsUpButton = renderSlot(
100
+ thumbsUpButton,
101
+ CopilotChatAssistantMessage.ThumbsUpButton,
102
+ {
103
+ onClick: onThumbsUp,
104
+ },
105
+ );
106
+
107
+ const boundThumbsDownButton = renderSlot(
108
+ thumbsDownButton,
109
+ CopilotChatAssistantMessage.ThumbsDownButton,
110
+ {
111
+ onClick: onThumbsDown,
112
+ },
113
+ );
114
+
115
+ const boundReadAloudButton = renderSlot(
116
+ readAloudButton,
117
+ CopilotChatAssistantMessage.ReadAloudButton,
118
+ {
119
+ onClick: onReadAloud,
120
+ },
121
+ );
122
+
123
+ const boundRegenerateButton = renderSlot(
124
+ regenerateButton,
125
+ CopilotChatAssistantMessage.RegenerateButton,
126
+ {
127
+ onClick: onRegenerate,
128
+ },
129
+ );
130
+
131
+ const boundToolbar = renderSlot(
132
+ toolbar,
133
+ CopilotChatAssistantMessage.Toolbar,
134
+ {
135
+ children: (
136
+ <div className="cpk:flex cpk:items-center cpk:gap-1">
137
+ {boundCopyButton}
138
+ {(onThumbsUp || thumbsUpButton) && boundThumbsUpButton}
139
+ {(onThumbsDown || thumbsDownButton) && boundThumbsDownButton}
140
+ {(onReadAloud || readAloudButton) && boundReadAloudButton}
141
+ {(onRegenerate || regenerateButton) && boundRegenerateButton}
142
+ {additionalToolbarItems}
143
+ </div>
144
+ ),
145
+ },
146
+ );
147
+
148
+ const boundToolCallsView = renderSlot(
149
+ toolCallsView,
150
+ CopilotChatToolCallsView,
151
+ {
152
+ message,
153
+ messages,
154
+ },
155
+ );
156
+
157
+ // Don't show toolbar if message has no content (only tool calls)
158
+ const hasContent = !!(message.content && message.content.trim().length > 0);
159
+ const isLatestAssistantMessage =
160
+ message.role === "assistant" &&
161
+ messages?.[messages.length - 1]?.id === message.id;
162
+ const shouldShowToolbar =
163
+ toolbarVisible && hasContent && !(isRunning && isLatestAssistantMessage);
164
+
165
+ if (children) {
166
+ return (
167
+ <div data-copilotkit style={{ display: "contents" }}>
168
+ {children({
169
+ markdownRenderer: boundMarkdownRenderer,
170
+ toolbar: boundToolbar,
171
+ toolCallsView: boundToolCallsView,
172
+ copyButton: boundCopyButton,
173
+ thumbsUpButton: boundThumbsUpButton,
174
+ thumbsDownButton: boundThumbsDownButton,
175
+ readAloudButton: boundReadAloudButton,
176
+ regenerateButton: boundRegenerateButton,
177
+ message,
178
+ messages,
179
+ isRunning,
180
+ onThumbsUp,
181
+ onThumbsDown,
182
+ onReadAloud,
183
+ onRegenerate,
184
+ additionalToolbarItems,
185
+ toolbarVisible: shouldShowToolbar,
186
+ })}
187
+ </div>
188
+ );
189
+ }
190
+
191
+ return (
192
+ <div
193
+ data-copilotkit
194
+ data-testid="copilot-assistant-message"
195
+ className={twMerge(
196
+ "copilotKitMessage copilotKitAssistantMessage",
197
+ className,
198
+ )}
199
+ {...props}
200
+ data-message-id={message.id}
201
+ >
202
+ <div className="cpk:prose cpk:max-w-full cpk:break-words cpk:dark:prose-invert">
203
+ {boundMarkdownRenderer}
204
+ </div>
205
+ {boundToolCallsView}
206
+ {shouldShowToolbar && boundToolbar}
207
+ </div>
208
+ );
209
+ }
210
+
211
+ // eslint-disable-next-line @typescript-eslint/no-namespace
212
+ export namespace CopilotChatAssistantMessage {
213
+ export const MarkdownRenderer: React.FC<
214
+ Omit<React.ComponentProps<typeof Streamdown>, "children"> & {
215
+ content: string;
216
+ }
217
+ > = ({ content, className, ...props }) => (
218
+ <Streamdown className={className} {...props}>
219
+ {content ?? ""}
220
+ </Streamdown>
221
+ );
222
+
223
+ export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({
224
+ className,
225
+ ...props
226
+ }) => (
227
+ <div
228
+ data-testid="copilot-assistant-toolbar"
229
+ className={twMerge(
230
+ "cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:-ml-[5px] cpk:-mt-[0px]",
231
+ className,
232
+ )}
233
+ {...props}
234
+ />
235
+ );
236
+
237
+ export const ToolbarButton: React.FC<
238
+ React.ButtonHTMLAttributes<HTMLButtonElement> & {
239
+ title: string;
240
+ children: React.ReactNode;
241
+ }
242
+ > = ({ title, children, ...props }) => {
243
+ return (
244
+ <Tooltip>
245
+ <TooltipTrigger asChild>
246
+ <Button
247
+ type="button"
248
+ variant="assistantMessageToolbarButton"
249
+ aria-label={title}
250
+ {...props}
251
+ >
252
+ {children}
253
+ </Button>
254
+ </TooltipTrigger>
255
+ <TooltipContent side="bottom">
256
+ <p>{title}</p>
257
+ </TooltipContent>
258
+ </Tooltip>
259
+ );
260
+ };
261
+
262
+ export const CopyButton: React.FC<
263
+ React.ButtonHTMLAttributes<HTMLButtonElement>
264
+ > = ({ className, title, onClick, ...props }) => {
265
+ const config = useCopilotChatConfiguration();
266
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
267
+ const [copied, setCopied] = useState(false);
268
+
269
+ const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
270
+ setCopied(true);
271
+ setTimeout(() => setCopied(false), 2000);
272
+
273
+ if (onClick) {
274
+ onClick(event);
275
+ }
276
+ };
277
+
278
+ return (
279
+ <ToolbarButton
280
+ data-testid="copilot-copy-button"
281
+ title={title || labels.assistantMessageToolbarCopyMessageLabel}
282
+ onClick={handleClick}
283
+ className={className}
284
+ {...props}
285
+ >
286
+ {copied ? (
287
+ <Check className="cpk:size-[18px]" />
288
+ ) : (
289
+ <Copy className="cpk:size-[18px]" />
290
+ )}
291
+ </ToolbarButton>
292
+ );
293
+ };
294
+
295
+ export const ThumbsUpButton: React.FC<
296
+ React.ButtonHTMLAttributes<HTMLButtonElement>
297
+ > = ({ title, ...props }) => {
298
+ const config = useCopilotChatConfiguration();
299
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
300
+ return (
301
+ <ToolbarButton
302
+ data-testid="copilot-thumbs-up-button"
303
+ title={title || labels.assistantMessageToolbarThumbsUpLabel}
304
+ {...props}
305
+ >
306
+ <ThumbsUp className="cpk:size-[18px]" />
307
+ </ToolbarButton>
308
+ );
309
+ };
310
+
311
+ export const ThumbsDownButton: React.FC<
312
+ React.ButtonHTMLAttributes<HTMLButtonElement>
313
+ > = ({ title, ...props }) => {
314
+ const config = useCopilotChatConfiguration();
315
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
316
+ return (
317
+ <ToolbarButton
318
+ data-testid="copilot-thumbs-down-button"
319
+ title={title || labels.assistantMessageToolbarThumbsDownLabel}
320
+ {...props}
321
+ >
322
+ <ThumbsDown className="cpk:size-[18px]" />
323
+ </ToolbarButton>
324
+ );
325
+ };
326
+
327
+ export const ReadAloudButton: React.FC<
328
+ React.ButtonHTMLAttributes<HTMLButtonElement>
329
+ > = ({ title, ...props }) => {
330
+ const config = useCopilotChatConfiguration();
331
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
332
+ return (
333
+ <ToolbarButton
334
+ data-testid="copilot-read-aloud-button"
335
+ title={title || labels.assistantMessageToolbarReadAloudLabel}
336
+ {...props}
337
+ >
338
+ <Volume2 className="cpk:size-[20px]" />
339
+ </ToolbarButton>
340
+ );
341
+ };
342
+
343
+ export const RegenerateButton: React.FC<
344
+ React.ButtonHTMLAttributes<HTMLButtonElement>
345
+ > = ({ title, ...props }) => {
346
+ const config = useCopilotChatConfiguration();
347
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
348
+ return (
349
+ <ToolbarButton
350
+ data-testid="copilot-regenerate-button"
351
+ title={title || labels.assistantMessageToolbarRegenerateLabel}
352
+ {...props}
353
+ >
354
+ <RefreshCw className="cpk:size-[18px]" />
355
+ </ToolbarButton>
356
+ );
357
+ };
358
+ }
359
+
360
+ CopilotChatAssistantMessage.MarkdownRenderer.displayName =
361
+ "CopilotChatAssistantMessage.MarkdownRenderer";
362
+ CopilotChatAssistantMessage.Toolbar.displayName =
363
+ "CopilotChatAssistantMessage.Toolbar";
364
+ CopilotChatAssistantMessage.CopyButton.displayName =
365
+ "CopilotChatAssistantMessage.CopyButton";
366
+ CopilotChatAssistantMessage.ThumbsUpButton.displayName =
367
+ "CopilotChatAssistantMessage.ThumbsUpButton";
368
+ CopilotChatAssistantMessage.ThumbsDownButton.displayName =
369
+ "CopilotChatAssistantMessage.ThumbsDownButton";
370
+ CopilotChatAssistantMessage.ReadAloudButton.displayName =
371
+ "CopilotChatAssistantMessage.ReadAloudButton";
372
+ CopilotChatAssistantMessage.RegenerateButton.displayName =
373
+ "CopilotChatAssistantMessage.RegenerateButton";
374
+
375
+ export default CopilotChatAssistantMessage;