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