@yourgpt/copilot-sdk 0.1.0

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.
@@ -0,0 +1,4019 @@
1
+ import { useCopilot } from '../chunk-QUGTRQSS.js';
2
+ import '../chunk-N4OA2J32.js';
3
+ import { clsx } from 'clsx';
4
+ import { twMerge } from 'tailwind-merge';
5
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
6
+ import { marked } from 'marked';
7
+ import * as React8 from 'react';
8
+ import React8__default, { memo, createContext, useId, useMemo, useState, useEffect, useRef, useLayoutEffect, useCallback, useContext } from 'react';
9
+ import ReactMarkdown from 'react-markdown';
10
+ import remarkBreaks from 'remark-breaks';
11
+ import remarkGfm from 'remark-gfm';
12
+ import { codeToHtml } from 'shiki';
13
+ import { Slot } from '@radix-ui/react-slot';
14
+ import { cva } from 'class-variance-authority';
15
+ import { useStickToBottomContext, StickToBottom as StickToBottom$1 } from 'use-stick-to-bottom';
16
+ import { Tooltip as Tooltip$1 } from '@base-ui/react/tooltip';
17
+ import * as AvatarPrimitive from '@radix-ui/react-avatar';
18
+ import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
19
+
20
+ function cn(...inputs) {
21
+ return twMerge(clsx(inputs));
22
+ }
23
+ function CircularLoader({
24
+ className,
25
+ size = "md"
26
+ }) {
27
+ const sizeClasses = {
28
+ sm: "size-4",
29
+ md: "size-5",
30
+ lg: "size-6"
31
+ };
32
+ return /* @__PURE__ */ jsx(
33
+ "div",
34
+ {
35
+ className: cn(
36
+ "border-primary animate-spin rounded-full border-2 border-t-transparent",
37
+ sizeClasses[size],
38
+ className
39
+ ),
40
+ children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading" })
41
+ }
42
+ );
43
+ }
44
+ function ClassicLoader({
45
+ className,
46
+ size = "md"
47
+ }) {
48
+ const sizeClasses = {
49
+ sm: "size-4",
50
+ md: "size-5",
51
+ lg: "size-6"
52
+ };
53
+ const barSizes = {
54
+ sm: { height: "6px", width: "1.5px" },
55
+ md: { height: "8px", width: "2px" },
56
+ lg: { height: "10px", width: "2.5px" }
57
+ };
58
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative", sizeClasses[size], className), children: [
59
+ /* @__PURE__ */ jsx("div", { className: "absolute h-full w-full", children: [...Array(12)].map((_, i) => /* @__PURE__ */ jsx(
60
+ "div",
61
+ {
62
+ className: "bg-primary absolute animate-[spinner-fade_1.2s_linear_infinite] rounded-full",
63
+ style: {
64
+ top: "0",
65
+ left: "50%",
66
+ marginLeft: size === "sm" ? "-0.75px" : size === "lg" ? "-1.25px" : "-1px",
67
+ transformOrigin: `${size === "sm" ? "0.75px" : size === "lg" ? "1.25px" : "1px"} ${size === "sm" ? "10px" : size === "lg" ? "14px" : "12px"}`,
68
+ transform: `rotate(${i * 30}deg)`,
69
+ opacity: 0,
70
+ animationDelay: `${i * 0.1}s`,
71
+ height: barSizes[size].height,
72
+ width: barSizes[size].width
73
+ }
74
+ },
75
+ i
76
+ )) }),
77
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading" })
78
+ ] });
79
+ }
80
+ function PulseLoader({
81
+ className,
82
+ size = "md"
83
+ }) {
84
+ const sizeClasses = {
85
+ sm: "size-4",
86
+ md: "size-5",
87
+ lg: "size-6"
88
+ };
89
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative", sizeClasses[size], className), children: [
90
+ /* @__PURE__ */ jsx("div", { className: "border-primary absolute inset-0 animate-[thin-pulse_1.5s_ease-in-out_infinite] rounded-full border-2" }),
91
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading" })
92
+ ] });
93
+ }
94
+ function PulseDotLoader({
95
+ className,
96
+ size = "md"
97
+ }) {
98
+ const sizeClasses = {
99
+ sm: "size-1",
100
+ md: "size-2",
101
+ lg: "size-3"
102
+ };
103
+ return /* @__PURE__ */ jsx(
104
+ "div",
105
+ {
106
+ className: cn(
107
+ "bg-primary animate-[pulse-dot_1.2s_ease-in-out_infinite] rounded-full",
108
+ sizeClasses[size],
109
+ className
110
+ ),
111
+ children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading" })
112
+ }
113
+ );
114
+ }
115
+ function DotsLoader({
116
+ className,
117
+ size = "md"
118
+ }) {
119
+ const dotSizes = {
120
+ sm: "h-1.5 w-1.5",
121
+ md: "h-2 w-2",
122
+ lg: "h-2.5 w-2.5"
123
+ };
124
+ const containerSizes = {
125
+ sm: "h-4",
126
+ md: "h-5",
127
+ lg: "h-6"
128
+ };
129
+ return /* @__PURE__ */ jsxs(
130
+ "div",
131
+ {
132
+ className: cn(
133
+ "flex items-center space-x-1",
134
+ containerSizes[size],
135
+ className
136
+ ),
137
+ children: [
138
+ [...Array(3)].map((_, i) => /* @__PURE__ */ jsx(
139
+ "div",
140
+ {
141
+ className: cn(
142
+ "bg-primary animate-[bounce-dots_1.4s_ease-in-out_infinite] rounded-full",
143
+ dotSizes[size]
144
+ ),
145
+ style: {
146
+ animationDelay: `${i * 160}ms`
147
+ }
148
+ },
149
+ i
150
+ )),
151
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading" })
152
+ ]
153
+ }
154
+ );
155
+ }
156
+ function TypingLoader({
157
+ className,
158
+ size = "md"
159
+ }) {
160
+ const dotSizes = {
161
+ sm: "h-1 w-1",
162
+ md: "h-1.5 w-1.5",
163
+ lg: "h-2 w-2"
164
+ };
165
+ const containerSizes = {
166
+ sm: "h-4",
167
+ md: "h-5",
168
+ lg: "h-6"
169
+ };
170
+ return /* @__PURE__ */ jsxs(
171
+ "div",
172
+ {
173
+ className: cn(
174
+ "flex items-center space-x-1",
175
+ containerSizes[size],
176
+ className
177
+ ),
178
+ children: [
179
+ [...Array(3)].map((_, i) => /* @__PURE__ */ jsx(
180
+ "div",
181
+ {
182
+ className: cn(
183
+ "bg-primary animate-[typing_1s_infinite] rounded-full",
184
+ dotSizes[size]
185
+ ),
186
+ style: {
187
+ animationDelay: `${i * 250}ms`
188
+ }
189
+ },
190
+ i
191
+ )),
192
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading" })
193
+ ]
194
+ }
195
+ );
196
+ }
197
+ function WaveLoader({
198
+ className,
199
+ size = "md"
200
+ }) {
201
+ const barWidths = {
202
+ sm: "w-0.5",
203
+ md: "w-0.5",
204
+ lg: "w-1"
205
+ };
206
+ const containerSizes = {
207
+ sm: "h-4",
208
+ md: "h-5",
209
+ lg: "h-6"
210
+ };
211
+ const heights = {
212
+ sm: ["6px", "9px", "12px", "9px", "6px"],
213
+ md: ["8px", "12px", "16px", "12px", "8px"],
214
+ lg: ["10px", "15px", "20px", "15px", "10px"]
215
+ };
216
+ return /* @__PURE__ */ jsxs(
217
+ "div",
218
+ {
219
+ className: cn(
220
+ "flex items-center gap-0.5",
221
+ containerSizes[size],
222
+ className
223
+ ),
224
+ children: [
225
+ [...Array(5)].map((_, i) => /* @__PURE__ */ jsx(
226
+ "div",
227
+ {
228
+ className: cn(
229
+ "bg-primary animate-[wave_1s_ease-in-out_infinite] rounded-full",
230
+ barWidths[size]
231
+ ),
232
+ style: {
233
+ animationDelay: `${i * 100}ms`,
234
+ height: heights[size][i]
235
+ }
236
+ },
237
+ i
238
+ )),
239
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading" })
240
+ ]
241
+ }
242
+ );
243
+ }
244
+ function BarsLoader({
245
+ className,
246
+ size = "md"
247
+ }) {
248
+ const barWidths = {
249
+ sm: "w-1",
250
+ md: "w-1.5",
251
+ lg: "w-2"
252
+ };
253
+ const containerSizes = {
254
+ sm: "h-4 gap-1",
255
+ md: "h-5 gap-1.5",
256
+ lg: "h-6 gap-2"
257
+ };
258
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex", containerSizes[size], className), children: [
259
+ [...Array(3)].map((_, i) => /* @__PURE__ */ jsx(
260
+ "div",
261
+ {
262
+ className: cn(
263
+ "bg-primary h-full animate-[wave-bars_1.2s_ease-in-out_infinite]",
264
+ barWidths[size]
265
+ ),
266
+ style: {
267
+ animationDelay: `${i * 0.2}s`
268
+ }
269
+ },
270
+ i
271
+ )),
272
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading" })
273
+ ] });
274
+ }
275
+ function TerminalLoader({
276
+ className,
277
+ size = "md"
278
+ }) {
279
+ const cursorSizes = {
280
+ sm: "h-3 w-1.5",
281
+ md: "h-4 w-2",
282
+ lg: "h-5 w-2.5"
283
+ };
284
+ const textSizes = {
285
+ sm: "text-xs",
286
+ md: "text-sm",
287
+ lg: "text-base"
288
+ };
289
+ const containerSizes = {
290
+ sm: "h-4",
291
+ md: "h-5",
292
+ lg: "h-6"
293
+ };
294
+ return /* @__PURE__ */ jsxs(
295
+ "div",
296
+ {
297
+ className: cn(
298
+ "flex items-center space-x-1",
299
+ containerSizes[size],
300
+ className
301
+ ),
302
+ children: [
303
+ /* @__PURE__ */ jsx("span", { className: cn("text-primary font-mono", textSizes[size]), children: ">" }),
304
+ /* @__PURE__ */ jsx(
305
+ "div",
306
+ {
307
+ className: cn(
308
+ "bg-primary animate-[blink_1s_step-end_infinite]",
309
+ cursorSizes[size]
310
+ )
311
+ }
312
+ ),
313
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading" })
314
+ ]
315
+ }
316
+ );
317
+ }
318
+ function TextBlinkLoader({
319
+ text = "Thinking",
320
+ className,
321
+ size = "md"
322
+ }) {
323
+ const textSizes = {
324
+ sm: "text-xs",
325
+ md: "text-sm",
326
+ lg: "text-base"
327
+ };
328
+ return /* @__PURE__ */ jsx(
329
+ "div",
330
+ {
331
+ className: cn(
332
+ "animate-[text-blink_2s_ease-in-out_infinite] font-medium",
333
+ textSizes[size],
334
+ className
335
+ ),
336
+ children: text
337
+ }
338
+ );
339
+ }
340
+ function TextShimmerLoader({
341
+ text = "Thinking",
342
+ className,
343
+ size = "md"
344
+ }) {
345
+ const textSizes = {
346
+ sm: "text-xs",
347
+ md: "text-sm",
348
+ lg: "text-base"
349
+ };
350
+ return /* @__PURE__ */ jsx(
351
+ "div",
352
+ {
353
+ className: cn(
354
+ "bg-[linear-gradient(to_right,var(--muted-foreground)_40%,var(--foreground)_60%,var(--muted-foreground)_80%)]",
355
+ "bg-size-[200%_auto] bg-clip-text font-medium text-transparent",
356
+ "animate-[shimmer_4s_infinite_linear]",
357
+ textSizes[size],
358
+ className
359
+ ),
360
+ children: text
361
+ }
362
+ );
363
+ }
364
+ function TextDotsLoader({
365
+ className,
366
+ text = "Thinking",
367
+ size = "md"
368
+ }) {
369
+ const textSizes = {
370
+ sm: "text-xs",
371
+ md: "text-sm",
372
+ lg: "text-base"
373
+ };
374
+ return /* @__PURE__ */ jsxs("div", { className: cn("inline-flex items-center", className), children: [
375
+ /* @__PURE__ */ jsx("span", { className: cn("text-primary font-medium", textSizes[size]), children: text }),
376
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex", children: [
377
+ /* @__PURE__ */ jsx("span", { className: "text-primary animate-[loading-dots_1.4s_infinite_0.2s]", children: "." }),
378
+ /* @__PURE__ */ jsx("span", { className: "text-primary animate-[loading-dots_1.4s_infinite_0.4s]", children: "." }),
379
+ /* @__PURE__ */ jsx("span", { className: "text-primary animate-[loading-dots_1.4s_infinite_0.6s]", children: "." })
380
+ ] })
381
+ ] });
382
+ }
383
+ function Loader({
384
+ variant = "circular",
385
+ size = "md",
386
+ text,
387
+ className
388
+ }) {
389
+ switch (variant) {
390
+ case "circular":
391
+ return /* @__PURE__ */ jsx(CircularLoader, { size, className });
392
+ case "classic":
393
+ return /* @__PURE__ */ jsx(ClassicLoader, { size, className });
394
+ case "pulse":
395
+ return /* @__PURE__ */ jsx(PulseLoader, { size, className });
396
+ case "pulse-dot":
397
+ return /* @__PURE__ */ jsx(PulseDotLoader, { size, className });
398
+ case "dots":
399
+ return /* @__PURE__ */ jsx(DotsLoader, { size, className });
400
+ case "typing":
401
+ return /* @__PURE__ */ jsx(TypingLoader, { size, className });
402
+ case "wave":
403
+ return /* @__PURE__ */ jsx(WaveLoader, { size, className });
404
+ case "bars":
405
+ return /* @__PURE__ */ jsx(BarsLoader, { size, className });
406
+ case "terminal":
407
+ return /* @__PURE__ */ jsx(TerminalLoader, { size, className });
408
+ case "text-blink":
409
+ return /* @__PURE__ */ jsx(TextBlinkLoader, { text, size, className });
410
+ case "text-shimmer":
411
+ return /* @__PURE__ */ jsx(TextShimmerLoader, { text, size, className });
412
+ case "loading-dots":
413
+ return /* @__PURE__ */ jsx(TextDotsLoader, { text, size, className });
414
+ default:
415
+ return /* @__PURE__ */ jsx(CircularLoader, { size, className });
416
+ }
417
+ }
418
+ function CodeBlock({ children, className, ...props }) {
419
+ return /* @__PURE__ */ jsx(
420
+ "div",
421
+ {
422
+ className: cn(
423
+ "not-prose flex w-full flex-col overflow-clip border",
424
+ "border-border bg-card text-card-foreground rounded-xl",
425
+ className
426
+ ),
427
+ ...props,
428
+ children
429
+ }
430
+ );
431
+ }
432
+ function CodeBlockCode({
433
+ code,
434
+ language = "tsx",
435
+ theme = "github-light",
436
+ className,
437
+ ...props
438
+ }) {
439
+ const [highlightedHtml, setHighlightedHtml] = useState(null);
440
+ useEffect(() => {
441
+ async function highlight() {
442
+ if (!code) {
443
+ setHighlightedHtml("<pre><code></code></pre>");
444
+ return;
445
+ }
446
+ const html = await codeToHtml(code, { lang: language, theme });
447
+ setHighlightedHtml(html);
448
+ }
449
+ highlight();
450
+ }, [code, language, theme]);
451
+ const classNames = cn(
452
+ "w-full overflow-x-auto text-[13px] [&>pre]:px-4 [&>pre]:py-4",
453
+ className
454
+ );
455
+ return highlightedHtml ? /* @__PURE__ */ jsx(
456
+ "div",
457
+ {
458
+ className: classNames,
459
+ dangerouslySetInnerHTML: { __html: highlightedHtml },
460
+ ...props
461
+ }
462
+ ) : /* @__PURE__ */ jsx("div", { className: classNames, ...props, children: /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: code }) }) });
463
+ }
464
+ function parseMarkdownIntoBlocks(markdown) {
465
+ const tokens = marked.lexer(markdown);
466
+ return tokens.map((token) => token.raw);
467
+ }
468
+ function extractLanguage(className) {
469
+ if (!className) return "plaintext";
470
+ const match = className.match(/language-(\w+)/);
471
+ return match ? match[1] : "plaintext";
472
+ }
473
+ var INITIAL_COMPONENTS = {
474
+ code: function CodeComponent({ className, children, ...props }) {
475
+ const isInline = !props.node?.position?.start.line || props.node?.position?.start.line === props.node?.position?.end.line;
476
+ if (isInline) {
477
+ return /* @__PURE__ */ jsx(
478
+ "span",
479
+ {
480
+ className: cn(
481
+ "bg-primary-foreground rounded-sm px-1 font-mono text-sm",
482
+ className
483
+ ),
484
+ ...props,
485
+ children
486
+ }
487
+ );
488
+ }
489
+ const language = extractLanguage(className);
490
+ return /* @__PURE__ */ jsx(CodeBlock, { className, children: /* @__PURE__ */ jsx(CodeBlockCode, { code: children, language }) });
491
+ },
492
+ pre: function PreComponent({ children }) {
493
+ return /* @__PURE__ */ jsx(Fragment, { children });
494
+ }
495
+ };
496
+ var MemoizedMarkdownBlock = memo(
497
+ function MarkdownBlock({
498
+ content,
499
+ components = INITIAL_COMPONENTS
500
+ }) {
501
+ return /* @__PURE__ */ jsx(
502
+ ReactMarkdown,
503
+ {
504
+ remarkPlugins: [remarkGfm, remarkBreaks],
505
+ components,
506
+ children: content
507
+ }
508
+ );
509
+ },
510
+ function propsAreEqual(prevProps, nextProps) {
511
+ return prevProps.content === nextProps.content;
512
+ }
513
+ );
514
+ MemoizedMarkdownBlock.displayName = "MemoizedMarkdownBlock";
515
+ function MarkdownComponent({
516
+ children,
517
+ id,
518
+ className,
519
+ components = INITIAL_COMPONENTS
520
+ }) {
521
+ const generatedId = useId();
522
+ const blockId = id ?? generatedId;
523
+ const blocks = useMemo(() => parseMarkdownIntoBlocks(children), [children]);
524
+ return /* @__PURE__ */ jsx("div", { className, children: blocks.map((block, index) => /* @__PURE__ */ jsx(
525
+ MemoizedMarkdownBlock,
526
+ {
527
+ content: block,
528
+ components
529
+ },
530
+ `${blockId}-block-${index}`
531
+ )) });
532
+ }
533
+ var Markdown = memo(MarkdownComponent);
534
+ Markdown.displayName = "Markdown";
535
+ var buttonVariants = cva(
536
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
537
+ {
538
+ variants: {
539
+ variant: {
540
+ default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
541
+ destructive: "bg-destructive text-white shadow-sm hover:bg-destructive/90",
542
+ outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
543
+ secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
544
+ ghost: "hover:bg-accent hover:text-accent-foreground",
545
+ link: "text-primary underline-offset-4 hover:underline"
546
+ },
547
+ size: {
548
+ default: "h-9 px-4 py-2",
549
+ sm: "h-8 rounded-md px-3 text-xs",
550
+ lg: "h-10 rounded-md px-8",
551
+ icon: "h-9 w-9"
552
+ }
553
+ },
554
+ defaultVariants: {
555
+ variant: "default",
556
+ size: "default"
557
+ }
558
+ }
559
+ );
560
+ var Button = React8.forwardRef(
561
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
562
+ const Comp = asChild ? Slot : "button";
563
+ return /* @__PURE__ */ jsx(
564
+ Comp,
565
+ {
566
+ className: cn(buttonVariants({ variant, size, className })),
567
+ ref,
568
+ ...props
569
+ }
570
+ );
571
+ }
572
+ );
573
+ Button.displayName = "Button";
574
+ function ThumbsUpIcon({ className }) {
575
+ return /* @__PURE__ */ jsxs(
576
+ "svg",
577
+ {
578
+ xmlns: "http://www.w3.org/2000/svg",
579
+ viewBox: "0 0 24 24",
580
+ fill: "none",
581
+ stroke: "currentColor",
582
+ strokeWidth: "2",
583
+ strokeLinecap: "round",
584
+ strokeLinejoin: "round",
585
+ className,
586
+ children: [
587
+ /* @__PURE__ */ jsx("path", { d: "M7 10v12" }),
588
+ /* @__PURE__ */ jsx("path", { d: "M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z" })
589
+ ]
590
+ }
591
+ );
592
+ }
593
+ function ThumbsDownIcon({ className }) {
594
+ return /* @__PURE__ */ jsxs(
595
+ "svg",
596
+ {
597
+ xmlns: "http://www.w3.org/2000/svg",
598
+ viewBox: "0 0 24 24",
599
+ fill: "none",
600
+ stroke: "currentColor",
601
+ strokeWidth: "2",
602
+ strokeLinecap: "round",
603
+ strokeLinejoin: "round",
604
+ className,
605
+ children: [
606
+ /* @__PURE__ */ jsx("path", { d: "M17 14V2" }),
607
+ /* @__PURE__ */ jsx("path", { d: "M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z" })
608
+ ]
609
+ }
610
+ );
611
+ }
612
+ function XIcon({ className }) {
613
+ return /* @__PURE__ */ jsxs(
614
+ "svg",
615
+ {
616
+ xmlns: "http://www.w3.org/2000/svg",
617
+ viewBox: "0 0 24 24",
618
+ fill: "none",
619
+ stroke: "currentColor",
620
+ strokeWidth: "2",
621
+ strokeLinecap: "round",
622
+ strokeLinejoin: "round",
623
+ className,
624
+ children: [
625
+ /* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
626
+ /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
627
+ ]
628
+ }
629
+ );
630
+ }
631
+ function FeedbackBar({
632
+ className,
633
+ title,
634
+ icon,
635
+ onHelpful,
636
+ onNotHelpful,
637
+ onClose
638
+ }) {
639
+ return /* @__PURE__ */ jsx(
640
+ "div",
641
+ {
642
+ className: cn(
643
+ "bg-background border-border inline-flex rounded-[12px] border text-sm",
644
+ className
645
+ ),
646
+ children: /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center justify-between", children: [
647
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 items-center justify-start gap-4 py-3 pl-4", children: [
648
+ icon,
649
+ /* @__PURE__ */ jsx("span", { className: "text-foreground font-medium", children: title })
650
+ ] }),
651
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-0.5 px-3 py-0", children: [
652
+ /* @__PURE__ */ jsx(
653
+ "button",
654
+ {
655
+ type: "button",
656
+ className: "text-muted-foreground hover:text-foreground flex size-8 items-center justify-center rounded-md transition-colors",
657
+ "aria-label": "Helpful",
658
+ onClick: onHelpful,
659
+ children: /* @__PURE__ */ jsx(ThumbsUpIcon, { className: "size-4" })
660
+ }
661
+ ),
662
+ /* @__PURE__ */ jsx(
663
+ "button",
664
+ {
665
+ type: "button",
666
+ className: "text-muted-foreground hover:text-foreground flex size-8 items-center justify-center rounded-md transition-colors",
667
+ "aria-label": "Not helpful",
668
+ onClick: onNotHelpful,
669
+ children: /* @__PURE__ */ jsx(ThumbsDownIcon, { className: "size-4" })
670
+ }
671
+ )
672
+ ] }),
673
+ /* @__PURE__ */ jsx("div", { className: "border-border flex items-center justify-center border-l", children: /* @__PURE__ */ jsx(
674
+ "button",
675
+ {
676
+ type: "button",
677
+ onClick: onClose,
678
+ className: "text-muted-foreground hover:text-foreground flex items-center justify-center rounded-md p-3",
679
+ "aria-label": "Close",
680
+ children: /* @__PURE__ */ jsx(XIcon, { className: "size-5" })
681
+ }
682
+ ) })
683
+ ] })
684
+ }
685
+ );
686
+ }
687
+ var StickToBottom = StickToBottom$1;
688
+ function useChatContainer() {
689
+ const context = useStickToBottomContext();
690
+ return {
691
+ isAtBottom: context.isAtBottom,
692
+ scrollToBottom: context.scrollToBottom
693
+ };
694
+ }
695
+ function ChatContainerRoot({
696
+ children,
697
+ className,
698
+ ...props
699
+ }) {
700
+ return /* @__PURE__ */ jsx(
701
+ StickToBottom,
702
+ {
703
+ className: cn("flex overflow-y-auto", className),
704
+ resize: "smooth",
705
+ initial: "instant",
706
+ role: "log",
707
+ ...props,
708
+ children
709
+ }
710
+ );
711
+ }
712
+ function ChatContainerContent({
713
+ children,
714
+ className,
715
+ ...props
716
+ }) {
717
+ return /* @__PURE__ */ jsx(
718
+ StickToBottom.Content,
719
+ {
720
+ className: cn("flex w-full flex-col", className),
721
+ ...props,
722
+ children
723
+ }
724
+ );
725
+ }
726
+ function ChatContainerScrollAnchor({
727
+ className,
728
+ ...props
729
+ }) {
730
+ return /* @__PURE__ */ jsx(
731
+ "div",
732
+ {
733
+ className: cn("h-px w-full shrink-0 scroll-mt-4", className),
734
+ "aria-hidden": "true",
735
+ ...props
736
+ }
737
+ );
738
+ }
739
+ function ChevronDownIcon({ className }) {
740
+ return /* @__PURE__ */ jsx(
741
+ "svg",
742
+ {
743
+ xmlns: "http://www.w3.org/2000/svg",
744
+ viewBox: "0 0 24 24",
745
+ fill: "none",
746
+ stroke: "currentColor",
747
+ strokeWidth: "2",
748
+ strokeLinecap: "round",
749
+ strokeLinejoin: "round",
750
+ className,
751
+ children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })
752
+ }
753
+ );
754
+ }
755
+ function ScrollButton({
756
+ className,
757
+ variant = "outline",
758
+ size = "sm",
759
+ ...props
760
+ }) {
761
+ const { isAtBottom, scrollToBottom } = useChatContainer();
762
+ return /* @__PURE__ */ jsx(
763
+ Button,
764
+ {
765
+ variant,
766
+ size,
767
+ className: cn(
768
+ "h-10 w-10 rounded-full transition-all duration-150 ease-out",
769
+ !isAtBottom ? "translate-y-0 scale-100 opacity-100" : "pointer-events-none translate-y-4 scale-95 opacity-0",
770
+ className
771
+ ),
772
+ onClick: () => scrollToBottom(),
773
+ ...props,
774
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-5 w-5" })
775
+ }
776
+ );
777
+ }
778
+ function TooltipProvider({
779
+ children,
780
+ delayDuration = 300
781
+ }) {
782
+ return /* @__PURE__ */ jsx(Tooltip$1.Provider, { delay: delayDuration, children });
783
+ }
784
+ function Tooltip({ children, open, defaultOpen, onOpenChange }) {
785
+ return /* @__PURE__ */ jsx(
786
+ Tooltip$1.Root,
787
+ {
788
+ open,
789
+ defaultOpen,
790
+ onOpenChange,
791
+ children
792
+ }
793
+ );
794
+ }
795
+ function TooltipTrigger({
796
+ children,
797
+ asChild,
798
+ disabled,
799
+ ...props
800
+ }) {
801
+ if (asChild && React8__default.isValidElement(children)) {
802
+ return /* @__PURE__ */ jsx(Tooltip$1.Trigger, { disabled, render: children, ...props });
803
+ }
804
+ return /* @__PURE__ */ jsx(Tooltip$1.Trigger, { disabled, ...props, children });
805
+ }
806
+ function TooltipContent({
807
+ children,
808
+ className,
809
+ side = "top",
810
+ align = "center",
811
+ sideOffset = 8,
812
+ showArrow = true
813
+ }) {
814
+ return /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsx(Tooltip$1.Positioner, { side, align, sideOffset, children: /* @__PURE__ */ jsxs(
815
+ Tooltip$1.Popup,
816
+ {
817
+ className: cn(
818
+ "z-50 rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground shadow-md",
819
+ "animate-in fade-in-0 zoom-in-95",
820
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
821
+ className
822
+ ),
823
+ children: [
824
+ children,
825
+ showArrow && /* @__PURE__ */ jsx(Tooltip$1.Arrow, { className: "fill-primary" })
826
+ ]
827
+ }
828
+ ) }) });
829
+ }
830
+ var Avatar = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
831
+ AvatarPrimitive.Root,
832
+ {
833
+ ref,
834
+ className: cn(
835
+ "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
836
+ className
837
+ ),
838
+ ...props
839
+ }
840
+ ));
841
+ Avatar.displayName = AvatarPrimitive.Root.displayName;
842
+ var AvatarImage = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
843
+ AvatarPrimitive.Image,
844
+ {
845
+ ref,
846
+ className: cn("aspect-square h-full w-full", className),
847
+ ...props
848
+ }
849
+ ));
850
+ AvatarImage.displayName = AvatarPrimitive.Image.displayName;
851
+ var AvatarFallback = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
852
+ AvatarPrimitive.Fallback,
853
+ {
854
+ ref,
855
+ className: cn(
856
+ "flex h-full w-full items-center justify-center rounded-full bg-muted",
857
+ className
858
+ ),
859
+ ...props
860
+ }
861
+ ));
862
+ AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
863
+ var Message = ({ children, className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("flex gap-3", className), ...props, children });
864
+ var MessageAvatar = ({
865
+ src,
866
+ alt,
867
+ fallback,
868
+ delayMs,
869
+ className
870
+ }) => {
871
+ return /* @__PURE__ */ jsxs(Avatar, { className: cn("size-7 shrink-0", className), children: [
872
+ /* @__PURE__ */ jsx(AvatarImage, { src, alt }),
873
+ fallback && /* @__PURE__ */ jsx(AvatarFallback, { delayMs, children: fallback })
874
+ ] });
875
+ };
876
+ var proseSizeMap = {
877
+ sm: "prose-sm",
878
+ base: "prose-base",
879
+ lg: "prose-lg"
880
+ };
881
+ var MessageContent = ({
882
+ children,
883
+ markdown = false,
884
+ className,
885
+ size = "sm",
886
+ ...props
887
+ }) => {
888
+ const classNames = cn(
889
+ "rounded-lg p-2 bg-secondary prose break-words whitespace-normal max-w-none",
890
+ "text-foreground prose-headings:text-foreground prose-p:text-foreground prose-strong:text-foreground prose-li:text-foreground prose-a:text-foreground prose-ol:text-foreground prose-ul:text-foreground prose-code:text-foreground",
891
+ proseSizeMap[size],
892
+ className
893
+ );
894
+ return markdown ? /* @__PURE__ */ jsx(Markdown, { className: classNames, ...props, children }) : /* @__PURE__ */ jsx("div", { className: classNames, ...props, children });
895
+ };
896
+ var Textarea = React8.forwardRef(({ className, ...props }, ref) => {
897
+ return /* @__PURE__ */ jsx(
898
+ "textarea",
899
+ {
900
+ className: cn(
901
+ "flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
902
+ className
903
+ ),
904
+ ref,
905
+ ...props
906
+ }
907
+ );
908
+ });
909
+ Textarea.displayName = "Textarea";
910
+ var PromptInputContext = createContext({
911
+ isLoading: false,
912
+ value: "",
913
+ setValue: () => {
914
+ },
915
+ maxHeight: 240,
916
+ onSubmit: void 0,
917
+ disabled: false,
918
+ textareaRef: { current: null }
919
+ });
920
+ function usePromptInput() {
921
+ return useContext(PromptInputContext);
922
+ }
923
+ function PromptInput({
924
+ className,
925
+ isLoading = false,
926
+ maxHeight = 240,
927
+ value,
928
+ onValueChange,
929
+ onSubmit,
930
+ children,
931
+ disabled = false,
932
+ onClick,
933
+ ...props
934
+ }) {
935
+ const [internalValue, setInternalValue] = useState(value || "");
936
+ const textareaRef = useRef(null);
937
+ const handleChange = (newValue) => {
938
+ setInternalValue(newValue);
939
+ onValueChange?.(newValue);
940
+ };
941
+ const handleClick = (e) => {
942
+ if (!disabled) textareaRef.current?.focus();
943
+ onClick?.(e);
944
+ };
945
+ return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(
946
+ PromptInputContext.Provider,
947
+ {
948
+ value: {
949
+ isLoading,
950
+ value: value ?? internalValue,
951
+ setValue: onValueChange ?? handleChange,
952
+ maxHeight,
953
+ onSubmit,
954
+ disabled,
955
+ textareaRef
956
+ },
957
+ children: /* @__PURE__ */ jsx(
958
+ "div",
959
+ {
960
+ onClick: handleClick,
961
+ className: cn(
962
+ "border-input bg-background cursor-text rounded-3xl border p-2 shadow-xs",
963
+ disabled && "cursor-not-allowed opacity-60",
964
+ className
965
+ ),
966
+ ...props,
967
+ children
968
+ }
969
+ )
970
+ }
971
+ ) });
972
+ }
973
+ function PromptInputTextarea({
974
+ className,
975
+ onKeyDown,
976
+ disableAutosize = false,
977
+ ...props
978
+ }) {
979
+ const { value, setValue, maxHeight, onSubmit, disabled, textareaRef } = usePromptInput();
980
+ const adjustHeight = (el) => {
981
+ if (!el || disableAutosize) return;
982
+ el.style.height = "auto";
983
+ if (typeof maxHeight === "number") {
984
+ el.style.height = `${Math.min(el.scrollHeight, maxHeight)}px`;
985
+ } else {
986
+ el.style.height = `min(${el.scrollHeight}px, ${maxHeight})`;
987
+ }
988
+ };
989
+ const handleRef = (el) => {
990
+ textareaRef.current = el;
991
+ adjustHeight(el);
992
+ };
993
+ useLayoutEffect(() => {
994
+ if (!textareaRef.current || disableAutosize) return;
995
+ const el = textareaRef.current;
996
+ el.style.height = "auto";
997
+ if (typeof maxHeight === "number") {
998
+ el.style.height = `${Math.min(el.scrollHeight, maxHeight)}px`;
999
+ } else {
1000
+ el.style.height = `min(${el.scrollHeight}px, ${maxHeight})`;
1001
+ }
1002
+ }, [value, maxHeight, disableAutosize]);
1003
+ const handleChange = (e) => {
1004
+ adjustHeight(e.target);
1005
+ setValue(e.target.value);
1006
+ };
1007
+ const handleKeyDown = (e) => {
1008
+ if (e.key === "Enter" && !e.shiftKey) {
1009
+ e.preventDefault();
1010
+ onSubmit?.();
1011
+ }
1012
+ onKeyDown?.(e);
1013
+ };
1014
+ return /* @__PURE__ */ jsx(
1015
+ Textarea,
1016
+ {
1017
+ ref: handleRef,
1018
+ value,
1019
+ onChange: handleChange,
1020
+ onKeyDown: handleKeyDown,
1021
+ className: cn(
1022
+ "text-foreground min-h-[44px] w-full resize-none border-none bg-transparent shadow-none outline-none focus-visible:ring-0 focus-visible:ring-offset-0",
1023
+ className
1024
+ ),
1025
+ rows: 1,
1026
+ disabled,
1027
+ ...props
1028
+ }
1029
+ );
1030
+ }
1031
+ function PromptInputActions({
1032
+ children,
1033
+ className,
1034
+ ...props
1035
+ }) {
1036
+ return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-2", className), ...props, children });
1037
+ }
1038
+ function PromptInputAction({
1039
+ tooltip,
1040
+ children,
1041
+ className,
1042
+ side = "top"
1043
+ }) {
1044
+ const { disabled } = usePromptInput();
1045
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
1046
+ /* @__PURE__ */ jsx(
1047
+ TooltipTrigger,
1048
+ {
1049
+ asChild: true,
1050
+ disabled,
1051
+ onClick: (e) => e.stopPropagation(),
1052
+ children
1053
+ }
1054
+ ),
1055
+ /* @__PURE__ */ jsx(TooltipContent, { side, className, showArrow: true, children: tooltip })
1056
+ ] });
1057
+ }
1058
+ var HoverCard = HoverCardPrimitive.Root;
1059
+ var HoverCardTrigger = HoverCardPrimitive.Trigger;
1060
+ var HoverCardContent = React8.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
1061
+ HoverCardPrimitive.Content,
1062
+ {
1063
+ ref,
1064
+ align,
1065
+ sideOffset,
1066
+ className: cn(
1067
+ "z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none 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 origin-[--radix-hover-card-content-transform-origin]",
1068
+ className
1069
+ ),
1070
+ ...props
1071
+ }
1072
+ ));
1073
+ HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
1074
+ var SourceContext = createContext(null);
1075
+ function useSourceContext() {
1076
+ const ctx = useContext(SourceContext);
1077
+ if (!ctx) throw new Error("Source.* must be used inside <Source>");
1078
+ return ctx;
1079
+ }
1080
+ function Source({ href, children }) {
1081
+ let domain = "";
1082
+ try {
1083
+ domain = new URL(href).hostname;
1084
+ } catch {
1085
+ domain = href.split("/").pop() || href;
1086
+ }
1087
+ return /* @__PURE__ */ jsx(SourceContext.Provider, { value: { href, domain }, children: /* @__PURE__ */ jsx(HoverCard, { openDelay: 150, closeDelay: 0, children }) });
1088
+ }
1089
+ function SourceTrigger({
1090
+ label,
1091
+ showFavicon = false,
1092
+ className
1093
+ }) {
1094
+ const { href, domain } = useSourceContext();
1095
+ const labelToShow = label ?? domain.replace("www.", "");
1096
+ return /* @__PURE__ */ jsx(HoverCardTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1097
+ "a",
1098
+ {
1099
+ href,
1100
+ target: "_blank",
1101
+ rel: "noopener noreferrer",
1102
+ className: cn(
1103
+ "bg-muted text-muted-foreground hover:bg-muted-foreground/30 hover:text-primary inline-flex h-5 max-w-32 items-center gap-1 overflow-hidden rounded-full py-0 text-xs no-underline transition-colors duration-150",
1104
+ showFavicon ? "pr-2 pl-1" : "px-1",
1105
+ className
1106
+ ),
1107
+ children: [
1108
+ showFavicon && /* @__PURE__ */ jsx(
1109
+ "img",
1110
+ {
1111
+ src: `https://www.google.com/s2/favicons?sz=64&domain_url=${encodeURIComponent(
1112
+ href
1113
+ )}`,
1114
+ alt: "favicon",
1115
+ width: 14,
1116
+ height: 14,
1117
+ className: "size-3.5 rounded-full"
1118
+ }
1119
+ ),
1120
+ /* @__PURE__ */ jsx("span", { className: "truncate tabular-nums text-center font-normal", children: labelToShow })
1121
+ ]
1122
+ }
1123
+ ) });
1124
+ }
1125
+ function SourceContent({
1126
+ title,
1127
+ description,
1128
+ className
1129
+ }) {
1130
+ const { href, domain } = useSourceContext();
1131
+ return /* @__PURE__ */ jsx(HoverCardContent, { className: cn("w-80 p-0 shadow-xs", className), children: /* @__PURE__ */ jsxs(
1132
+ "a",
1133
+ {
1134
+ href,
1135
+ target: "_blank",
1136
+ rel: "noopener noreferrer",
1137
+ className: "flex flex-col gap-2 p-3",
1138
+ children: [
1139
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
1140
+ /* @__PURE__ */ jsx(
1141
+ "img",
1142
+ {
1143
+ src: `https://www.google.com/s2/favicons?sz=64&domain_url=${encodeURIComponent(
1144
+ href
1145
+ )}`,
1146
+ alt: "favicon",
1147
+ className: "size-4 rounded-full",
1148
+ width: 16,
1149
+ height: 16
1150
+ }
1151
+ ),
1152
+ /* @__PURE__ */ jsx("div", { className: "text-primary truncate text-sm", children: domain.replace("www.", "") })
1153
+ ] }),
1154
+ /* @__PURE__ */ jsx("div", { className: "line-clamp-2 text-sm font-medium", children: title }),
1155
+ /* @__PURE__ */ jsx("div", { className: "text-muted-foreground line-clamp-2 text-sm", children: description })
1156
+ ]
1157
+ }
1158
+ ) });
1159
+ }
1160
+ var ReasoningContext = React8.createContext(
1161
+ null
1162
+ );
1163
+ function useReasoningContext() {
1164
+ const context = React8.useContext(ReasoningContext);
1165
+ if (!context) {
1166
+ throw new Error(
1167
+ "Reasoning components must be used within a Reasoning provider"
1168
+ );
1169
+ }
1170
+ return context;
1171
+ }
1172
+ function Reasoning({
1173
+ children,
1174
+ isStreaming = false,
1175
+ open: controlledOpen,
1176
+ onOpenChange,
1177
+ defaultOpen = false,
1178
+ className
1179
+ }) {
1180
+ const [uncontrolledOpen, setUncontrolledOpen] = React8.useState(defaultOpen);
1181
+ const prevStreamingRef = React8.useRef(isStreaming);
1182
+ const isControlled = controlledOpen !== void 0;
1183
+ const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
1184
+ const setIsOpen = React8.useCallback(
1185
+ (open) => {
1186
+ if (onOpenChange) {
1187
+ onOpenChange(open);
1188
+ }
1189
+ if (!isControlled) {
1190
+ setUncontrolledOpen(open);
1191
+ }
1192
+ },
1193
+ [isControlled, onOpenChange]
1194
+ );
1195
+ React8.useEffect(() => {
1196
+ if (isStreaming && !prevStreamingRef.current) {
1197
+ setIsOpen(true);
1198
+ } else if (!isStreaming && prevStreamingRef.current) {
1199
+ setIsOpen(false);
1200
+ }
1201
+ prevStreamingRef.current = isStreaming;
1202
+ }, [isStreaming, setIsOpen]);
1203
+ return /* @__PURE__ */ jsx(ReasoningContext.Provider, { value: { isOpen, setIsOpen, isStreaming }, children: /* @__PURE__ */ jsx("div", { className: cn("reasoning", className), children }) });
1204
+ }
1205
+ function ReasoningTrigger({
1206
+ children,
1207
+ className
1208
+ }) {
1209
+ const { isOpen, setIsOpen, isStreaming } = useReasoningContext();
1210
+ return /* @__PURE__ */ jsxs(
1211
+ "button",
1212
+ {
1213
+ type: "button",
1214
+ onClick: () => setIsOpen(!isOpen),
1215
+ className: cn(
1216
+ "flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors",
1217
+ "py-1 px-0 bg-transparent border-none cursor-pointer",
1218
+ className
1219
+ ),
1220
+ "aria-expanded": isOpen,
1221
+ children: [
1222
+ /* @__PURE__ */ jsx(
1223
+ "svg",
1224
+ {
1225
+ className: cn(
1226
+ "size-3 transition-transform duration-200",
1227
+ isOpen && "rotate-90"
1228
+ ),
1229
+ fill: "none",
1230
+ viewBox: "0 0 24 24",
1231
+ stroke: "currentColor",
1232
+ strokeWidth: 2,
1233
+ children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" })
1234
+ }
1235
+ ),
1236
+ isStreaming && /* @__PURE__ */ jsxs("span", { className: "relative flex h-2 w-2", children: [
1237
+ /* @__PURE__ */ jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75" }),
1238
+ /* @__PURE__ */ jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-primary" })
1239
+ ] }),
1240
+ children
1241
+ ]
1242
+ }
1243
+ );
1244
+ }
1245
+ function ReasoningContent({
1246
+ children,
1247
+ markdown = false,
1248
+ className
1249
+ }) {
1250
+ const { isOpen } = useReasoningContext();
1251
+ const contentRef = React8.useRef(null);
1252
+ const [height, setHeight] = React8.useState(0);
1253
+ React8.useEffect(() => {
1254
+ if (contentRef.current) {
1255
+ const resizeObserver = new ResizeObserver((entries) => {
1256
+ for (const entry of entries) {
1257
+ setHeight(entry.contentRect.height);
1258
+ }
1259
+ });
1260
+ resizeObserver.observe(contentRef.current);
1261
+ return () => resizeObserver.disconnect();
1262
+ }
1263
+ }, []);
1264
+ return /* @__PURE__ */ jsx(
1265
+ "div",
1266
+ {
1267
+ className: cn(
1268
+ "overflow-hidden transition-[max-height] duration-200 ease-out",
1269
+ isOpen ? "opacity-100" : "opacity-0"
1270
+ ),
1271
+ style: { maxHeight: isOpen ? height : 0 },
1272
+ "aria-hidden": !isOpen,
1273
+ children: /* @__PURE__ */ jsx(
1274
+ "div",
1275
+ {
1276
+ ref: contentRef,
1277
+ className: cn(
1278
+ "mt-1 pl-3 border-l-2 border-muted-foreground/20",
1279
+ "text-xs text-muted-foreground",
1280
+ className
1281
+ ),
1282
+ children: markdown && typeof children === "string" ? /* @__PURE__ */ jsx(Markdown, { className: "prose-xs", children }) : /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap", children })
1283
+ }
1284
+ )
1285
+ }
1286
+ );
1287
+ }
1288
+ function SimpleReasoning({
1289
+ content,
1290
+ isStreaming = false,
1291
+ streamingLabel = "Thinking...",
1292
+ collapsedLabel = "View reasoning",
1293
+ markdown = true,
1294
+ className
1295
+ }) {
1296
+ if (!content) return null;
1297
+ return /* @__PURE__ */ jsxs(Reasoning, { isStreaming, className, children: [
1298
+ /* @__PURE__ */ jsx(ReasoningTrigger, { children: isStreaming ? streamingLabel : collapsedLabel }),
1299
+ /* @__PURE__ */ jsx(ReasoningContent, { markdown, children: content })
1300
+ ] });
1301
+ }
1302
+ var CopilotUIContext = React8.createContext(
1303
+ null
1304
+ );
1305
+ function useCopilotUI() {
1306
+ const context = React8.useContext(CopilotUIContext);
1307
+ if (!context) {
1308
+ return {
1309
+ debug: false,
1310
+ defaultDebugExpanded: false,
1311
+ isDebug: false
1312
+ };
1313
+ }
1314
+ return context;
1315
+ }
1316
+ function CopilotUIProvider({
1317
+ children,
1318
+ debug = false,
1319
+ defaultDebugExpanded = false
1320
+ }) {
1321
+ const value = React8.useMemo(
1322
+ () => ({
1323
+ debug,
1324
+ defaultDebugExpanded,
1325
+ isDebug: debug
1326
+ }),
1327
+ [debug, defaultDebugExpanded]
1328
+ );
1329
+ return /* @__PURE__ */ jsx(CopilotUIContext.Provider, { value, children });
1330
+ }
1331
+ function toolNameToTitle(name) {
1332
+ let result = name.replace(/_/g, " ");
1333
+ result = result.replace(/([a-z])([A-Z])/g, "$1 $2");
1334
+ return result.charAt(0).toUpperCase() + result.slice(1).toLowerCase();
1335
+ }
1336
+ function getDisplayTitle(step) {
1337
+ const fallbackTitle = toolNameToTitle(step.name);
1338
+ switch (step.status) {
1339
+ case "pending":
1340
+ return step.title ?? fallbackTitle;
1341
+ case "executing":
1342
+ if (step.executingTitle) return step.executingTitle;
1343
+ return step.title ? `${step.title}...` : `${fallbackTitle}...`;
1344
+ case "completed":
1345
+ return step.completedTitle ?? step.title ?? fallbackTitle;
1346
+ case "error":
1347
+ case "failed":
1348
+ case "rejected":
1349
+ return step.title ?? fallbackTitle;
1350
+ default:
1351
+ return fallbackTitle;
1352
+ }
1353
+ }
1354
+ function StatusIndicator({ status, className }) {
1355
+ const baseClasses = "flex-shrink-0";
1356
+ switch (status) {
1357
+ case "pending":
1358
+ return /* @__PURE__ */ jsx(
1359
+ "div",
1360
+ {
1361
+ className: cn(
1362
+ baseClasses,
1363
+ "size-3 flex items-center justify-center",
1364
+ className
1365
+ ),
1366
+ children: /* @__PURE__ */ jsx("div", { className: "size-1.5 rounded-full bg-muted-foreground/40" })
1367
+ }
1368
+ );
1369
+ case "executing":
1370
+ return null;
1371
+ case "completed":
1372
+ return /* @__PURE__ */ jsx(
1373
+ "div",
1374
+ {
1375
+ className: cn(
1376
+ baseClasses,
1377
+ "size-3 flex items-center justify-center",
1378
+ className
1379
+ ),
1380
+ children: /* @__PURE__ */ jsx(
1381
+ "svg",
1382
+ {
1383
+ className: "size-3 text-green-500",
1384
+ fill: "none",
1385
+ viewBox: "0 0 24 24",
1386
+ stroke: "currentColor",
1387
+ strokeWidth: 3,
1388
+ children: /* @__PURE__ */ jsx(
1389
+ "path",
1390
+ {
1391
+ strokeLinecap: "round",
1392
+ strokeLinejoin: "round",
1393
+ d: "M5 13l4 4L19 7"
1394
+ }
1395
+ )
1396
+ }
1397
+ )
1398
+ }
1399
+ );
1400
+ case "error":
1401
+ case "failed":
1402
+ case "rejected":
1403
+ return /* @__PURE__ */ jsx(
1404
+ "div",
1405
+ {
1406
+ className: cn(
1407
+ baseClasses,
1408
+ "size-3 flex items-center justify-center",
1409
+ className
1410
+ ),
1411
+ children: /* @__PURE__ */ jsx(
1412
+ "svg",
1413
+ {
1414
+ className: "size-3 text-red-500",
1415
+ fill: "none",
1416
+ viewBox: "0 0 24 24",
1417
+ stroke: "currentColor",
1418
+ strokeWidth: 3,
1419
+ children: /* @__PURE__ */ jsx(
1420
+ "path",
1421
+ {
1422
+ strokeLinecap: "round",
1423
+ strokeLinejoin: "round",
1424
+ d: "M6 18L18 6M6 6l12 12"
1425
+ }
1426
+ )
1427
+ }
1428
+ )
1429
+ }
1430
+ );
1431
+ }
1432
+ }
1433
+ function formatResult(result) {
1434
+ if (!result) return "";
1435
+ if (result.message) return result.message;
1436
+ if (result.error) return result.error;
1437
+ if (result.data) {
1438
+ const data = result.data;
1439
+ if (data.image && typeof data.image === "string" && data.image.startsWith("data:image")) {
1440
+ return `Image (${data.width || "?"}x${data.height || "?"})`;
1441
+ }
1442
+ return JSON.stringify(result.data);
1443
+ }
1444
+ return result.success ? "Success" : "Failed";
1445
+ }
1446
+ function getResultImage(result) {
1447
+ if (!result?.data) return null;
1448
+ const data = result.data;
1449
+ if (data.image && typeof data.image === "string" && data.image.startsWith("data:image")) {
1450
+ return data.image;
1451
+ }
1452
+ return null;
1453
+ }
1454
+ function ToolStep({
1455
+ step,
1456
+ showLine = false,
1457
+ debug: debugProp,
1458
+ defaultExpanded,
1459
+ className
1460
+ }) {
1461
+ const { isDebug, defaultDebugExpanded } = useCopilotUI();
1462
+ const debug = debugProp ?? isDebug;
1463
+ const [expanded, setExpanded] = React8.useState(
1464
+ defaultExpanded ?? defaultDebugExpanded ?? false
1465
+ );
1466
+ const displayTitle = getDisplayTitle(step);
1467
+ const hasDebugContent = step.args && Object.keys(step.args).length > 0 || step.result;
1468
+ const isExecuting = step.status === "executing";
1469
+ const isCompleted = step.status === "completed";
1470
+ const isError = step.status === "error" || step.status === "failed" || step.status === "rejected";
1471
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
1472
+ showLine && /* @__PURE__ */ jsx(
1473
+ "div",
1474
+ {
1475
+ className: "absolute left-[5px] top-4 bottom-0 w-px bg-border",
1476
+ "aria-hidden": "true"
1477
+ }
1478
+ ),
1479
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
1480
+ !isExecuting && /* @__PURE__ */ jsx(StatusIndicator, { status: step.status, className: "mt-0.5" }),
1481
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
1482
+ /* @__PURE__ */ jsxs(
1483
+ "button",
1484
+ {
1485
+ type: "button",
1486
+ onClick: () => debug && hasDebugContent && setExpanded(!expanded),
1487
+ disabled: !debug || !hasDebugContent,
1488
+ className: cn(
1489
+ "flex items-center gap-2 text-left min-w-0 w-full",
1490
+ debug && hasDebugContent && "cursor-pointer hover:text-foreground",
1491
+ !debug && "cursor-default"
1492
+ ),
1493
+ children: [
1494
+ isExecuting ? /* @__PURE__ */ jsx(TextShimmerLoader, { text: displayTitle, size: "sm" }) : /* @__PURE__ */ jsx(
1495
+ "span",
1496
+ {
1497
+ className: cn(
1498
+ "text-sm truncate",
1499
+ isCompleted && "text-foreground",
1500
+ isError && "text-red-500",
1501
+ step.status === "pending" && "text-muted-foreground/60"
1502
+ ),
1503
+ children: displayTitle
1504
+ }
1505
+ ),
1506
+ debug && hasDebugContent && /* @__PURE__ */ jsx(
1507
+ "svg",
1508
+ {
1509
+ className: cn(
1510
+ "size-3 text-muted-foreground/40 transition-transform ml-auto flex-shrink-0",
1511
+ expanded && "rotate-90"
1512
+ ),
1513
+ fill: "none",
1514
+ viewBox: "0 0 24 24",
1515
+ stroke: "currentColor",
1516
+ strokeWidth: 2,
1517
+ children: /* @__PURE__ */ jsx(
1518
+ "path",
1519
+ {
1520
+ strokeLinecap: "round",
1521
+ strokeLinejoin: "round",
1522
+ d: "M9 5l7 7-7 7"
1523
+ }
1524
+ )
1525
+ }
1526
+ )
1527
+ ]
1528
+ }
1529
+ ),
1530
+ debug && expanded && hasDebugContent && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 space-y-1.5", children: [
1531
+ step.args && Object.keys(step.args).length > 0 && /* @__PURE__ */ jsxs("div", { className: "text-[10px] font-mono bg-muted/50 rounded px-2 py-1 overflow-x-auto", children: [
1532
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "args: " }),
1533
+ JSON.stringify(step.args)
1534
+ ] }),
1535
+ step.result && /* @__PURE__ */ jsxs(
1536
+ "div",
1537
+ {
1538
+ className: cn(
1539
+ "text-[10px] font-mono rounded px-2 py-1 overflow-x-auto whitespace-pre-wrap break-all",
1540
+ step.result.success !== false ? "bg-green-500/10 text-green-600 dark:text-green-400" : "bg-red-500/10 text-red-600 dark:text-red-400"
1541
+ ),
1542
+ children: [
1543
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "result: " }),
1544
+ formatResult(step.result),
1545
+ getResultImage(step.result) && /* @__PURE__ */ jsx(
1546
+ "img",
1547
+ {
1548
+ src: getResultImage(step.result),
1549
+ alt: "Screenshot",
1550
+ className: "mt-1.5 rounded border border-border max-w-full max-h-48 object-contain"
1551
+ }
1552
+ )
1553
+ ]
1554
+ }
1555
+ )
1556
+ ] }),
1557
+ isError && step.error && !step.result && /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-[10px] font-mono bg-red-500/10 text-red-600 dark:text-red-400 rounded px-1.5 py-0.5", children: step.error })
1558
+ ] })
1559
+ ] })
1560
+ ] });
1561
+ }
1562
+ function ToolSteps({
1563
+ steps,
1564
+ debug,
1565
+ defaultExpanded = false,
1566
+ className
1567
+ }) {
1568
+ if (steps.length === 0) return null;
1569
+ return /* @__PURE__ */ jsx("div", { className: cn("space-y-1.5", className), children: steps.map((step, index) => /* @__PURE__ */ jsx(
1570
+ ToolStep,
1571
+ {
1572
+ step,
1573
+ showLine: index < steps.length - 1,
1574
+ debug,
1575
+ defaultExpanded
1576
+ },
1577
+ step.id
1578
+ )) });
1579
+ }
1580
+ function InlineToolSteps({
1581
+ steps,
1582
+ maxVisible = 5,
1583
+ className
1584
+ }) {
1585
+ if (steps.length === 0) return null;
1586
+ const visibleSteps = steps.slice(0, maxVisible);
1587
+ const hiddenCount = steps.length - maxVisible;
1588
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-1", className), children: [
1589
+ visibleSteps.map((step) => /* @__PURE__ */ jsx(
1590
+ "div",
1591
+ {
1592
+ title: `${step.name}: ${step.status}`,
1593
+ className: "flex items-center",
1594
+ children: /* @__PURE__ */ jsx(StatusIndicator, { status: step.status })
1595
+ },
1596
+ step.id
1597
+ )),
1598
+ hiddenCount > 0 && /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
1599
+ "+",
1600
+ hiddenCount
1601
+ ] })
1602
+ ] });
1603
+ }
1604
+ function SendIcon({ className }) {
1605
+ return /* @__PURE__ */ jsxs(
1606
+ "svg",
1607
+ {
1608
+ xmlns: "http://www.w3.org/2000/svg",
1609
+ viewBox: "0 0 24 24",
1610
+ fill: "none",
1611
+ stroke: "currentColor",
1612
+ strokeWidth: "2",
1613
+ strokeLinecap: "round",
1614
+ strokeLinejoin: "round",
1615
+ className,
1616
+ children: [
1617
+ /* @__PURE__ */ jsx("path", { d: "m22 2-7 20-4-9-9-4Z" }),
1618
+ /* @__PURE__ */ jsx("path", { d: "M22 2 11 13" })
1619
+ ]
1620
+ }
1621
+ );
1622
+ }
1623
+ function StopIcon({ className }) {
1624
+ return /* @__PURE__ */ jsx(
1625
+ "svg",
1626
+ {
1627
+ xmlns: "http://www.w3.org/2000/svg",
1628
+ viewBox: "0 0 24 24",
1629
+ fill: "currentColor",
1630
+ className,
1631
+ children: /* @__PURE__ */ jsx("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2" })
1632
+ }
1633
+ );
1634
+ }
1635
+ function CloseIcon({ className }) {
1636
+ return /* @__PURE__ */ jsxs(
1637
+ "svg",
1638
+ {
1639
+ xmlns: "http://www.w3.org/2000/svg",
1640
+ viewBox: "0 0 24 24",
1641
+ fill: "none",
1642
+ stroke: "currentColor",
1643
+ strokeWidth: "2",
1644
+ strokeLinecap: "round",
1645
+ strokeLinejoin: "round",
1646
+ className,
1647
+ children: [
1648
+ /* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
1649
+ /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
1650
+ ]
1651
+ }
1652
+ );
1653
+ }
1654
+ function ChevronDownIcon2({ className }) {
1655
+ return /* @__PURE__ */ jsx(
1656
+ "svg",
1657
+ {
1658
+ xmlns: "http://www.w3.org/2000/svg",
1659
+ viewBox: "0 0 24 24",
1660
+ fill: "none",
1661
+ stroke: "currentColor",
1662
+ strokeWidth: "2",
1663
+ strokeLinecap: "round",
1664
+ strokeLinejoin: "round",
1665
+ className,
1666
+ children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })
1667
+ }
1668
+ );
1669
+ }
1670
+ function ChevronUpIcon({ className }) {
1671
+ return /* @__PURE__ */ jsx(
1672
+ "svg",
1673
+ {
1674
+ xmlns: "http://www.w3.org/2000/svg",
1675
+ viewBox: "0 0 24 24",
1676
+ fill: "none",
1677
+ stroke: "currentColor",
1678
+ strokeWidth: "2",
1679
+ strokeLinecap: "round",
1680
+ strokeLinejoin: "round",
1681
+ className,
1682
+ children: /* @__PURE__ */ jsx("path", { d: "m18 15-6-6-6 6" })
1683
+ }
1684
+ );
1685
+ }
1686
+ function CopyIcon({ className }) {
1687
+ return /* @__PURE__ */ jsxs(
1688
+ "svg",
1689
+ {
1690
+ xmlns: "http://www.w3.org/2000/svg",
1691
+ viewBox: "0 0 24 24",
1692
+ fill: "none",
1693
+ stroke: "currentColor",
1694
+ strokeWidth: "2",
1695
+ strokeLinecap: "round",
1696
+ strokeLinejoin: "round",
1697
+ className,
1698
+ children: [
1699
+ /* @__PURE__ */ jsx("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" }),
1700
+ /* @__PURE__ */ jsx("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
1701
+ ]
1702
+ }
1703
+ );
1704
+ }
1705
+ function CheckIcon({ className }) {
1706
+ return /* @__PURE__ */ jsx(
1707
+ "svg",
1708
+ {
1709
+ xmlns: "http://www.w3.org/2000/svg",
1710
+ viewBox: "0 0 24 24",
1711
+ fill: "none",
1712
+ stroke: "currentColor",
1713
+ strokeWidth: "2",
1714
+ strokeLinecap: "round",
1715
+ strokeLinejoin: "round",
1716
+ className,
1717
+ children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" })
1718
+ }
1719
+ );
1720
+ }
1721
+ function ThumbsUpIcon2({ className }) {
1722
+ return /* @__PURE__ */ jsxs(
1723
+ "svg",
1724
+ {
1725
+ xmlns: "http://www.w3.org/2000/svg",
1726
+ viewBox: "0 0 24 24",
1727
+ fill: "none",
1728
+ stroke: "currentColor",
1729
+ strokeWidth: "2",
1730
+ strokeLinecap: "round",
1731
+ strokeLinejoin: "round",
1732
+ className,
1733
+ children: [
1734
+ /* @__PURE__ */ jsx("path", { d: "M7 10v12" }),
1735
+ /* @__PURE__ */ jsx("path", { d: "M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z" })
1736
+ ]
1737
+ }
1738
+ );
1739
+ }
1740
+ function ThumbsDownIcon2({ className }) {
1741
+ return /* @__PURE__ */ jsxs(
1742
+ "svg",
1743
+ {
1744
+ xmlns: "http://www.w3.org/2000/svg",
1745
+ viewBox: "0 0 24 24",
1746
+ fill: "none",
1747
+ stroke: "currentColor",
1748
+ strokeWidth: "2",
1749
+ strokeLinecap: "round",
1750
+ strokeLinejoin: "round",
1751
+ className,
1752
+ children: [
1753
+ /* @__PURE__ */ jsx("path", { d: "M17 14V2" }),
1754
+ /* @__PURE__ */ jsx("path", { d: "M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z" })
1755
+ ]
1756
+ }
1757
+ );
1758
+ }
1759
+ function RefreshIcon({ className }) {
1760
+ return /* @__PURE__ */ jsxs(
1761
+ "svg",
1762
+ {
1763
+ xmlns: "http://www.w3.org/2000/svg",
1764
+ viewBox: "0 0 24 24",
1765
+ fill: "none",
1766
+ stroke: "currentColor",
1767
+ strokeWidth: "2",
1768
+ strokeLinecap: "round",
1769
+ strokeLinejoin: "round",
1770
+ className,
1771
+ children: [
1772
+ /* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
1773
+ /* @__PURE__ */ jsx("path", { d: "M21 3v5h-5" }),
1774
+ /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
1775
+ /* @__PURE__ */ jsx("path", { d: "M8 16H3v5" })
1776
+ ]
1777
+ }
1778
+ );
1779
+ }
1780
+ function UserIcon({ className }) {
1781
+ return /* @__PURE__ */ jsxs(
1782
+ "svg",
1783
+ {
1784
+ xmlns: "http://www.w3.org/2000/svg",
1785
+ viewBox: "0 0 24 24",
1786
+ fill: "none",
1787
+ stroke: "currentColor",
1788
+ strokeWidth: "2",
1789
+ strokeLinecap: "round",
1790
+ strokeLinejoin: "round",
1791
+ className,
1792
+ children: [
1793
+ /* @__PURE__ */ jsx("path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" }),
1794
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "7", r: "4" })
1795
+ ]
1796
+ }
1797
+ );
1798
+ }
1799
+ function BotIcon({ className }) {
1800
+ return /* @__PURE__ */ jsxs(
1801
+ "svg",
1802
+ {
1803
+ xmlns: "http://www.w3.org/2000/svg",
1804
+ viewBox: "0 0 24 24",
1805
+ fill: "none",
1806
+ stroke: "currentColor",
1807
+ strokeWidth: "2",
1808
+ strokeLinecap: "round",
1809
+ strokeLinejoin: "round",
1810
+ className,
1811
+ children: [
1812
+ /* @__PURE__ */ jsx("path", { d: "M12 8V4H8" }),
1813
+ /* @__PURE__ */ jsx("rect", { width: "16", height: "12", x: "4", y: "8", rx: "2" }),
1814
+ /* @__PURE__ */ jsx("path", { d: "M2 14h2" }),
1815
+ /* @__PURE__ */ jsx("path", { d: "M20 14h2" }),
1816
+ /* @__PURE__ */ jsx("path", { d: "M15 13v2" }),
1817
+ /* @__PURE__ */ jsx("path", { d: "M9 13v2" })
1818
+ ]
1819
+ }
1820
+ );
1821
+ }
1822
+ function PlusIcon({ className }) {
1823
+ return /* @__PURE__ */ jsxs(
1824
+ "svg",
1825
+ {
1826
+ xmlns: "http://www.w3.org/2000/svg",
1827
+ width: "24",
1828
+ height: "24",
1829
+ viewBox: "0 0 24 24",
1830
+ fill: "none",
1831
+ stroke: "currentColor",
1832
+ strokeWidth: "2",
1833
+ strokeLinecap: "round",
1834
+ strokeLinejoin: "round",
1835
+ className,
1836
+ children: [
1837
+ /* @__PURE__ */ jsx("path", { d: "M5 12h14" }),
1838
+ /* @__PURE__ */ jsx("path", { d: "M12 5v14" })
1839
+ ]
1840
+ }
1841
+ );
1842
+ }
1843
+ function ArrowUpIcon({ className }) {
1844
+ return /* @__PURE__ */ jsxs(
1845
+ "svg",
1846
+ {
1847
+ xmlns: "http://www.w3.org/2000/svg",
1848
+ width: "24",
1849
+ height: "24",
1850
+ viewBox: "0 0 24 24",
1851
+ fill: "none",
1852
+ stroke: "currentColor",
1853
+ strokeWidth: "2",
1854
+ strokeLinecap: "round",
1855
+ strokeLinejoin: "round",
1856
+ className,
1857
+ children: [
1858
+ /* @__PURE__ */ jsx("path", { d: "m5 12 7-7 7 7" }),
1859
+ /* @__PURE__ */ jsx("path", { d: "M12 19V5" })
1860
+ ]
1861
+ }
1862
+ );
1863
+ }
1864
+ function XIcon2({ className }) {
1865
+ return /* @__PURE__ */ jsxs(
1866
+ "svg",
1867
+ {
1868
+ xmlns: "http://www.w3.org/2000/svg",
1869
+ width: "24",
1870
+ height: "24",
1871
+ viewBox: "0 0 24 24",
1872
+ fill: "none",
1873
+ stroke: "currentColor",
1874
+ strokeWidth: "2",
1875
+ strokeLinecap: "round",
1876
+ strokeLinejoin: "round",
1877
+ className,
1878
+ children: [
1879
+ /* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
1880
+ /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
1881
+ ]
1882
+ }
1883
+ );
1884
+ }
1885
+ function AlertTriangleIcon({ className }) {
1886
+ return /* @__PURE__ */ jsxs(
1887
+ "svg",
1888
+ {
1889
+ xmlns: "http://www.w3.org/2000/svg",
1890
+ width: "24",
1891
+ height: "24",
1892
+ viewBox: "0 0 24 24",
1893
+ fill: "none",
1894
+ stroke: "currentColor",
1895
+ strokeWidth: "2",
1896
+ strokeLinecap: "round",
1897
+ strokeLinejoin: "round",
1898
+ className,
1899
+ children: [
1900
+ /* @__PURE__ */ jsx("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }),
1901
+ /* @__PURE__ */ jsx("path", { d: "M12 9v4" }),
1902
+ /* @__PURE__ */ jsx("path", { d: "M12 17h.01" })
1903
+ ]
1904
+ }
1905
+ );
1906
+ }
1907
+ var ConfirmationContext = React8.createContext(null);
1908
+ function useConfirmationContext() {
1909
+ const context = React8.useContext(ConfirmationContext);
1910
+ if (!context) {
1911
+ throw new Error(
1912
+ "Confirmation components must be used within a Confirmation provider"
1913
+ );
1914
+ }
1915
+ return context;
1916
+ }
1917
+ function Confirmation({
1918
+ children,
1919
+ state = "pending",
1920
+ message,
1921
+ onApprove,
1922
+ onReject,
1923
+ className
1924
+ }) {
1925
+ return /* @__PURE__ */ jsx(
1926
+ ConfirmationContext.Provider,
1927
+ {
1928
+ value: { state, message, onApprove, onReject },
1929
+ children: /* @__PURE__ */ jsx(
1930
+ "div",
1931
+ {
1932
+ className: cn(
1933
+ "confirmation rounded-lg border bg-card text-card-foreground",
1934
+ className
1935
+ ),
1936
+ children
1937
+ }
1938
+ )
1939
+ }
1940
+ );
1941
+ }
1942
+ function ConfirmationPending({
1943
+ children,
1944
+ className
1945
+ }) {
1946
+ const { state } = useConfirmationContext();
1947
+ if (state !== "pending") return null;
1948
+ return /* @__PURE__ */ jsx("div", { className: cn("p-4", className), children });
1949
+ }
1950
+ function ConfirmationApproved({
1951
+ children,
1952
+ className
1953
+ }) {
1954
+ const { state } = useConfirmationContext();
1955
+ if (state !== "approved") return null;
1956
+ return /* @__PURE__ */ jsxs(
1957
+ "div",
1958
+ {
1959
+ className: cn(
1960
+ "flex items-center gap-2 px-4 py-2 text-sm text-green-600 dark:text-green-400",
1961
+ className
1962
+ ),
1963
+ children: [
1964
+ /* @__PURE__ */ jsx(CheckIcon, { className: "h-4 w-4" }),
1965
+ children || /* @__PURE__ */ jsx("span", { children: "Approved" })
1966
+ ]
1967
+ }
1968
+ );
1969
+ }
1970
+ function ConfirmationRejected({
1971
+ children,
1972
+ className
1973
+ }) {
1974
+ const { state } = useConfirmationContext();
1975
+ if (state !== "rejected") return null;
1976
+ return /* @__PURE__ */ jsxs(
1977
+ "div",
1978
+ {
1979
+ className: cn(
1980
+ "flex items-center gap-2 px-4 py-2 text-sm text-red-600 dark:text-red-400",
1981
+ className
1982
+ ),
1983
+ children: [
1984
+ /* @__PURE__ */ jsx(XIcon2, { className: "h-4 w-4" }),
1985
+ children || /* @__PURE__ */ jsx("span", { children: "Rejected" })
1986
+ ]
1987
+ }
1988
+ );
1989
+ }
1990
+ function ConfirmationMessage({
1991
+ children,
1992
+ className
1993
+ }) {
1994
+ const { message } = useConfirmationContext();
1995
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex items-start gap-3", className), children: [
1996
+ /* @__PURE__ */ jsx(AlertTriangleIcon, { className: "mt-0.5 h-5 w-5 flex-shrink-0 text-amber-500" }),
1997
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground", children: children || message || "This action requires your approval." })
1998
+ ] });
1999
+ }
2000
+ function ConfirmationActions({
2001
+ children,
2002
+ className,
2003
+ rejectLabel = "Reject",
2004
+ approveLabel = "Approve"
2005
+ }) {
2006
+ const { onApprove, onReject } = useConfirmationContext();
2007
+ if (children) {
2008
+ return /* @__PURE__ */ jsx("div", { className: cn("mt-3 flex justify-end gap-2", className), children });
2009
+ }
2010
+ return /* @__PURE__ */ jsxs("div", { className: cn("mt-3 flex justify-end gap-2", className), children: [
2011
+ /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: onReject, children: rejectLabel }),
2012
+ /* @__PURE__ */ jsx(Button, { variant: "default", size: "sm", onClick: onApprove, children: approveLabel })
2013
+ ] });
2014
+ }
2015
+ function SimpleConfirmation({
2016
+ state,
2017
+ message,
2018
+ onApprove,
2019
+ onReject,
2020
+ rejectLabel,
2021
+ approveLabel,
2022
+ className
2023
+ }) {
2024
+ return /* @__PURE__ */ jsxs(
2025
+ Confirmation,
2026
+ {
2027
+ state,
2028
+ message,
2029
+ onApprove,
2030
+ onReject,
2031
+ className,
2032
+ children: [
2033
+ /* @__PURE__ */ jsxs(ConfirmationPending, { children: [
2034
+ /* @__PURE__ */ jsx(ConfirmationMessage, {}),
2035
+ /* @__PURE__ */ jsx(
2036
+ ConfirmationActions,
2037
+ {
2038
+ rejectLabel,
2039
+ approveLabel
2040
+ }
2041
+ )
2042
+ ] }),
2043
+ /* @__PURE__ */ jsx(ConfirmationApproved, {}),
2044
+ /* @__PURE__ */ jsx(ConfirmationRejected, {})
2045
+ ]
2046
+ }
2047
+ );
2048
+ }
2049
+ var DEFAULT_PERMISSION_OPTIONS = [
2050
+ {
2051
+ value: "ask",
2052
+ label: "Ask every time",
2053
+ description: "Always prompt before this tool runs"
2054
+ },
2055
+ {
2056
+ value: "allow_always",
2057
+ label: "Allow always",
2058
+ description: "Never ask again, always approve"
2059
+ },
2060
+ {
2061
+ value: "session",
2062
+ label: "Allow this session",
2063
+ description: "Allow until you close this page"
2064
+ },
2065
+ {
2066
+ value: "deny_always",
2067
+ label: "Deny always",
2068
+ description: "Never ask again, always deny"
2069
+ }
2070
+ ];
2071
+ function PermissionConfirmation({
2072
+ state,
2073
+ toolName,
2074
+ message,
2075
+ onApprove,
2076
+ onReject,
2077
+ showPermissionOptions = true,
2078
+ permissionOptions = DEFAULT_PERMISSION_OPTIONS,
2079
+ className
2080
+ }) {
2081
+ const [selectedPermission, setSelectedPermission] = React8.useState("ask");
2082
+ const [showOptions, setShowOptions] = React8.useState(false);
2083
+ const handleApprove = () => {
2084
+ onApprove?.(selectedPermission);
2085
+ };
2086
+ const handleReject = () => {
2087
+ onReject?.(
2088
+ selectedPermission === "deny_always" ? "deny_always" : void 0
2089
+ );
2090
+ };
2091
+ if (state === "approved") {
2092
+ return /* @__PURE__ */ jsxs(
2093
+ "div",
2094
+ {
2095
+ className: cn(
2096
+ "flex items-center gap-2 px-4 py-2 text-sm text-green-600 dark:text-green-400 rounded-lg border bg-green-50 dark:bg-green-950/20",
2097
+ className
2098
+ ),
2099
+ children: [
2100
+ /* @__PURE__ */ jsx(CheckIcon, { className: "h-4 w-4" }),
2101
+ /* @__PURE__ */ jsx("span", { children: "Approved" })
2102
+ ]
2103
+ }
2104
+ );
2105
+ }
2106
+ if (state === "rejected") {
2107
+ return /* @__PURE__ */ jsxs(
2108
+ "div",
2109
+ {
2110
+ className: cn(
2111
+ "flex items-center gap-2 px-4 py-2 text-sm text-red-600 dark:text-red-400 rounded-lg border bg-red-50 dark:bg-red-950/20",
2112
+ className
2113
+ ),
2114
+ children: [
2115
+ /* @__PURE__ */ jsx(XIcon2, { className: "h-4 w-4" }),
2116
+ /* @__PURE__ */ jsx("span", { children: "Rejected" })
2117
+ ]
2118
+ }
2119
+ );
2120
+ }
2121
+ return /* @__PURE__ */ jsxs(
2122
+ "div",
2123
+ {
2124
+ className: cn(
2125
+ "rounded-lg border bg-card text-card-foreground p-4",
2126
+ className
2127
+ ),
2128
+ children: [
2129
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 mb-3", children: [
2130
+ /* @__PURE__ */ jsx(AlertTriangleIcon, { className: "mt-0.5 h-5 w-5 flex-shrink-0 text-amber-500" }),
2131
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
2132
+ toolName && /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: toolName }),
2133
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: message || "This tool requires your approval to execute." })
2134
+ ] })
2135
+ ] }),
2136
+ showPermissionOptions && /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
2137
+ /* @__PURE__ */ jsxs(
2138
+ "button",
2139
+ {
2140
+ type: "button",
2141
+ onClick: () => setShowOptions(!showOptions),
2142
+ className: "flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors",
2143
+ children: [
2144
+ /* @__PURE__ */ jsx("span", { children: permissionOptions.find((o) => o.value === selectedPermission)?.label }),
2145
+ /* @__PURE__ */ jsx(
2146
+ "svg",
2147
+ {
2148
+ className: cn(
2149
+ "h-4 w-4 transition-transform",
2150
+ showOptions && "rotate-180"
2151
+ ),
2152
+ fill: "none",
2153
+ viewBox: "0 0 24 24",
2154
+ stroke: "currentColor",
2155
+ strokeWidth: 2,
2156
+ children: /* @__PURE__ */ jsx(
2157
+ "path",
2158
+ {
2159
+ strokeLinecap: "round",
2160
+ strokeLinejoin: "round",
2161
+ d: "M19 9l-7 7-7-7"
2162
+ }
2163
+ )
2164
+ }
2165
+ )
2166
+ ]
2167
+ }
2168
+ ),
2169
+ showOptions && /* @__PURE__ */ jsx("div", { className: "mt-2 space-y-1 pl-1", children: permissionOptions.map((option) => /* @__PURE__ */ jsxs(
2170
+ "label",
2171
+ {
2172
+ className: cn(
2173
+ "flex items-start gap-2 p-2 rounded-md cursor-pointer transition-colors",
2174
+ selectedPermission === option.value ? "bg-primary/10" : "hover:bg-muted/50"
2175
+ ),
2176
+ children: [
2177
+ /* @__PURE__ */ jsx(
2178
+ "input",
2179
+ {
2180
+ type: "radio",
2181
+ name: "permission",
2182
+ value: option.value,
2183
+ checked: selectedPermission === option.value,
2184
+ onChange: () => setSelectedPermission(option.value),
2185
+ className: "mt-0.5"
2186
+ }
2187
+ ),
2188
+ /* @__PURE__ */ jsxs("div", { children: [
2189
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: option.label }),
2190
+ option.description && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: option.description })
2191
+ ] })
2192
+ ]
2193
+ },
2194
+ option.value
2195
+ )) })
2196
+ ] }),
2197
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
2198
+ /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: handleReject, children: "Deny" }),
2199
+ /* @__PURE__ */ jsx(Button, { variant: "default", size: "sm", onClick: handleApprove, children: "Allow" })
2200
+ ] })
2201
+ ]
2202
+ }
2203
+ );
2204
+ }
2205
+ function CompactPermissionConfirmation({
2206
+ state,
2207
+ message,
2208
+ onApprove,
2209
+ onReject,
2210
+ className
2211
+ }) {
2212
+ const [rememberChoice, setRememberChoice] = React8.useState(false);
2213
+ const handleApprove = () => {
2214
+ onApprove?.(rememberChoice ? "allow_always" : "ask");
2215
+ };
2216
+ const handleReject = () => {
2217
+ onReject?.(rememberChoice ? "deny_always" : void 0);
2218
+ };
2219
+ if (state === "approved") {
2220
+ return /* @__PURE__ */ jsxs(
2221
+ "div",
2222
+ {
2223
+ className: cn(
2224
+ "flex items-center gap-2 px-4 py-2 text-sm text-green-600 dark:text-green-400",
2225
+ className
2226
+ ),
2227
+ children: [
2228
+ /* @__PURE__ */ jsx(CheckIcon, { className: "h-4 w-4" }),
2229
+ /* @__PURE__ */ jsx("span", { children: "Approved" })
2230
+ ]
2231
+ }
2232
+ );
2233
+ }
2234
+ if (state === "rejected") {
2235
+ return /* @__PURE__ */ jsxs(
2236
+ "div",
2237
+ {
2238
+ className: cn(
2239
+ "flex items-center gap-2 px-4 py-2 text-sm text-red-600 dark:text-red-400",
2240
+ className
2241
+ ),
2242
+ children: [
2243
+ /* @__PURE__ */ jsx(XIcon2, { className: "h-4 w-4" }),
2244
+ /* @__PURE__ */ jsx("span", { children: "Rejected" })
2245
+ ]
2246
+ }
2247
+ );
2248
+ }
2249
+ return /* @__PURE__ */ jsxs(
2250
+ "div",
2251
+ {
2252
+ className: cn(
2253
+ "rounded-lg border bg-card text-card-foreground p-4",
2254
+ className
2255
+ ),
2256
+ children: [
2257
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 mb-3", children: [
2258
+ /* @__PURE__ */ jsx(AlertTriangleIcon, { className: "mt-0.5 h-5 w-5 flex-shrink-0 text-amber-500" }),
2259
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground", children: message || "This action requires your approval." })
2260
+ ] }),
2261
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
2262
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm text-muted-foreground cursor-pointer", children: [
2263
+ /* @__PURE__ */ jsx(
2264
+ "input",
2265
+ {
2266
+ type: "checkbox",
2267
+ checked: rememberChoice,
2268
+ onChange: (e) => setRememberChoice(e.target.checked),
2269
+ className: "rounded border-gray-300"
2270
+ }
2271
+ ),
2272
+ "Don't ask again"
2273
+ ] }),
2274
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
2275
+ /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: handleReject, children: "Deny" }),
2276
+ /* @__PURE__ */ jsx(Button, { variant: "default", size: "sm", onClick: handleApprove, children: "Allow" })
2277
+ ] })
2278
+ ] })
2279
+ ]
2280
+ }
2281
+ );
2282
+ }
2283
+ function parseFollowUps(content) {
2284
+ if (!content) {
2285
+ return { cleanContent: content, followUps: [] };
2286
+ }
2287
+ const followUpRegex = /\[FOLLOWUP:\s*([^\]]+)\]/gi;
2288
+ const matches = content.match(followUpRegex);
2289
+ if (!matches || matches.length === 0) {
2290
+ return { cleanContent: content, followUps: [] };
2291
+ }
2292
+ const lastMatch = matches[matches.length - 1];
2293
+ const innerContent = lastMatch.replace(/\[FOLLOWUP:\s*|\]/gi, "");
2294
+ const followUps = innerContent.split("|").map((q) => q.trim()).filter((q) => q.length > 0);
2295
+ const cleanContent = content.replace(followUpRegex, "").trim();
2296
+ return { cleanContent, followUps };
2297
+ }
2298
+ function FollowUpQuestions({
2299
+ questions,
2300
+ onSelect,
2301
+ className,
2302
+ buttonClassName
2303
+ }) {
2304
+ if (!questions || questions.length === 0) {
2305
+ return null;
2306
+ }
2307
+ return /* @__PURE__ */ jsx("div", { className: cn("flex flex-wrap gap-2 mt-2", className), children: questions.map((question, index) => /* @__PURE__ */ jsx(
2308
+ "button",
2309
+ {
2310
+ onClick: () => onSelect(question),
2311
+ className: cn(
2312
+ "px-3 py-1.5 text-sm rounded-full",
2313
+ "bg-primary/10 hover:bg-primary/20 text-primary",
2314
+ "border border-primary/20 hover:border-primary/40",
2315
+ "transition-colors duration-150",
2316
+ "text-left whitespace-nowrap",
2317
+ buttonClassName
2318
+ ),
2319
+ children: question
2320
+ },
2321
+ index
2322
+ )) });
2323
+ }
2324
+ function DevLogger({
2325
+ state,
2326
+ position = "bottom-right",
2327
+ className
2328
+ }) {
2329
+ const [isOpen, setIsOpen] = useState(false);
2330
+ const [activeTab, setActiveTab] = useState("chat");
2331
+ const positionClasses = {
2332
+ "bottom-left": "bottom-4 left-4",
2333
+ "bottom-right": "bottom-4 right-4",
2334
+ "top-left": "top-4 left-4",
2335
+ "top-right": "top-4 right-4"
2336
+ };
2337
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2338
+ /* @__PURE__ */ jsx(
2339
+ "button",
2340
+ {
2341
+ type: "button",
2342
+ onClick: () => setIsOpen(true),
2343
+ className: cn(
2344
+ "fixed z-[9999] flex items-center justify-center",
2345
+ "w-12 h-12 rounded-full shadow-lg",
2346
+ "bg-orange-500 hover:bg-orange-600 text-white",
2347
+ "transition-transform hover:scale-110",
2348
+ positionClasses[position],
2349
+ className
2350
+ ),
2351
+ title: "Open SDK DevLogger",
2352
+ children: /* @__PURE__ */ jsx(
2353
+ "svg",
2354
+ {
2355
+ className: "w-6 h-6",
2356
+ fill: "none",
2357
+ viewBox: "0 0 24 24",
2358
+ stroke: "currentColor",
2359
+ strokeWidth: 2,
2360
+ children: /* @__PURE__ */ jsx(
2361
+ "path",
2362
+ {
2363
+ strokeLinecap: "round",
2364
+ strokeLinejoin: "round",
2365
+ d: "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
2366
+ }
2367
+ )
2368
+ }
2369
+ )
2370
+ }
2371
+ ),
2372
+ isOpen && /* @__PURE__ */ jsx(
2373
+ "div",
2374
+ {
2375
+ className: "fixed inset-0 z-[10000] flex items-center justify-center bg-black/50",
2376
+ onClick: () => setIsOpen(false),
2377
+ children: /* @__PURE__ */ jsxs(
2378
+ "div",
2379
+ {
2380
+ className: "bg-background border rounded-lg shadow-xl w-[600px] max-h-[80vh] overflow-hidden",
2381
+ onClick: (e) => e.stopPropagation(),
2382
+ children: [
2383
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b bg-muted/50", children: [
2384
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2385
+ /* @__PURE__ */ jsx("div", { className: "w-3 h-3 rounded-full bg-orange-500" }),
2386
+ /* @__PURE__ */ jsx("h2", { className: "font-semibold text-sm", children: "Copilot SDK DevLogger" })
2387
+ ] }),
2388
+ /* @__PURE__ */ jsx(
2389
+ "button",
2390
+ {
2391
+ type: "button",
2392
+ onClick: () => setIsOpen(false),
2393
+ className: "text-muted-foreground hover:text-foreground",
2394
+ children: /* @__PURE__ */ jsx(
2395
+ "svg",
2396
+ {
2397
+ className: "w-5 h-5",
2398
+ fill: "none",
2399
+ viewBox: "0 0 24 24",
2400
+ stroke: "currentColor",
2401
+ children: /* @__PURE__ */ jsx(
2402
+ "path",
2403
+ {
2404
+ strokeLinecap: "round",
2405
+ strokeLinejoin: "round",
2406
+ strokeWidth: 2,
2407
+ d: "M6 18L18 6M6 6l12 12"
2408
+ }
2409
+ )
2410
+ }
2411
+ )
2412
+ }
2413
+ )
2414
+ ] }),
2415
+ /* @__PURE__ */ jsx("div", { className: "flex border-b", children: ["chat", "tools", "agent", "config"].map((tab) => /* @__PURE__ */ jsx(
2416
+ "button",
2417
+ {
2418
+ type: "button",
2419
+ onClick: () => setActiveTab(tab),
2420
+ className: cn(
2421
+ "px-4 py-2 text-sm font-medium capitalize",
2422
+ activeTab === tab ? "border-b-2 border-primary text-primary" : "text-muted-foreground hover:text-foreground"
2423
+ ),
2424
+ children: tab
2425
+ },
2426
+ tab
2427
+ )) }),
2428
+ /* @__PURE__ */ jsxs("div", { className: "p-4 overflow-y-auto max-h-[60vh]", children: [
2429
+ activeTab === "chat" && /* @__PURE__ */ jsx(ChatTab, { state }),
2430
+ activeTab === "tools" && /* @__PURE__ */ jsx(ToolsTab, { state }),
2431
+ activeTab === "agent" && /* @__PURE__ */ jsx(AgentTab, { state }),
2432
+ activeTab === "config" && /* @__PURE__ */ jsx(ConfigTab, { state })
2433
+ ] })
2434
+ ]
2435
+ }
2436
+ )
2437
+ }
2438
+ )
2439
+ ] });
2440
+ }
2441
+ function ChatTab({ state }) {
2442
+ return /* @__PURE__ */ jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs(Section, { title: "Status", children: [
2443
+ /* @__PURE__ */ jsx(Row, { label: "Loading", value: state.chat.isLoading ? "Yes" : "No" }),
2444
+ /* @__PURE__ */ jsx(Row, { label: "Message Count", value: state.chat.messageCount }),
2445
+ /* @__PURE__ */ jsx(Row, { label: "Thread ID", value: state.chat.threadId, mono: true }),
2446
+ /* @__PURE__ */ jsx(
2447
+ Row,
2448
+ {
2449
+ label: "Error",
2450
+ value: state.chat.error || "None",
2451
+ valueClass: state.chat.error ? "text-red-500" : "text-green-500"
2452
+ }
2453
+ )
2454
+ ] }) });
2455
+ }
2456
+ function ToolsTab({ state }) {
2457
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
2458
+ /* @__PURE__ */ jsxs(Section, { title: "Smart Context", children: [
2459
+ /* @__PURE__ */ jsx(Row, { label: "Enabled", value: state.tools.isEnabled ? "Yes" : "No" }),
2460
+ /* @__PURE__ */ jsx(Row, { label: "Capturing", value: state.tools.isCapturing ? "Yes" : "No" }),
2461
+ /* @__PURE__ */ jsx(
2462
+ Row,
2463
+ {
2464
+ label: "Pending Consent",
2465
+ value: state.tools.pendingConsent ? "Yes" : "No"
2466
+ }
2467
+ )
2468
+ ] }),
2469
+ /* @__PURE__ */ jsx(Section, { title: "Registered Tools", children: state.registered.tools.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No tools registered" }) : /* @__PURE__ */ jsx("div", { className: "space-y-1", children: state.registered.tools.map((tool) => /* @__PURE__ */ jsxs(
2470
+ "div",
2471
+ {
2472
+ className: "flex items-center justify-between text-sm",
2473
+ children: [
2474
+ /* @__PURE__ */ jsx("code", { className: "bg-muted px-1.5 py-0.5 rounded text-xs", children: tool.name }),
2475
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-xs", children: tool.location })
2476
+ ]
2477
+ },
2478
+ tool.name
2479
+ )) }) }),
2480
+ /* @__PURE__ */ jsxs(Section, { title: "Permissions", children: [
2481
+ /* @__PURE__ */ jsx(Row, { label: "Loaded", value: state.permissions.loaded ? "Yes" : "No" }),
2482
+ state.permissions.stored.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-2 space-y-1", children: state.permissions.stored.map((p) => /* @__PURE__ */ jsxs(
2483
+ "div",
2484
+ {
2485
+ className: "flex items-center justify-between text-sm",
2486
+ children: [
2487
+ /* @__PURE__ */ jsx("code", { className: "bg-muted px-1.5 py-0.5 rounded text-xs", children: p.toolName }),
2488
+ /* @__PURE__ */ jsx(Badge, { level: p.level })
2489
+ ]
2490
+ },
2491
+ p.toolName
2492
+ )) })
2493
+ ] })
2494
+ ] });
2495
+ }
2496
+ function AgentTab({ state }) {
2497
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
2498
+ /* @__PURE__ */ jsxs(Section, { title: "Loop State", children: [
2499
+ /* @__PURE__ */ jsx(
2500
+ Row,
2501
+ {
2502
+ label: "Iteration",
2503
+ value: `${state.agentLoop.iteration} / ${state.agentLoop.maxIterations}`
2504
+ }
2505
+ ),
2506
+ /* @__PURE__ */ jsx(
2507
+ Row,
2508
+ {
2509
+ label: "Pending Approvals",
2510
+ value: state.agentLoop.pendingApprovals
2511
+ }
2512
+ )
2513
+ ] }),
2514
+ /* @__PURE__ */ jsx(Section, { title: "Tool Executions", children: state.agentLoop.toolExecutions.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No executions" }) : /* @__PURE__ */ jsx("div", { className: "space-y-2", children: state.agentLoop.toolExecutions.map((exec) => /* @__PURE__ */ jsxs(
2515
+ "div",
2516
+ {
2517
+ className: "border rounded p-2 text-sm space-y-1",
2518
+ children: [
2519
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
2520
+ /* @__PURE__ */ jsx("code", { className: "font-medium", children: exec.name }),
2521
+ /* @__PURE__ */ jsx(StatusBadge, { status: exec.status })
2522
+ ] }),
2523
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [
2524
+ /* @__PURE__ */ jsxs("span", { children: [
2525
+ "ID: ",
2526
+ exec.id.slice(0, 12),
2527
+ "..."
2528
+ ] }),
2529
+ /* @__PURE__ */ jsxs("span", { children: [
2530
+ "Approval: ",
2531
+ exec.approvalStatus
2532
+ ] })
2533
+ ] })
2534
+ ]
2535
+ },
2536
+ exec.id
2537
+ )) }) }),
2538
+ /* @__PURE__ */ jsx(Section, { title: "Registered Actions", children: state.registered.actions.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No actions registered" }) : /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: state.registered.actions.map((action) => /* @__PURE__ */ jsx(
2539
+ "code",
2540
+ {
2541
+ className: "bg-muted px-1.5 py-0.5 rounded text-xs",
2542
+ children: action.name
2543
+ },
2544
+ action.name
2545
+ )) }) }),
2546
+ /* @__PURE__ */ jsx(Section, { title: "Context Tree", children: /* @__PURE__ */ jsx(Row, { label: "Context Items", value: state.registered.contextCount }) })
2547
+ ] });
2548
+ }
2549
+ function ConfigTab({ state }) {
2550
+ return /* @__PURE__ */ jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs(Section, { title: "Provider", children: [
2551
+ /* @__PURE__ */ jsx(Row, { label: "Provider", value: state.config.provider || "Not set" }),
2552
+ /* @__PURE__ */ jsx(Row, { label: "Model", value: state.config.model || "Default" }),
2553
+ /* @__PURE__ */ jsx(
2554
+ Row,
2555
+ {
2556
+ label: "Runtime URL",
2557
+ value: state.config.runtimeUrl || "Not set",
2558
+ mono: true
2559
+ }
2560
+ )
2561
+ ] }) });
2562
+ }
2563
+ function Section({
2564
+ title,
2565
+ children
2566
+ }) {
2567
+ return /* @__PURE__ */ jsxs("div", { children: [
2568
+ /* @__PURE__ */ jsx("h3", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-2", children: title }),
2569
+ children
2570
+ ] });
2571
+ }
2572
+ function Row({
2573
+ label,
2574
+ value,
2575
+ mono,
2576
+ valueClass
2577
+ }) {
2578
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between py-1 text-sm", children: [
2579
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
2580
+ /* @__PURE__ */ jsx(
2581
+ "span",
2582
+ {
2583
+ className: cn(
2584
+ mono && "font-mono text-xs bg-muted px-1.5 py-0.5 rounded",
2585
+ valueClass
2586
+ ),
2587
+ children: value
2588
+ }
2589
+ )
2590
+ ] });
2591
+ }
2592
+ function Badge({ level }) {
2593
+ const colors = {
2594
+ allow_always: "bg-green-100 text-green-800",
2595
+ deny_always: "bg-red-100 text-red-800",
2596
+ session: "bg-blue-100 text-blue-800",
2597
+ ask: "bg-gray-100 text-gray-800"
2598
+ };
2599
+ return /* @__PURE__ */ jsx(
2600
+ "span",
2601
+ {
2602
+ className: cn(
2603
+ "px-1.5 py-0.5 rounded text-xs font-medium",
2604
+ colors[level] || colors.ask
2605
+ ),
2606
+ children: level
2607
+ }
2608
+ );
2609
+ }
2610
+ function StatusBadge({ status }) {
2611
+ const colors = {
2612
+ pending: "bg-yellow-100 text-yellow-800",
2613
+ executing: "bg-blue-100 text-blue-800",
2614
+ completed: "bg-green-100 text-green-800",
2615
+ error: "bg-red-100 text-red-800"
2616
+ };
2617
+ return /* @__PURE__ */ jsx(
2618
+ "span",
2619
+ {
2620
+ className: cn(
2621
+ "px-1.5 py-0.5 rounded text-xs font-medium",
2622
+ colors[status] || "bg-gray-100 text-gray-800"
2623
+ ),
2624
+ children: status
2625
+ }
2626
+ );
2627
+ }
2628
+ var icons = {
2629
+ vision: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2630
+ /* @__PURE__ */ jsx("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }),
2631
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3" })
2632
+ ] }),
2633
+ tools: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { d: "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z" }) }),
2634
+ thinking: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2635
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
2636
+ /* @__PURE__ */ jsx("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
2637
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
2638
+ ] }),
2639
+ streaming: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { d: "M22 12h-4l-3 9L9 3l-3 9H2" }) }),
2640
+ pdf: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2641
+ /* @__PURE__ */ jsx("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
2642
+ /* @__PURE__ */ jsx("polyline", { points: "14 2 14 8 20 8" }),
2643
+ /* @__PURE__ */ jsx("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
2644
+ /* @__PURE__ */ jsx("line", { x1: "16", y1: "17", x2: "8", y2: "17" }),
2645
+ /* @__PURE__ */ jsx("polyline", { points: "10 9 9 9 8 9" })
2646
+ ] }),
2647
+ audio: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2648
+ /* @__PURE__ */ jsx("path", { d: "M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" }),
2649
+ /* @__PURE__ */ jsx("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
2650
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "19", x2: "12", y2: "23" }),
2651
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "23", x2: "16", y2: "23" })
2652
+ ] }),
2653
+ video: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2654
+ /* @__PURE__ */ jsx("polygon", { points: "23 7 16 12 23 17 23 7" }),
2655
+ /* @__PURE__ */ jsx("rect", { x: "1", y: "5", width: "15", height: "14", rx: "2", ry: "2" })
2656
+ ] }),
2657
+ json: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
2658
+ /* @__PURE__ */ jsx("path", { d: "M4 6h16" }),
2659
+ /* @__PURE__ */ jsx("path", { d: "M4 12h16" }),
2660
+ /* @__PURE__ */ jsx("path", { d: "M4 18h12" })
2661
+ ] })
2662
+ };
2663
+ var labels = {
2664
+ vision: "Vision",
2665
+ tools: "Tools",
2666
+ thinking: "Thinking",
2667
+ streaming: "Streaming",
2668
+ pdf: "PDF",
2669
+ audio: "Audio",
2670
+ video: "Video",
2671
+ json: "JSON"
2672
+ };
2673
+ var descriptions = {
2674
+ vision: "Supports image inputs",
2675
+ tools: "Supports function calling",
2676
+ thinking: "Extended reasoning mode",
2677
+ streaming: "Real-time streaming",
2678
+ pdf: "Can process PDF files",
2679
+ audio: "Supports audio inputs",
2680
+ video: "Supports video inputs",
2681
+ json: "Structured JSON output"
2682
+ };
2683
+ function CapabilityBadge({
2684
+ type,
2685
+ supported = true,
2686
+ showLabel = false,
2687
+ size = "sm",
2688
+ className
2689
+ }) {
2690
+ const sizeClasses = {
2691
+ sm: "h-5 px-1.5 text-[10px]",
2692
+ md: "h-6 px-2 text-xs",
2693
+ lg: "h-7 px-2.5 text-sm"
2694
+ };
2695
+ const iconSizes = {
2696
+ sm: "w-3 h-3",
2697
+ md: "w-3.5 h-3.5",
2698
+ lg: "w-4 h-4"
2699
+ };
2700
+ return /* @__PURE__ */ jsxs(
2701
+ "div",
2702
+ {
2703
+ className: cn(
2704
+ "inline-flex items-center gap-1 rounded-full font-medium transition-colors",
2705
+ sizeClasses[size],
2706
+ supported ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground opacity-50",
2707
+ className
2708
+ ),
2709
+ title: `${labels[type]}: ${descriptions[type]}`,
2710
+ children: [
2711
+ /* @__PURE__ */ jsx("span", { className: cn("flex-shrink-0", iconSizes[size]), children: icons[type] }),
2712
+ showLabel && /* @__PURE__ */ jsx("span", { children: labels[type] })
2713
+ ]
2714
+ }
2715
+ );
2716
+ }
2717
+ function CapabilityList({
2718
+ capabilities,
2719
+ showLabels = false,
2720
+ onlySupported = true,
2721
+ size = "sm",
2722
+ className
2723
+ }) {
2724
+ const items = [
2725
+ { type: "vision", supported: capabilities.supportsVision ?? false },
2726
+ { type: "tools", supported: capabilities.supportsTools ?? false },
2727
+ { type: "thinking", supported: capabilities.supportsThinking ?? false },
2728
+ { type: "streaming", supported: capabilities.supportsStreaming ?? false },
2729
+ { type: "pdf", supported: capabilities.supportsPDF ?? false },
2730
+ { type: "audio", supported: capabilities.supportsAudio ?? false },
2731
+ { type: "video", supported: capabilities.supportsVideo ?? false },
2732
+ { type: "json", supported: capabilities.supportsJsonMode ?? false }
2733
+ ];
2734
+ const filteredItems = onlySupported ? items.filter((item) => item.supported) : items;
2735
+ if (filteredItems.length === 0) return null;
2736
+ return /* @__PURE__ */ jsx("div", { className: cn("flex flex-wrap gap-1", className), children: filteredItems.map((item) => /* @__PURE__ */ jsx(
2737
+ CapabilityBadge,
2738
+ {
2739
+ type: item.type,
2740
+ supported: item.supported,
2741
+ showLabel: showLabels,
2742
+ size
2743
+ },
2744
+ item.type
2745
+ )) });
2746
+ }
2747
+ function ModelSelector({
2748
+ value,
2749
+ onChange,
2750
+ providers,
2751
+ models,
2752
+ currentCapabilities,
2753
+ placeholder = "Select model...",
2754
+ disabled = false,
2755
+ size = "md",
2756
+ showCapabilities = true,
2757
+ className
2758
+ }) {
2759
+ const [isOpen, setIsOpen] = React8.useState(false);
2760
+ const containerRef = React8.useRef(null);
2761
+ React8.useEffect(() => {
2762
+ function handleClickOutside(event) {
2763
+ if (containerRef.current && !containerRef.current.contains(event.target)) {
2764
+ setIsOpen(false);
2765
+ }
2766
+ }
2767
+ document.addEventListener("mousedown", handleClickOutside);
2768
+ return () => document.removeEventListener("mousedown", handleClickOutside);
2769
+ }, []);
2770
+ const selectedModel = React8.useMemo(() => {
2771
+ if (!value) return null;
2772
+ if (providers) {
2773
+ for (const provider of providers) {
2774
+ const model = provider.models.find((m) => m.id === value);
2775
+ if (model) return { ...model, provider: provider.name };
2776
+ }
2777
+ }
2778
+ if (models) {
2779
+ return models.find((m) => m.id === value) || null;
2780
+ }
2781
+ return null;
2782
+ }, [value, providers, models]);
2783
+ const sizeClasses = {
2784
+ sm: "h-8 text-xs px-2",
2785
+ md: "h-9 text-sm px-3",
2786
+ lg: "h-10 text-base px-4"
2787
+ };
2788
+ const handleSelect = (modelId, provider) => {
2789
+ onChange?.(modelId, provider);
2790
+ setIsOpen(false);
2791
+ };
2792
+ return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: cn("relative", className), children: [
2793
+ /* @__PURE__ */ jsxs(
2794
+ "button",
2795
+ {
2796
+ type: "button",
2797
+ onClick: () => !disabled && setIsOpen(!isOpen),
2798
+ disabled,
2799
+ className: cn(
2800
+ "flex items-center justify-between gap-2 w-full rounded-md border bg-background",
2801
+ "hover:bg-accent hover:text-accent-foreground",
2802
+ "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
2803
+ "disabled:cursor-not-allowed disabled:opacity-50",
2804
+ sizeClasses[size]
2805
+ ),
2806
+ children: [
2807
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 min-w-0", children: selectedModel ? /* @__PURE__ */ jsxs(Fragment, { children: [
2808
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: selectedModel.name || selectedModel.id }),
2809
+ selectedModel.provider && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-[10px] uppercase", children: selectedModel.provider })
2810
+ ] }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder }) }),
2811
+ /* @__PURE__ */ jsx(
2812
+ "svg",
2813
+ {
2814
+ className: cn(
2815
+ "w-4 h-4 flex-shrink-0 text-muted-foreground transition-transform",
2816
+ isOpen && "rotate-180"
2817
+ ),
2818
+ fill: "none",
2819
+ viewBox: "0 0 24 24",
2820
+ stroke: "currentColor",
2821
+ strokeWidth: 2,
2822
+ children: /* @__PURE__ */ jsx(
2823
+ "path",
2824
+ {
2825
+ strokeLinecap: "round",
2826
+ strokeLinejoin: "round",
2827
+ d: "M19 9l-7 7-7-7"
2828
+ }
2829
+ )
2830
+ }
2831
+ )
2832
+ ]
2833
+ }
2834
+ ),
2835
+ showCapabilities && currentCapabilities && /* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
2836
+ CapabilityList,
2837
+ {
2838
+ capabilities: currentCapabilities,
2839
+ size: "sm",
2840
+ onlySupported: true
2841
+ }
2842
+ ) }),
2843
+ isOpen && /* @__PURE__ */ jsxs(
2844
+ "div",
2845
+ {
2846
+ className: cn(
2847
+ "absolute z-50 top-full left-0 right-0 mt-1",
2848
+ "max-h-[300px] overflow-auto",
2849
+ "rounded-md border bg-popover text-popover-foreground shadow-md",
2850
+ "animate-in fade-in-0 zoom-in-95"
2851
+ ),
2852
+ children: [
2853
+ providers?.map((provider) => /* @__PURE__ */ jsxs("div", { children: [
2854
+ /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-[10px] font-semibold text-muted-foreground uppercase tracking-wider bg-muted/50", children: provider.label || provider.name }),
2855
+ provider.models.map((model) => /* @__PURE__ */ jsxs(
2856
+ "button",
2857
+ {
2858
+ type: "button",
2859
+ onClick: () => handleSelect(model.id, provider.name),
2860
+ className: cn(
2861
+ "flex flex-col gap-0.5 w-full px-3 py-2 text-left",
2862
+ "hover:bg-accent hover:text-accent-foreground",
2863
+ "focus:bg-accent focus:text-accent-foreground focus:outline-none",
2864
+ value === model.id && "bg-accent"
2865
+ ),
2866
+ children: [
2867
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2868
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-sm", children: model.name || model.id }),
2869
+ value === model.id && /* @__PURE__ */ jsx(
2870
+ "svg",
2871
+ {
2872
+ className: "w-4 h-4 text-primary",
2873
+ fill: "none",
2874
+ viewBox: "0 0 24 24",
2875
+ stroke: "currentColor",
2876
+ strokeWidth: 2,
2877
+ children: /* @__PURE__ */ jsx(
2878
+ "path",
2879
+ {
2880
+ strokeLinecap: "round",
2881
+ strokeLinejoin: "round",
2882
+ d: "M5 13l4 4L19 7"
2883
+ }
2884
+ )
2885
+ }
2886
+ )
2887
+ ] }),
2888
+ showCapabilities && model.capabilities && /* @__PURE__ */ jsx(
2889
+ CapabilityList,
2890
+ {
2891
+ capabilities: model.capabilities,
2892
+ size: "sm",
2893
+ onlySupported: true
2894
+ }
2895
+ )
2896
+ ]
2897
+ },
2898
+ model.id
2899
+ ))
2900
+ ] }, provider.name)),
2901
+ models?.map((model) => /* @__PURE__ */ jsxs(
2902
+ "button",
2903
+ {
2904
+ type: "button",
2905
+ onClick: () => handleSelect(model.id, model.provider),
2906
+ className: cn(
2907
+ "flex flex-col gap-0.5 w-full px-3 py-2 text-left",
2908
+ "hover:bg-accent hover:text-accent-foreground",
2909
+ "focus:bg-accent focus:text-accent-foreground focus:outline-none",
2910
+ value === model.id && "bg-accent"
2911
+ ),
2912
+ children: [
2913
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2914
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-sm", children: model.name || model.id }),
2915
+ model.provider && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-[10px] uppercase", children: model.provider }),
2916
+ value === model.id && /* @__PURE__ */ jsx(
2917
+ "svg",
2918
+ {
2919
+ className: "w-4 h-4 text-primary ml-auto",
2920
+ fill: "none",
2921
+ viewBox: "0 0 24 24",
2922
+ stroke: "currentColor",
2923
+ strokeWidth: 2,
2924
+ children: /* @__PURE__ */ jsx(
2925
+ "path",
2926
+ {
2927
+ strokeLinecap: "round",
2928
+ strokeLinejoin: "round",
2929
+ d: "M5 13l4 4L19 7"
2930
+ }
2931
+ )
2932
+ }
2933
+ )
2934
+ ] }),
2935
+ showCapabilities && model.capabilities && /* @__PURE__ */ jsx(
2936
+ CapabilityList,
2937
+ {
2938
+ capabilities: model.capabilities,
2939
+ size: "sm",
2940
+ onlySupported: true
2941
+ }
2942
+ )
2943
+ ]
2944
+ },
2945
+ model.id
2946
+ )),
2947
+ !providers?.length && !models?.length && /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "No models available" })
2948
+ ]
2949
+ }
2950
+ )
2951
+ ] });
2952
+ }
2953
+ function SimpleModelSelector({
2954
+ value,
2955
+ onChange,
2956
+ models,
2957
+ disabled = false,
2958
+ className
2959
+ }) {
2960
+ return /* @__PURE__ */ jsxs(
2961
+ "select",
2962
+ {
2963
+ value: value || "",
2964
+ onChange: (e) => onChange?.(e.target.value),
2965
+ disabled,
2966
+ className: cn(
2967
+ "h-9 px-3 rounded-md border bg-background text-sm",
2968
+ "focus:outline-none focus:ring-2 focus:ring-ring",
2969
+ "disabled:cursor-not-allowed disabled:opacity-50",
2970
+ className
2971
+ ),
2972
+ children: [
2973
+ /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select model..." }),
2974
+ models.map((modelId) => /* @__PURE__ */ jsx("option", { value: modelId, children: modelId }, modelId))
2975
+ ]
2976
+ }
2977
+ );
2978
+ }
2979
+ function ChatHeader({ title, onClose, className }) {
2980
+ return /* @__PURE__ */ jsxs(
2981
+ "div",
2982
+ {
2983
+ className: cn(
2984
+ "flex items-center justify-between border-b px-4 py-3",
2985
+ className
2986
+ ),
2987
+ children: [
2988
+ /* @__PURE__ */ jsx("h2", { className: "font-semibold text-foreground", children: title || "Chat" }),
2989
+ onClose && /* @__PURE__ */ jsx(
2990
+ "button",
2991
+ {
2992
+ type: "button",
2993
+ onClick: onClose,
2994
+ className: "rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
2995
+ "aria-label": "Close chat",
2996
+ children: /* @__PURE__ */ jsx(CloseIcon, { className: "h-5 w-5" })
2997
+ }
2998
+ )
2999
+ ]
3000
+ }
3001
+ );
3002
+ }
3003
+ function Suggestions({
3004
+ suggestions,
3005
+ onSuggestionClick,
3006
+ className
3007
+ }) {
3008
+ if (!suggestions.length) return null;
3009
+ return /* @__PURE__ */ jsx("div", { className: cn("flex flex-wrap gap-2 px-4 py-2", className), children: suggestions.map((suggestion, index) => /* @__PURE__ */ jsx(
3010
+ "button",
3011
+ {
3012
+ type: "button",
3013
+ onClick: () => onSuggestionClick?.(suggestion),
3014
+ className: "inline-flex items-center rounded-full border bg-background px-3 py-1.5 text-sm transition-colors hover:bg-muted",
3015
+ children: suggestion
3016
+ },
3017
+ index
3018
+ )) });
3019
+ }
3020
+ function DefaultMessage({
3021
+ message,
3022
+ userAvatar,
3023
+ assistantAvatar,
3024
+ showUserAvatar = false,
3025
+ userMessageClassName,
3026
+ assistantMessageClassName,
3027
+ size = "sm",
3028
+ isLastMessage = false,
3029
+ isLoading = false,
3030
+ toolRenderers,
3031
+ onApproveToolExecution,
3032
+ onRejectToolExecution,
3033
+ showFollowUps = true,
3034
+ onFollowUpClick,
3035
+ followUpClassName,
3036
+ followUpButtonClassName
3037
+ }) {
3038
+ const isUser = message.role === "user";
3039
+ const isStreaming = isLastMessage && isLoading;
3040
+ const { cleanContent, followUps } = React8.useMemo(() => {
3041
+ if (isUser || !message.content) {
3042
+ return { cleanContent: message.content, followUps: [] };
3043
+ }
3044
+ return parseFollowUps(message.content);
3045
+ }, [message.content, isUser]);
3046
+ const shouldShowFollowUps = showFollowUps && !isUser && isLastMessage && !isLoading && followUps.length > 0 && onFollowUpClick;
3047
+ if (isUser) {
3048
+ const hasAttachments = message.attachments && message.attachments.length > 0;
3049
+ return /* @__PURE__ */ jsxs(
3050
+ Message,
3051
+ {
3052
+ className: cn(
3053
+ "flex gap-2",
3054
+ showUserAvatar ? "justify-end" : "justify-end"
3055
+ ),
3056
+ children: [
3057
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end max-w-[80%]", children: [
3058
+ message.content && /* @__PURE__ */ jsx(
3059
+ MessageContent,
3060
+ {
3061
+ className: cn(
3062
+ "rounded-lg px-4 py-2 bg-primary text-primary-foreground",
3063
+ userMessageClassName
3064
+ ),
3065
+ size,
3066
+ children: message.content
3067
+ }
3068
+ ),
3069
+ hasAttachments && /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-2 justify-end", children: message.attachments.map((attachment, index) => /* @__PURE__ */ jsx(AttachmentPreview, { attachment }, index)) })
3070
+ ] }),
3071
+ showUserAvatar && /* @__PURE__ */ jsx(
3072
+ MessageAvatar,
3073
+ {
3074
+ src: userAvatar.src || "",
3075
+ alt: "User",
3076
+ fallback: userAvatar.fallback
3077
+ }
3078
+ )
3079
+ ]
3080
+ }
3081
+ );
3082
+ }
3083
+ const pendingApprovalTools = message.toolExecutions?.filter(
3084
+ (exec) => exec.approvalStatus === "required"
3085
+ );
3086
+ const completedTools = message.toolExecutions?.filter(
3087
+ (exec) => exec.approvalStatus !== "required"
3088
+ );
3089
+ const toolsWithCustomRenderer = completedTools?.filter(
3090
+ (exec) => toolRenderers && toolRenderers[exec.name]
3091
+ );
3092
+ const toolsWithoutCustomRenderer = completedTools?.filter(
3093
+ (exec) => !toolRenderers || !toolRenderers[exec.name]
3094
+ );
3095
+ const toolSteps = toolsWithoutCustomRenderer?.map((exec) => ({
3096
+ id: exec.id,
3097
+ name: exec.name,
3098
+ args: exec.args,
3099
+ status: exec.status,
3100
+ result: exec.result,
3101
+ error: exec.error
3102
+ }));
3103
+ return /* @__PURE__ */ jsxs(Message, { className: "flex gap-2", children: [
3104
+ /* @__PURE__ */ jsx(
3105
+ MessageAvatar,
3106
+ {
3107
+ src: assistantAvatar.src || "",
3108
+ alt: "Assistant",
3109
+ fallback: assistantAvatar.fallback,
3110
+ className: "bg-primary text-primary-foreground"
3111
+ }
3112
+ ),
3113
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 max-w-[80%]", children: [
3114
+ message.thinking && /* @__PURE__ */ jsx(
3115
+ SimpleReasoning,
3116
+ {
3117
+ content: message.thinking,
3118
+ isStreaming,
3119
+ className: "mb-2"
3120
+ }
3121
+ ),
3122
+ cleanContent?.trim() && /* @__PURE__ */ jsx(
3123
+ MessageContent,
3124
+ {
3125
+ className: cn(
3126
+ "rounded-lg px-4 py-2 bg-muted",
3127
+ assistantMessageClassName
3128
+ ),
3129
+ markdown: true,
3130
+ size,
3131
+ children: cleanContent
3132
+ }
3133
+ ),
3134
+ toolsWithCustomRenderer && toolsWithCustomRenderer.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-2 space-y-2", children: toolsWithCustomRenderer.map((exec) => {
3135
+ const Renderer = toolRenderers[exec.name];
3136
+ return /* @__PURE__ */ jsx(
3137
+ Renderer,
3138
+ {
3139
+ execution: {
3140
+ id: exec.id,
3141
+ name: exec.name,
3142
+ args: exec.args,
3143
+ status: exec.status,
3144
+ result: exec.result,
3145
+ error: exec.error,
3146
+ approvalStatus: exec.approvalStatus
3147
+ }
3148
+ },
3149
+ exec.id
3150
+ );
3151
+ }) }),
3152
+ toolSteps && toolSteps.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-2 rounded-lg bg-muted/50 px-3 py-2", children: /* @__PURE__ */ jsx(ToolSteps, { steps: toolSteps }) }),
3153
+ pendingApprovalTools && pendingApprovalTools.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-2 space-y-2", children: pendingApprovalTools.map((tool) => /* @__PURE__ */ jsx(
3154
+ PermissionConfirmation,
3155
+ {
3156
+ state: "pending",
3157
+ toolName: tool.name,
3158
+ message: tool.approvalMessage || `This tool wants to execute. Do you approve?`,
3159
+ onApprove: (permissionLevel) => onApproveToolExecution?.(tool.id, permissionLevel),
3160
+ onReject: (permissionLevel) => onRejectToolExecution?.(tool.id, void 0, permissionLevel)
3161
+ },
3162
+ tool.id
3163
+ )) }),
3164
+ message.attachments && message.attachments.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-2", children: message.attachments.map((attachment, index) => /* @__PURE__ */ jsx(AttachmentPreview, { attachment }, index)) }),
3165
+ shouldShowFollowUps && /* @__PURE__ */ jsx(
3166
+ FollowUpQuestions,
3167
+ {
3168
+ questions: followUps,
3169
+ onSelect: onFollowUpClick,
3170
+ className: followUpClassName,
3171
+ buttonClassName: followUpButtonClassName
3172
+ }
3173
+ )
3174
+ ] })
3175
+ ] });
3176
+ }
3177
+ function AttachmentPreview({ attachment }) {
3178
+ const [expanded, setExpanded] = React8.useState(false);
3179
+ if (attachment.type !== "image") {
3180
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-lg border bg-muted/50 px-3 py-2 text-sm", children: [
3181
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: attachment.type }),
3182
+ /* @__PURE__ */ jsx("span", { children: attachment.filename || "Attachment" })
3183
+ ] });
3184
+ }
3185
+ let src;
3186
+ if (attachment.url) {
3187
+ src = attachment.url;
3188
+ } else if (attachment.data) {
3189
+ src = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType};base64,${attachment.data}`;
3190
+ } else {
3191
+ return null;
3192
+ }
3193
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3194
+ /* @__PURE__ */ jsx(
3195
+ "button",
3196
+ {
3197
+ type: "button",
3198
+ onClick: () => setExpanded(true),
3199
+ className: "relative rounded-lg overflow-hidden border bg-muted/50 hover:opacity-90 transition-opacity",
3200
+ children: /* @__PURE__ */ jsx(
3201
+ "img",
3202
+ {
3203
+ src,
3204
+ alt: attachment.filename || "Image",
3205
+ className: "max-w-[200px] max-h-[150px] object-cover"
3206
+ }
3207
+ )
3208
+ }
3209
+ ),
3210
+ expanded && /* @__PURE__ */ jsx(
3211
+ "div",
3212
+ {
3213
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-black/80",
3214
+ onClick: () => setExpanded(false),
3215
+ children: /* @__PURE__ */ jsxs("div", { className: "relative max-w-[90vw] max-h-[90vh]", children: [
3216
+ /* @__PURE__ */ jsx(
3217
+ "img",
3218
+ {
3219
+ src,
3220
+ alt: attachment.filename || "Image (expanded)",
3221
+ className: "max-w-full max-h-full object-contain rounded-lg"
3222
+ }
3223
+ ),
3224
+ /* @__PURE__ */ jsx(
3225
+ "button",
3226
+ {
3227
+ type: "button",
3228
+ className: "absolute top-2 right-2 bg-white/90 rounded-full p-2 hover:bg-white transition-colors",
3229
+ onClick: (e) => {
3230
+ e.stopPropagation();
3231
+ setExpanded(false);
3232
+ },
3233
+ children: /* @__PURE__ */ jsx(
3234
+ "svg",
3235
+ {
3236
+ className: "w-4 h-4",
3237
+ fill: "none",
3238
+ viewBox: "0 0 24 24",
3239
+ stroke: "currentColor",
3240
+ strokeWidth: 2,
3241
+ children: /* @__PURE__ */ jsx(
3242
+ "path",
3243
+ {
3244
+ strokeLinecap: "round",
3245
+ strokeLinejoin: "round",
3246
+ d: "M6 18L18 6M6 6l12 12"
3247
+ }
3248
+ )
3249
+ }
3250
+ )
3251
+ }
3252
+ )
3253
+ ] })
3254
+ }
3255
+ )
3256
+ ] });
3257
+ }
3258
+ var DEFAULT_MAX_FILE_SIZE = 5 * 1024 * 1024;
3259
+ var DEFAULT_ALLOWED_TYPES = ["image/*", "application/pdf"];
3260
+ function getAttachmentType(mimeType) {
3261
+ if (mimeType.startsWith("image/")) return "image";
3262
+ if (mimeType.startsWith("audio/")) return "audio";
3263
+ if (mimeType.startsWith("video/")) return "video";
3264
+ return "file";
3265
+ }
3266
+ function fileToBase64(file) {
3267
+ return new Promise((resolve, reject) => {
3268
+ const reader = new FileReader();
3269
+ reader.onload = () => {
3270
+ if (typeof reader.result === "string") {
3271
+ resolve(reader.result);
3272
+ } else {
3273
+ reject(new Error("Failed to read file"));
3274
+ }
3275
+ };
3276
+ reader.onerror = () => reject(new Error("Failed to read file"));
3277
+ reader.readAsDataURL(file);
3278
+ });
3279
+ }
3280
+ function generateAttachmentId() {
3281
+ return `att_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
3282
+ }
3283
+ function Chat({
3284
+ // Core
3285
+ messages = [],
3286
+ onSendMessage,
3287
+ onStop,
3288
+ isLoading = false,
3289
+ // Labels
3290
+ placeholder = "Type a message...",
3291
+ welcomeMessage,
3292
+ title,
3293
+ // Header
3294
+ showHeader = false,
3295
+ onClose,
3296
+ // Appearance
3297
+ showPoweredBy = true,
3298
+ showUserAvatar = false,
3299
+ userAvatar = { fallback: "U" },
3300
+ assistantAvatar = { fallback: "AI" },
3301
+ loaderVariant = "typing",
3302
+ fontSize = "sm",
3303
+ // Attachments
3304
+ maxFileSize = DEFAULT_MAX_FILE_SIZE,
3305
+ allowedFileTypes = DEFAULT_ALLOWED_TYPES,
3306
+ attachmentsEnabled = true,
3307
+ attachmentsDisabledTooltip = "Attachments not supported by this model",
3308
+ processAttachment: processAttachmentProp,
3309
+ // Suggestions
3310
+ suggestions = [],
3311
+ onSuggestionClick,
3312
+ // Tool Executions
3313
+ isProcessing = false,
3314
+ toolRenderers,
3315
+ onApproveToolExecution,
3316
+ onRejectToolExecution,
3317
+ // Follow-up Questions
3318
+ showFollowUps = true,
3319
+ followUpClassName,
3320
+ followUpButtonClassName,
3321
+ // Custom rendering
3322
+ renderMessage,
3323
+ renderInput,
3324
+ renderHeader,
3325
+ // Styling
3326
+ className,
3327
+ classNames = {}
3328
+ }) {
3329
+ const [input, setInput] = useState("");
3330
+ const [pendingAttachments, setPendingAttachments] = useState([]);
3331
+ const [isDragging, setIsDragging] = useState(false);
3332
+ const fileInputRef = useRef(null);
3333
+ const fileInputId = useId();
3334
+ const isFileTypeAllowed = useCallback(
3335
+ (file) => {
3336
+ for (const type of allowedFileTypes) {
3337
+ if (type.endsWith("/*")) {
3338
+ const category = type.slice(0, -2);
3339
+ if (file.type.startsWith(category + "/")) return true;
3340
+ } else if (file.type === type) {
3341
+ return true;
3342
+ }
3343
+ }
3344
+ return false;
3345
+ },
3346
+ [allowedFileTypes]
3347
+ );
3348
+ const handleFileSelect = useCallback(
3349
+ async (files) => {
3350
+ if (!files || !attachmentsEnabled) return;
3351
+ for (const file of Array.from(files)) {
3352
+ if (file.size > maxFileSize) {
3353
+ const sizeMB = (maxFileSize / (1024 * 1024)).toFixed(0);
3354
+ console.warn(`File ${file.name} exceeds ${sizeMB}MB limit`);
3355
+ continue;
3356
+ }
3357
+ if (!isFileTypeAllowed(file)) {
3358
+ console.warn(`File type ${file.type} is not allowed`);
3359
+ continue;
3360
+ }
3361
+ const id = generateAttachmentId();
3362
+ const previewUrl = URL.createObjectURL(file);
3363
+ setPendingAttachments((prev) => [
3364
+ ...prev,
3365
+ {
3366
+ id,
3367
+ file,
3368
+ previewUrl,
3369
+ attachment: {
3370
+ type: getAttachmentType(file.type),
3371
+ data: "",
3372
+ mimeType: file.type,
3373
+ filename: file.name
3374
+ },
3375
+ status: "processing"
3376
+ }
3377
+ ]);
3378
+ try {
3379
+ let attachment;
3380
+ if (processAttachmentProp) {
3381
+ attachment = await processAttachmentProp(file);
3382
+ } else {
3383
+ const data = await fileToBase64(file);
3384
+ attachment = {
3385
+ type: getAttachmentType(file.type),
3386
+ data,
3387
+ mimeType: file.type,
3388
+ filename: file.name
3389
+ };
3390
+ }
3391
+ setPendingAttachments(
3392
+ (prev) => prev.map(
3393
+ (att) => att.id === id ? { ...att, status: "ready", attachment } : att
3394
+ )
3395
+ );
3396
+ } catch (error) {
3397
+ setPendingAttachments(
3398
+ (prev) => prev.map(
3399
+ (att) => att.id === id ? {
3400
+ ...att,
3401
+ status: "error",
3402
+ error: "Failed to process file"
3403
+ } : att
3404
+ )
3405
+ );
3406
+ }
3407
+ }
3408
+ },
3409
+ [attachmentsEnabled, maxFileSize, isFileTypeAllowed, processAttachmentProp]
3410
+ );
3411
+ const handleInputChange = useCallback(
3412
+ (e) => {
3413
+ handleFileSelect(e.target.files);
3414
+ if (fileInputRef.current) {
3415
+ fileInputRef.current.value = "";
3416
+ }
3417
+ },
3418
+ [handleFileSelect]
3419
+ );
3420
+ const removePendingAttachment = useCallback((id) => {
3421
+ setPendingAttachments((prev) => {
3422
+ const att = prev.find((a) => a.id === id);
3423
+ if (att) {
3424
+ URL.revokeObjectURL(att.previewUrl);
3425
+ }
3426
+ return prev.filter((a) => a.id !== id);
3427
+ });
3428
+ }, []);
3429
+ const handleDragOver = useCallback(
3430
+ (e) => {
3431
+ e.preventDefault();
3432
+ e.stopPropagation();
3433
+ if (attachmentsEnabled) {
3434
+ setIsDragging(true);
3435
+ }
3436
+ },
3437
+ [attachmentsEnabled]
3438
+ );
3439
+ const handleDragLeave = useCallback((e) => {
3440
+ e.preventDefault();
3441
+ e.stopPropagation();
3442
+ setIsDragging(false);
3443
+ }, []);
3444
+ const handleDrop = useCallback(
3445
+ (e) => {
3446
+ e.preventDefault();
3447
+ e.stopPropagation();
3448
+ setIsDragging(false);
3449
+ if (attachmentsEnabled) {
3450
+ handleFileSelect(e.dataTransfer.files);
3451
+ }
3452
+ },
3453
+ [attachmentsEnabled, handleFileSelect]
3454
+ );
3455
+ const handleSubmit = useCallback(() => {
3456
+ const hasContent = input.trim();
3457
+ const hasAttachments = pendingAttachments.some(
3458
+ (att) => att.status === "ready"
3459
+ );
3460
+ if (!hasContent && !hasAttachments || isLoading) return;
3461
+ const attachments = pendingAttachments.filter((att) => att.status === "ready").map((att) => att.attachment);
3462
+ onSendMessage?.(input, attachments.length > 0 ? attachments : void 0);
3463
+ pendingAttachments.forEach((att) => URL.revokeObjectURL(att.previewUrl));
3464
+ setPendingAttachments([]);
3465
+ setInput("");
3466
+ }, [input, isLoading, onSendMessage, pendingAttachments]);
3467
+ const handleSuggestionClick = useCallback(
3468
+ (suggestion) => {
3469
+ if (onSuggestionClick) {
3470
+ onSuggestionClick(suggestion);
3471
+ } else {
3472
+ onSendMessage?.(suggestion);
3473
+ }
3474
+ },
3475
+ [onSuggestionClick, onSendMessage]
3476
+ );
3477
+ const acceptString = allowedFileTypes.join(",");
3478
+ return /* @__PURE__ */ jsxs(
3479
+ "div",
3480
+ {
3481
+ className: cn(
3482
+ "flex h-full flex-col bg-background relative",
3483
+ className,
3484
+ classNames.root
3485
+ ),
3486
+ onDragOver: handleDragOver,
3487
+ onDragLeave: handleDragLeave,
3488
+ onDrop: handleDrop,
3489
+ children: [
3490
+ isDragging && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-50 bg-primary/10 border-2 border-dashed border-primary flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "text-primary font-medium text-lg", children: "Drop files here" }) }),
3491
+ showHeader && (renderHeader ? renderHeader() : /* @__PURE__ */ jsx(
3492
+ ChatHeader,
3493
+ {
3494
+ title,
3495
+ onClose,
3496
+ className: classNames.header
3497
+ }
3498
+ )),
3499
+ /* @__PURE__ */ jsxs(
3500
+ ChatContainerRoot,
3501
+ {
3502
+ className: cn("relative flex-1", classNames.container),
3503
+ children: [
3504
+ /* @__PURE__ */ jsxs(
3505
+ ChatContainerContent,
3506
+ {
3507
+ className: cn("gap-4 p-4", classNames.messageList),
3508
+ children: [
3509
+ messages.length === 0 && /* @__PURE__ */ jsx("div", { className: "py-8 text-center text-muted-foreground", children: welcomeMessage || "Send a message to start the conversation" }),
3510
+ messages.map((message, index) => {
3511
+ const isLastMessage = index === messages.length - 1;
3512
+ const isEmptyAssistant = message.role === "assistant" && !message.content?.trim();
3513
+ const hasToolCalls = message.tool_calls && message.tool_calls.length > 0;
3514
+ const hasToolExecutions = message.toolExecutions && message.toolExecutions.length > 0;
3515
+ const hasPendingApprovals = message.toolExecutions?.some(
3516
+ (exec) => exec.approvalStatus === "required"
3517
+ );
3518
+ if (isEmptyAssistant) {
3519
+ if (hasToolCalls || hasToolExecutions) ; else if (isLastMessage && hasPendingApprovals) ; else if (isLastMessage && isLoading && !isProcessing) {
3520
+ return /* @__PURE__ */ jsxs(Message, { className: "flex gap-2", children: [
3521
+ /* @__PURE__ */ jsx(
3522
+ MessageAvatar,
3523
+ {
3524
+ src: assistantAvatar.src || "",
3525
+ alt: "Assistant",
3526
+ fallback: assistantAvatar.fallback,
3527
+ className: "bg-primary text-primary-foreground"
3528
+ }
3529
+ ),
3530
+ /* @__PURE__ */ jsx("div", { className: "rounded-lg bg-muted px-4 py-2", children: /* @__PURE__ */ jsx(Loader, { variant: loaderVariant, size: "sm" }) })
3531
+ ] }, message.id);
3532
+ } else {
3533
+ return null;
3534
+ }
3535
+ }
3536
+ const savedExecutions = message.metadata?.toolExecutions;
3537
+ const messageToolExecutions = message.toolExecutions || savedExecutions;
3538
+ const messageWithExecutions = messageToolExecutions ? { ...message, toolExecutions: messageToolExecutions } : message;
3539
+ const handleFollowUpClick = (question) => {
3540
+ if (onSuggestionClick) {
3541
+ onSuggestionClick(question);
3542
+ } else {
3543
+ onSendMessage?.(question);
3544
+ }
3545
+ };
3546
+ return renderMessage ? /* @__PURE__ */ jsx(React8__default.Fragment, { children: renderMessage(messageWithExecutions, index) }, message.id) : /* @__PURE__ */ jsx(
3547
+ DefaultMessage,
3548
+ {
3549
+ message: messageWithExecutions,
3550
+ userAvatar,
3551
+ assistantAvatar,
3552
+ showUserAvatar,
3553
+ userMessageClassName: classNames.userMessage,
3554
+ assistantMessageClassName: classNames.assistantMessage,
3555
+ size: fontSize,
3556
+ isLastMessage,
3557
+ isLoading,
3558
+ toolRenderers,
3559
+ onApproveToolExecution,
3560
+ onRejectToolExecution,
3561
+ showFollowUps,
3562
+ onFollowUpClick: handleFollowUpClick,
3563
+ followUpClassName,
3564
+ followUpButtonClassName
3565
+ },
3566
+ message.id
3567
+ );
3568
+ }),
3569
+ isProcessing && /* @__PURE__ */ jsxs(Message, { className: "flex gap-2", children: [
3570
+ /* @__PURE__ */ jsx(
3571
+ MessageAvatar,
3572
+ {
3573
+ src: assistantAvatar?.src || "",
3574
+ alt: "Assistant",
3575
+ fallback: assistantAvatar?.fallback || "AI",
3576
+ className: "bg-primary text-primary-foreground"
3577
+ }
3578
+ ),
3579
+ /* @__PURE__ */ jsxs("div", { className: "rounded-lg bg-muted px-4 py-2 flex items-center gap-2", children: [
3580
+ /* @__PURE__ */ jsx(Loader, { variant: "dots", size: "sm" }),
3581
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Continuing..." })
3582
+ ] })
3583
+ ] }),
3584
+ isLoading && !isProcessing && (() => {
3585
+ const lastMessage = messages[messages.length - 1];
3586
+ if (lastMessage?.role === "user") {
3587
+ return /* @__PURE__ */ jsxs(Message, { className: "flex gap-2", children: [
3588
+ /* @__PURE__ */ jsx(
3589
+ MessageAvatar,
3590
+ {
3591
+ src: assistantAvatar?.src || "",
3592
+ alt: "Assistant",
3593
+ fallback: assistantAvatar?.fallback || "AI",
3594
+ className: "bg-primary text-primary-foreground"
3595
+ }
3596
+ ),
3597
+ /* @__PURE__ */ jsx("div", { className: "rounded-lg bg-muted px-4 py-2", children: /* @__PURE__ */ jsx(Loader, { variant: loaderVariant, size: "sm" }) })
3598
+ ] });
3599
+ }
3600
+ return null;
3601
+ })(),
3602
+ /* @__PURE__ */ jsx(ChatContainerScrollAnchor, {})
3603
+ ]
3604
+ }
3605
+ ),
3606
+ /* @__PURE__ */ jsx("div", { className: "absolute right-4 bottom-4", children: /* @__PURE__ */ jsx(ScrollButton, { className: "shadow-sm" }) })
3607
+ ]
3608
+ }
3609
+ ),
3610
+ suggestions.length > 0 && !isLoading && /* @__PURE__ */ jsx(
3611
+ Suggestions,
3612
+ {
3613
+ suggestions,
3614
+ onSuggestionClick: handleSuggestionClick,
3615
+ className: classNames.suggestions
3616
+ }
3617
+ ),
3618
+ renderInput ? renderInput() : /* @__PURE__ */ jsxs("div", { className: cn("p-2", classNames.input), children: [
3619
+ pendingAttachments.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 p-2 mb-2 bg-muted/30 rounded-lg", children: pendingAttachments.map((att) => /* @__PURE__ */ jsxs("div", { className: "relative group", children: [
3620
+ att.attachment.type === "image" ? /* @__PURE__ */ jsx(
3621
+ "img",
3622
+ {
3623
+ src: att.previewUrl,
3624
+ alt: att.file.name,
3625
+ className: "w-16 h-16 object-cover rounded-lg border"
3626
+ }
3627
+ ) : /* @__PURE__ */ jsxs("div", { className: "w-16 h-16 bg-muted rounded-lg border flex flex-col items-center justify-center p-1", children: [
3628
+ /* @__PURE__ */ jsx(
3629
+ "svg",
3630
+ {
3631
+ className: "w-6 h-6 text-muted-foreground",
3632
+ fill: "none",
3633
+ viewBox: "0 0 24 24",
3634
+ stroke: "currentColor",
3635
+ children: /* @__PURE__ */ jsx(
3636
+ "path",
3637
+ {
3638
+ strokeLinecap: "round",
3639
+ strokeLinejoin: "round",
3640
+ strokeWidth: 1.5,
3641
+ d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
3642
+ }
3643
+ )
3644
+ }
3645
+ ),
3646
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground truncate w-full text-center mt-1", children: att.file.name.length > 10 ? att.file.name.slice(0, 8) + "..." : att.file.name })
3647
+ ] }),
3648
+ att.status === "processing" && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-background/80 rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsx(Loader, { variant: "dots", size: "sm" }) }),
3649
+ att.status === "error" && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-destructive/20 rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "text-destructive text-xs", children: "Error" }) }),
3650
+ /* @__PURE__ */ jsx(
3651
+ "button",
3652
+ {
3653
+ onClick: () => removePendingAttachment(att.id),
3654
+ className: "absolute -top-1.5 -right-1.5 bg-destructive text-destructive-foreground rounded-full p-0.5 opacity-0 group-hover:opacity-100 transition-opacity",
3655
+ type: "button",
3656
+ children: /* @__PURE__ */ jsx(XIcon2, { className: "w-3 h-3" })
3657
+ }
3658
+ )
3659
+ ] }, att.id)) }),
3660
+ /* @__PURE__ */ jsxs(
3661
+ PromptInput,
3662
+ {
3663
+ value: input,
3664
+ onValueChange: setInput,
3665
+ isLoading,
3666
+ onSubmit: handleSubmit,
3667
+ className: "",
3668
+ children: [
3669
+ /* @__PURE__ */ jsx(PromptInputTextarea, { placeholder }),
3670
+ /* @__PURE__ */ jsxs(PromptInputActions, { className: "flex justify-between", children: [
3671
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
3672
+ PromptInputAction,
3673
+ {
3674
+ tooltip: attachmentsEnabled ? "Attach files" : attachmentsDisabledTooltip,
3675
+ children: /* @__PURE__ */ jsxs(
3676
+ "label",
3677
+ {
3678
+ htmlFor: fileInputId,
3679
+ className: cn(
3680
+ "flex h-8 w-8 items-center justify-center rounded-2xl",
3681
+ attachmentsEnabled ? "hover:bg-secondary-foreground/10 cursor-pointer" : "opacity-50 cursor-not-allowed"
3682
+ ),
3683
+ children: [
3684
+ /* @__PURE__ */ jsx(
3685
+ "input",
3686
+ {
3687
+ ref: fileInputRef,
3688
+ type: "file",
3689
+ multiple: true,
3690
+ accept: acceptString,
3691
+ onChange: handleInputChange,
3692
+ className: "hidden",
3693
+ id: fileInputId,
3694
+ disabled: !attachmentsEnabled
3695
+ }
3696
+ ),
3697
+ /* @__PURE__ */ jsx(PlusIcon, { className: "text-primary size-5" })
3698
+ ]
3699
+ }
3700
+ )
3701
+ }
3702
+ ) }),
3703
+ /* @__PURE__ */ jsx(PromptInputAction, { tooltip: isLoading ? "Stop" : "Send", children: isLoading ? /* @__PURE__ */ jsx(
3704
+ Button,
3705
+ {
3706
+ size: "sm",
3707
+ variant: "destructive",
3708
+ className: "rounded-full size-9",
3709
+ onClick: onStop,
3710
+ children: /* @__PURE__ */ jsx(StopIcon, { className: "h-4 w-4" })
3711
+ }
3712
+ ) : /* @__PURE__ */ jsx(
3713
+ Button,
3714
+ {
3715
+ size: "sm",
3716
+ className: "rounded-full size-9",
3717
+ onClick: handleSubmit,
3718
+ disabled: !input.trim() && !pendingAttachments.some((att) => att.status === "ready"),
3719
+ children: /* @__PURE__ */ jsx(ArrowUpIcon, { className: "h-4 w-4" })
3720
+ }
3721
+ ) })
3722
+ ] })
3723
+ ]
3724
+ }
3725
+ )
3726
+ ] })
3727
+ ]
3728
+ }
3729
+ );
3730
+ }
3731
+ function ToolExecutionMessage({
3732
+ executions,
3733
+ assistantAvatar = { fallback: "AI" },
3734
+ onApprove,
3735
+ onReject,
3736
+ className
3737
+ }) {
3738
+ if (!executions || executions.length === 0) return null;
3739
+ const pendingApprovals = executions.filter(
3740
+ (exec) => exec.approvalStatus === "required"
3741
+ );
3742
+ const otherExecutions = executions.filter(
3743
+ (exec) => exec.approvalStatus !== "required"
3744
+ );
3745
+ const toolSteps = otherExecutions.map((exec) => ({
3746
+ id: exec.id,
3747
+ name: exec.name,
3748
+ args: exec.args,
3749
+ status: exec.status,
3750
+ result: exec.result,
3751
+ error: exec.error
3752
+ }));
3753
+ const hasExecuting = executions.some((exec) => exec.status === "executing");
3754
+ executions.some((exec) => exec.status === "completed");
3755
+ const allCompleted = executions.every(
3756
+ (exec) => exec.status === "completed" || exec.status === "error"
3757
+ );
3758
+ return /* @__PURE__ */ jsxs(Message, { className: cn("flex gap-2", className), children: [
3759
+ /* @__PURE__ */ jsx(
3760
+ MessageAvatar,
3761
+ {
3762
+ src: assistantAvatar.src || "",
3763
+ alt: "Assistant",
3764
+ fallback: assistantAvatar.fallback,
3765
+ className: "bg-primary text-primary-foreground"
3766
+ }
3767
+ ),
3768
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 max-w-[85%]", children: [
3769
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 mb-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
3770
+ hasExecuting && /* @__PURE__ */ jsxs(
3771
+ "svg",
3772
+ {
3773
+ className: "size-3.5 animate-spin text-primary",
3774
+ fill: "none",
3775
+ viewBox: "0 0 24 24",
3776
+ children: [
3777
+ /* @__PURE__ */ jsx(
3778
+ "circle",
3779
+ {
3780
+ className: "opacity-25",
3781
+ cx: "12",
3782
+ cy: "12",
3783
+ r: "10",
3784
+ stroke: "currentColor",
3785
+ strokeWidth: "4"
3786
+ }
3787
+ ),
3788
+ /* @__PURE__ */ jsx(
3789
+ "path",
3790
+ {
3791
+ className: "opacity-75",
3792
+ fill: "currentColor",
3793
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
3794
+ }
3795
+ )
3796
+ ]
3797
+ }
3798
+ ),
3799
+ !hasExecuting && allCompleted && /* @__PURE__ */ jsx(
3800
+ "svg",
3801
+ {
3802
+ className: "size-3.5 text-green-500",
3803
+ fill: "none",
3804
+ viewBox: "0 0 24 24",
3805
+ stroke: "currentColor",
3806
+ strokeWidth: 2.5,
3807
+ children: /* @__PURE__ */ jsx(
3808
+ "path",
3809
+ {
3810
+ strokeLinecap: "round",
3811
+ strokeLinejoin: "round",
3812
+ d: "M5 13l4 4L19 7"
3813
+ }
3814
+ )
3815
+ }
3816
+ ),
3817
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: hasExecuting ? "Running tools..." : allCompleted ? `${executions.length} tool${executions.length > 1 ? "s" : ""} completed` : "Tools" })
3818
+ ] }) }),
3819
+ pendingApprovals.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-2 space-y-2", children: pendingApprovals.map((tool) => /* @__PURE__ */ jsx(
3820
+ PermissionConfirmation,
3821
+ {
3822
+ state: "pending",
3823
+ toolName: tool.name,
3824
+ message: tool.approvalMessage || `This tool wants to execute. Do you approve?`,
3825
+ onApprove: (permissionLevel) => onApprove?.(tool.id, permissionLevel),
3826
+ onReject: (permissionLevel) => onReject?.(tool.id, void 0, permissionLevel)
3827
+ },
3828
+ tool.id
3829
+ )) }),
3830
+ toolSteps.length > 0 && /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card px-3 py-2.5 shadow-sm", children: /* @__PURE__ */ jsx(ToolSteps, { steps: toolSteps }) })
3831
+ ] })
3832
+ ] });
3833
+ }
3834
+ function CopilotChat(props) {
3835
+ const {
3836
+ messages,
3837
+ isLoading,
3838
+ sendMessage,
3839
+ stop,
3840
+ toolExecutions: rawToolExecutions,
3841
+ approveToolExecution,
3842
+ rejectToolExecution
3843
+ } = useCopilot();
3844
+ const toolExecutions = rawToolExecutions.map(
3845
+ (exec) => ({
3846
+ id: exec.id,
3847
+ name: exec.name,
3848
+ args: exec.args,
3849
+ status: exec.status,
3850
+ result: exec.result,
3851
+ error: exec.error,
3852
+ timestamp: exec.startedAt ? exec.startedAt.getTime() : Date.now(),
3853
+ approvalStatus: exec.approvalStatus
3854
+ })
3855
+ );
3856
+ const toolResultsMap = /* @__PURE__ */ new Map();
3857
+ messages.filter((m) => m.role === "tool" && m.toolCallId).forEach((m) => {
3858
+ toolResultsMap.set(m.toolCallId, m.content ?? "");
3859
+ });
3860
+ const visibleMessages = messages.filter((m) => m.role !== "tool").map((m) => {
3861
+ let messageToolExecutions;
3862
+ if (m.role === "assistant" && m.toolCalls && m.toolCalls.length > 0) {
3863
+ const toolCallIds = new Set(
3864
+ m.toolCalls.map((tc) => tc.id)
3865
+ );
3866
+ const liveExecutions = toolExecutions.filter(
3867
+ (exec) => toolCallIds.has(exec.id)
3868
+ );
3869
+ if (liveExecutions.length > 0) {
3870
+ messageToolExecutions = liveExecutions.map(
3871
+ (exec) => {
3872
+ if (!exec.result && toolResultsMap.has(exec.id)) {
3873
+ const resultContent = toolResultsMap.get(exec.id);
3874
+ try {
3875
+ return { ...exec, result: JSON.parse(resultContent) };
3876
+ } catch {
3877
+ return {
3878
+ ...exec,
3879
+ result: { success: true, message: resultContent }
3880
+ };
3881
+ }
3882
+ }
3883
+ return exec;
3884
+ }
3885
+ );
3886
+ } else {
3887
+ messageToolExecutions = m.toolCalls.map(
3888
+ (tc) => {
3889
+ const resultContent = toolResultsMap.get(tc.id);
3890
+ let result = void 0;
3891
+ if (resultContent) {
3892
+ try {
3893
+ result = JSON.parse(resultContent);
3894
+ } catch {
3895
+ result = { success: true, message: resultContent };
3896
+ }
3897
+ }
3898
+ let args = {};
3899
+ try {
3900
+ args = JSON.parse(tc.function.arguments || "{}");
3901
+ } catch {
3902
+ }
3903
+ return {
3904
+ id: tc.id,
3905
+ name: tc.function.name,
3906
+ args,
3907
+ status: result ? "completed" : "pending",
3908
+ result,
3909
+ timestamp: Date.now()
3910
+ // Historical - use current time
3911
+ };
3912
+ }
3913
+ );
3914
+ }
3915
+ }
3916
+ const savedExecutions = m.metadata?.toolExecutions;
3917
+ if (savedExecutions && savedExecutions.length > 0 && !messageToolExecutions) {
3918
+ messageToolExecutions = savedExecutions;
3919
+ }
3920
+ return {
3921
+ id: m.id,
3922
+ role: m.role,
3923
+ content: m.content ?? "",
3924
+ thinking: m.thinking,
3925
+ // Include attachments (images, files)
3926
+ attachments: m.attachments,
3927
+ // Include tool_calls for assistant messages
3928
+ tool_calls: m.toolCalls,
3929
+ // Attach matched tool executions to assistant messages
3930
+ toolExecutions: messageToolExecutions
3931
+ };
3932
+ });
3933
+ const suggestions = visibleMessages.length === 0 && props.suggestions?.length ? props.suggestions : [];
3934
+ const lastMessage = messages[messages.length - 1];
3935
+ const isInToolFlow = lastMessage?.role === "assistant" && lastMessage.toolCalls?.length;
3936
+ let isProcessingToolResults = false;
3937
+ if (isLoading && isInToolFlow) {
3938
+ const currentToolCallIds = new Set(
3939
+ lastMessage.toolCalls?.map(
3940
+ (tc) => tc.id
3941
+ ) || []
3942
+ );
3943
+ const currentExecutions = toolExecutions.filter(
3944
+ (exec) => currentToolCallIds.has(exec.id)
3945
+ );
3946
+ const hasCompletedTools = currentExecutions.some(
3947
+ (exec) => exec.status === "completed" || exec.status === "error" || exec.status === "failed"
3948
+ );
3949
+ const hasExecutingTools = currentExecutions.some(
3950
+ (exec) => exec.status === "executing" || exec.status === "pending"
3951
+ );
3952
+ isProcessingToolResults = hasCompletedTools && !hasExecutingTools;
3953
+ }
3954
+ return /* @__PURE__ */ jsx(
3955
+ Chat,
3956
+ {
3957
+ ...props,
3958
+ messages: visibleMessages,
3959
+ onSendMessage: sendMessage,
3960
+ onStop: stop,
3961
+ isLoading,
3962
+ showPoweredBy: props.showPoweredBy ?? true,
3963
+ suggestions,
3964
+ isProcessing: isProcessingToolResults,
3965
+ onApproveToolExecution: approveToolExecution,
3966
+ onRejectToolExecution: rejectToolExecution
3967
+ }
3968
+ );
3969
+ }
3970
+ var ConnectedChat = CopilotChat;
3971
+ function YourGPTLogo({ className }) {
3972
+ return /* @__PURE__ */ jsxs(
3973
+ "svg",
3974
+ {
3975
+ xmlns: "http://www.w3.org/2000/svg",
3976
+ viewBox: "0 0 24 24",
3977
+ fill: "none",
3978
+ stroke: "currentColor",
3979
+ strokeWidth: "2",
3980
+ strokeLinecap: "round",
3981
+ strokeLinejoin: "round",
3982
+ className,
3983
+ children: [
3984
+ /* @__PURE__ */ jsx("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
3985
+ /* @__PURE__ */ jsx("path", { d: "M2 17l10 5 10-5" }),
3986
+ /* @__PURE__ */ jsx("path", { d: "M2 12l10 5 10-5" })
3987
+ ]
3988
+ }
3989
+ );
3990
+ }
3991
+ function PoweredBy({ className, showLogo = true }) {
3992
+ return /* @__PURE__ */ jsxs(
3993
+ "div",
3994
+ {
3995
+ className: cn(
3996
+ "flex items-center justify-center gap-1.5 py-2 text-xs text-muted-foreground",
3997
+ className
3998
+ ),
3999
+ children: [
4000
+ /* @__PURE__ */ jsx("span", { children: "Powered by" }),
4001
+ showLogo && /* @__PURE__ */ jsx(YourGPTLogo, { className: "h-3 w-3" }),
4002
+ /* @__PURE__ */ jsx(
4003
+ "a",
4004
+ {
4005
+ href: "https://yourgpt.ai",
4006
+ target: "_blank",
4007
+ rel: "noopener noreferrer",
4008
+ className: "font-medium text-foreground hover:underline",
4009
+ children: "YourGPT"
4010
+ }
4011
+ )
4012
+ ]
4013
+ }
4014
+ );
4015
+ }
4016
+
4017
+ export { AlertTriangleIcon, BotIcon, Button, CapabilityBadge, CapabilityList, Chat, ChatContainerContent, ChatContainerRoot, ChatContainerScrollAnchor, CheckIcon, ChevronDownIcon2 as ChevronDownIcon, ChevronUpIcon, CloseIcon, CodeBlock, CompactPermissionConfirmation, Confirmation, ConfirmationActions, ConfirmationApproved, ConfirmationMessage, ConfirmationPending, ConfirmationRejected, ConnectedChat, CopilotChat, CopilotUIProvider, CopyIcon, DEFAULT_PERMISSION_OPTIONS, DevLogger, FeedbackBar, FollowUpQuestions, InlineToolSteps, Loader, Markdown, MessageAvatar, MessageContent, Message as MessagePrimitive, ModelSelector, PermissionConfirmation, PoweredBy, PromptInput, PromptInputAction, PromptInputActions, PromptInputTextarea, Reasoning, ReasoningContent, ReasoningTrigger, RefreshIcon, ScrollButton, SendIcon, SimpleConfirmation, SimpleModelSelector, SimpleReasoning, Source, SourceContent, SourceTrigger, StopIcon, ThumbsDownIcon2 as ThumbsDownIcon, ThumbsUpIcon2 as ThumbsUpIcon, ToolExecutionMessage, ToolStep, ToolSteps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserIcon, XIcon2 as XIcon, cn, parseFollowUps, useChatContainer, useCopilotUI };
4018
+ //# sourceMappingURL=index.js.map
4019
+ //# sourceMappingURL=index.js.map