@copilotkitnext/react 0.0.1

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 (60) hide show
  1. package/.turbo/turbo-build$colon$css.log +9 -0
  2. package/.turbo/turbo-build.log +28 -0
  3. package/.turbo/turbo-check-types.log +0 -0
  4. package/.turbo/turbo-lint.log +78 -0
  5. package/.turbo/turbo-test.log +79 -0
  6. package/LICENSE +11 -0
  7. package/components.json +20 -0
  8. package/dist/index.d.mts +363 -0
  9. package/dist/index.d.ts +363 -0
  10. package/dist/index.js +2322 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/index.mjs +2291 -0
  13. package/dist/index.mjs.map +1 -0
  14. package/dist/styles.css +2 -0
  15. package/eslint.config.mjs +11 -0
  16. package/package.json +84 -0
  17. package/postcss.config.js +7 -0
  18. package/src/__tests__/setup.ts +2 -0
  19. package/src/components/chat/CopilotChat.tsx +90 -0
  20. package/src/components/chat/CopilotChatAssistantMessage.tsx +478 -0
  21. package/src/components/chat/CopilotChatAudioRecorder.tsx +157 -0
  22. package/src/components/chat/CopilotChatInput.tsx +596 -0
  23. package/src/components/chat/CopilotChatMessageView.tsx +85 -0
  24. package/src/components/chat/CopilotChatToolCallsView.tsx +43 -0
  25. package/src/components/chat/CopilotChatUserMessage.tsx +337 -0
  26. package/src/components/chat/CopilotChatView.tsx +385 -0
  27. package/src/components/chat/__tests__/CopilotChatAssistantMessage.test.tsx +684 -0
  28. package/src/components/chat/__tests__/CopilotChatInput.test.tsx +531 -0
  29. package/src/components/chat/__tests__/setup.ts +1 -0
  30. package/src/components/chat/index.ts +35 -0
  31. package/src/components/index.ts +4 -0
  32. package/src/components/ui/button.tsx +123 -0
  33. package/src/components/ui/dropdown-menu.tsx +257 -0
  34. package/src/components/ui/tooltip.tsx +59 -0
  35. package/src/hooks/index.ts +6 -0
  36. package/src/hooks/use-agent-context.tsx +17 -0
  37. package/src/hooks/use-agent.tsx +48 -0
  38. package/src/hooks/use-frontend-tool.tsx +46 -0
  39. package/src/hooks/use-human-in-the-loop.tsx +76 -0
  40. package/src/hooks/use-render-tool-call.tsx +81 -0
  41. package/src/index.ts +4 -0
  42. package/src/lib/__tests__/completePartialMarkdown.test.ts +495 -0
  43. package/src/lib/__tests__/renderSlot.test.tsx +610 -0
  44. package/src/lib/slots.tsx +55 -0
  45. package/src/lib/utils.ts +6 -0
  46. package/src/providers/CopilotChatConfigurationProvider.tsx +81 -0
  47. package/src/providers/CopilotKitProvider.tsx +269 -0
  48. package/src/providers/__tests__/CopilotKitProvider.test.tsx +487 -0
  49. package/src/providers/__tests__/CopilotKitProvider.wildcard.test.tsx +261 -0
  50. package/src/providers/index.ts +14 -0
  51. package/src/styles/globals.css +302 -0
  52. package/src/types/frontend-tool.ts +8 -0
  53. package/src/types/human-in-the-loop.ts +33 -0
  54. package/src/types/index.ts +3 -0
  55. package/src/types/react-tool-call-render.ts +29 -0
  56. package/tailwind.config.js +9 -0
  57. package/test.css +2355 -0
  58. package/tsconfig.json +23 -0
  59. package/tsup.config.ts +19 -0
  60. package/vitest.config.mjs +15 -0
package/dist/index.js ADDED
@@ -0,0 +1,2322 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ AudioRecorderError: () => AudioRecorderError,
34
+ CopilotChat: () => CopilotChat,
35
+ CopilotChatAssistantMessage: () => CopilotChatAssistantMessage_default,
36
+ CopilotChatAudioRecorder: () => CopilotChatAudioRecorder,
37
+ CopilotChatConfigurationProvider: () => CopilotChatConfigurationProvider,
38
+ CopilotChatInput: () => CopilotChatInput_default,
39
+ CopilotChatMessageView: () => CopilotChatMessageView_default,
40
+ CopilotChatToolCallsView: () => CopilotChatToolCallsView_default,
41
+ CopilotChatUserMessage: () => CopilotChatUserMessage_default,
42
+ CopilotChatView: () => CopilotChatView_default,
43
+ CopilotKitProvider: () => CopilotKitProvider,
44
+ useAgent: () => useAgent,
45
+ useAgentContext: () => useAgentContext,
46
+ useCopilotChatConfiguration: () => useCopilotChatConfiguration,
47
+ useCopilotKit: () => useCopilotKit,
48
+ useFrontendTool: () => useFrontendTool,
49
+ useHumanInTheLoop: () => useHumanInTheLoop,
50
+ useRenderToolCall: () => useRenderToolCall
51
+ });
52
+ module.exports = __toCommonJS(index_exports);
53
+
54
+ // src/components/chat/CopilotChatInput.tsx
55
+ var import_react4 = require("react");
56
+ var import_tailwind_merge3 = require("tailwind-merge");
57
+ var import_lucide_react2 = require("lucide-react");
58
+
59
+ // src/providers/CopilotChatConfigurationProvider.tsx
60
+ var import_react = require("react");
61
+ var import_jsx_runtime = require("react/jsx-runtime");
62
+ var CopilotChatDefaultLabels = {
63
+ chatInputPlaceholder: "Type a message...",
64
+ chatInputToolbarStartTranscribeButtonLabel: "Transcribe",
65
+ chatInputToolbarCancelTranscribeButtonLabel: "Cancel",
66
+ chatInputToolbarFinishTranscribeButtonLabel: "Finish",
67
+ chatInputToolbarAddButtonLabel: "Add photos or files",
68
+ chatInputToolbarToolsButtonLabel: "Tools",
69
+ assistantMessageToolbarCopyCodeLabel: "Copy",
70
+ assistantMessageToolbarCopyCodeCopiedLabel: "Copied",
71
+ assistantMessageToolbarCopyMessageLabel: "Copy",
72
+ assistantMessageToolbarThumbsUpLabel: "Good response",
73
+ assistantMessageToolbarThumbsDownLabel: "Bad response",
74
+ assistantMessageToolbarReadAloudLabel: "Read aloud",
75
+ assistantMessageToolbarRegenerateLabel: "Regenerate",
76
+ userMessageToolbarCopyMessageLabel: "Copy",
77
+ userMessageToolbarEditMessageLabel: "Edit",
78
+ chatDisclaimerText: "AI can make mistakes. Please verify important information."
79
+ };
80
+ var CopilotChatConfiguration = (0, import_react.createContext)(null);
81
+ var CopilotChatConfigurationProvider = ({ children, labels = {}, inputValue, onSubmitInput, onChangeInput }) => {
82
+ const mergedLabels = {
83
+ ...CopilotChatDefaultLabels,
84
+ ...labels
85
+ };
86
+ const configurationValue = {
87
+ labels: mergedLabels,
88
+ inputValue,
89
+ onSubmitInput,
90
+ onChangeInput
91
+ };
92
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CopilotChatConfiguration.Provider, { value: configurationValue, children });
93
+ };
94
+ var useCopilotChatConfiguration = () => {
95
+ const configuration = (0, import_react.useContext)(CopilotChatConfiguration);
96
+ if (!configuration) {
97
+ throw new Error(
98
+ "useCopilotChatConfiguration must be used within CopilotChatConfigurationProvider"
99
+ );
100
+ }
101
+ return configuration;
102
+ };
103
+
104
+ // src/components/ui/button.tsx
105
+ var import_react_slot = require("@radix-ui/react-slot");
106
+ var import_class_variance_authority = require("class-variance-authority");
107
+
108
+ // src/lib/utils.ts
109
+ var import_clsx = require("clsx");
110
+ var import_tailwind_merge = require("tailwind-merge");
111
+ function cn(...inputs) {
112
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
113
+ }
114
+
115
+ // src/components/ui/button.tsx
116
+ var import_jsx_runtime2 = require("react/jsx-runtime");
117
+ var buttonVariants = (0, import_class_variance_authority.cva)(
118
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
119
+ {
120
+ variants: {
121
+ variant: {
122
+ default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
123
+ destructive: "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
124
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
125
+ secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
126
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 cursor-pointer",
127
+ link: "text-primary underline-offset-4 hover:underline",
128
+ assistantMessageToolbarButton: [
129
+ "cursor-pointer",
130
+ // Background and text
131
+ "p-0 text-[rgb(93,93,93)] hover:bg-[#E8E8E8]",
132
+ // Dark mode - lighter gray for better contrast
133
+ "dark:text-[rgb(243,243,243)] dark:hover:bg-[#303030]",
134
+ // Shape and sizing
135
+ "h-8 w-8",
136
+ // Interactions
137
+ "transition-colors",
138
+ // Hover states
139
+ "hover:text-[rgb(93,93,93)]",
140
+ "dark:hover:text-[rgb(243,243,243)]"
141
+ ],
142
+ chatInputToolbarPrimary: [
143
+ "cursor-pointer",
144
+ // Background and text
145
+ "bg-black text-white",
146
+ // Dark mode
147
+ "dark:bg-white dark:text-black dark:focus-visible:outline-white",
148
+ // Shape and sizing
149
+ "rounded-full",
150
+ // Interactions
151
+ "transition-colors",
152
+ // Focus states
153
+ "focus:outline-none",
154
+ // Hover states
155
+ "hover:opacity-70 disabled:hover:opacity-100",
156
+ // Disabled states
157
+ "disabled:cursor-not-allowed disabled:bg-[#00000014] disabled:text-[rgb(13,13,13)]",
158
+ "dark:disabled:bg-[#454545] dark:disabled:text-white "
159
+ ],
160
+ chatInputToolbarSecondary: [
161
+ "cursor-pointer",
162
+ // Background and text
163
+ "bg-transparent text-[#444444]",
164
+ // Dark mode
165
+ "dark:text-white dark:border-[#404040]",
166
+ // Shape and sizing
167
+ "rounded-full",
168
+ // Interactions
169
+ "transition-colors",
170
+ // Focus states
171
+ "focus:outline-none",
172
+ // Hover states
173
+ "hover:bg-[#f8f8f8] hover:text-[#333333]",
174
+ "dark:hover:bg-[#404040] dark:hover:text-[#FFFFFF]",
175
+ // Disabled states
176
+ "disabled:cursor-not-allowed disabled:opacity-50",
177
+ "disabled:hover:bg-transparent disabled:hover:text-[#444444]",
178
+ "dark:disabled:hover:bg-transparent dark:disabled:hover:text-[#CCCCCC]"
179
+ ]
180
+ },
181
+ size: {
182
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
183
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
184
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
185
+ icon: "size-9",
186
+ chatInputToolbarIcon: [
187
+ // Shape and sizing
188
+ "h-9 w-9 rounded-full"
189
+ ],
190
+ chatInputToolbarIconLabel: [
191
+ // Shape and sizing
192
+ "h-9 px-3 rounded-full",
193
+ // Layout
194
+ "gap-2",
195
+ // Typography
196
+ "font-normal"
197
+ ]
198
+ }
199
+ },
200
+ defaultVariants: {
201
+ variant: "default",
202
+ size: "default"
203
+ }
204
+ }
205
+ );
206
+ function Button({
207
+ className,
208
+ variant,
209
+ size,
210
+ asChild = false,
211
+ ...props
212
+ }) {
213
+ const Comp = asChild ? import_react_slot.Slot : "button";
214
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
215
+ Comp,
216
+ {
217
+ "data-slot": "button",
218
+ className: cn(buttonVariants({ variant, size, className })),
219
+ ...props
220
+ }
221
+ );
222
+ }
223
+
224
+ // src/components/ui/tooltip.tsx
225
+ var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"));
226
+ var import_jsx_runtime3 = require("react/jsx-runtime");
227
+ function TooltipProvider({
228
+ delayDuration = 0,
229
+ ...props
230
+ }) {
231
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
232
+ TooltipPrimitive.Provider,
233
+ {
234
+ "data-slot": "tooltip-provider",
235
+ delayDuration,
236
+ ...props
237
+ }
238
+ );
239
+ }
240
+ function Tooltip({
241
+ ...props
242
+ }) {
243
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props }) });
244
+ }
245
+ function TooltipTrigger({
246
+ ...props
247
+ }) {
248
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
249
+ }
250
+ function TooltipContent({
251
+ className,
252
+ sideOffset = 0,
253
+ children,
254
+ ...props
255
+ }) {
256
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TooltipPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
257
+ TooltipPrimitive.Content,
258
+ {
259
+ "data-slot": "tooltip-content",
260
+ sideOffset,
261
+ className: cn(
262
+ "bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
263
+ className
264
+ ),
265
+ ...props,
266
+ children: [
267
+ children,
268
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TooltipPrimitive.Arrow, { className: "bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })
269
+ ]
270
+ }
271
+ ) });
272
+ }
273
+
274
+ // src/components/ui/dropdown-menu.tsx
275
+ var DropdownMenuPrimitive = __toESM(require("@radix-ui/react-dropdown-menu"));
276
+ var import_lucide_react = require("lucide-react");
277
+ var import_jsx_runtime4 = require("react/jsx-runtime");
278
+ function DropdownMenu({
279
+ ...props
280
+ }) {
281
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
282
+ }
283
+ function DropdownMenuTrigger({
284
+ ...props
285
+ }) {
286
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
287
+ DropdownMenuPrimitive.Trigger,
288
+ {
289
+ "data-slot": "dropdown-menu-trigger",
290
+ ...props
291
+ }
292
+ );
293
+ }
294
+ function DropdownMenuContent({
295
+ className,
296
+ sideOffset = 4,
297
+ ...props
298
+ }) {
299
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
300
+ DropdownMenuPrimitive.Content,
301
+ {
302
+ "data-slot": "dropdown-menu-content",
303
+ sideOffset,
304
+ className: cn(
305
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
306
+ className
307
+ ),
308
+ ...props
309
+ }
310
+ ) });
311
+ }
312
+ function DropdownMenuItem({
313
+ className,
314
+ inset,
315
+ variant = "default",
316
+ ...props
317
+ }) {
318
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
319
+ DropdownMenuPrimitive.Item,
320
+ {
321
+ "data-slot": "dropdown-menu-item",
322
+ "data-inset": inset,
323
+ "data-variant": variant,
324
+ className: cn(
325
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
326
+ className
327
+ ),
328
+ ...props
329
+ }
330
+ );
331
+ }
332
+ function DropdownMenuSeparator({
333
+ className,
334
+ ...props
335
+ }) {
336
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
337
+ DropdownMenuPrimitive.Separator,
338
+ {
339
+ "data-slot": "dropdown-menu-separator",
340
+ className: cn("bg-border -mx-1 my-1 h-px", className),
341
+ ...props
342
+ }
343
+ );
344
+ }
345
+ function DropdownMenuSub({
346
+ ...props
347
+ }) {
348
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
349
+ }
350
+ function DropdownMenuSubTrigger({
351
+ className,
352
+ inset,
353
+ children,
354
+ ...props
355
+ }) {
356
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
357
+ DropdownMenuPrimitive.SubTrigger,
358
+ {
359
+ "data-slot": "dropdown-menu-sub-trigger",
360
+ "data-inset": inset,
361
+ className: cn(
362
+ "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8",
363
+ className
364
+ ),
365
+ ...props,
366
+ children: [
367
+ children,
368
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react.ChevronRightIcon, { className: "ml-auto size-4" })
369
+ ]
370
+ }
371
+ );
372
+ }
373
+ function DropdownMenuSubContent({
374
+ className,
375
+ ...props
376
+ }) {
377
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
378
+ DropdownMenuPrimitive.SubContent,
379
+ {
380
+ "data-slot": "dropdown-menu-sub-content",
381
+ className: cn(
382
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
383
+ className
384
+ ),
385
+ ...props
386
+ }
387
+ );
388
+ }
389
+
390
+ // src/components/chat/CopilotChatAudioRecorder.tsx
391
+ var import_react2 = require("react");
392
+ var import_tailwind_merge2 = require("tailwind-merge");
393
+ var import_jsx_runtime5 = require("react/jsx-runtime");
394
+ var AudioRecorderError = class extends Error {
395
+ constructor(message) {
396
+ super(message);
397
+ this.name = "AudioRecorderError";
398
+ }
399
+ };
400
+ var CopilotChatAudioRecorder = (0, import_react2.forwardRef)((props, ref) => {
401
+ const { className, ...divProps } = props;
402
+ const canvasRef = (0, import_react2.useRef)(null);
403
+ const getLoudness = (n) => {
404
+ const elapsed = Date.now() / 1e3;
405
+ const samples = [];
406
+ for (let i = 0; i < n; i++) {
407
+ const position = i / n * 10 + elapsed * 0.5;
408
+ const wave1 = Math.sin(position * 2) * 0.3;
409
+ const wave2 = Math.sin(position * 5 + elapsed) * 0.2;
410
+ const wave3 = Math.sin(position * 0.5 + elapsed * 0.3) * 0.4;
411
+ const noise = (Math.random() - 0.5) * 0.1;
412
+ const envelope = Math.sin(elapsed * 0.7) * 0.5 + 0.5;
413
+ let amplitude = (wave1 + wave2 + wave3 + noise) * envelope;
414
+ amplitude = Math.max(0, Math.min(1, amplitude * 0.5 + 0.3));
415
+ samples.push(amplitude);
416
+ }
417
+ return samples;
418
+ };
419
+ (0, import_react2.useEffect)(() => {
420
+ const canvas = canvasRef.current;
421
+ if (!canvas) return;
422
+ const ctx = canvas.getContext("2d");
423
+ if (!ctx) return;
424
+ let animationId;
425
+ const draw = () => {
426
+ const rect = canvas.getBoundingClientRect();
427
+ const dpr = window.devicePixelRatio || 1;
428
+ if (canvas.width !== rect.width * dpr || canvas.height !== rect.height * dpr) {
429
+ canvas.width = rect.width * dpr;
430
+ canvas.height = rect.height * dpr;
431
+ ctx.scale(dpr, dpr);
432
+ ctx.imageSmoothingEnabled = false;
433
+ }
434
+ const barWidth = 2;
435
+ const minHeight = 2;
436
+ const maxHeight = 20;
437
+ const gap = 2;
438
+ const numSamples = Math.ceil(rect.width / (barWidth + gap));
439
+ const loudnessData = getLoudness(numSamples);
440
+ ctx.clearRect(0, 0, rect.width, rect.height);
441
+ const computedStyle = getComputedStyle(canvas);
442
+ const currentForeground = computedStyle.color;
443
+ ctx.fillStyle = currentForeground;
444
+ const centerY = rect.height / 2;
445
+ for (let i = 0; i < loudnessData.length; i++) {
446
+ const sample = loudnessData[i] ?? 0;
447
+ const barHeight = Math.round(
448
+ sample * (maxHeight - minHeight) + minHeight
449
+ );
450
+ const x = Math.round(i * (barWidth + gap));
451
+ const y = Math.round(centerY - barHeight / 2);
452
+ ctx.fillRect(x, y, barWidth, barHeight);
453
+ }
454
+ animationId = requestAnimationFrame(draw);
455
+ };
456
+ draw();
457
+ return () => {
458
+ if (animationId) {
459
+ cancelAnimationFrame(animationId);
460
+ }
461
+ };
462
+ }, []);
463
+ (0, import_react2.useImperativeHandle)(
464
+ ref,
465
+ () => ({
466
+ get state() {
467
+ return "idle";
468
+ },
469
+ start: async () => {
470
+ },
471
+ stop: () => new Promise((resolve) => {
472
+ const emptyBlob = new Blob([], { type: "audio/webm" });
473
+ resolve(emptyBlob);
474
+ }),
475
+ dispose: () => {
476
+ }
477
+ }),
478
+ []
479
+ );
480
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: (0, import_tailwind_merge2.twMerge)("h-[44px] w-full px-5", className), ...divProps, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
481
+ "canvas",
482
+ {
483
+ ref: canvasRef,
484
+ className: "w-full h-full",
485
+ style: { imageRendering: "pixelated" }
486
+ }
487
+ ) });
488
+ });
489
+ CopilotChatAudioRecorder.displayName = "WebAudioRecorder";
490
+
491
+ // src/lib/slots.tsx
492
+ var import_react3 = __toESM(require("react"));
493
+ function renderSlot(slot, DefaultComponent, props) {
494
+ if (typeof slot === "string") {
495
+ return import_react3.default.createElement(DefaultComponent, {
496
+ ...props,
497
+ className: slot
498
+ });
499
+ }
500
+ if (typeof slot === "function") {
501
+ const Comp = slot;
502
+ return import_react3.default.createElement(Comp, props);
503
+ }
504
+ if (slot && typeof slot === "object" && !import_react3.default.isValidElement(slot)) {
505
+ return import_react3.default.createElement(DefaultComponent, {
506
+ ...props,
507
+ ...slot
508
+ });
509
+ }
510
+ return import_react3.default.createElement(DefaultComponent, props);
511
+ }
512
+
513
+ // src/components/chat/CopilotChatInput.tsx
514
+ var import_jsx_runtime6 = require("react/jsx-runtime");
515
+ function CopilotChatInput({
516
+ mode = "input",
517
+ onSubmitMessage,
518
+ onStartTranscribe,
519
+ onCancelTranscribe,
520
+ onFinishTranscribe,
521
+ onAddFile,
522
+ onChange,
523
+ value,
524
+ toolsMenu,
525
+ autoFocus = true,
526
+ additionalToolbarItems,
527
+ textArea,
528
+ sendButton,
529
+ startTranscribeButton,
530
+ cancelTranscribeButton,
531
+ finishTranscribeButton,
532
+ addFileButton,
533
+ toolsButton,
534
+ toolbar,
535
+ audioRecorder,
536
+ children,
537
+ className,
538
+ ...props
539
+ }) {
540
+ const { inputValue, onSubmitInput, onChangeInput } = useCopilotChatConfiguration();
541
+ value ??= inputValue;
542
+ onSubmitMessage ??= onSubmitInput;
543
+ onChange ??= onChangeInput;
544
+ const inputRef = (0, import_react4.useRef)(null);
545
+ const audioRecorderRef = (0, import_react4.useRef)(null);
546
+ (0, import_react4.useEffect)(() => {
547
+ const recorder = audioRecorderRef.current;
548
+ if (!recorder) {
549
+ return;
550
+ }
551
+ if (mode === "transcribe") {
552
+ recorder.start().catch(console.error);
553
+ } else {
554
+ if (recorder.state === "recording") {
555
+ recorder.stop().catch(console.error);
556
+ }
557
+ }
558
+ }, [mode]);
559
+ const handleChange = (e) => {
560
+ onChange?.(e.target.value);
561
+ };
562
+ const handleKeyDown = (e) => {
563
+ if (e.key === "Enter" && !e.shiftKey) {
564
+ e.preventDefault();
565
+ send();
566
+ }
567
+ };
568
+ const send = () => {
569
+ const trimmed = value?.trim();
570
+ if (trimmed) {
571
+ onSubmitMessage?.(trimmed);
572
+ if (inputRef.current) {
573
+ inputRef.current.focus();
574
+ }
575
+ }
576
+ };
577
+ const BoundTextArea = renderSlot(textArea, CopilotChatInput.TextArea, {
578
+ ref: inputRef,
579
+ value,
580
+ onChange: handleChange,
581
+ onKeyDown: handleKeyDown,
582
+ autoFocus
583
+ });
584
+ const BoundAudioRecorder = renderSlot(
585
+ audioRecorder,
586
+ CopilotChatAudioRecorder,
587
+ {
588
+ ref: audioRecorderRef
589
+ }
590
+ );
591
+ const BoundSendButton = renderSlot(sendButton, CopilotChatInput.SendButton, {
592
+ onClick: send,
593
+ disabled: !value?.trim() || !onSubmitMessage
594
+ });
595
+ const BoundStartTranscribeButton = renderSlot(
596
+ startTranscribeButton,
597
+ CopilotChatInput.StartTranscribeButton,
598
+ {
599
+ onClick: onStartTranscribe
600
+ }
601
+ );
602
+ const BoundCancelTranscribeButton = renderSlot(
603
+ cancelTranscribeButton,
604
+ CopilotChatInput.CancelTranscribeButton,
605
+ {
606
+ onClick: onCancelTranscribe
607
+ }
608
+ );
609
+ const BoundFinishTranscribeButton = renderSlot(
610
+ finishTranscribeButton,
611
+ CopilotChatInput.FinishTranscribeButton,
612
+ {
613
+ onClick: onFinishTranscribe
614
+ }
615
+ );
616
+ const BoundAddFileButton = renderSlot(
617
+ addFileButton,
618
+ CopilotChatInput.AddFileButton,
619
+ {
620
+ onClick: onAddFile,
621
+ disabled: mode === "transcribe"
622
+ }
623
+ );
624
+ const BoundToolsButton = renderSlot(
625
+ toolsButton,
626
+ CopilotChatInput.ToolsButton,
627
+ {
628
+ disabled: mode === "transcribe",
629
+ toolsMenu
630
+ }
631
+ );
632
+ const BoundToolbar = renderSlot(
633
+ typeof toolbar === "string" || toolbar === void 0 ? (0, import_tailwind_merge3.twMerge)(
634
+ toolbar,
635
+ "w-full h-[60px] bg-transparent flex items-center justify-between"
636
+ ) : toolbar,
637
+ CopilotChatInput.Toolbar,
638
+ {
639
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
640
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center", children: [
641
+ onAddFile && BoundAddFileButton,
642
+ BoundToolsButton,
643
+ additionalToolbarItems
644
+ ] }),
645
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex items-center", children: mode === "transcribe" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
646
+ onCancelTranscribe && BoundCancelTranscribeButton,
647
+ onFinishTranscribe && BoundFinishTranscribeButton
648
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
649
+ onStartTranscribe && BoundStartTranscribeButton,
650
+ BoundSendButton
651
+ ] }) })
652
+ ] })
653
+ }
654
+ );
655
+ if (children) {
656
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: children({
657
+ textArea: BoundTextArea,
658
+ audioRecorder: BoundAudioRecorder,
659
+ sendButton: BoundSendButton,
660
+ startTranscribeButton: BoundStartTranscribeButton,
661
+ cancelTranscribeButton: BoundCancelTranscribeButton,
662
+ finishTranscribeButton: BoundFinishTranscribeButton,
663
+ addFileButton: BoundAddFileButton,
664
+ toolsButton: BoundToolsButton,
665
+ toolbar: BoundToolbar,
666
+ onSubmitMessage,
667
+ onStartTranscribe,
668
+ onCancelTranscribe,
669
+ onFinishTranscribe,
670
+ onAddFile,
671
+ mode,
672
+ toolsMenu,
673
+ autoFocus,
674
+ additionalToolbarItems
675
+ }) });
676
+ }
677
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
678
+ "div",
679
+ {
680
+ className: (0, import_tailwind_merge3.twMerge)(
681
+ // Layout
682
+ "flex w-full flex-col items-center justify-center",
683
+ // Interaction
684
+ "cursor-text",
685
+ // Overflow and clipping
686
+ "overflow-visible bg-clip-padding contain-inline-size",
687
+ // Background
688
+ "bg-white dark:bg-[#303030]",
689
+ // Visual effects
690
+ "shadow-[0_4px_4px_0_#0000000a,0_0_1px_0_#0000009e] rounded-[28px]",
691
+ className
692
+ ),
693
+ ...props,
694
+ children: [
695
+ mode === "transcribe" ? BoundAudioRecorder : BoundTextArea,
696
+ BoundToolbar
697
+ ]
698
+ }
699
+ );
700
+ }
701
+ ((CopilotChatInput2) => {
702
+ CopilotChatInput2.SendButton = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mr-[10px]", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
703
+ Button,
704
+ {
705
+ type: "button",
706
+ variant: "chatInputToolbarPrimary",
707
+ size: "chatInputToolbarIcon",
708
+ className,
709
+ ...props,
710
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react2.ArrowUp, { className: "size-[18px]" })
711
+ }
712
+ ) });
713
+ CopilotChatInput2.ToolbarButton = ({ icon, labelKey, defaultClassName, className, ...props }) => {
714
+ const { labels } = useCopilotChatConfiguration();
715
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Tooltip, { children: [
716
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
717
+ Button,
718
+ {
719
+ type: "button",
720
+ variant: "chatInputToolbarSecondary",
721
+ size: "chatInputToolbarIcon",
722
+ className: (0, import_tailwind_merge3.twMerge)(defaultClassName, className),
723
+ ...props,
724
+ children: icon
725
+ }
726
+ ) }),
727
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TooltipContent, { side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: labels[labelKey] }) })
728
+ ] });
729
+ };
730
+ CopilotChatInput2.StartTranscribeButton = (props) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
731
+ CopilotChatInput2.ToolbarButton,
732
+ {
733
+ icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react2.Mic, { className: "size-[18px]" }),
734
+ labelKey: "chatInputToolbarStartTranscribeButtonLabel",
735
+ defaultClassName: "mr-2",
736
+ ...props
737
+ }
738
+ );
739
+ CopilotChatInput2.CancelTranscribeButton = (props) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
740
+ CopilotChatInput2.ToolbarButton,
741
+ {
742
+ icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react2.X, { className: "size-[18px]" }),
743
+ labelKey: "chatInputToolbarCancelTranscribeButtonLabel",
744
+ defaultClassName: "mr-2",
745
+ ...props
746
+ }
747
+ );
748
+ CopilotChatInput2.FinishTranscribeButton = (props) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
749
+ CopilotChatInput2.ToolbarButton,
750
+ {
751
+ icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react2.Check, { className: "size-[18px]" }),
752
+ labelKey: "chatInputToolbarFinishTranscribeButtonLabel",
753
+ defaultClassName: "mr-[10px]",
754
+ ...props
755
+ }
756
+ );
757
+ CopilotChatInput2.AddFileButton = (props) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
758
+ CopilotChatInput2.ToolbarButton,
759
+ {
760
+ icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react2.Plus, { className: "size-[20px]" }),
761
+ labelKey: "chatInputToolbarAddButtonLabel",
762
+ defaultClassName: "ml-2",
763
+ ...props
764
+ }
765
+ );
766
+ CopilotChatInput2.ToolsButton = ({ className, toolsMenu, ...props }) => {
767
+ const { labels } = useCopilotChatConfiguration();
768
+ const renderMenuItems = (items) => {
769
+ return items.map((item, index) => {
770
+ if (item === "-") {
771
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DropdownMenuSeparator, {}, index);
772
+ } else if (item.items && item.items.length > 0) {
773
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DropdownMenuSub, { children: [
774
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DropdownMenuSubTrigger, { children: item.label }),
775
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DropdownMenuSubContent, { children: renderMenuItems(item.items) })
776
+ ] }, index);
777
+ } else {
778
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DropdownMenuItem, { onClick: item.action, children: item.label }, index);
779
+ }
780
+ });
781
+ };
782
+ if (!toolsMenu || toolsMenu.length === 0) {
783
+ return null;
784
+ }
785
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DropdownMenu, { children: [
786
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
787
+ Button,
788
+ {
789
+ type: "button",
790
+ variant: "chatInputToolbarSecondary",
791
+ size: "chatInputToolbarIconLabel",
792
+ className,
793
+ ...props,
794
+ children: [
795
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react2.Settings2, { className: "size-[18px]" }),
796
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-sm font-normal", children: labels.chatInputToolbarToolsButtonLabel })
797
+ ]
798
+ }
799
+ ) }),
800
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DropdownMenuContent, { side: "top", align: "end", children: renderMenuItems(toolsMenu) })
801
+ ] });
802
+ };
803
+ CopilotChatInput2.Toolbar = ({
804
+ className,
805
+ ...props
806
+ }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
807
+ "div",
808
+ {
809
+ className: (0, import_tailwind_merge3.twMerge)(
810
+ "w-full h-[60px] bg-transparent flex items-center",
811
+ className
812
+ ),
813
+ ...props
814
+ }
815
+ );
816
+ CopilotChatInput2.TextArea = (0, import_react4.forwardRef)(
817
+ function TextArea2({ maxRows = 5, style, className, ...props }, ref) {
818
+ const internalTextareaRef = (0, import_react4.useRef)(null);
819
+ const [maxHeight, setMaxHeight] = (0, import_react4.useState)(0);
820
+ const { labels } = useCopilotChatConfiguration();
821
+ (0, import_react4.useImperativeHandle)(
822
+ ref,
823
+ () => internalTextareaRef.current
824
+ );
825
+ const adjustHeight = () => {
826
+ const textarea = internalTextareaRef.current;
827
+ if (textarea && maxHeight > 0) {
828
+ textarea.style.height = "auto";
829
+ textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
830
+ }
831
+ };
832
+ (0, import_react4.useEffect)(() => {
833
+ const calculateMaxHeight = () => {
834
+ const textarea = internalTextareaRef.current;
835
+ if (textarea) {
836
+ const currentValue = textarea.value;
837
+ textarea.value = "";
838
+ textarea.style.height = "auto";
839
+ const computedStyle = window.getComputedStyle(textarea);
840
+ const paddingTop = parseFloat(computedStyle.paddingTop);
841
+ const paddingBottom = parseFloat(computedStyle.paddingBottom);
842
+ const contentHeight = textarea.scrollHeight - paddingTop - paddingBottom;
843
+ setMaxHeight(contentHeight * maxRows + paddingTop + paddingBottom);
844
+ textarea.value = currentValue;
845
+ if (currentValue) {
846
+ textarea.style.height = "auto";
847
+ textarea.style.height = `${Math.min(textarea.scrollHeight, contentHeight * maxRows + paddingTop + paddingBottom)}px`;
848
+ }
849
+ if (props.autoFocus) {
850
+ textarea.focus();
851
+ }
852
+ }
853
+ };
854
+ calculateMaxHeight();
855
+ }, [maxRows, props.autoFocus]);
856
+ (0, import_react4.useEffect)(() => {
857
+ adjustHeight();
858
+ }, [props.value, maxHeight]);
859
+ const handleInput = (e) => {
860
+ adjustHeight();
861
+ if (props.onChange) {
862
+ props.onChange(e);
863
+ }
864
+ };
865
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
866
+ "textarea",
867
+ {
868
+ ref: internalTextareaRef,
869
+ ...props,
870
+ onChange: handleInput,
871
+ style: {
872
+ overflow: "auto",
873
+ resize: "none",
874
+ maxHeight: `${maxHeight}px`,
875
+ ...style
876
+ },
877
+ placeholder: labels.chatInputPlaceholder,
878
+ className: (0, import_tailwind_merge3.twMerge)(
879
+ // Layout and sizing
880
+ "w-full p-5 pb-0",
881
+ // Behavior
882
+ "outline-none resize-none",
883
+ // Background
884
+ "bg-transparent",
885
+ // Typography
886
+ "antialiased font-regular leading-relaxed text-[16px]",
887
+ // Placeholder styles
888
+ "placeholder:text-[#00000077] dark:placeholder:text-[#fffc]",
889
+ className
890
+ ),
891
+ rows: 1
892
+ }
893
+ );
894
+ }
895
+ );
896
+ CopilotChatInput2.AudioRecorder = CopilotChatAudioRecorder;
897
+ })(CopilotChatInput || (CopilotChatInput = {}));
898
+ CopilotChatInput.TextArea.displayName = "CopilotChatInput.TextArea";
899
+ CopilotChatInput.SendButton.displayName = "CopilotChatInput.SendButton";
900
+ CopilotChatInput.ToolbarButton.displayName = "CopilotChatInput.ToolbarButton";
901
+ CopilotChatInput.StartTranscribeButton.displayName = "CopilotChatInput.StartTranscribeButton";
902
+ CopilotChatInput.CancelTranscribeButton.displayName = "CopilotChatInput.CancelTranscribeButton";
903
+ CopilotChatInput.FinishTranscribeButton.displayName = "CopilotChatInput.FinishTranscribeButton";
904
+ CopilotChatInput.AddFileButton.displayName = "CopilotChatInput.AddButton";
905
+ CopilotChatInput.ToolsButton.displayName = "CopilotChatInput.ToolsButton";
906
+ CopilotChatInput.Toolbar.displayName = "CopilotChatInput.Toolbar";
907
+ var CopilotChatInput_default = CopilotChatInput;
908
+
909
+ // src/components/chat/CopilotChatAssistantMessage.tsx
910
+ var import_react_markdown = require("react-markdown");
911
+ var import_remark_gfm = __toESM(require("remark-gfm"));
912
+ var import_remark_math = __toESM(require("remark-math"));
913
+ var import_rehype_pretty_code = __toESM(require("rehype-pretty-code"));
914
+ var import_rehype_katex = __toESM(require("rehype-katex"));
915
+ var import_react13 = require("react");
916
+ var import_lucide_react3 = require("lucide-react");
917
+ var import_tailwind_merge4 = require("tailwind-merge");
918
+ var import_katex_min = require("katex/dist/katex.min.css");
919
+ var import_core3 = require("@copilotkitnext/core");
920
+
921
+ // src/hooks/use-render-tool-call.tsx
922
+ var import_react6 = require("react");
923
+ var import_core2 = require("@copilotkitnext/core");
924
+
925
+ // src/providers/CopilotKitProvider.tsx
926
+ var import_react5 = require("react");
927
+ var import_core = require("@copilotkitnext/core");
928
+ var import_jsx_runtime7 = require("react/jsx-runtime");
929
+ var CopilotKitContext = (0, import_react5.createContext)({
930
+ copilotkit: null,
931
+ renderToolCalls: [],
932
+ currentRenderToolCalls: [],
933
+ setCurrentRenderToolCalls: () => {
934
+ }
935
+ });
936
+ function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
937
+ const empty = (0, import_react5.useMemo)(() => [], []);
938
+ const value = prop ?? empty;
939
+ const initial = (0, import_react5.useRef)(value);
940
+ (0, import_react5.useEffect)(() => {
941
+ if (warningMessage && value !== initial.current && (isMeaningfulChange ? isMeaningfulChange(initial.current, value) : true)) {
942
+ console.error(warningMessage);
943
+ }
944
+ }, [value, warningMessage]);
945
+ return value;
946
+ }
947
+ var CopilotKitProvider = ({
948
+ children,
949
+ runtimeUrl,
950
+ headers = {},
951
+ properties = {},
952
+ agents = {},
953
+ renderToolCalls,
954
+ frontendTools,
955
+ humanInTheLoop
956
+ }) => {
957
+ const renderToolCallsList = useStableArrayProp(
958
+ renderToolCalls,
959
+ "renderToolCalls must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.",
960
+ (initial, next) => {
961
+ const key = (rc) => `${rc?.agentId ?? ""}:${rc?.name ?? ""}`;
962
+ const setFrom = (arr) => new Set(arr.map(key));
963
+ const a = setFrom(initial);
964
+ const b = setFrom(next);
965
+ if (a.size !== b.size) return true;
966
+ for (const k of a) if (!b.has(k)) return true;
967
+ return false;
968
+ }
969
+ );
970
+ const frontendToolsList = useStableArrayProp(
971
+ frontendTools,
972
+ "frontendTools must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead."
973
+ );
974
+ const humanInTheLoopList = useStableArrayProp(
975
+ humanInTheLoop,
976
+ "humanInTheLoop must be a stable array. If you want to dynamically add or remove human-in-the-loop tools, use `useHumanInTheLoop` instead."
977
+ );
978
+ const initialRenderToolCalls = (0, import_react5.useMemo)(() => renderToolCallsList, []);
979
+ const [currentRenderToolCalls, setCurrentRenderToolCalls] = (0, import_react5.useState)([]);
980
+ const processedHumanInTheLoopTools = (0, import_react5.useMemo)(() => {
981
+ const processedTools = [];
982
+ const processedRenderToolCalls = [];
983
+ humanInTheLoopList.forEach((tool) => {
984
+ const frontendTool = {
985
+ name: tool.name,
986
+ description: tool.description,
987
+ parameters: tool.parameters,
988
+ followUp: tool.followUp,
989
+ ...tool.agentId && { agentId: tool.agentId },
990
+ handler: async () => {
991
+ return new Promise((resolve) => {
992
+ console.warn(
993
+ `Human-in-the-loop tool '${tool.name}' called but no interactive handler is set up.`
994
+ );
995
+ resolve(void 0);
996
+ });
997
+ }
998
+ };
999
+ processedTools.push(frontendTool);
1000
+ if (tool.render) {
1001
+ processedRenderToolCalls.push({
1002
+ name: tool.name,
1003
+ args: tool.parameters,
1004
+ render: tool.render,
1005
+ ...tool.agentId && { agentId: tool.agentId }
1006
+ });
1007
+ }
1008
+ });
1009
+ return { tools: processedTools, renderToolCalls: processedRenderToolCalls };
1010
+ }, [humanInTheLoopList]);
1011
+ const allTools = (0, import_react5.useMemo)(() => {
1012
+ const tools = {};
1013
+ frontendToolsList.forEach((tool) => {
1014
+ tools[tool.name] = tool;
1015
+ });
1016
+ processedHumanInTheLoopTools.tools.forEach((tool) => {
1017
+ tools[tool.name] = tool;
1018
+ });
1019
+ return tools;
1020
+ }, [frontendToolsList, processedHumanInTheLoopTools]);
1021
+ const allRenderToolCalls = (0, import_react5.useMemo)(() => {
1022
+ const combined = [...renderToolCallsList];
1023
+ frontendToolsList.forEach((tool) => {
1024
+ if (tool.render && tool.parameters) {
1025
+ combined.push({
1026
+ name: tool.name,
1027
+ args: tool.parameters,
1028
+ render: tool.render
1029
+ });
1030
+ }
1031
+ });
1032
+ combined.push(...processedHumanInTheLoopTools.renderToolCalls);
1033
+ return combined;
1034
+ }, [renderToolCallsList, frontendToolsList, processedHumanInTheLoopTools]);
1035
+ const copilotkit = (0, import_react5.useMemo)(() => {
1036
+ const config = {
1037
+ // Don't set runtimeUrl during initialization to prevent server-side fetching
1038
+ runtimeUrl: void 0,
1039
+ headers,
1040
+ properties,
1041
+ agents,
1042
+ tools: allTools
1043
+ };
1044
+ const copilotkit2 = new import_core.CopilotKitCore(config);
1045
+ return copilotkit2;
1046
+ }, [allTools]);
1047
+ (0, import_react5.useEffect)(() => {
1048
+ setCurrentRenderToolCalls(
1049
+ (prev) => prev === allRenderToolCalls ? prev : allRenderToolCalls
1050
+ );
1051
+ }, [allRenderToolCalls]);
1052
+ (0, import_react5.useEffect)(() => {
1053
+ copilotkit.setRuntimeUrl(runtimeUrl);
1054
+ copilotkit.setHeaders(headers);
1055
+ copilotkit.setProperties(properties);
1056
+ copilotkit.setAgents(agents);
1057
+ }, [runtimeUrl, headers, properties, agents]);
1058
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1059
+ CopilotKitContext.Provider,
1060
+ {
1061
+ value: {
1062
+ copilotkit,
1063
+ renderToolCalls: allRenderToolCalls,
1064
+ currentRenderToolCalls,
1065
+ setCurrentRenderToolCalls
1066
+ },
1067
+ children
1068
+ }
1069
+ );
1070
+ };
1071
+ var useCopilotKit = () => {
1072
+ const context = (0, import_react5.useContext)(CopilotKitContext);
1073
+ const [, forceUpdate] = (0, import_react5.useReducer)((x) => x + 1, 0);
1074
+ if (!context) {
1075
+ throw new Error("useCopilotKit must be used within CopilotKitProvider");
1076
+ }
1077
+ (0, import_react5.useEffect)(() => {
1078
+ const unsubscribe = context.copilotkit.subscribe({
1079
+ onRuntimeLoaded: () => {
1080
+ forceUpdate();
1081
+ },
1082
+ onRuntimeLoadError: () => {
1083
+ forceUpdate();
1084
+ }
1085
+ });
1086
+ return () => {
1087
+ unsubscribe();
1088
+ };
1089
+ }, []);
1090
+ return context;
1091
+ };
1092
+
1093
+ // src/hooks/use-render-tool-call.tsx
1094
+ var import_shared = require("@copilotkitnext/shared");
1095
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1096
+ function useRenderToolCall() {
1097
+ const { currentRenderToolCalls } = useCopilotKit();
1098
+ const renderToolCall = (0, import_react6.useCallback)(
1099
+ ({
1100
+ toolCall,
1101
+ toolMessage,
1102
+ isLoading
1103
+ }) => {
1104
+ const renderConfig = currentRenderToolCalls.find(
1105
+ (rc) => rc.name === toolCall.function.name
1106
+ ) || currentRenderToolCalls.find((rc) => rc.name === "*");
1107
+ if (!renderConfig) {
1108
+ return null;
1109
+ }
1110
+ const RenderComponent = renderConfig.render;
1111
+ const args = (0, import_shared.partialJSONParse)(toolCall.function.arguments);
1112
+ if (toolMessage) {
1113
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1114
+ RenderComponent,
1115
+ {
1116
+ args,
1117
+ status: import_core2.ToolCallStatus.Complete,
1118
+ result: toolMessage.content
1119
+ },
1120
+ toolCall.id
1121
+ );
1122
+ } else if (isLoading) {
1123
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1124
+ RenderComponent,
1125
+ {
1126
+ args,
1127
+ status: import_core2.ToolCallStatus.InProgress,
1128
+ result: void 0
1129
+ },
1130
+ toolCall.id
1131
+ );
1132
+ } else {
1133
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1134
+ RenderComponent,
1135
+ {
1136
+ args,
1137
+ status: import_core2.ToolCallStatus.Complete,
1138
+ result: ""
1139
+ },
1140
+ toolCall.id
1141
+ );
1142
+ }
1143
+ },
1144
+ [currentRenderToolCalls]
1145
+ );
1146
+ return renderToolCall;
1147
+ }
1148
+
1149
+ // src/hooks/use-frontend-tool.tsx
1150
+ var import_react7 = require("react");
1151
+ function useFrontendTool(tool) {
1152
+ const { renderToolCalls, copilotkit, setCurrentRenderToolCalls } = useCopilotKit();
1153
+ (0, import_react7.useEffect)(() => {
1154
+ if (tool.name in copilotkit.tools) {
1155
+ console.warn(
1156
+ `Tool '${tool.name}' already exists. It will be overridden.`
1157
+ );
1158
+ }
1159
+ copilotkit.addTool(tool);
1160
+ if (tool.render && tool.name in renderToolCalls) {
1161
+ console.warn(
1162
+ `Render component for tool '${tool.name}' already exists. It will be overridden.`
1163
+ );
1164
+ }
1165
+ if (tool.render && tool.parameters) {
1166
+ setCurrentRenderToolCalls((prev) => [
1167
+ ...prev,
1168
+ {
1169
+ name: tool.name,
1170
+ args: tool.parameters,
1171
+ render: tool.render
1172
+ }
1173
+ ]);
1174
+ }
1175
+ return () => {
1176
+ copilotkit.removeTool(tool.name);
1177
+ setCurrentRenderToolCalls(
1178
+ (prev) => prev.filter((rc) => rc.name !== tool.name)
1179
+ );
1180
+ };
1181
+ }, [tool, copilotkit, renderToolCalls, setCurrentRenderToolCalls]);
1182
+ }
1183
+
1184
+ // src/hooks/use-human-in-the-loop.tsx
1185
+ var import_react8 = require("react");
1186
+ var import_react9 = __toESM(require("react"));
1187
+ function useHumanInTheLoop(tool) {
1188
+ const [status, setStatus] = (0, import_react8.useState)(
1189
+ "inProgress"
1190
+ );
1191
+ const resolvePromiseRef = (0, import_react8.useRef)(null);
1192
+ const respond = (0, import_react8.useCallback)(async (result) => {
1193
+ if (resolvePromiseRef.current) {
1194
+ resolvePromiseRef.current(result);
1195
+ setStatus("complete");
1196
+ resolvePromiseRef.current = null;
1197
+ }
1198
+ }, []);
1199
+ const handler = (0, import_react8.useCallback)(async () => {
1200
+ return new Promise((resolve) => {
1201
+ setStatus("executing");
1202
+ resolvePromiseRef.current = resolve;
1203
+ });
1204
+ }, []);
1205
+ const RenderComponent = (0, import_react8.useCallback)(
1206
+ (props) => {
1207
+ const ToolComponent = tool.render;
1208
+ if (status === "inProgress" && props.status === "inProgress") {
1209
+ const enhancedProps = {
1210
+ ...props,
1211
+ name: tool.name,
1212
+ description: tool.description || "",
1213
+ respond: void 0
1214
+ };
1215
+ return import_react9.default.createElement(ToolComponent, enhancedProps);
1216
+ } else if (status === "executing" && props.status === "executing") {
1217
+ const enhancedProps = {
1218
+ ...props,
1219
+ name: tool.name,
1220
+ description: tool.description || "",
1221
+ respond
1222
+ };
1223
+ return import_react9.default.createElement(ToolComponent, enhancedProps);
1224
+ } else if (status === "complete" && props.status === "complete") {
1225
+ const enhancedProps = {
1226
+ ...props,
1227
+ name: tool.name,
1228
+ description: tool.description || "",
1229
+ respond: void 0
1230
+ };
1231
+ return import_react9.default.createElement(ToolComponent, enhancedProps);
1232
+ }
1233
+ return import_react9.default.createElement(ToolComponent, props);
1234
+ },
1235
+ [tool.render, tool.name, tool.description, status, respond]
1236
+ );
1237
+ const frontendTool = {
1238
+ ...tool,
1239
+ handler,
1240
+ render: RenderComponent
1241
+ };
1242
+ useFrontendTool(frontendTool);
1243
+ }
1244
+
1245
+ // src/hooks/use-agent.tsx
1246
+ var import_react10 = require("react");
1247
+ var import_shared2 = require("@copilotkitnext/shared");
1248
+ function useAgent({ agentId } = {}) {
1249
+ agentId ??= import_shared2.DEFAULT_AGENT_ID;
1250
+ const { copilotkit } = useCopilotKit();
1251
+ const [, forceUpdate] = (0, import_react10.useReducer)((x) => x + 1, 0);
1252
+ const [isRunning, setIsRunning] = (0, import_react10.useState)(false);
1253
+ const agent = (0, import_react10.useMemo)(() => {
1254
+ return copilotkit.getAgent(agentId);
1255
+ }, [agentId, copilotkit.agents, copilotkit.didLoadRuntime, copilotkit]);
1256
+ (0, import_react10.useEffect)(() => {
1257
+ const subscription = agent?.subscribe({
1258
+ onMessagesChanged() {
1259
+ forceUpdate();
1260
+ },
1261
+ onStateChanged() {
1262
+ forceUpdate();
1263
+ },
1264
+ onRunInitialized() {
1265
+ setIsRunning(true);
1266
+ },
1267
+ onRunFinalized() {
1268
+ setIsRunning(false);
1269
+ },
1270
+ onRunFailed() {
1271
+ setIsRunning(false);
1272
+ }
1273
+ });
1274
+ return () => subscription?.unsubscribe();
1275
+ }, [agent]);
1276
+ return {
1277
+ agent,
1278
+ isRunning
1279
+ };
1280
+ }
1281
+
1282
+ // src/hooks/use-agent-context.tsx
1283
+ var import_react11 = require("react");
1284
+ function useAgentContext(context) {
1285
+ const { description, value } = context;
1286
+ const { copilotkit } = useCopilotKit();
1287
+ (0, import_react11.useEffect)(() => {
1288
+ if (!copilotkit) return;
1289
+ const id = copilotkit.addContext(context);
1290
+ return () => {
1291
+ copilotkit.removeContext(id);
1292
+ };
1293
+ }, [description, value, copilotkit]);
1294
+ }
1295
+
1296
+ // src/components/chat/CopilotChatToolCallsView.tsx
1297
+ var import_react12 = __toESM(require("react"));
1298
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1299
+ function CopilotChatToolCallsView({
1300
+ message,
1301
+ messages = [],
1302
+ isLoading = false
1303
+ }) {
1304
+ const renderToolCall = useRenderToolCall();
1305
+ if (!message.toolCalls || message.toolCalls.length === 0) {
1306
+ return null;
1307
+ }
1308
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: message.toolCalls.map((toolCall) => {
1309
+ const toolMessage = messages.find(
1310
+ (m) => m.role === "tool" && m.toolCallId === toolCall.id
1311
+ );
1312
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react12.default.Fragment, { children: renderToolCall({
1313
+ toolCall,
1314
+ toolMessage,
1315
+ isLoading
1316
+ }) }, toolCall.id);
1317
+ }) });
1318
+ }
1319
+ var CopilotChatToolCallsView_default = CopilotChatToolCallsView;
1320
+
1321
+ // src/components/chat/CopilotChatAssistantMessage.tsx
1322
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1323
+ function CopilotChatAssistantMessage({
1324
+ message,
1325
+ messages,
1326
+ isLoading,
1327
+ onThumbsUp,
1328
+ onThumbsDown,
1329
+ onReadAloud,
1330
+ onRegenerate,
1331
+ additionalToolbarItems,
1332
+ toolbarVisible = true,
1333
+ markdownRenderer,
1334
+ toolbar,
1335
+ copyButton,
1336
+ thumbsUpButton,
1337
+ thumbsDownButton,
1338
+ readAloudButton,
1339
+ regenerateButton,
1340
+ toolCallsView,
1341
+ children,
1342
+ className,
1343
+ ...props
1344
+ }) {
1345
+ const boundMarkdownRenderer = renderSlot(
1346
+ markdownRenderer,
1347
+ CopilotChatAssistantMessage.MarkdownRenderer,
1348
+ {
1349
+ content: message.content || ""
1350
+ }
1351
+ );
1352
+ const boundCopyButton = renderSlot(
1353
+ copyButton,
1354
+ CopilotChatAssistantMessage.CopyButton,
1355
+ {
1356
+ onClick: async () => {
1357
+ if (message.content) {
1358
+ try {
1359
+ await navigator.clipboard.writeText(message.content);
1360
+ } catch (err) {
1361
+ console.error("Failed to copy message:", err);
1362
+ }
1363
+ }
1364
+ }
1365
+ }
1366
+ );
1367
+ const boundThumbsUpButton = renderSlot(
1368
+ thumbsUpButton,
1369
+ CopilotChatAssistantMessage.ThumbsUpButton,
1370
+ {
1371
+ onClick: onThumbsUp
1372
+ }
1373
+ );
1374
+ const boundThumbsDownButton = renderSlot(
1375
+ thumbsDownButton,
1376
+ CopilotChatAssistantMessage.ThumbsDownButton,
1377
+ {
1378
+ onClick: onThumbsDown
1379
+ }
1380
+ );
1381
+ const boundReadAloudButton = renderSlot(
1382
+ readAloudButton,
1383
+ CopilotChatAssistantMessage.ReadAloudButton,
1384
+ {
1385
+ onClick: onReadAloud
1386
+ }
1387
+ );
1388
+ const boundRegenerateButton = renderSlot(
1389
+ regenerateButton,
1390
+ CopilotChatAssistantMessage.RegenerateButton,
1391
+ {
1392
+ onClick: onRegenerate
1393
+ }
1394
+ );
1395
+ const boundToolbar = renderSlot(
1396
+ toolbar,
1397
+ CopilotChatAssistantMessage.Toolbar,
1398
+ {
1399
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1", children: [
1400
+ boundCopyButton,
1401
+ (onThumbsUp || thumbsUpButton) && boundThumbsUpButton,
1402
+ (onThumbsDown || thumbsDownButton) && boundThumbsDownButton,
1403
+ (onReadAloud || readAloudButton) && boundReadAloudButton,
1404
+ (onRegenerate || regenerateButton) && boundRegenerateButton,
1405
+ additionalToolbarItems
1406
+ ] })
1407
+ }
1408
+ );
1409
+ const boundToolCallsView = renderSlot(
1410
+ toolCallsView,
1411
+ CopilotChatToolCallsView_default,
1412
+ {
1413
+ message,
1414
+ messages,
1415
+ isLoading
1416
+ }
1417
+ );
1418
+ if (children) {
1419
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: children({
1420
+ markdownRenderer: boundMarkdownRenderer,
1421
+ toolbar: boundToolbar,
1422
+ toolCallsView: boundToolCallsView,
1423
+ copyButton: boundCopyButton,
1424
+ thumbsUpButton: boundThumbsUpButton,
1425
+ thumbsDownButton: boundThumbsDownButton,
1426
+ readAloudButton: boundReadAloudButton,
1427
+ regenerateButton: boundRegenerateButton,
1428
+ message,
1429
+ messages,
1430
+ isLoading,
1431
+ onThumbsUp,
1432
+ onThumbsDown,
1433
+ onReadAloud,
1434
+ onRegenerate,
1435
+ additionalToolbarItems,
1436
+ toolbarVisible
1437
+ }) });
1438
+ }
1439
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1440
+ "div",
1441
+ {
1442
+ className: (0, import_tailwind_merge4.twMerge)(
1443
+ "prose max-w-full break-words dark:prose-invert",
1444
+ className
1445
+ ),
1446
+ ...props,
1447
+ "data-message-id": message.id,
1448
+ children: [
1449
+ boundMarkdownRenderer,
1450
+ boundToolCallsView,
1451
+ toolbarVisible && boundToolbar
1452
+ ]
1453
+ }
1454
+ );
1455
+ }
1456
+ ((CopilotChatAssistantMessage2) => {
1457
+ const InlineCode = ({
1458
+ children,
1459
+ ...props
1460
+ }) => {
1461
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1462
+ "code",
1463
+ {
1464
+ className: "px-[4.8px] py-[2.5px] bg-[rgb(236,236,236)] dark:bg-gray-800 rounded text-sm font-mono font-medium! text-foreground!",
1465
+ ...props,
1466
+ children
1467
+ }
1468
+ );
1469
+ };
1470
+ const CodeBlock = ({ children, className, onClick, ...props }) => {
1471
+ const { labels } = useCopilotChatConfiguration();
1472
+ const [copied, setCopied] = (0, import_react13.useState)(false);
1473
+ const getCodeContent = (node) => {
1474
+ if (typeof node === "string") return node;
1475
+ if (Array.isArray(node)) return node.map(getCodeContent).join("");
1476
+ if (node?.props?.children) return getCodeContent(node.props.children);
1477
+ return "";
1478
+ };
1479
+ const codeContent = getCodeContent(children);
1480
+ const language = props["data-language"];
1481
+ const copyToClipboard = async () => {
1482
+ if (!codeContent.trim()) return;
1483
+ try {
1484
+ setCopied(true);
1485
+ setTimeout(() => setCopied(false), 2e3);
1486
+ if (onClick) {
1487
+ onClick();
1488
+ }
1489
+ } catch (err) {
1490
+ console.error("Failed to copy code:", err);
1491
+ }
1492
+ };
1493
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "relative", children: [
1494
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between px-4 pr-3 py-3 text-xs", children: [
1495
+ language && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-regular text-muted-foreground dark:text-white", children: language }),
1496
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1497
+ "button",
1498
+ {
1499
+ className: cn(
1500
+ "px-2 gap-0.5 text-xs flex items-center cursor-pointer text-muted-foreground dark:text-white"
1501
+ ),
1502
+ onClick: copyToClipboard,
1503
+ title: copied ? labels.assistantMessageToolbarCopyCodeCopiedLabel : `${labels.assistantMessageToolbarCopyCodeLabel} code`,
1504
+ children: [
1505
+ copied ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.Check, { className: "h-[10px]! w-[10px]!" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.Copy, { className: "h-[10px]! w-[10px]!" }),
1506
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[11px]", children: copied ? labels.assistantMessageToolbarCopyCodeCopiedLabel : labels.assistantMessageToolbarCopyCodeLabel })
1507
+ ]
1508
+ }
1509
+ )
1510
+ ] }),
1511
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1512
+ "pre",
1513
+ {
1514
+ className: cn(
1515
+ className,
1516
+ "rounded-2xl bg-transparent border-t-0 my-1!"
1517
+ ),
1518
+ ...props,
1519
+ children
1520
+ }
1521
+ )
1522
+ ] });
1523
+ };
1524
+ CopilotChatAssistantMessage2.MarkdownRenderer = ({ content, className }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1525
+ import_react_markdown.MarkdownHooks,
1526
+ {
1527
+ remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
1528
+ rehypePlugins: [
1529
+ [
1530
+ import_rehype_pretty_code.default,
1531
+ {
1532
+ keepBackground: false,
1533
+ theme: {
1534
+ dark: "one-dark-pro",
1535
+ light: "one-light"
1536
+ },
1537
+ bypassInlineCode: true
1538
+ }
1539
+ ],
1540
+ import_rehype_katex.default
1541
+ ],
1542
+ components: {
1543
+ pre: CodeBlock,
1544
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1545
+ code: ({ className: className2, children, ...props }) => {
1546
+ if (typeof children === "string") {
1547
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(InlineCode, { ...props, children });
1548
+ }
1549
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("code", { className: className2, ...props, children });
1550
+ }
1551
+ },
1552
+ children: (0, import_core3.completePartialMarkdown)(content || "")
1553
+ }
1554
+ ) });
1555
+ CopilotChatAssistantMessage2.Toolbar = ({
1556
+ className,
1557
+ ...props
1558
+ }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1559
+ "div",
1560
+ {
1561
+ className: (0, import_tailwind_merge4.twMerge)(
1562
+ "w-full bg-transparent flex items-center -ml-[5px] -mt-[0px]",
1563
+ className
1564
+ ),
1565
+ ...props
1566
+ }
1567
+ );
1568
+ CopilotChatAssistantMessage2.ToolbarButton = ({ title, children, ...props }) => {
1569
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Tooltip, { children: [
1570
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1571
+ Button,
1572
+ {
1573
+ type: "button",
1574
+ variant: "assistantMessageToolbarButton",
1575
+ "aria-label": title,
1576
+ ...props,
1577
+ children
1578
+ }
1579
+ ) }),
1580
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipContent, { side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: title }) })
1581
+ ] });
1582
+ };
1583
+ CopilotChatAssistantMessage2.CopyButton = ({ className, title, onClick, ...props }) => {
1584
+ const { labels } = useCopilotChatConfiguration();
1585
+ const [copied, setCopied] = (0, import_react13.useState)(false);
1586
+ const handleClick = (event) => {
1587
+ setCopied(true);
1588
+ setTimeout(() => setCopied(false), 2e3);
1589
+ if (onClick) {
1590
+ onClick(event);
1591
+ }
1592
+ };
1593
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1594
+ CopilotChatAssistantMessage2.ToolbarButton,
1595
+ {
1596
+ title: title || labels.assistantMessageToolbarCopyMessageLabel,
1597
+ onClick: handleClick,
1598
+ className,
1599
+ ...props,
1600
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.Check, { className: "size-[18px]" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.Copy, { className: "size-[18px]" })
1601
+ }
1602
+ );
1603
+ };
1604
+ CopilotChatAssistantMessage2.ThumbsUpButton = ({ title, ...props }) => {
1605
+ const { labels } = useCopilotChatConfiguration();
1606
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1607
+ CopilotChatAssistantMessage2.ToolbarButton,
1608
+ {
1609
+ title: title || labels.assistantMessageToolbarThumbsUpLabel,
1610
+ ...props,
1611
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.ThumbsUp, { className: "size-[18px]" })
1612
+ }
1613
+ );
1614
+ };
1615
+ CopilotChatAssistantMessage2.ThumbsDownButton = ({ title, ...props }) => {
1616
+ const { labels } = useCopilotChatConfiguration();
1617
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1618
+ CopilotChatAssistantMessage2.ToolbarButton,
1619
+ {
1620
+ title: title || labels.assistantMessageToolbarThumbsDownLabel,
1621
+ ...props,
1622
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.ThumbsDown, { className: "size-[18px]" })
1623
+ }
1624
+ );
1625
+ };
1626
+ CopilotChatAssistantMessage2.ReadAloudButton = ({ title, ...props }) => {
1627
+ const { labels } = useCopilotChatConfiguration();
1628
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1629
+ CopilotChatAssistantMessage2.ToolbarButton,
1630
+ {
1631
+ title: title || labels.assistantMessageToolbarReadAloudLabel,
1632
+ ...props,
1633
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.Volume2, { className: "size-[20px]" })
1634
+ }
1635
+ );
1636
+ };
1637
+ CopilotChatAssistantMessage2.RegenerateButton = ({ title, ...props }) => {
1638
+ const { labels } = useCopilotChatConfiguration();
1639
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1640
+ CopilotChatAssistantMessage2.ToolbarButton,
1641
+ {
1642
+ title: title || labels.assistantMessageToolbarRegenerateLabel,
1643
+ ...props,
1644
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.RefreshCw, { className: "size-[18px]" })
1645
+ }
1646
+ );
1647
+ };
1648
+ })(CopilotChatAssistantMessage || (CopilotChatAssistantMessage = {}));
1649
+ CopilotChatAssistantMessage.MarkdownRenderer.displayName = "CopilotChatAssistantMessage.MarkdownRenderer";
1650
+ CopilotChatAssistantMessage.Toolbar.displayName = "CopilotChatAssistantMessage.Toolbar";
1651
+ CopilotChatAssistantMessage.CopyButton.displayName = "CopilotChatAssistantMessage.CopyButton";
1652
+ CopilotChatAssistantMessage.ThumbsUpButton.displayName = "CopilotChatAssistantMessage.ThumbsUpButton";
1653
+ CopilotChatAssistantMessage.ThumbsDownButton.displayName = "CopilotChatAssistantMessage.ThumbsDownButton";
1654
+ CopilotChatAssistantMessage.ReadAloudButton.displayName = "CopilotChatAssistantMessage.ReadAloudButton";
1655
+ CopilotChatAssistantMessage.RegenerateButton.displayName = "CopilotChatAssistantMessage.RegenerateButton";
1656
+ var CopilotChatAssistantMessage_default = CopilotChatAssistantMessage;
1657
+
1658
+ // src/components/chat/CopilotChatUserMessage.tsx
1659
+ var import_react14 = require("react");
1660
+ var import_lucide_react4 = require("lucide-react");
1661
+ var import_tailwind_merge5 = require("tailwind-merge");
1662
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1663
+ function CopilotChatUserMessage({
1664
+ message,
1665
+ onEditMessage,
1666
+ branchIndex,
1667
+ numberOfBranches,
1668
+ onSwitchToBranch,
1669
+ additionalToolbarItems,
1670
+ messageRenderer,
1671
+ toolbar,
1672
+ copyButton,
1673
+ editButton,
1674
+ branchNavigation,
1675
+ children,
1676
+ className,
1677
+ ...props
1678
+ }) {
1679
+ const BoundMessageRenderer = renderSlot(
1680
+ messageRenderer,
1681
+ CopilotChatUserMessage.MessageRenderer,
1682
+ {
1683
+ content: message.content || ""
1684
+ }
1685
+ );
1686
+ const BoundCopyButton = renderSlot(
1687
+ copyButton,
1688
+ CopilotChatUserMessage.CopyButton,
1689
+ {
1690
+ onClick: async () => {
1691
+ if (message.content) {
1692
+ try {
1693
+ await navigator.clipboard.writeText(message.content);
1694
+ } catch (err) {
1695
+ console.error("Failed to copy message:", err);
1696
+ }
1697
+ }
1698
+ }
1699
+ }
1700
+ );
1701
+ const BoundEditButton = renderSlot(
1702
+ editButton,
1703
+ CopilotChatUserMessage.EditButton,
1704
+ {
1705
+ onClick: () => onEditMessage?.({ message })
1706
+ }
1707
+ );
1708
+ const BoundBranchNavigation = renderSlot(
1709
+ branchNavigation,
1710
+ CopilotChatUserMessage.BranchNavigation,
1711
+ {
1712
+ currentBranch: branchIndex,
1713
+ numberOfBranches,
1714
+ onSwitchToBranch,
1715
+ message
1716
+ }
1717
+ );
1718
+ const showBranchNavigation = numberOfBranches && numberOfBranches > 1 && onSwitchToBranch;
1719
+ const BoundToolbar = renderSlot(toolbar, CopilotChatUserMessage.Toolbar, {
1720
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-1 justify-end", children: [
1721
+ additionalToolbarItems,
1722
+ BoundCopyButton,
1723
+ onEditMessage && BoundEditButton,
1724
+ showBranchNavigation && BoundBranchNavigation
1725
+ ] })
1726
+ });
1727
+ if (children) {
1728
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: children({
1729
+ messageRenderer: BoundMessageRenderer,
1730
+ toolbar: BoundToolbar,
1731
+ copyButton: BoundCopyButton,
1732
+ editButton: BoundEditButton,
1733
+ branchNavigation: BoundBranchNavigation,
1734
+ message,
1735
+ branchIndex,
1736
+ numberOfBranches,
1737
+ additionalToolbarItems
1738
+ }) });
1739
+ }
1740
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1741
+ "div",
1742
+ {
1743
+ className: (0, import_tailwind_merge5.twMerge)("flex flex-col items-end group pt-10", className),
1744
+ "data-message-id": message.id,
1745
+ ...props,
1746
+ children: [
1747
+ BoundMessageRenderer,
1748
+ BoundToolbar
1749
+ ]
1750
+ }
1751
+ );
1752
+ }
1753
+ ((CopilotChatUserMessage2) => {
1754
+ CopilotChatUserMessage2.Container = ({ children, className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1755
+ "div",
1756
+ {
1757
+ className: (0, import_tailwind_merge5.twMerge)("flex flex-col items-end group", className),
1758
+ ...props,
1759
+ children
1760
+ }
1761
+ );
1762
+ CopilotChatUserMessage2.MessageRenderer = ({ content, className }) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1763
+ "div",
1764
+ {
1765
+ className: (0, import_tailwind_merge5.twMerge)(
1766
+ "prose dark:prose-invert bg-muted relative max-w-[80%] rounded-[18px] px-4 py-1.5 data-[multiline]:py-3 inline-block whitespace-pre-wrap",
1767
+ className
1768
+ ),
1769
+ children: content
1770
+ }
1771
+ );
1772
+ CopilotChatUserMessage2.Toolbar = ({
1773
+ className,
1774
+ ...props
1775
+ }) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1776
+ "div",
1777
+ {
1778
+ className: (0, import_tailwind_merge5.twMerge)(
1779
+ "w-full bg-transparent flex items-center justify-end -mr-[5px] mt-[4px] invisible group-hover:visible",
1780
+ className
1781
+ ),
1782
+ ...props
1783
+ }
1784
+ );
1785
+ CopilotChatUserMessage2.ToolbarButton = ({ title, children, className, ...props }) => {
1786
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Tooltip, { children: [
1787
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1788
+ Button,
1789
+ {
1790
+ type: "button",
1791
+ variant: "assistantMessageToolbarButton",
1792
+ "aria-label": title,
1793
+ className: (0, import_tailwind_merge5.twMerge)(className),
1794
+ ...props,
1795
+ children
1796
+ }
1797
+ ) }),
1798
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipContent, { side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: title }) })
1799
+ ] });
1800
+ };
1801
+ CopilotChatUserMessage2.CopyButton = ({ className, title, onClick, ...props }) => {
1802
+ const { labels } = useCopilotChatConfiguration();
1803
+ const [copied, setCopied] = (0, import_react14.useState)(false);
1804
+ const handleClick = (event) => {
1805
+ setCopied(true);
1806
+ setTimeout(() => setCopied(false), 2e3);
1807
+ if (onClick) {
1808
+ onClick(event);
1809
+ }
1810
+ };
1811
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1812
+ CopilotChatUserMessage2.ToolbarButton,
1813
+ {
1814
+ title: title || labels.userMessageToolbarCopyMessageLabel,
1815
+ onClick: handleClick,
1816
+ className,
1817
+ ...props,
1818
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Check, { className: "size-[18px]" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Copy, { className: "size-[18px]" })
1819
+ }
1820
+ );
1821
+ };
1822
+ CopilotChatUserMessage2.EditButton = ({ className, title, ...props }) => {
1823
+ const { labels } = useCopilotChatConfiguration();
1824
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1825
+ CopilotChatUserMessage2.ToolbarButton,
1826
+ {
1827
+ title: title || labels.userMessageToolbarEditMessageLabel,
1828
+ className,
1829
+ ...props,
1830
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Edit, { className: "size-[18px]" })
1831
+ }
1832
+ );
1833
+ };
1834
+ CopilotChatUserMessage2.BranchNavigation = ({
1835
+ className,
1836
+ currentBranch = 0,
1837
+ numberOfBranches = 1,
1838
+ onSwitchToBranch,
1839
+ message,
1840
+ ...props
1841
+ }) => {
1842
+ if (!numberOfBranches || numberOfBranches <= 1 || !onSwitchToBranch) {
1843
+ return null;
1844
+ }
1845
+ const canGoPrev = currentBranch > 0;
1846
+ const canGoNext = currentBranch < numberOfBranches - 1;
1847
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: (0, import_tailwind_merge5.twMerge)("flex items-center gap-1", className), ...props, children: [
1848
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1849
+ Button,
1850
+ {
1851
+ type: "button",
1852
+ variant: "assistantMessageToolbarButton",
1853
+ onClick: () => onSwitchToBranch?.({
1854
+ branchIndex: currentBranch - 1,
1855
+ numberOfBranches,
1856
+ message
1857
+ }),
1858
+ disabled: !canGoPrev,
1859
+ className: "h-6 w-6 p-0",
1860
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.ChevronLeft, { className: "size-[20px]" })
1861
+ }
1862
+ ),
1863
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-sm text-muted-foreground px-0 font-medium", children: [
1864
+ currentBranch + 1,
1865
+ "/",
1866
+ numberOfBranches
1867
+ ] }),
1868
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1869
+ Button,
1870
+ {
1871
+ type: "button",
1872
+ variant: "assistantMessageToolbarButton",
1873
+ onClick: () => onSwitchToBranch?.({
1874
+ branchIndex: currentBranch + 1,
1875
+ numberOfBranches,
1876
+ message
1877
+ }),
1878
+ disabled: !canGoNext,
1879
+ className: "h-6 w-6 p-0",
1880
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.ChevronRight, { className: "size-[20px]" })
1881
+ }
1882
+ )
1883
+ ] });
1884
+ };
1885
+ })(CopilotChatUserMessage || (CopilotChatUserMessage = {}));
1886
+ CopilotChatUserMessage.Container.displayName = "CopilotChatUserMessage.Container";
1887
+ CopilotChatUserMessage.MessageRenderer.displayName = "CopilotChatUserMessage.MessageRenderer";
1888
+ CopilotChatUserMessage.Toolbar.displayName = "CopilotChatUserMessage.Toolbar";
1889
+ CopilotChatUserMessage.ToolbarButton.displayName = "CopilotChatUserMessage.ToolbarButton";
1890
+ CopilotChatUserMessage.CopyButton.displayName = "CopilotChatUserMessage.CopyButton";
1891
+ CopilotChatUserMessage.EditButton.displayName = "CopilotChatUserMessage.EditButton";
1892
+ CopilotChatUserMessage.BranchNavigation.displayName = "CopilotChatUserMessage.BranchNavigation";
1893
+ var CopilotChatUserMessage_default = CopilotChatUserMessage;
1894
+
1895
+ // src/components/chat/CopilotChatMessageView.tsx
1896
+ var import_tailwind_merge6 = require("tailwind-merge");
1897
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1898
+ function CopilotChatMessageView({
1899
+ messages = [],
1900
+ assistantMessage,
1901
+ userMessage,
1902
+ cursor,
1903
+ isLoading = false,
1904
+ children,
1905
+ className,
1906
+ ...props
1907
+ }) {
1908
+ const messageElements = messages.map((message) => {
1909
+ if (message.role === "assistant") {
1910
+ return renderSlot(assistantMessage, CopilotChatAssistantMessage_default, {
1911
+ key: message.id,
1912
+ message,
1913
+ messages,
1914
+ isLoading
1915
+ });
1916
+ } else if (message.role === "user") {
1917
+ return renderSlot(userMessage, CopilotChatUserMessage_default, {
1918
+ key: message.id,
1919
+ message
1920
+ });
1921
+ }
1922
+ return;
1923
+ }).filter(Boolean);
1924
+ if (children) {
1925
+ return children({ messageElements, messages, isLoading });
1926
+ }
1927
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: (0, import_tailwind_merge6.twMerge)("flex flex-col", className), ...props, children: [
1928
+ messageElements,
1929
+ isLoading && renderSlot(cursor, CopilotChatMessageView.Cursor, {})
1930
+ ] });
1931
+ }
1932
+ CopilotChatMessageView.Cursor = function Cursor({
1933
+ className,
1934
+ ...props
1935
+ }) {
1936
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1937
+ "div",
1938
+ {
1939
+ className: (0, import_tailwind_merge6.twMerge)(
1940
+ "w-[11px] h-[11px] rounded-full bg-foreground animate-pulse-cursor ml-1",
1941
+ className
1942
+ ),
1943
+ ...props
1944
+ }
1945
+ );
1946
+ };
1947
+ var CopilotChatMessageView_default = CopilotChatMessageView;
1948
+
1949
+ // src/components/chat/CopilotChatView.tsx
1950
+ var import_react15 = __toESM(require("react"));
1951
+ var import_tailwind_merge7 = require("tailwind-merge");
1952
+ var import_use_stick_to_bottom = require("use-stick-to-bottom");
1953
+ var import_lucide_react5 = require("lucide-react");
1954
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1955
+ function CopilotChatView({
1956
+ messageView,
1957
+ input,
1958
+ scrollView,
1959
+ scrollToBottomButton,
1960
+ feather,
1961
+ inputContainer,
1962
+ disclaimer,
1963
+ messages = [],
1964
+ autoScroll = true,
1965
+ children,
1966
+ className,
1967
+ ...props
1968
+ }) {
1969
+ const inputContainerRef = (0, import_react15.useRef)(null);
1970
+ const [inputContainerHeight, setInputContainerHeight] = (0, import_react15.useState)(0);
1971
+ const [isResizing, setIsResizing] = (0, import_react15.useState)(false);
1972
+ const resizeTimeoutRef = (0, import_react15.useRef)(null);
1973
+ (0, import_react15.useEffect)(() => {
1974
+ const element = inputContainerRef.current;
1975
+ if (!element) return;
1976
+ const resizeObserver = new ResizeObserver((entries) => {
1977
+ for (const entry of entries) {
1978
+ const newHeight = entry.contentRect.height;
1979
+ setInputContainerHeight((prevHeight) => {
1980
+ if (newHeight !== prevHeight) {
1981
+ setIsResizing(true);
1982
+ if (resizeTimeoutRef.current) {
1983
+ clearTimeout(resizeTimeoutRef.current);
1984
+ }
1985
+ resizeTimeoutRef.current = setTimeout(() => {
1986
+ setIsResizing(false);
1987
+ }, 250);
1988
+ return newHeight;
1989
+ }
1990
+ return prevHeight;
1991
+ });
1992
+ }
1993
+ });
1994
+ resizeObserver.observe(element);
1995
+ setInputContainerHeight(element.offsetHeight);
1996
+ return () => {
1997
+ resizeObserver.disconnect();
1998
+ if (resizeTimeoutRef.current) {
1999
+ clearTimeout(resizeTimeoutRef.current);
2000
+ }
2001
+ };
2002
+ }, []);
2003
+ const BoundMessageView = renderSlot(messageView, CopilotChatMessageView_default, {
2004
+ messages
2005
+ });
2006
+ const BoundInput = renderSlot(input, CopilotChatInput_default, {});
2007
+ const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
2008
+ const BoundScrollView = renderSlot(scrollView, CopilotChatView.ScrollView, {
2009
+ autoScroll,
2010
+ scrollToBottomButton,
2011
+ inputContainerHeight,
2012
+ isResizing,
2013
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { paddingBottom: `${inputContainerHeight + 32}px` }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "max-w-3xl mx-auto", children: BoundMessageView }) })
2014
+ });
2015
+ const BoundScrollToBottomButton = renderSlot(
2016
+ scrollToBottomButton,
2017
+ CopilotChatView.ScrollToBottomButton,
2018
+ {}
2019
+ );
2020
+ const BoundDisclaimer = renderSlot(
2021
+ disclaimer,
2022
+ CopilotChatView.Disclaimer,
2023
+ {}
2024
+ );
2025
+ const BoundInputContainer = renderSlot(
2026
+ inputContainer,
2027
+ CopilotChatView.InputContainer,
2028
+ {
2029
+ ref: inputContainerRef,
2030
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
2031
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "max-w-3xl mx-auto py-0 px-4 sm:px-0", children: BoundInput }),
2032
+ BoundDisclaimer
2033
+ ] })
2034
+ }
2035
+ );
2036
+ if (children) {
2037
+ return children({
2038
+ messageView: BoundMessageView,
2039
+ input: BoundInput,
2040
+ scrollView: BoundScrollView,
2041
+ scrollToBottomButton: BoundScrollToBottomButton,
2042
+ feather: BoundFeather,
2043
+ inputContainer: BoundInputContainer,
2044
+ disclaimer: BoundDisclaimer
2045
+ });
2046
+ }
2047
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: (0, import_tailwind_merge7.twMerge)("relative h-full", className), ...props, children: [
2048
+ BoundScrollView,
2049
+ BoundFeather,
2050
+ BoundInputContainer
2051
+ ] });
2052
+ }
2053
+ ((CopilotChatView2) => {
2054
+ const ScrollContent = ({ children, scrollToBottomButton, inputContainerHeight, isResizing }) => {
2055
+ const { isAtBottom, scrollToBottom } = (0, import_use_stick_to_bottom.useStickToBottomContext)();
2056
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
2057
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_use_stick_to_bottom.StickToBottom.Content, { className: "overflow-y-scroll overflow-x-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "px-4 sm:px-0", children }) }),
2058
+ !isAtBottom && !isResizing && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2059
+ "div",
2060
+ {
2061
+ className: "absolute inset-x-0 flex justify-center z-10",
2062
+ style: {
2063
+ bottom: `${inputContainerHeight + 16}px`
2064
+ },
2065
+ children: renderSlot(
2066
+ scrollToBottomButton,
2067
+ CopilotChatView2.ScrollToBottomButton,
2068
+ {
2069
+ onClick: () => scrollToBottom()
2070
+ }
2071
+ )
2072
+ }
2073
+ )
2074
+ ] });
2075
+ };
2076
+ CopilotChatView2.ScrollView = ({
2077
+ children,
2078
+ autoScroll = true,
2079
+ scrollToBottomButton,
2080
+ inputContainerHeight = 0,
2081
+ isResizing = false,
2082
+ className,
2083
+ ...props
2084
+ }) => {
2085
+ const [hasMounted, setHasMounted] = (0, import_react15.useState)(false);
2086
+ const { scrollRef, contentRef, scrollToBottom } = (0, import_use_stick_to_bottom.useStickToBottom)();
2087
+ const [showScrollButton, setShowScrollButton] = (0, import_react15.useState)(false);
2088
+ (0, import_react15.useEffect)(() => {
2089
+ setHasMounted(true);
2090
+ }, []);
2091
+ (0, import_react15.useEffect)(() => {
2092
+ if (autoScroll) return;
2093
+ const scrollElement = scrollRef.current;
2094
+ if (!scrollElement) return;
2095
+ const checkScroll = () => {
2096
+ const atBottom = scrollElement.scrollHeight - scrollElement.scrollTop - scrollElement.clientHeight < 10;
2097
+ setShowScrollButton(!atBottom);
2098
+ };
2099
+ checkScroll();
2100
+ scrollElement.addEventListener("scroll", checkScroll);
2101
+ const resizeObserver = new ResizeObserver(checkScroll);
2102
+ resizeObserver.observe(scrollElement);
2103
+ return () => {
2104
+ scrollElement.removeEventListener("scroll", checkScroll);
2105
+ resizeObserver.disconnect();
2106
+ };
2107
+ }, [scrollRef, autoScroll]);
2108
+ if (!hasMounted) {
2109
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-full max-h-full flex flex-col min-h-0 overflow-y-scroll overflow-x-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "px-4 sm:px-0", children }) });
2110
+ }
2111
+ if (!autoScroll) {
2112
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2113
+ "div",
2114
+ {
2115
+ ref: scrollRef,
2116
+ className: cn("h-full max-h-full flex flex-col min-h-0 overflow-y-scroll overflow-x-hidden relative", className),
2117
+ ...props,
2118
+ children: [
2119
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ref: contentRef, className: "px-4 sm:px-0", children }),
2120
+ showScrollButton && !isResizing && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2121
+ "div",
2122
+ {
2123
+ className: "absolute inset-x-0 flex justify-center z-10",
2124
+ style: {
2125
+ bottom: `${inputContainerHeight + 16}px`
2126
+ },
2127
+ children: renderSlot(
2128
+ scrollToBottomButton,
2129
+ CopilotChatView2.ScrollToBottomButton,
2130
+ {
2131
+ onClick: () => scrollToBottom()
2132
+ }
2133
+ )
2134
+ }
2135
+ )
2136
+ ]
2137
+ }
2138
+ );
2139
+ }
2140
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2141
+ import_use_stick_to_bottom.StickToBottom,
2142
+ {
2143
+ className: cn("h-full max-h-full flex flex-col min-h-0 relative", className),
2144
+ resize: "smooth",
2145
+ initial: "smooth",
2146
+ ...props,
2147
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2148
+ ScrollContent,
2149
+ {
2150
+ scrollToBottomButton,
2151
+ inputContainerHeight,
2152
+ isResizing,
2153
+ children
2154
+ }
2155
+ )
2156
+ }
2157
+ );
2158
+ };
2159
+ CopilotChatView2.ScrollToBottomButton = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2160
+ Button,
2161
+ {
2162
+ variant: "outline",
2163
+ size: "sm",
2164
+ className: (0, import_tailwind_merge7.twMerge)(
2165
+ "rounded-full w-10 h-10 p-0",
2166
+ "bg-white dark:bg-gray-900",
2167
+ "shadow-lg border border-gray-200 dark:border-gray-700",
2168
+ "hover:bg-gray-50 dark:hover:bg-gray-800",
2169
+ "flex items-center justify-center cursor-pointer",
2170
+ className
2171
+ ),
2172
+ ...props,
2173
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react5.ChevronDown, { className: "w-4 h-4 text-gray-600 dark:text-white" })
2174
+ }
2175
+ );
2176
+ CopilotChatView2.Feather = ({
2177
+ className,
2178
+ style,
2179
+ ...props
2180
+ }) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2181
+ "div",
2182
+ {
2183
+ className: cn(
2184
+ "absolute bottom-0 left-0 right-4 h-24 pointer-events-none z-10 bg-gradient-to-t",
2185
+ "from-white via-white to-transparent",
2186
+ "dark:from-[rgb(33,33,33)] dark:via-[rgb(33,33,33)]",
2187
+ className
2188
+ ),
2189
+ style,
2190
+ ...props
2191
+ }
2192
+ );
2193
+ CopilotChatView2.InputContainer = import_react15.default.forwardRef(({ children, className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2194
+ "div",
2195
+ {
2196
+ ref,
2197
+ className: cn("absolute bottom-0 left-0 right-0 z-20", className),
2198
+ ...props,
2199
+ children
2200
+ }
2201
+ ));
2202
+ CopilotChatView2.InputContainer.displayName = "CopilotChatView.InputContainer";
2203
+ CopilotChatView2.Disclaimer = ({
2204
+ className,
2205
+ ...props
2206
+ }) => {
2207
+ const { labels } = useCopilotChatConfiguration();
2208
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2209
+ "div",
2210
+ {
2211
+ className: cn(
2212
+ "text-center text-xs text-muted-foreground py-3 px-4 max-w-3xl mx-auto",
2213
+ className
2214
+ ),
2215
+ ...props,
2216
+ children: labels.chatDisclaimerText
2217
+ }
2218
+ );
2219
+ };
2220
+ })(CopilotChatView || (CopilotChatView = {}));
2221
+ var CopilotChatView_default = CopilotChatView;
2222
+
2223
+ // src/components/chat/CopilotChat.tsx
2224
+ var import_shared3 = require("@copilotkitnext/shared");
2225
+ var import_react16 = require("react");
2226
+ var import_ts_deepmerge = require("ts-deepmerge");
2227
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2228
+ function CopilotChat({
2229
+ agentId = import_shared3.DEFAULT_AGENT_ID,
2230
+ threadId,
2231
+ ...props
2232
+ }) {
2233
+ const { agent } = useAgent({ agentId });
2234
+ const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
2235
+ threadId = threadId ?? (0, import_react16.useMemo)(() => (0, import_shared3.randomUUID)(), []);
2236
+ const subscriber = {
2237
+ onTextMessageStartEvent: () => setIsLoading(false),
2238
+ onToolCallStartEvent: () => setIsLoading(false)
2239
+ };
2240
+ (0, import_react16.useEffect)(() => {
2241
+ const connect = async () => {
2242
+ setIsLoading(true);
2243
+ await agent?.runAgent(
2244
+ {
2245
+ forwardedProps: { __copilotkitConnect: true }
2246
+ },
2247
+ subscriber
2248
+ );
2249
+ setIsLoading(false);
2250
+ };
2251
+ if (agent) {
2252
+ agent.threadId = threadId;
2253
+ if ("isCopilotKitAgent" in agent) {
2254
+ connect();
2255
+ } else {
2256
+ setIsLoading(false);
2257
+ }
2258
+ }
2259
+ return () => {
2260
+ };
2261
+ }, [threadId, agent]);
2262
+ const [inputValue, setInputValue] = (0, import_react16.useState)("");
2263
+ const onSubmitInput = (0, import_react16.useCallback)(
2264
+ async (value) => {
2265
+ setInputValue("");
2266
+ agent?.addMessage({
2267
+ id: (0, import_shared3.randomUUID)(),
2268
+ role: "user",
2269
+ content: value
2270
+ });
2271
+ setIsLoading(true);
2272
+ await agent?.runAgent({}, subscriber);
2273
+ setIsLoading(false);
2274
+ },
2275
+ [agent]
2276
+ );
2277
+ const mergedProps = (0, import_ts_deepmerge.merge)(
2278
+ {
2279
+ messageView: { isLoading }
2280
+ },
2281
+ {
2282
+ ...props,
2283
+ ...typeof props.messageView === "string" ? { messageView: { className: props.messageView } } : props.messageView !== void 0 ? { messageView: props.messageView } : {}
2284
+ }
2285
+ );
2286
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2287
+ CopilotChatConfigurationProvider,
2288
+ {
2289
+ inputValue,
2290
+ onSubmitInput,
2291
+ onChangeInput: setInputValue,
2292
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2293
+ CopilotChatView,
2294
+ {
2295
+ ...{ messages: agent?.messages ?? [], ...mergedProps }
2296
+ }
2297
+ )
2298
+ }
2299
+ );
2300
+ }
2301
+ // Annotate the CommonJS export names for ESM import in node:
2302
+ 0 && (module.exports = {
2303
+ AudioRecorderError,
2304
+ CopilotChat,
2305
+ CopilotChatAssistantMessage,
2306
+ CopilotChatAudioRecorder,
2307
+ CopilotChatConfigurationProvider,
2308
+ CopilotChatInput,
2309
+ CopilotChatMessageView,
2310
+ CopilotChatToolCallsView,
2311
+ CopilotChatUserMessage,
2312
+ CopilotChatView,
2313
+ CopilotKitProvider,
2314
+ useAgent,
2315
+ useAgentContext,
2316
+ useCopilotChatConfiguration,
2317
+ useCopilotKit,
2318
+ useFrontendTool,
2319
+ useHumanInTheLoop,
2320
+ useRenderToolCall
2321
+ });
2322
+ //# sourceMappingURL=index.js.map