@tinkrapp/widget 1.0.1 → 1.0.2

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.
package/dist/react.cjs CHANGED
@@ -1,21 +1,21 @@
1
1
  'use strict';
2
2
 
3
- var React = require('react');
4
- var react = require('@assistant-ui/react');
3
+ var React2 = require('react');
4
+ var react$1 = require('@assistant-ui/react');
5
5
  var reactAiSdk = require('@assistant-ui/react-ai-sdk');
6
6
  var react$2 = require('@emotion/react');
7
7
  var assistantStream = require('assistant-stream');
8
- var ReactMarkdown = require('react-markdown');
9
- var remarkGfm = require('remark-gfm');
8
+ var jsxRuntime = require('react/jsx-runtime');
9
+ var styled = require('@emotion/styled');
10
+ var react = require('motion/react');
10
11
  var lucideReact = require('lucide-react');
11
12
  var clsx = require('clsx');
12
13
  var tailwindMerge = require('tailwind-merge');
14
+ var ReactMarkdown = require('react-markdown');
15
+ var remarkGfm = require('remark-gfm');
13
16
  var reactSlot = require('@radix-ui/react-slot');
14
17
  var TooltipPrimitive = require('@radix-ui/react-tooltip');
15
- var jsxRuntime = require('react/jsx-runtime');
16
18
  var classVarianceAuthority = require('class-variance-authority');
17
- var styled = require('@emotion/styled');
18
- var react$1 = require('motion/react');
19
19
  var shallow = require('zustand/shallow');
20
20
  var DialogPrimitive = require('@radix-ui/react-dialog');
21
21
  var AvatarPrimitive = require('@radix-ui/react-avatar');
@@ -43,11 +43,11 @@ function _interopNamespace(e) {
43
43
  return Object.freeze(n);
44
44
  }
45
45
 
46
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
46
+ var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
47
+ var styled__default = /*#__PURE__*/_interopDefault(styled);
47
48
  var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
48
49
  var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
49
50
  var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
50
- var styled__default = /*#__PURE__*/_interopDefault(styled);
51
51
  var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
52
52
  var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
53
53
  var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
@@ -279,657 +279,243 @@ var WidgetClient = class {
279
279
  this.events.emit("state:change", { previous, current: newState });
280
280
  }
281
281
  };
282
- function cn(...inputs) {
283
- return tailwindMerge.twMerge(clsx.clsx(inputs));
284
- }
285
- function TooltipProvider({
286
- delayDuration = 0,
287
- ...props
288
- }) {
282
+ var MessageContext = React2.createContext(null);
283
+ function MessageContextProvider({ children }) {
284
+ const [selectedContext, setSelectedContext] = React2.useState([]);
285
+ const addContextItem = React2.useCallback((item) => {
286
+ console.log("[MessageContext] Adding context item:", item.id, item.title);
287
+ setSelectedContext((prev2) => {
288
+ if (prev2.some((i) => i.id === item.id)) {
289
+ console.log("[MessageContext] Item already exists, skipping");
290
+ return prev2;
291
+ }
292
+ console.log("[MessageContext] Context items count:", prev2.length + 1);
293
+ return [...prev2, item];
294
+ });
295
+ }, []);
296
+ const removeContextItem = React2.useCallback((id) => {
297
+ setSelectedContext((prev2) => prev2.filter((item) => item.id !== id));
298
+ }, []);
299
+ const clearContext = React2.useCallback(() => {
300
+ console.log("[MessageContext] Clearing context");
301
+ setSelectedContext([]);
302
+ }, []);
303
+ const setContext = React2.useCallback((items) => {
304
+ setSelectedContext(items);
305
+ }, []);
306
+ const consumeContext = React2.useCallback(() => {
307
+ const context = selectedContext;
308
+ console.log("[MessageContext] Consuming context:", context.length, "items");
309
+ return context;
310
+ }, [selectedContext]);
289
311
  return /* @__PURE__ */ jsxRuntime.jsx(
290
- TooltipPrimitive__namespace.Provider,
312
+ MessageContext.Provider,
291
313
  {
292
- "data-slot": "tooltip-provider",
293
- delayDuration,
294
- ...props
314
+ value: {
315
+ selectedContext,
316
+ addContextItem,
317
+ removeContextItem,
318
+ clearContext,
319
+ setContext,
320
+ consumeContext
321
+ },
322
+ children
295
323
  }
296
324
  );
297
325
  }
298
- function Tooltip({
299
- ...props
300
- }) {
301
- return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Root, { "data-slot": "tooltip", ...props }) });
302
- }
303
- function TooltipTrigger({
304
- ...props
305
- }) {
306
- return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Trigger, { "data-slot": "tooltip-trigger", ...props });
326
+ function useMessageContext() {
327
+ const context = React2.useContext(MessageContext);
328
+ if (!context) {
329
+ throw new Error(
330
+ "useMessageContext must be used within a MessageContextProvider"
331
+ );
332
+ }
333
+ return context;
307
334
  }
308
- function TooltipContent({
309
- className,
310
- sideOffset = 0,
311
- children,
312
- ...props
313
- }) {
314
- return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
315
- TooltipPrimitive__namespace.Content,
316
- {
317
- "data-slot": "tooltip-content",
318
- sideOffset,
319
- className: cn(
320
- "bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
321
- className
322
- ),
323
- ...props,
324
- children: [
325
- children,
326
- /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Arrow, { className: "bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })
327
- ]
335
+
336
+ // src/react/styles/theme.ts
337
+ var theme = {
338
+ colors: {
339
+ background: {
340
+ primary: "#1a1a1a",
341
+ secondary: "#2a2a2a",
342
+ tertiary: "#3a3a3a"
343
+ },
344
+ accent: {
345
+ primary: "#c9a227",
346
+ hover: "#d4af37",
347
+ muted: "rgba(201, 162, 39, 0.4)"
348
+ },
349
+ text: {
350
+ primary: "#ffffff",
351
+ secondary: "#888888",
352
+ tertiary: "#cccccc",
353
+ inverse: "#1a1a1a"
354
+ },
355
+ border: "#2a2a2a",
356
+ shadow: "rgba(0, 0, 0, 0.4)"
357
+ },
358
+ spacing: {
359
+ xs: "0.25rem",
360
+ sm: "0.5rem",
361
+ md: "1rem",
362
+ lg: "1.5rem",
363
+ xl: "2rem",
364
+ "2xl": "3rem"
365
+ },
366
+ radii: {
367
+ sm: "0.5rem",
368
+ md: "0.75rem",
369
+ lg: "1rem",
370
+ xl: "1.5rem",
371
+ full: "50%"
372
+ },
373
+ typography: {
374
+ fontFamily: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
375
+ fontSize: {
376
+ xs: "0.75rem",
377
+ sm: "0.875rem",
378
+ md: "1rem",
379
+ lg: "1.125rem",
380
+ xl: "1.25rem",
381
+ "2xl": "1.5rem"
382
+ },
383
+ fontWeight: {
384
+ normal: 400,
385
+ medium: 500,
386
+ semibold: 600,
387
+ bold: 700
388
+ },
389
+ lineHeight: {
390
+ tight: 1.25,
391
+ normal: 1.5,
392
+ relaxed: 1.7
328
393
  }
329
- ) });
394
+ },
395
+ zIndex: {
396
+ widget: 9999,
397
+ overlay: 9998
398
+ },
399
+ shadows: {
400
+ sm: "0 2px 8px rgba(0, 0, 0, 0.2)",
401
+ md: "0 4px 16px rgba(0, 0, 0, 0.3)",
402
+ lg: "0 8px 32px rgba(0, 0, 0, 0.4)",
403
+ accent: "0 4px 16px rgba(201, 162, 39, 0.4)",
404
+ accentHover: "0 6px 20px rgba(201, 162, 39, 0.5)"
405
+ },
406
+ transitions: {
407
+ fast: "0.15s ease",
408
+ normal: "0.2s ease",
409
+ slow: "0.3s ease"
410
+ }
411
+ };
412
+ function sheetForTag(tag) {
413
+ if (tag.sheet) {
414
+ return tag.sheet;
415
+ }
416
+ for (var i = 0; i < document.styleSheets.length; i++) {
417
+ if (document.styleSheets[i].ownerNode === tag) {
418
+ return document.styleSheets[i];
419
+ }
420
+ }
421
+ return void 0;
330
422
  }
331
- var buttonVariants = classVarianceAuthority.cva(
332
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
333
- {
334
- variants: {
335
- variant: {
336
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
337
- destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
338
- outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
339
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
340
- ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
341
- link: "text-primary underline-offset-4 hover:underline"
342
- },
343
- size: {
344
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
345
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
346
- lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
347
- icon: "size-9",
348
- "icon-sm": "size-8",
349
- "icon-lg": "size-10"
423
+ function createStyleElement(options) {
424
+ var tag = document.createElement("style");
425
+ tag.setAttribute("data-emotion", options.key);
426
+ if (options.nonce !== void 0) {
427
+ tag.setAttribute("nonce", options.nonce);
428
+ }
429
+ tag.appendChild(document.createTextNode(""));
430
+ tag.setAttribute("data-s", "");
431
+ return tag;
432
+ }
433
+ var StyleSheet = /* @__PURE__ */ (function() {
434
+ function StyleSheet2(options) {
435
+ var _this = this;
436
+ this._insertTag = function(tag) {
437
+ var before;
438
+ if (_this.tags.length === 0) {
439
+ if (_this.insertionPoint) {
440
+ before = _this.insertionPoint.nextSibling;
441
+ } else if (_this.prepend) {
442
+ before = _this.container.firstChild;
443
+ } else {
444
+ before = _this.before;
445
+ }
446
+ } else {
447
+ before = _this.tags[_this.tags.length - 1].nextSibling;
350
448
  }
351
- },
352
- defaultVariants: {
353
- variant: "default",
354
- size: "default"
355
- }
449
+ _this.container.insertBefore(tag, before);
450
+ _this.tags.push(tag);
451
+ };
452
+ this.isSpeedy = options.speedy === void 0 ? true : options.speedy;
453
+ this.tags = [];
454
+ this.ctr = 0;
455
+ this.nonce = options.nonce;
456
+ this.key = options.key;
457
+ this.container = options.container;
458
+ this.prepend = options.prepend;
459
+ this.insertionPoint = options.insertionPoint;
460
+ this.before = null;
356
461
  }
357
- );
358
- var Button = React__namespace.forwardRef(({ className, variant = "default", size = "default", asChild = false, ...props }, ref) => {
359
- const Comp = asChild ? reactSlot.Slot : "button";
360
- return /* @__PURE__ */ jsxRuntime.jsx(
361
- Comp,
362
- {
363
- ref,
364
- "data-slot": "button",
365
- "data-variant": variant,
366
- "data-size": size,
367
- className: cn(buttonVariants({ variant, size, className })),
368
- ...props
462
+ var _proto = StyleSheet2.prototype;
463
+ _proto.hydrate = function hydrate(nodes) {
464
+ nodes.forEach(this._insertTag);
465
+ };
466
+ _proto.insert = function insert(rule) {
467
+ if (this.ctr % (this.isSpeedy ? 65e3 : 1) === 0) {
468
+ this._insertTag(createStyleElement(this));
369
469
  }
370
- );
371
- });
372
- Button.displayName = "Button";
373
- var TooltipIconButton = React.forwardRef(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
374
- return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
375
- /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "ghost", size: "icon-sm", ...rest, ref, children: [
376
- /* @__PURE__ */ jsxRuntime.jsx(reactSlot.Slottable, { children }),
377
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "aui-sr-only sr-only", children: tooltip })
378
- ] }) }),
379
- /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side, children: tooltip })
380
- ] });
381
- });
382
- TooltipIconButton.displayName = "TooltipIconButton";
383
- var ToolCard = ({
384
- title,
385
- subtitle,
386
- isStreaming,
387
- isError = false,
388
- icon,
389
- persistentContent,
390
- children,
391
- footer
392
- }) => {
393
- const [manualExpanded, setManualExpanded] = React.useState(null);
394
- const prevStreamingRef = React.useRef(isStreaming);
395
- const contentRef = React.useRef(null);
396
- const isExpanded = manualExpanded ?? isStreaming;
397
- React.useEffect(() => {
398
- if (isStreaming && !prevStreamingRef.current) {
399
- setManualExpanded(null);
400
- }
401
- prevStreamingRef.current = isStreaming;
402
- }, [isStreaming]);
403
- React.useEffect(() => {
404
- if (isStreaming && contentRef.current) {
405
- contentRef.current.scrollTop = contentRef.current.scrollHeight;
406
- }
407
- });
408
- const renderIcon = () => {
409
- if (icon) return icon;
410
- const iconClass = cn("h-4 w-4", isStreaming && "animate-spin");
411
- if (isStreaming) {
412
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2Icon, { className: iconClass });
413
- }
414
- if (isError) {
415
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircleIcon, { className: "h-4 w-4 text-red-400" });
416
- }
417
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "h-4 w-4" });
418
- };
419
- const handleToggle = () => {
420
- if (!isStreaming) {
421
- setManualExpanded((prev2) => prev2 === null ? true : !prev2);
470
+ var tag = this.tags[this.tags.length - 1];
471
+ if (this.isSpeedy) {
472
+ var sheet = sheetForTag(tag);
473
+ try {
474
+ sheet.insertRule(rule, sheet.cssRules.length);
475
+ } catch (e) {
476
+ }
477
+ } else {
478
+ tag.appendChild(document.createTextNode(rule));
422
479
  }
480
+ this.ctr++;
423
481
  };
424
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-2 overflow-hidden rounded-xl border border-border shadow-sm", children: [
425
- /* @__PURE__ */ jsxRuntime.jsxs(
426
- "div",
427
- {
428
- className: cn(
429
- "flex items-center gap-2 p-2 cursor-pointer transition-colors text-white bg-primary-foreground",
430
- !isStreaming && "hover:opacity-90"
431
- ),
432
- onClick: handleToggle,
433
- children: [
434
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: renderIcon() }),
435
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
436
- subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium opacity-80 leading-tight text-xs text-muted-foreground", children: subtitle }),
437
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "truncate font-semibold leading-tight text-sm text-muted-foreground", children: title })
438
- ] }),
439
- /* @__PURE__ */ jsxRuntime.jsx(
440
- "button",
441
- {
442
- className: "p-1 rounded hover:bg-white/20 transition-colors",
443
- "aria-label": isExpanded ? "Collapse" : "Expand",
444
- onClick: (e) => {
445
- e.stopPropagation();
446
- handleToggle();
447
- },
448
- children: isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUpIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "h-4 w-4" })
449
- }
450
- )
451
- ]
452
- }
453
- ),
454
- persistentContent,
455
- isExpanded && /* @__PURE__ */ jsxRuntime.jsx(
456
- "div",
457
- {
458
- ref: contentRef,
459
- className: "p-2 max-h-[400px] overflow-y-auto bg-secondary",
460
- children
461
- }
462
- ),
463
- isExpanded && footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end gap-2 border-t border-white/10 p-2 bg-primary-foreground/80", children: footer })
464
- ] });
465
- };
466
- var useCopyToClipboard = ({
467
- copiedDuration = 3e3
468
- } = {}) => {
469
- const [isCopied, setIsCopied] = React.useState(false);
470
- const copyToClipboard = (value) => {
471
- if (!value) return;
472
- navigator.clipboard.writeText(value).then(() => {
473
- setIsCopied(true);
474
- setTimeout(() => setIsCopied(false), copiedDuration);
482
+ _proto.flush = function flush() {
483
+ this.tags.forEach(function(tag) {
484
+ var _tag$parentNode;
485
+ return (_tag$parentNode = tag.parentNode) == null ? void 0 : _tag$parentNode.removeChild(tag);
475
486
  });
487
+ this.tags = [];
488
+ this.ctr = 0;
476
489
  };
477
- return { isCopied, copyToClipboard };
478
- };
479
- var MarkdownContent = React.memo(({ content }) => {
480
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aui-md max-w-none text-white", children: /* @__PURE__ */ jsxRuntime.jsx(
481
- ReactMarkdown__default.default,
482
- {
483
- remarkPlugins: [remarkGfm__default.default],
484
- components: {
485
- h1: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
486
- "h1",
487
- {
488
- className: cn(
489
- "mb-2 font-extrabold tracking-tight last:mb-0 text-white",
490
- className
491
- ),
492
- style: { fontSize: "12px" },
493
- ...props
494
- }
495
- ),
496
- h2: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
497
- "h2",
498
- {
499
- className: cn(
500
- "mt-3 mb-1.5 font-semibold tracking-tight first:mt-0 last:mb-0 text-white",
501
- className
502
- ),
503
- style: { fontSize: "10px" },
504
- ...props
505
- }
506
- ),
507
- h3: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
508
- "h3",
509
- {
510
- className: cn(
511
- "mt-2 mb-1 font-semibold tracking-tight first:mt-0 last:mb-0 text-white",
512
- className
513
- ),
514
- style: { fontSize: "9px" },
515
- ...props
516
- }
517
- ),
518
- p: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
519
- "p",
520
- {
521
- className: cn(
522
- "mt-1.5 mb-1.5 leading-relaxed first:mt-0 last:mb-0 text-white/90",
523
- className
524
- ),
525
- ...props
526
- }
527
- ),
528
- ul: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
529
- "ul",
530
- {
531
- className: cn(
532
- "my-1.5 ml-3 list-disc [&>li]:mt-0.5 text-white/90",
533
- className
534
- ),
535
- ...props
536
- }
537
- ),
538
- ol: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
539
- "ol",
540
- {
541
- className: cn(
542
- "my-1.5 ml-3 list-decimal [&>li]:mt-0.5 text-white/90",
543
- className
544
- ),
545
- ...props
546
- }
547
- ),
548
- blockquote: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
549
- "blockquote",
550
- {
551
- className: cn(
552
- "border-l-2 border-white/30 pl-2 italic text-white/70",
553
- className
554
- ),
555
- ...props
556
- }
557
- ),
558
- pre: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
559
- "pre",
560
- {
561
- className: cn(
562
- "overflow-x-auto rounded bg-black/30 p-1.5 text-white/90 my-1.5",
563
- className
564
- ),
565
- ...props
566
- }
567
- ),
568
- code: ({ className, ...props }) => {
569
- const isInline = !className?.includes("language-");
570
- return /* @__PURE__ */ jsxRuntime.jsx(
571
- "code",
572
- {
573
- className: cn(
574
- isInline && "rounded bg-black/30 px-0.5 py-0.5 font-mono text-white/90",
575
- className
576
- ),
577
- ...props
578
- }
579
- );
580
- },
581
- a: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
582
- "a",
583
- {
584
- className: cn(
585
- "font-medium text-blue-300 underline underline-offset-2",
586
- className
587
- ),
588
- target: "_blank",
589
- rel: "noopener noreferrer",
590
- ...props
591
- }
592
- ),
593
- hr: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
594
- "hr",
595
- {
596
- className: cn("my-2 border-b border-white/20", className),
597
- ...props
598
- }
599
- )
600
- },
601
- children: content
602
- }
603
- ) });
604
- });
605
- MarkdownContent.displayName = "MarkdownContent";
606
- var DetailedAnswerToolUI = react.makeAssistantToolUI({
607
- toolName: "generateDetailedAnswer",
608
- render: function DetailedAnswerUI({ args, result, status }) {
609
- const { isCopied, copyToClipboard } = useCopyToClipboard();
610
- const isStreaming = status.type === "running";
611
- const isError = status.type === "incomplete";
612
- const title = result?.title || args.title || "Generating...";
613
- const content = result?.content || args.content || "";
614
- const summary = result?.summary || args.summary || "";
615
- const handleCopy = () => {
616
- if (content) {
617
- copyToClipboard(content);
618
- }
619
- };
620
- const handleOpenFullScreen = () => {
621
- const newWindow = window.open("", "_blank");
622
- if (newWindow) {
623
- newWindow.document.write(`
624
- <!DOCTYPE html>
625
- <html>
626
- <head>
627
- <title>${title}</title>
628
- <meta charset="utf-8">
629
- <meta name="viewport" content="width=device-width, initial-scale=1">
630
- <style>
631
- body {
632
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
633
- max-width: 800px;
634
- margin: 0 auto;
635
- padding: 2rem;
636
- line-height: 1.6;
637
- color: #1a1a1a;
638
- }
639
- h1 { border-bottom: 1px solid #eee; padding-bottom: 0.5rem; }
640
- pre { background: #f5f5f5; padding: 1rem; overflow-x: auto; border-radius: 4px; }
641
- code { background: #f5f5f5; padding: 0.2em 0.4em; border-radius: 3px; font-size: 0.9em; }
642
- pre code { background: none; padding: 0; }
643
- blockquote { border-left: 4px solid #ddd; margin: 0; padding-left: 1rem; color: #666; }
644
- </style>
645
- </head>
646
- <body>
647
- <h1>${title}</h1>
648
- <div id="content">${content.replace(/</g, "&lt;").replace(/>/g, "&gt;")}</div>
649
- <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
650
- <script>
651
- document.getElementById('content').innerHTML = marked.parse(${JSON.stringify(
652
- content
653
- )});
654
- </script>
655
- </body>
656
- </html>
657
- `);
658
- newWindow.document.close();
659
- }
660
- };
661
- const persistentSummary = summary ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 text-white/80 border-b border-white/10 bg-primary-foreground text-xs", children: summary }) : void 0;
662
- const footerActions = content ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
663
- /* @__PURE__ */ jsxRuntime.jsx(
664
- TooltipIconButton,
665
- {
666
- tooltip: isCopied ? "Copied!" : "Copy markdown",
667
- onClick: handleCopy,
668
- className: "flex items-center justify-center rounded-md p-1.5 text-white/70 hover:bg-white/10 transition-colors",
669
- children: isCopied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CopyIcon, { className: "h-3.5 w-3.5" })
670
- }
671
- ),
672
- /* @__PURE__ */ jsxRuntime.jsx(
673
- TooltipIconButton,
674
- {
675
- tooltip: "Open in new window",
676
- onClick: handleOpenFullScreen,
677
- className: "flex items-center justify-center rounded-md p-1.5 text-white/70 hover:bg-white/10 transition-colors",
678
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLinkIcon, { className: "h-3.5 w-3.5" })
679
- }
680
- )
681
- ] }) : void 0;
682
- return /* @__PURE__ */ jsxRuntime.jsx(
683
- ToolCard,
684
- {
685
- title,
686
- isStreaming,
687
- isError,
688
- icon: !isStreaming && !isError ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileTextIcon, { className: "h-4 w-4" }) : void 0,
689
- persistentContent: persistentSummary,
690
- footer: footerActions,
691
- children: content ? /* @__PURE__ */ jsxRuntime.jsx(MarkdownContent, { content }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground italic", children: "Generating content..." })
692
- }
693
- );
694
- }
695
- });
696
- var MessageContext = React.createContext(null);
697
- function MessageContextProvider({ children }) {
698
- const [selectedContext, setSelectedContext] = React.useState([]);
699
- const addContextItem = React.useCallback((item) => {
700
- console.log("[MessageContext] Adding context item:", item.id, item.title);
701
- setSelectedContext((prev2) => {
702
- if (prev2.some((i) => i.id === item.id)) {
703
- console.log("[MessageContext] Item already exists, skipping");
704
- return prev2;
705
- }
706
- console.log("[MessageContext] Context items count:", prev2.length + 1);
707
- return [...prev2, item];
708
- });
709
- }, []);
710
- const removeContextItem = React.useCallback((id) => {
711
- setSelectedContext((prev2) => prev2.filter((item) => item.id !== id));
712
- }, []);
713
- const clearContext = React.useCallback(() => {
714
- console.log("[MessageContext] Clearing context");
715
- setSelectedContext([]);
716
- }, []);
717
- const setContext = React.useCallback((items) => {
718
- setSelectedContext(items);
719
- }, []);
720
- const consumeContext = React.useCallback(() => {
721
- const context = selectedContext;
722
- console.log("[MessageContext] Consuming context:", context.length, "items");
723
- return context;
724
- }, [selectedContext]);
725
- return /* @__PURE__ */ jsxRuntime.jsx(
726
- MessageContext.Provider,
727
- {
728
- value: {
729
- selectedContext,
730
- addContextItem,
731
- removeContextItem,
732
- clearContext,
733
- setContext,
734
- consumeContext
735
- },
736
- children
737
- }
738
- );
490
+ return StyleSheet2;
491
+ })();
492
+
493
+ // ../../node_modules/stylis/src/Enum.js
494
+ var MS = "-ms-";
495
+ var MOZ = "-moz-";
496
+ var WEBKIT = "-webkit-";
497
+ var COMMENT = "comm";
498
+ var RULESET = "rule";
499
+ var DECLARATION = "decl";
500
+ var IMPORT = "@import";
501
+ var KEYFRAMES = "@keyframes";
502
+ var LAYER = "@layer";
503
+
504
+ // ../../node_modules/stylis/src/Utility.js
505
+ var abs = Math.abs;
506
+ var from = String.fromCharCode;
507
+ var assign = Object.assign;
508
+ function hash(value, length2) {
509
+ return charat(value, 0) ^ 45 ? (((length2 << 2 ^ charat(value, 0)) << 2 ^ charat(value, 1)) << 2 ^ charat(value, 2)) << 2 ^ charat(value, 3) : 0;
739
510
  }
740
- function useMessageContext() {
741
- const context = React.useContext(MessageContext);
742
- if (!context) {
743
- throw new Error(
744
- "useMessageContext must be used within a MessageContextProvider"
745
- );
746
- }
747
- return context;
511
+ function trim(value) {
512
+ return value.trim();
748
513
  }
749
-
750
- // src/react/styles/theme.ts
751
- var theme = {
752
- colors: {
753
- background: {
754
- primary: "#1a1a1a",
755
- secondary: "#2a2a2a",
756
- tertiary: "#3a3a3a"
757
- },
758
- accent: {
759
- primary: "#c9a227",
760
- hover: "#d4af37",
761
- muted: "rgba(201, 162, 39, 0.4)"
762
- },
763
- text: {
764
- primary: "#ffffff",
765
- secondary: "#888888",
766
- tertiary: "#cccccc",
767
- inverse: "#1a1a1a"
768
- },
769
- border: "#2a2a2a",
770
- shadow: "rgba(0, 0, 0, 0.4)"
771
- },
772
- spacing: {
773
- xs: "0.25rem",
774
- sm: "0.5rem",
775
- md: "1rem",
776
- lg: "1.5rem",
777
- xl: "2rem",
778
- "2xl": "3rem"
779
- },
780
- radii: {
781
- sm: "0.5rem",
782
- md: "0.75rem",
783
- lg: "1rem",
784
- xl: "1.5rem",
785
- full: "50%"
786
- },
787
- typography: {
788
- fontFamily: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
789
- fontSize: {
790
- xs: "0.75rem",
791
- sm: "0.875rem",
792
- md: "1rem",
793
- lg: "1.125rem",
794
- xl: "1.25rem",
795
- "2xl": "1.5rem"
796
- },
797
- fontWeight: {
798
- normal: 400,
799
- medium: 500,
800
- semibold: 600,
801
- bold: 700
802
- },
803
- lineHeight: {
804
- tight: 1.25,
805
- normal: 1.5,
806
- relaxed: 1.7
807
- }
808
- },
809
- zIndex: {
810
- widget: 9999,
811
- overlay: 9998
812
- },
813
- shadows: {
814
- sm: "0 2px 8px rgba(0, 0, 0, 0.2)",
815
- md: "0 4px 16px rgba(0, 0, 0, 0.3)",
816
- lg: "0 8px 32px rgba(0, 0, 0, 0.4)",
817
- accent: "0 4px 16px rgba(201, 162, 39, 0.4)",
818
- accentHover: "0 6px 20px rgba(201, 162, 39, 0.5)"
819
- },
820
- transitions: {
821
- fast: "0.15s ease",
822
- normal: "0.2s ease",
823
- slow: "0.3s ease"
824
- }
825
- };
826
- function sheetForTag(tag) {
827
- if (tag.sheet) {
828
- return tag.sheet;
829
- }
830
- for (var i = 0; i < document.styleSheets.length; i++) {
831
- if (document.styleSheets[i].ownerNode === tag) {
832
- return document.styleSheets[i];
833
- }
834
- }
835
- return void 0;
514
+ function match(value, pattern) {
515
+ return (value = pattern.exec(value)) ? value[0] : value;
836
516
  }
837
- function createStyleElement(options) {
838
- var tag = document.createElement("style");
839
- tag.setAttribute("data-emotion", options.key);
840
- if (options.nonce !== void 0) {
841
- tag.setAttribute("nonce", options.nonce);
842
- }
843
- tag.appendChild(document.createTextNode(""));
844
- tag.setAttribute("data-s", "");
845
- return tag;
846
- }
847
- var StyleSheet = /* @__PURE__ */ (function() {
848
- function StyleSheet2(options) {
849
- var _this = this;
850
- this._insertTag = function(tag) {
851
- var before;
852
- if (_this.tags.length === 0) {
853
- if (_this.insertionPoint) {
854
- before = _this.insertionPoint.nextSibling;
855
- } else if (_this.prepend) {
856
- before = _this.container.firstChild;
857
- } else {
858
- before = _this.before;
859
- }
860
- } else {
861
- before = _this.tags[_this.tags.length - 1].nextSibling;
862
- }
863
- _this.container.insertBefore(tag, before);
864
- _this.tags.push(tag);
865
- };
866
- this.isSpeedy = options.speedy === void 0 ? true : options.speedy;
867
- this.tags = [];
868
- this.ctr = 0;
869
- this.nonce = options.nonce;
870
- this.key = options.key;
871
- this.container = options.container;
872
- this.prepend = options.prepend;
873
- this.insertionPoint = options.insertionPoint;
874
- this.before = null;
875
- }
876
- var _proto = StyleSheet2.prototype;
877
- _proto.hydrate = function hydrate(nodes) {
878
- nodes.forEach(this._insertTag);
879
- };
880
- _proto.insert = function insert(rule) {
881
- if (this.ctr % (this.isSpeedy ? 65e3 : 1) === 0) {
882
- this._insertTag(createStyleElement(this));
883
- }
884
- var tag = this.tags[this.tags.length - 1];
885
- if (this.isSpeedy) {
886
- var sheet = sheetForTag(tag);
887
- try {
888
- sheet.insertRule(rule, sheet.cssRules.length);
889
- } catch (e) {
890
- }
891
- } else {
892
- tag.appendChild(document.createTextNode(rule));
893
- }
894
- this.ctr++;
895
- };
896
- _proto.flush = function flush() {
897
- this.tags.forEach(function(tag) {
898
- var _tag$parentNode;
899
- return (_tag$parentNode = tag.parentNode) == null ? void 0 : _tag$parentNode.removeChild(tag);
900
- });
901
- this.tags = [];
902
- this.ctr = 0;
903
- };
904
- return StyleSheet2;
905
- })();
906
-
907
- // ../../node_modules/stylis/src/Enum.js
908
- var MS = "-ms-";
909
- var MOZ = "-moz-";
910
- var WEBKIT = "-webkit-";
911
- var COMMENT = "comm";
912
- var RULESET = "rule";
913
- var DECLARATION = "decl";
914
- var IMPORT = "@import";
915
- var KEYFRAMES = "@keyframes";
916
- var LAYER = "@layer";
917
-
918
- // ../../node_modules/stylis/src/Utility.js
919
- var abs = Math.abs;
920
- var from = String.fromCharCode;
921
- var assign = Object.assign;
922
- function hash(value, length2) {
923
- return charat(value, 0) ^ 45 ? (((length2 << 2 ^ charat(value, 0)) << 2 ^ charat(value, 1)) << 2 ^ charat(value, 2)) << 2 ^ charat(value, 3) : 0;
924
- }
925
- function trim(value) {
926
- return value.trim();
927
- }
928
- function match(value, pattern) {
929
- return (value = pattern.exec(value)) ? value[0] : value;
930
- }
931
- function replace(value, pattern, replacement) {
932
- return value.replace(pattern, replacement);
517
+ function replace(value, pattern, replacement) {
518
+ return value.replace(pattern, replacement);
933
519
  }
934
520
  function indexof(value, search) {
935
521
  return value.indexOf(search);
@@ -1819,7 +1405,7 @@ var IconButton = styled__default.default.button`
1819
1405
  color: ${({ theme: theme2 }) => theme2.colors.text.secondary};
1820
1406
  }
1821
1407
  `;
1822
- var FAB = styled__default.default(react$1.motion.button)`
1408
+ var FAB = styled__default.default(react.motion.button)`
1823
1409
  width: 48px;
1824
1410
  height: 48px;
1825
1411
  border-radius: 50%;
@@ -2030,7 +1616,7 @@ var WidgetRoot = styled__default.default.div`
2030
1616
  z-index: ${({ theme: theme2 }) => theme2.zIndex.widget};
2031
1617
  font-family: ${({ theme: theme2 }) => theme2.typography.fontFamily};
2032
1618
  `;
2033
- var WidgetPanel = styled__default.default(react$1.motion.div)`
1619
+ var WidgetPanel = styled__default.default(react.motion.div)`
2034
1620
  width: 400px;
2035
1621
  height: 700px;
2036
1622
  border-radius: ${({ theme: theme2 }) => theme2.radii.xl};
@@ -2084,7 +1670,7 @@ styled__default.default.div`
2084
1670
  text-align: center;
2085
1671
  padding: ${({ theme: theme2 }) => theme2.spacing.xl};
2086
1672
  `;
2087
- var WidgetContext = React.createContext(null);
1673
+ var WidgetContext = React2.createContext(null);
2088
1674
  function generateUserId() {
2089
1675
  return crypto.randomUUID();
2090
1676
  }
@@ -2095,431 +1681,949 @@ function createApiHeaders(userId, assistantId) {
2095
1681
  "X-Assistant-Id": assistantId
2096
1682
  };
2097
1683
  }
2098
- function createThreadListAdapter(baseUrl, userId, assistantId) {
2099
- const headers = createApiHeaders(userId, assistantId);
2100
- return {
2101
- // List all threads for this user
2102
- async list() {
1684
+ function createThreadListAdapter(baseUrl, userId, assistantId) {
1685
+ const headers = createApiHeaders(userId, assistantId);
1686
+ return {
1687
+ // List all threads for this user
1688
+ async list() {
1689
+ try {
1690
+ const response = await fetch(`${baseUrl}/api/widget/threads`, {
1691
+ headers
1692
+ });
1693
+ if (!response.ok) {
1694
+ console.error("[Threads] List failed:", response.status);
1695
+ return { threads: [] };
1696
+ }
1697
+ const data = await response.json();
1698
+ return { threads: data.threads || [] };
1699
+ } catch (error) {
1700
+ console.error("[Threads] List error:", error);
1701
+ return { threads: [] };
1702
+ }
1703
+ },
1704
+ // Fetch a single thread's details
1705
+ async fetch(remoteId) {
1706
+ const response = await fetch(
1707
+ `${baseUrl}/api/widget/threads/${remoteId}`,
1708
+ {
1709
+ headers
1710
+ }
1711
+ );
1712
+ if (!response.ok) {
1713
+ throw new Error(`Failed to fetch thread: ${response.status}`);
1714
+ }
1715
+ const data = await response.json();
1716
+ return {
1717
+ remoteId: data.remoteId,
1718
+ status: data.status,
1719
+ title: data.title
1720
+ };
1721
+ },
1722
+ // Initialize a new thread
1723
+ async initialize(localId) {
1724
+ try {
1725
+ const response = await fetch(`${baseUrl}/api/widget/threads`, {
1726
+ method: "POST",
1727
+ headers,
1728
+ body: JSON.stringify({ localId })
1729
+ });
1730
+ if (!response.ok) {
1731
+ throw new Error(`Failed to create thread: ${response.status}`);
1732
+ }
1733
+ const data = await response.json();
1734
+ return { remoteId: data.remoteId, externalId: data.externalId };
1735
+ } catch (error) {
1736
+ console.error("[Threads] Initialize error:", error);
1737
+ throw error;
1738
+ }
1739
+ },
1740
+ // Rename a thread
1741
+ async rename(remoteId, newTitle) {
1742
+ try {
1743
+ await fetch(`${baseUrl}/api/widget/threads/${remoteId}`, {
1744
+ method: "PATCH",
1745
+ headers,
1746
+ body: JSON.stringify({ title: newTitle })
1747
+ });
1748
+ } catch (error) {
1749
+ console.error("[Threads] Rename error:", error);
1750
+ }
1751
+ },
1752
+ // Archive a thread
1753
+ async archive(remoteId) {
1754
+ try {
1755
+ await fetch(`${baseUrl}/api/widget/threads/${remoteId}/archive`, {
1756
+ method: "POST",
1757
+ headers
1758
+ });
1759
+ } catch (error) {
1760
+ console.error("[Threads] Archive error:", error);
1761
+ }
1762
+ },
1763
+ // Unarchive a thread
1764
+ async unarchive(remoteId) {
1765
+ try {
1766
+ await fetch(`${baseUrl}/api/widget/threads/${remoteId}/unarchive`, {
1767
+ method: "POST",
1768
+ headers
1769
+ });
1770
+ } catch (error) {
1771
+ console.error("[Threads] Unarchive error:", error);
1772
+ }
1773
+ },
1774
+ // Delete a thread
1775
+ async delete(remoteId) {
1776
+ try {
1777
+ await fetch(`${baseUrl}/api/widget/threads/${remoteId}`, {
1778
+ method: "DELETE",
1779
+ headers
1780
+ });
1781
+ } catch (error) {
1782
+ console.error("[Threads] Delete error:", error);
1783
+ }
1784
+ },
1785
+ // Generate a title from messages
1786
+ async generateTitle(remoteId, messages) {
1787
+ return assistantStream.createAssistantStream(async (controller) => {
1788
+ try {
1789
+ const response = await fetch(
1790
+ `${baseUrl}/api/widget/threads/${remoteId}/title`,
1791
+ {
1792
+ method: "POST",
1793
+ headers,
1794
+ body: JSON.stringify({ messages })
1795
+ }
1796
+ );
1797
+ if (!response.ok) {
1798
+ throw new Error(`Title generation failed: ${response.status}`);
1799
+ }
1800
+ const data = await response.json();
1801
+ controller.appendText(data.title);
1802
+ controller.close();
1803
+ } catch (error) {
1804
+ console.error("[Threads] Title generation error:", error);
1805
+ controller.appendText("New Chat");
1806
+ controller.close();
1807
+ }
1808
+ });
1809
+ }
1810
+ };
1811
+ }
1812
+ async function saveMessages(baseUrl, userId, assistantId, threadId, messages) {
1813
+ try {
1814
+ const response = await fetch(
1815
+ `${baseUrl}/api/widget/threads/${threadId}/messages/sync`,
1816
+ {
1817
+ method: "POST",
1818
+ headers: createApiHeaders(userId, assistantId),
1819
+ body: JSON.stringify({ messages })
1820
+ }
1821
+ );
1822
+ if (!response.ok) {
1823
+ console.error("[Messages] Sync failed:", response.status);
1824
+ }
1825
+ } catch (error) {
1826
+ console.error("[Messages] Sync error:", error);
1827
+ }
1828
+ }
1829
+ function createHistoryAdapter(baseUrl, userId, assistantId, remoteId) {
1830
+ const headers = createApiHeaders(userId, assistantId);
1831
+ return {
1832
+ async load() {
1833
+ console.log("[History] load() called, remoteId:", remoteId);
1834
+ if (!remoteId) return { headId: null, messages: [] };
1835
+ try {
1836
+ const response = await fetch(
1837
+ `${baseUrl}/api/widget/threads/${remoteId}/messages`,
1838
+ { headers }
1839
+ );
1840
+ if (!response.ok) {
1841
+ console.error("[History] Failed to load messages:", response.status);
1842
+ return { headId: null, messages: [] };
1843
+ }
1844
+ const { messages } = await response.json();
1845
+ console.log("[History] Loaded messages:", messages.length);
1846
+ const formattedMessages = messages.map(
1847
+ (m, index) => ({
1848
+ parentId: index > 0 ? messages[index - 1].id : null,
1849
+ message: {
1850
+ id: m.id,
1851
+ role: m.role,
1852
+ parts: m.content,
1853
+ metadata: m.metadata,
1854
+ createdAt: new Date(m.createdAt)
1855
+ }
1856
+ })
1857
+ );
1858
+ console.log("[History] Formatted messages:", formattedMessages.length);
1859
+ return {
1860
+ headId: messages.length > 0 ? messages[messages.length - 1].id : null,
1861
+ messages: formattedMessages
1862
+ };
1863
+ } catch (error) {
1864
+ console.error("[History] Load error:", error);
1865
+ return { headId: null, messages: [] };
1866
+ }
1867
+ },
1868
+ async append(message) {
1869
+ console.log("[History] append() called");
1870
+ },
1871
+ // Required by useExternalHistory in @assistant-ui/react-ai-sdk
1872
+ withFormat(_formatAdapter) {
1873
+ console.log("[History.withFormat] called, remoteId:", remoteId);
1874
+ return {
1875
+ async load() {
1876
+ if (!remoteId) return { headId: null, messages: [] };
1877
+ try {
1878
+ const response = await fetch(
1879
+ `${baseUrl}/api/widget/threads/${remoteId}/messages`,
1880
+ { headers }
1881
+ );
1882
+ if (!response.ok) {
1883
+ console.error("[History.withFormat] Failed:", response.status);
1884
+ return { headId: null, messages: [] };
1885
+ }
1886
+ const { messages } = await response.json();
1887
+ console.log("[History.withFormat] Loaded:", messages.length);
1888
+ const formattedMessages = messages.map(
1889
+ (m, index) => ({
1890
+ parentId: index > 0 ? messages[index - 1].id : null,
1891
+ message: {
1892
+ id: m.id,
1893
+ role: m.role,
1894
+ parts: m.content,
1895
+ metadata: m.metadata,
1896
+ createdAt: new Date(m.createdAt)
1897
+ }
1898
+ })
1899
+ );
1900
+ return {
1901
+ headId: messages.length > 0 ? messages[messages.length - 1].id : null,
1902
+ messages: formattedMessages
1903
+ };
1904
+ } catch (error) {
1905
+ console.error("[History.withFormat] Error:", error);
1906
+ return { headId: null, messages: [] };
1907
+ }
1908
+ },
1909
+ async append(_item) {
1910
+ }
1911
+ };
1912
+ }
1913
+ };
1914
+ }
1915
+ function AssistantRuntimeWrapper({
1916
+ config,
1917
+ userId,
1918
+ children
1919
+ }) {
1920
+ const baseUrl = config.baseUrl || "http://localhost:3000";
1921
+ const assistantId = config.apiKey;
1922
+ const { consumeContext, clearContext } = useMessageContext();
1923
+ const contextRef = React2.useRef(consumeContext);
1924
+ contextRef.current = consumeContext;
1925
+ const clearContextRef = React2.useRef(clearContext);
1926
+ clearContextRef.current = clearContext;
1927
+ const threadListAdapter = React2.useMemo(
1928
+ () => createThreadListAdapter(baseUrl, userId, assistantId),
1929
+ [baseUrl, userId, assistantId]
1930
+ );
1931
+ const runtime = react$1.unstable_useRemoteThreadListRuntime({
1932
+ runtimeHook: function useChatThreadRuntime() {
1933
+ const threadId = react$1.useAssistantState(
1934
+ ({ threadListItem }) => threadListItem?.remoteId ?? void 0
1935
+ );
1936
+ const threadIdRef = React2.useRef(threadId);
1937
+ threadIdRef.current = threadId;
1938
+ const history = React2.useMemo(
1939
+ () => createHistoryAdapter(baseUrl, userId, assistantId, threadId),
1940
+ [threadId]
1941
+ );
1942
+ const transport = React2.useMemo(() => {
1943
+ console.log("[Widget] Creating transport for threadId:", threadId);
1944
+ return new reactAiSdk.AssistantChatTransport({
1945
+ api: `${baseUrl}/api/widget/chat`,
1946
+ headers: {
1947
+ "X-User-Id": userId,
1948
+ "X-Assistant-Id": assistantId
1949
+ },
1950
+ // Use body as a function to dynamically include context
1951
+ body: () => {
1952
+ const currentContext = contextRef.current();
1953
+ const contextIds = currentContext.map((item) => item.id);
1954
+ const contextMetadata = currentContext.map((item) => ({
1955
+ id: item.id,
1956
+ type: item.type,
1957
+ title: item.title
1958
+ }));
1959
+ console.log(
1960
+ "[Widget] Transport body - contextIds:",
1961
+ contextIds.length,
1962
+ "threadId:",
1963
+ threadId
1964
+ );
1965
+ if (contextIds.length > 0) {
1966
+ setTimeout(() => clearContextRef.current(), 0);
1967
+ }
1968
+ return {
1969
+ assistantId,
1970
+ threadId,
1971
+ ...contextIds.length > 0 && { contextIds, contextMetadata }
1972
+ };
1973
+ }
1974
+ });
1975
+ }, [threadId]);
1976
+ const runtime2 = reactAiSdk.useChatRuntime({
1977
+ transport,
1978
+ adapters: { history },
1979
+ onFinish: ({ message, messages }) => {
1980
+ const currentThreadId = threadIdRef.current;
1981
+ console.log(
1982
+ "[Widget] onFinish - threadId:",
1983
+ currentThreadId,
1984
+ "messages:",
1985
+ messages.length
1986
+ );
1987
+ if (currentThreadId && messages.length > 0) {
1988
+ saveMessages(
1989
+ baseUrl,
1990
+ userId,
1991
+ assistantId,
1992
+ currentThreadId,
1993
+ messages
1994
+ );
1995
+ }
1996
+ }
1997
+ });
1998
+ return runtime2;
1999
+ },
2000
+ adapter: threadListAdapter
2001
+ });
2002
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.AssistantRuntimeProvider, { runtime, children });
2003
+ }
2004
+ function WidgetProvider({
2005
+ config,
2006
+ children,
2007
+ autoInitialize = true
2008
+ }) {
2009
+ const [userId] = React2.useState(() => config.userId || generateUserId());
2010
+ const [client] = React2.useState(() => new WidgetClient(config));
2011
+ const [state, setState] = React2.useState(client.getState());
2012
+ React2.useEffect(() => {
2013
+ const unsubscribe = client.on("state:change", ({ current }) => {
2014
+ setState(current);
2015
+ });
2016
+ if (autoInitialize && state.status === "idle") {
2017
+ client.initialize().catch(console.error);
2018
+ }
2019
+ return () => {
2020
+ unsubscribe();
2021
+ client.destroy();
2022
+ };
2023
+ }, [client, autoInitialize, state.status]);
2024
+ const contextValue = React2.useMemo(
2025
+ () => ({ client, state, userId }),
2026
+ [client, state, userId]
2027
+ );
2028
+ return /* @__PURE__ */ jsxRuntime.jsx(react$2.CacheProvider, { value: widgetCache, children: /* @__PURE__ */ jsxRuntime.jsx(react$2.ThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsx(WidgetContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(MessageContextProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(AssistantRuntimeWrapper, { config, userId, children }) }) }) }) });
2029
+ }
2030
+ function useWidget() {
2031
+ const context = React2.useContext(WidgetContext);
2032
+ if (!context) {
2033
+ throw new Error("useWidget must be used within a WidgetProvider");
2034
+ }
2035
+ const { client, state } = context;
2036
+ const initialize = React2.useCallback(async () => {
2037
+ if (state.status === "idle") {
2038
+ await client.initialize();
2039
+ }
2040
+ }, [client, state.status]);
2041
+ const sendMessage = React2.useCallback(
2042
+ async (content) => {
2043
+ return client.sendMessage(content);
2044
+ },
2045
+ [client]
2046
+ );
2047
+ return {
2048
+ state,
2049
+ client,
2050
+ isIdle: state.status === "idle",
2051
+ isInitializing: state.status === "initializing",
2052
+ isReady: state.status === "ready",
2053
+ isLoading: state.status === "loading",
2054
+ isError: state.status === "error",
2055
+ messages: state.status === "ready" ? state.session.messages : [],
2056
+ error: state.status === "error" ? state.error : null,
2057
+ initialize,
2058
+ sendMessage
2059
+ };
2060
+ }
2061
+ function useChat() {
2062
+ const { sendMessage, messages, isLoading, isReady } = useWidget();
2063
+ const [input, setInput] = React2.useState("");
2064
+ const handleSubmit = React2.useCallback(
2065
+ async (e) => {
2066
+ e?.preventDefault();
2067
+ if (!input.trim() || !isReady || isLoading) {
2068
+ return;
2069
+ }
2070
+ const message = input.trim();
2071
+ setInput("");
2103
2072
  try {
2104
- const response = await fetch(`${baseUrl}/api/widget/threads`, {
2105
- headers
2106
- });
2107
- if (!response.ok) {
2108
- console.error("[Threads] List failed:", response.status);
2109
- return { threads: [] };
2110
- }
2111
- const data = await response.json();
2112
- return { threads: data.threads || [] };
2073
+ await sendMessage(message);
2113
2074
  } catch (error) {
2114
- console.error("[Threads] List error:", error);
2115
- return { threads: [] };
2075
+ console.error("Failed to send message:", error);
2076
+ setInput(message);
2116
2077
  }
2117
2078
  },
2118
- // Fetch a single thread's details
2119
- async fetch(remoteId) {
2120
- const response = await fetch(
2121
- `${baseUrl}/api/widget/threads/${remoteId}`,
2122
- {
2123
- headers
2079
+ [input, isReady, isLoading, sendMessage]
2080
+ );
2081
+ return {
2082
+ input,
2083
+ setInput,
2084
+ handleSubmit,
2085
+ messages,
2086
+ isLoading,
2087
+ canSubmit: isReady && !isLoading && input.trim().length > 0
2088
+ };
2089
+ }
2090
+ var ThreadListItem = () => {
2091
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadListItemPrimitive.Root, { className: "group relative flex items-center gap-2 px-2 py-1.5 hover:bg-muted/50 data-[active]:bg-muted cursor-pointer transition-colors rounded-sm", children: /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadListItemPrimitive.Trigger, { className: "flex flex-1 items-center gap-2 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadListItemPrimitive.Title, { fallback: "New Chat" }) }) }) });
2092
+ };
2093
+ var ChatHistoryPopover = ({
2094
+ onSelectThread
2095
+ }) => {
2096
+ const handleThreadSelect = () => {
2097
+ onSelectThread?.();
2098
+ };
2099
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", onClick: handleThreadSelect, children: [
2100
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", style: { color: "hsl(var(--muted-foreground))" }, children: "Previous 7 days" }) }),
2101
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-[300px] overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
2102
+ react$1.ThreadListPrimitive.Items,
2103
+ {
2104
+ components: {
2105
+ ThreadListItem
2124
2106
  }
2125
- );
2126
- if (!response.ok) {
2127
- throw new Error(`Failed to fetch thread: ${response.status}`);
2128
2107
  }
2129
- const data = await response.json();
2130
- return {
2131
- remoteId: data.remoteId,
2132
- status: data.status,
2133
- title: data.title
2134
- };
2135
- },
2136
- // Initialize a new thread
2137
- async initialize(localId) {
2138
- try {
2139
- const response = await fetch(`${baseUrl}/api/widget/threads`, {
2140
- method: "POST",
2141
- headers,
2142
- body: JSON.stringify({ localId })
2143
- });
2144
- if (!response.ok) {
2145
- throw new Error(`Failed to create thread: ${response.status}`);
2108
+ ) })
2109
+ ] });
2110
+ };
2111
+ function cn(...inputs) {
2112
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
2113
+ }
2114
+ var categoryIcons = {
2115
+ audio: lucideReact.HeadphonesIcon,
2116
+ "audio-overview": lucideReact.HeadphonesIcon,
2117
+ "video-overview": lucideReact.VideoIcon,
2118
+ "mind-map": lucideReact.NetworkIcon,
2119
+ reports: lucideReact.FileTextIcon,
2120
+ flashcards: lucideReact.LayersIcon,
2121
+ quiz: lucideReact.HelpCircleIcon,
2122
+ "slide-deck": lucideReact.PresentationIcon,
2123
+ infographic: lucideReact.BarChart3Icon
2124
+ };
2125
+ var categoryColors = {
2126
+ audio: "bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300",
2127
+ "audio-overview": "bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300",
2128
+ "video-overview": "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-300",
2129
+ "mind-map": "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300",
2130
+ reports: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300",
2131
+ flashcards: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-300",
2132
+ quiz: "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300",
2133
+ "slide-deck": "bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-300",
2134
+ infographic: "bg-teal-100 text-teal-700 dark:bg-teal-900/30 dark:text-teal-300"
2135
+ };
2136
+ var categoryLabels = {
2137
+ audio: "Audio",
2138
+ "audio-overview": "Audio Overview",
2139
+ "video-overview": "Video Overview",
2140
+ "mind-map": "Mind Map",
2141
+ reports: "Report",
2142
+ flashcards: "Flashcards",
2143
+ quiz: "Quiz",
2144
+ "slide-deck": "Slide Deck",
2145
+ infographic: "Infographic"
2146
+ };
2147
+ var ArtifactCard = ({
2148
+ category,
2149
+ title,
2150
+ content,
2151
+ isLoading,
2152
+ children
2153
+ }) => {
2154
+ const Icon = categoryIcons[category];
2155
+ const colorClass = categoryColors[category];
2156
+ const label = categoryLabels[category];
2157
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-3 overflow-hidden rounded-xl border border-border bg-card shadow-sm", children: [
2158
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-3 px-4 py-3", colorClass), children: [
2159
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-white/50 dark:bg-black/20", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2Icon, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4" }) }),
2160
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
2161
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium opacity-80", children: label }),
2162
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "truncate font-semibold text-sm", children: title })
2163
+ ] })
2164
+ ] }),
2165
+ content && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-3 text-sm text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "line-clamp-4 whitespace-pre-wrap", children: content }) }),
2166
+ children,
2167
+ !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-2 border-t border-border px-4 py-2", children: [
2168
+ /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium text-muted-foreground hover:bg-muted transition-colors", children: [
2169
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DownloadIcon, { className: "h-3 w-3" }),
2170
+ "Export"
2171
+ ] }),
2172
+ /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium text-muted-foreground hover:bg-muted transition-colors", children: [
2173
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLinkIcon, { className: "h-3 w-3" }),
2174
+ "Open"
2175
+ ] })
2176
+ ] })
2177
+ ] });
2178
+ };
2179
+ function createArtifactToolUI(category) {
2180
+ return react$1.makeAssistantToolUI({
2181
+ toolName: `create_${category.replace(/-/g, "_")}`,
2182
+ render: ({ args, result, status }) => {
2183
+ const isLoading = status.type === "running";
2184
+ return /* @__PURE__ */ jsxRuntime.jsx(
2185
+ ArtifactCard,
2186
+ {
2187
+ category,
2188
+ title: args.title || "Generating...",
2189
+ content: result?.content || args.content,
2190
+ isLoading
2146
2191
  }
2147
- const data = await response.json();
2148
- return { remoteId: data.remoteId, externalId: data.externalId };
2149
- } catch (error) {
2150
- console.error("[Threads] Initialize error:", error);
2151
- throw error;
2152
- }
2153
- },
2154
- // Rename a thread
2155
- async rename(remoteId, newTitle) {
2156
- try {
2157
- await fetch(`${baseUrl}/api/widget/threads/${remoteId}`, {
2158
- method: "PATCH",
2159
- headers,
2160
- body: JSON.stringify({ title: newTitle })
2161
- });
2162
- } catch (error) {
2163
- console.error("[Threads] Rename error:", error);
2164
- }
2165
- },
2166
- // Archive a thread
2167
- async archive(remoteId) {
2168
- try {
2169
- await fetch(`${baseUrl}/api/widget/threads/${remoteId}/archive`, {
2170
- method: "POST",
2171
- headers
2172
- });
2173
- } catch (error) {
2174
- console.error("[Threads] Archive error:", error);
2175
- }
2176
- },
2177
- // Unarchive a thread
2178
- async unarchive(remoteId) {
2179
- try {
2180
- await fetch(`${baseUrl}/api/widget/threads/${remoteId}/unarchive`, {
2181
- method: "POST",
2182
- headers
2183
- });
2184
- } catch (error) {
2185
- console.error("[Threads] Unarchive error:", error);
2186
- }
2187
- },
2188
- // Delete a thread
2189
- async delete(remoteId) {
2190
- try {
2191
- await fetch(`${baseUrl}/api/widget/threads/${remoteId}`, {
2192
- method: "DELETE",
2193
- headers
2194
- });
2195
- } catch (error) {
2196
- console.error("[Threads] Delete error:", error);
2192
+ );
2193
+ }
2194
+ });
2195
+ }
2196
+ var AudioOverviewToolUI = createArtifactToolUI("audio-overview");
2197
+ var VideoOverviewToolUI = createArtifactToolUI("video-overview");
2198
+ var MindMapToolUI = createArtifactToolUI("mind-map");
2199
+ var ReportsToolUI = createArtifactToolUI("reports");
2200
+ var FlashcardsToolUI = createArtifactToolUI("flashcards");
2201
+ var QuizToolUI = createArtifactToolUI("quiz");
2202
+ var SlideDeckToolUI = createArtifactToolUI("slide-deck");
2203
+ var InfographicToolUI = createArtifactToolUI("infographic");
2204
+ var ArtifactToolUIs = () => {
2205
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2206
+ /* @__PURE__ */ jsxRuntime.jsx(AudioOverviewToolUI, {}),
2207
+ /* @__PURE__ */ jsxRuntime.jsx(VideoOverviewToolUI, {}),
2208
+ /* @__PURE__ */ jsxRuntime.jsx(MindMapToolUI, {}),
2209
+ /* @__PURE__ */ jsxRuntime.jsx(ReportsToolUI, {}),
2210
+ /* @__PURE__ */ jsxRuntime.jsx(FlashcardsToolUI, {}),
2211
+ /* @__PURE__ */ jsxRuntime.jsx(QuizToolUI, {}),
2212
+ /* @__PURE__ */ jsxRuntime.jsx(SlideDeckToolUI, {}),
2213
+ /* @__PURE__ */ jsxRuntime.jsx(InfographicToolUI, {})
2214
+ ] });
2215
+ };
2216
+ function TooltipProvider({
2217
+ delayDuration = 0,
2218
+ ...props
2219
+ }) {
2220
+ return /* @__PURE__ */ jsxRuntime.jsx(
2221
+ TooltipPrimitive__namespace.Provider,
2222
+ {
2223
+ "data-slot": "tooltip-provider",
2224
+ delayDuration,
2225
+ ...props
2226
+ }
2227
+ );
2228
+ }
2229
+ function Tooltip({
2230
+ ...props
2231
+ }) {
2232
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Root, { "data-slot": "tooltip", ...props }) });
2233
+ }
2234
+ function TooltipTrigger({
2235
+ ...props
2236
+ }) {
2237
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Trigger, { "data-slot": "tooltip-trigger", ...props });
2238
+ }
2239
+ function TooltipContent({
2240
+ className,
2241
+ sideOffset = 0,
2242
+ children,
2243
+ ...props
2244
+ }) {
2245
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
2246
+ TooltipPrimitive__namespace.Content,
2247
+ {
2248
+ "data-slot": "tooltip-content",
2249
+ sideOffset,
2250
+ className: cn(
2251
+ "bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
2252
+ className
2253
+ ),
2254
+ ...props,
2255
+ children: [
2256
+ children,
2257
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Arrow, { className: "bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })
2258
+ ]
2259
+ }
2260
+ ) });
2261
+ }
2262
+ var buttonVariants = classVarianceAuthority.cva(
2263
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
2264
+ {
2265
+ variants: {
2266
+ variant: {
2267
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
2268
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
2269
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
2270
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
2271
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
2272
+ link: "text-primary underline-offset-4 hover:underline"
2273
+ },
2274
+ size: {
2275
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
2276
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
2277
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
2278
+ icon: "size-9",
2279
+ "icon-sm": "size-8",
2280
+ "icon-lg": "size-10"
2197
2281
  }
2198
2282
  },
2199
- // Generate a title from messages
2200
- async generateTitle(remoteId, messages) {
2201
- return assistantStream.createAssistantStream(async (controller) => {
2202
- try {
2203
- const response = await fetch(
2204
- `${baseUrl}/api/widget/threads/${remoteId}/title`,
2283
+ defaultVariants: {
2284
+ variant: "default",
2285
+ size: "default"
2286
+ }
2287
+ }
2288
+ );
2289
+ var Button2 = React2__namespace.forwardRef(({ className, variant = "default", size = "default", asChild = false, ...props }, ref) => {
2290
+ const Comp = asChild ? reactSlot.Slot : "button";
2291
+ return /* @__PURE__ */ jsxRuntime.jsx(
2292
+ Comp,
2293
+ {
2294
+ ref,
2295
+ "data-slot": "button",
2296
+ "data-variant": variant,
2297
+ "data-size": size,
2298
+ className: cn(buttonVariants({ variant, size, className })),
2299
+ ...props
2300
+ }
2301
+ );
2302
+ });
2303
+ Button2.displayName = "Button";
2304
+ var TooltipIconButton = React2.forwardRef(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
2305
+ return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
2306
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button2, { variant: "ghost", size: "icon-sm", ...rest, ref, children: [
2307
+ /* @__PURE__ */ jsxRuntime.jsx(reactSlot.Slottable, { children }),
2308
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "aui-sr-only sr-only", children: tooltip })
2309
+ ] }) }),
2310
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side, children: tooltip })
2311
+ ] });
2312
+ });
2313
+ TooltipIconButton.displayName = "TooltipIconButton";
2314
+ var ToolCard = ({
2315
+ title,
2316
+ subtitle,
2317
+ isStreaming,
2318
+ isError = false,
2319
+ icon,
2320
+ persistentContent,
2321
+ children,
2322
+ footer
2323
+ }) => {
2324
+ const [manualExpanded, setManualExpanded] = React2.useState(null);
2325
+ const prevStreamingRef = React2.useRef(isStreaming);
2326
+ const contentRef = React2.useRef(null);
2327
+ const isExpanded = manualExpanded ?? isStreaming;
2328
+ React2.useEffect(() => {
2329
+ if (isStreaming && !prevStreamingRef.current) {
2330
+ setManualExpanded(null);
2331
+ }
2332
+ prevStreamingRef.current = isStreaming;
2333
+ }, [isStreaming]);
2334
+ React2.useEffect(() => {
2335
+ if (isStreaming && contentRef.current) {
2336
+ contentRef.current.scrollTop = contentRef.current.scrollHeight;
2337
+ }
2338
+ });
2339
+ const renderIcon = () => {
2340
+ if (icon) return icon;
2341
+ const iconClass = cn("h-4 w-4", isStreaming && "animate-spin");
2342
+ if (isStreaming) {
2343
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2Icon, { className: iconClass });
2344
+ }
2345
+ if (isError) {
2346
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircleIcon, { className: "h-4 w-4 text-red-400" });
2347
+ }
2348
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "h-4 w-4" });
2349
+ };
2350
+ const handleToggle = () => {
2351
+ if (!isStreaming) {
2352
+ setManualExpanded((prev2) => prev2 === null ? true : !prev2);
2353
+ }
2354
+ };
2355
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-2 overflow-hidden rounded-xl border border-border shadow-sm", children: [
2356
+ /* @__PURE__ */ jsxRuntime.jsxs(
2357
+ "div",
2358
+ {
2359
+ className: cn(
2360
+ "flex items-center gap-2 p-2 cursor-pointer transition-colors text-white bg-primary-foreground",
2361
+ !isStreaming && "hover:opacity-90"
2362
+ ),
2363
+ onClick: handleToggle,
2364
+ children: [
2365
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: renderIcon() }),
2366
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
2367
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium opacity-80 leading-tight text-xs text-muted-foreground", children: subtitle }),
2368
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "truncate font-semibold leading-tight text-sm text-muted-foreground", children: title })
2369
+ ] }),
2370
+ /* @__PURE__ */ jsxRuntime.jsx(
2371
+ "button",
2205
2372
  {
2206
- method: "POST",
2207
- headers,
2208
- body: JSON.stringify({ messages })
2373
+ className: "p-1 rounded hover:bg-white/20 transition-colors",
2374
+ "aria-label": isExpanded ? "Collapse" : "Expand",
2375
+ onClick: (e) => {
2376
+ e.stopPropagation();
2377
+ handleToggle();
2378
+ },
2379
+ children: isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUpIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "h-4 w-4" })
2209
2380
  }
2210
- );
2211
- if (!response.ok) {
2212
- throw new Error(`Title generation failed: ${response.status}`);
2381
+ )
2382
+ ]
2383
+ }
2384
+ ),
2385
+ persistentContent,
2386
+ isExpanded && /* @__PURE__ */ jsxRuntime.jsx(
2387
+ "div",
2388
+ {
2389
+ ref: contentRef,
2390
+ className: "p-2 max-h-[400px] overflow-y-auto bg-secondary",
2391
+ children
2392
+ }
2393
+ ),
2394
+ isExpanded && footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end gap-2 border-t border-white/10 p-2 bg-primary-foreground/80", children: footer })
2395
+ ] });
2396
+ };
2397
+ var useCopyToClipboard = ({
2398
+ copiedDuration = 3e3
2399
+ } = {}) => {
2400
+ const [isCopied, setIsCopied] = React2.useState(false);
2401
+ const copyToClipboard = (value) => {
2402
+ if (!value) return;
2403
+ navigator.clipboard.writeText(value).then(() => {
2404
+ setIsCopied(true);
2405
+ setTimeout(() => setIsCopied(false), copiedDuration);
2406
+ });
2407
+ };
2408
+ return { isCopied, copyToClipboard };
2409
+ };
2410
+ var MarkdownContent = React2.memo(({ content }) => {
2411
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aui-md max-w-none text-white", children: /* @__PURE__ */ jsxRuntime.jsx(
2412
+ ReactMarkdown__default.default,
2413
+ {
2414
+ remarkPlugins: [remarkGfm__default.default],
2415
+ components: {
2416
+ h1: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2417
+ "h1",
2418
+ {
2419
+ className: cn(
2420
+ "mb-2 font-extrabold tracking-tight last:mb-0 text-white",
2421
+ className
2422
+ ),
2423
+ style: { fontSize: "12px" },
2424
+ ...props
2425
+ }
2426
+ ),
2427
+ h2: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2428
+ "h2",
2429
+ {
2430
+ className: cn(
2431
+ "mt-3 mb-1.5 font-semibold tracking-tight first:mt-0 last:mb-0 text-white",
2432
+ className
2433
+ ),
2434
+ style: { fontSize: "10px" },
2435
+ ...props
2436
+ }
2437
+ ),
2438
+ h3: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2439
+ "h3",
2440
+ {
2441
+ className: cn(
2442
+ "mt-2 mb-1 font-semibold tracking-tight first:mt-0 last:mb-0 text-white",
2443
+ className
2444
+ ),
2445
+ style: { fontSize: "9px" },
2446
+ ...props
2447
+ }
2448
+ ),
2449
+ p: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2450
+ "p",
2451
+ {
2452
+ className: cn(
2453
+ "mt-1.5 mb-1.5 leading-relaxed first:mt-0 last:mb-0 text-white/90",
2454
+ className
2455
+ ),
2456
+ ...props
2457
+ }
2458
+ ),
2459
+ ul: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2460
+ "ul",
2461
+ {
2462
+ className: cn(
2463
+ "my-1.5 ml-3 list-disc [&>li]:mt-0.5 text-white/90",
2464
+ className
2465
+ ),
2466
+ ...props
2467
+ }
2468
+ ),
2469
+ ol: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2470
+ "ol",
2471
+ {
2472
+ className: cn(
2473
+ "my-1.5 ml-3 list-decimal [&>li]:mt-0.5 text-white/90",
2474
+ className
2475
+ ),
2476
+ ...props
2477
+ }
2478
+ ),
2479
+ blockquote: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2480
+ "blockquote",
2481
+ {
2482
+ className: cn(
2483
+ "border-l-2 border-white/30 pl-2 italic text-white/70",
2484
+ className
2485
+ ),
2486
+ ...props
2213
2487
  }
2214
- const data = await response.json();
2215
- controller.appendText(data.title);
2216
- controller.close();
2217
- } catch (error) {
2218
- console.error("[Threads] Title generation error:", error);
2219
- controller.appendText("New Chat");
2220
- controller.close();
2221
- }
2222
- });
2223
- }
2224
- };
2225
- }
2226
- async function saveMessages(baseUrl, userId, assistantId, threadId, messages) {
2227
- try {
2228
- const response = await fetch(
2229
- `${baseUrl}/api/widget/threads/${threadId}/messages/sync`,
2230
- {
2231
- method: "POST",
2232
- headers: createApiHeaders(userId, assistantId),
2233
- body: JSON.stringify({ messages })
2234
- }
2235
- );
2236
- if (!response.ok) {
2237
- console.error("[Messages] Sync failed:", response.status);
2238
- }
2239
- } catch (error) {
2240
- console.error("[Messages] Sync error:", error);
2241
- }
2242
- }
2243
- function createHistoryAdapter(baseUrl, userId, assistantId, remoteId) {
2244
- const headers = createApiHeaders(userId, assistantId);
2245
- return {
2246
- async load() {
2247
- console.log("[History] load() called, remoteId:", remoteId);
2248
- if (!remoteId) return { headId: null, messages: [] };
2249
- try {
2250
- const response = await fetch(
2251
- `${baseUrl}/api/widget/threads/${remoteId}/messages`,
2252
- { headers }
2253
- );
2254
- if (!response.ok) {
2255
- console.error("[History] Failed to load messages:", response.status);
2256
- return { headId: null, messages: [] };
2257
- }
2258
- const { messages } = await response.json();
2259
- console.log("[History] Loaded messages:", messages.length);
2260
- const formattedMessages = messages.map(
2261
- (m, index) => ({
2262
- parentId: index > 0 ? messages[index - 1].id : null,
2263
- message: {
2264
- id: m.id,
2265
- role: m.role,
2266
- parts: m.content,
2267
- metadata: m.metadata,
2268
- createdAt: new Date(m.createdAt)
2269
- }
2270
- })
2271
- );
2272
- console.log("[History] Formatted messages:", formattedMessages.length);
2273
- return {
2274
- headId: messages.length > 0 ? messages[messages.length - 1].id : null,
2275
- messages: formattedMessages
2276
- };
2277
- } catch (error) {
2278
- console.error("[History] Load error:", error);
2279
- return { headId: null, messages: [] };
2280
- }
2281
- },
2282
- async append(message) {
2283
- console.log("[History] append() called");
2284
- },
2285
- // Required by useExternalHistory in @assistant-ui/react-ai-sdk
2286
- withFormat(_formatAdapter) {
2287
- console.log("[History.withFormat] called, remoteId:", remoteId);
2288
- return {
2289
- async load() {
2290
- if (!remoteId) return { headId: null, messages: [] };
2291
- try {
2292
- const response = await fetch(
2293
- `${baseUrl}/api/widget/threads/${remoteId}/messages`,
2294
- { headers }
2295
- );
2296
- if (!response.ok) {
2297
- console.error("[History.withFormat] Failed:", response.status);
2298
- return { headId: null, messages: [] };
2299
- }
2300
- const { messages } = await response.json();
2301
- console.log("[History.withFormat] Loaded:", messages.length);
2302
- const formattedMessages = messages.map(
2303
- (m, index) => ({
2304
- parentId: index > 0 ? messages[index - 1].id : null,
2305
- message: {
2306
- id: m.id,
2307
- role: m.role,
2308
- parts: m.content,
2309
- metadata: m.metadata,
2310
- createdAt: new Date(m.createdAt)
2311
- }
2312
- })
2313
- );
2314
- return {
2315
- headId: messages.length > 0 ? messages[messages.length - 1].id : null,
2316
- messages: formattedMessages
2317
- };
2318
- } catch (error) {
2319
- console.error("[History.withFormat] Error:", error);
2320
- return { headId: null, messages: [] };
2488
+ ),
2489
+ pre: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2490
+ "pre",
2491
+ {
2492
+ className: cn(
2493
+ "overflow-x-auto rounded bg-black/30 p-1.5 text-white/90 my-1.5",
2494
+ className
2495
+ ),
2496
+ ...props
2321
2497
  }
2322
- },
2323
- async append(_item) {
2324
- }
2325
- };
2326
- }
2327
- };
2328
- }
2329
- function AssistantRuntimeWrapper({
2330
- config,
2331
- userId,
2332
- children
2333
- }) {
2334
- const baseUrl = config.baseUrl || "http://localhost:3000";
2335
- const assistantId = config.apiKey;
2336
- const { consumeContext, clearContext } = useMessageContext();
2337
- const contextRef = React.useRef(consumeContext);
2338
- contextRef.current = consumeContext;
2339
- const clearContextRef = React.useRef(clearContext);
2340
- clearContextRef.current = clearContext;
2341
- const threadListAdapter = React.useMemo(
2342
- () => createThreadListAdapter(baseUrl, userId, assistantId),
2343
- [baseUrl, userId, assistantId]
2344
- );
2345
- const runtime = react.unstable_useRemoteThreadListRuntime({
2346
- runtimeHook: function useChatThreadRuntime() {
2347
- const threadId = react.useAssistantState(
2348
- ({ threadListItem }) => threadListItem?.remoteId ?? void 0
2349
- );
2350
- const threadIdRef = React.useRef(threadId);
2351
- threadIdRef.current = threadId;
2352
- const history = React.useMemo(
2353
- () => createHistoryAdapter(baseUrl, userId, assistantId, threadId),
2354
- [threadId]
2355
- );
2356
- const transport = React.useMemo(() => {
2357
- console.log("[Widget] Creating transport for threadId:", threadId);
2358
- return new reactAiSdk.AssistantChatTransport({
2359
- api: `${baseUrl}/api/widget/chat`,
2360
- headers: {
2361
- "X-User-Id": userId,
2362
- "X-Assistant-Id": assistantId
2363
- },
2364
- // Use body as a function to dynamically include context
2365
- body: () => {
2366
- const currentContext = contextRef.current();
2367
- const contextIds = currentContext.map((item) => item.id);
2368
- const contextMetadata = currentContext.map((item) => ({
2369
- id: item.id,
2370
- type: item.type,
2371
- title: item.title
2372
- }));
2373
- console.log("[Widget] Transport body - contextIds:", contextIds.length, "threadId:", threadId);
2374
- if (contextIds.length > 0) {
2375
- setTimeout(() => clearContextRef.current(), 0);
2498
+ ),
2499
+ code: ({ className, ...props }) => {
2500
+ const isInline = !className?.includes("language-");
2501
+ return /* @__PURE__ */ jsxRuntime.jsx(
2502
+ "code",
2503
+ {
2504
+ className: cn(
2505
+ isInline && "rounded bg-black/30 px-0.5 py-0.5 font-mono text-white/90",
2506
+ className
2507
+ ),
2508
+ ...props
2376
2509
  }
2377
- return {
2378
- assistantId,
2379
- threadId,
2380
- ...contextIds.length > 0 && { contextIds, contextMetadata }
2381
- };
2382
- }
2383
- });
2384
- }, [threadId]);
2385
- const runtime2 = reactAiSdk.useChatRuntime({
2386
- transport,
2387
- adapters: { history },
2388
- onFinish: ({ message, messages }) => {
2389
- const currentThreadId = threadIdRef.current;
2390
- console.log(
2391
- "[Widget] onFinish - threadId:",
2392
- currentThreadId,
2393
- "messages:",
2394
- messages.length
2395
2510
  );
2396
- if (currentThreadId && messages.length > 0) {
2397
- saveMessages(
2398
- baseUrl,
2399
- userId,
2400
- assistantId,
2401
- currentThreadId,
2402
- messages
2403
- );
2511
+ },
2512
+ a: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2513
+ "a",
2514
+ {
2515
+ className: cn(
2516
+ "font-medium text-blue-300 underline underline-offset-2",
2517
+ className
2518
+ ),
2519
+ target: "_blank",
2520
+ rel: "noopener noreferrer",
2521
+ ...props
2404
2522
  }
2405
- }
2406
- });
2407
- return runtime2;
2408
- },
2409
- adapter: threadListAdapter
2410
- });
2411
- return /* @__PURE__ */ jsxRuntime.jsxs(react.AssistantRuntimeProvider, { runtime, children: [
2412
- /* @__PURE__ */ jsxRuntime.jsx(DetailedAnswerToolUI, {}),
2413
- children
2414
- ] });
2415
- }
2416
- function WidgetProvider({
2417
- config,
2418
- children,
2419
- autoInitialize = true
2420
- }) {
2421
- const [userId] = React.useState(() => config.userId || generateUserId());
2422
- const [client] = React.useState(() => new WidgetClient(config));
2423
- const [state, setState] = React.useState(client.getState());
2424
- React.useEffect(() => {
2425
- const unsubscribe = client.on("state:change", ({ current }) => {
2426
- setState(current);
2427
- });
2428
- if (autoInitialize && state.status === "idle") {
2429
- client.initialize().catch(console.error);
2430
- }
2431
- return () => {
2432
- unsubscribe();
2433
- client.destroy();
2434
- };
2435
- }, [client, autoInitialize, state.status]);
2436
- const contextValue = React.useMemo(
2437
- () => ({ client, state, userId }),
2438
- [client, state, userId]
2439
- );
2440
- return /* @__PURE__ */ jsxRuntime.jsx(react$2.CacheProvider, { value: widgetCache, children: /* @__PURE__ */ jsxRuntime.jsx(react$2.ThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsx(WidgetContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(MessageContextProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(AssistantRuntimeWrapper, { config, userId, children }) }) }) }) });
2441
- }
2442
- function useWidget() {
2443
- const context = React.useContext(WidgetContext);
2444
- if (!context) {
2445
- throw new Error("useWidget must be used within a WidgetProvider");
2446
- }
2447
- const { client, state } = context;
2448
- const initialize = React.useCallback(async () => {
2449
- if (state.status === "idle") {
2450
- await client.initialize();
2523
+ ),
2524
+ hr: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2525
+ "hr",
2526
+ {
2527
+ className: cn("my-2 border-b border-white/20", className),
2528
+ ...props
2529
+ }
2530
+ )
2531
+ },
2532
+ children: content
2451
2533
  }
2452
- }, [client, state.status]);
2453
- const sendMessage = React.useCallback(
2454
- async (content) => {
2455
- return client.sendMessage(content);
2456
- },
2457
- [client]
2458
- );
2459
- return {
2460
- state,
2461
- client,
2462
- isIdle: state.status === "idle",
2463
- isInitializing: state.status === "initializing",
2464
- isReady: state.status === "ready",
2465
- isLoading: state.status === "loading",
2466
- isError: state.status === "error",
2467
- messages: state.status === "ready" ? state.session.messages : [],
2468
- error: state.status === "error" ? state.error : null,
2469
- initialize,
2470
- sendMessage
2471
- };
2472
- }
2473
- function useChat() {
2474
- const { sendMessage, messages, isLoading, isReady } = useWidget();
2475
- const [input, setInput] = React.useState("");
2476
- const handleSubmit = React.useCallback(
2477
- async (e) => {
2478
- e?.preventDefault();
2479
- if (!input.trim() || !isReady || isLoading) {
2480
- return;
2534
+ ) });
2535
+ });
2536
+ MarkdownContent.displayName = "MarkdownContent";
2537
+ var DetailedAnswerToolUI = react$1.makeAssistantToolUI({
2538
+ toolName: "generateDetailedAnswer",
2539
+ render: function DetailedAnswerUI({ args, result, status }) {
2540
+ const { isCopied, copyToClipboard } = useCopyToClipboard();
2541
+ const isStreaming = status.type === "running";
2542
+ const isError = status.type === "incomplete";
2543
+ const title = result?.title || args.title || "Generating...";
2544
+ const content = result?.content || args.content || "";
2545
+ const summary = result?.summary || args.summary || "";
2546
+ const handleCopy = () => {
2547
+ if (content) {
2548
+ copyToClipboard(content);
2481
2549
  }
2482
- const message = input.trim();
2483
- setInput("");
2484
- try {
2485
- await sendMessage(message);
2486
- } catch (error) {
2487
- console.error("Failed to send message:", error);
2488
- setInput(message);
2550
+ };
2551
+ const handleOpenFullScreen = () => {
2552
+ const newWindow = window.open("", "_blank");
2553
+ if (newWindow) {
2554
+ newWindow.document.write(`
2555
+ <!DOCTYPE html>
2556
+ <html>
2557
+ <head>
2558
+ <title>${title}</title>
2559
+ <meta charset="utf-8">
2560
+ <meta name="viewport" content="width=device-width, initial-scale=1">
2561
+ <style>
2562
+ body {
2563
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
2564
+ max-width: 800px;
2565
+ margin: 0 auto;
2566
+ padding: 2rem;
2567
+ line-height: 1.6;
2568
+ color: #1a1a1a;
2569
+ }
2570
+ h1 { border-bottom: 1px solid #eee; padding-bottom: 0.5rem; }
2571
+ pre { background: #f5f5f5; padding: 1rem; overflow-x: auto; border-radius: 4px; }
2572
+ code { background: #f5f5f5; padding: 0.2em 0.4em; border-radius: 3px; font-size: 0.9em; }
2573
+ pre code { background: none; padding: 0; }
2574
+ blockquote { border-left: 4px solid #ddd; margin: 0; padding-left: 1rem; color: #666; }
2575
+ </style>
2576
+ </head>
2577
+ <body>
2578
+ <h1>${title}</h1>
2579
+ <div id="content">${content.replace(/</g, "&lt;").replace(/>/g, "&gt;")}</div>
2580
+ <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
2581
+ <script>
2582
+ document.getElementById('content').innerHTML = marked.parse(${JSON.stringify(
2583
+ content
2584
+ )});
2585
+ </script>
2586
+ </body>
2587
+ </html>
2588
+ `);
2589
+ newWindow.document.close();
2489
2590
  }
2490
- },
2491
- [input, isReady, isLoading, sendMessage]
2492
- );
2493
- return {
2494
- input,
2495
- setInput,
2496
- handleSubmit,
2497
- messages,
2498
- isLoading,
2499
- canSubmit: isReady && !isLoading && input.trim().length > 0
2500
- };
2501
- }
2502
- var ThreadListItem = () => {
2503
- return /* @__PURE__ */ jsxRuntime.jsx(react.ThreadListItemPrimitive.Root, { className: "group relative flex items-center gap-2 px-2 py-1.5 hover:bg-muted/50 data-[active]:bg-muted cursor-pointer transition-colors rounded-sm", children: /* @__PURE__ */ jsxRuntime.jsx(react.ThreadListItemPrimitive.Trigger, { className: "flex flex-1 items-center gap-2 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(react.ThreadListItemPrimitive.Title, { fallback: "New Chat" }) }) }) });
2504
- };
2505
- var ChatHistoryPopover = ({
2506
- onSelectThread
2507
- }) => {
2508
- const handleThreadSelect = () => {
2509
- onSelectThread?.();
2510
- };
2511
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", onClick: handleThreadSelect, children: [
2512
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx(Text, { size: "xs", style: { color: "hsl(var(--muted-foreground))" }, children: "Previous 7 days" }) }),
2513
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-[300px] overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
2514
- react.ThreadListPrimitive.Items,
2515
- {
2516
- components: {
2517
- ThreadListItem
2591
+ };
2592
+ const persistentSummary = summary ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 text-white/80 border-b border-white/10 bg-primary-foreground text-xs", children: summary }) : void 0;
2593
+ const footerActions = content ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2594
+ /* @__PURE__ */ jsxRuntime.jsx(
2595
+ TooltipIconButton,
2596
+ {
2597
+ tooltip: isCopied ? "Copied!" : "Copy markdown",
2598
+ onClick: handleCopy,
2599
+ className: "flex items-center justify-center rounded-md p-1.5 text-white/70 hover:bg-white/10 transition-colors",
2600
+ children: isCopied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CopyIcon, { className: "h-3.5 w-3.5" })
2601
+ }
2602
+ ),
2603
+ /* @__PURE__ */ jsxRuntime.jsx(
2604
+ TooltipIconButton,
2605
+ {
2606
+ tooltip: "Open in new window",
2607
+ onClick: handleOpenFullScreen,
2608
+ className: "flex items-center justify-center rounded-md p-1.5 text-white/70 hover:bg-white/10 transition-colors",
2609
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLinkIcon, { className: "h-3.5 w-3.5" })
2518
2610
  }
2611
+ )
2612
+ ] }) : void 0;
2613
+ return /* @__PURE__ */ jsxRuntime.jsx(
2614
+ ToolCard,
2615
+ {
2616
+ title,
2617
+ isStreaming,
2618
+ isError,
2619
+ icon: !isStreaming && !isError ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileTextIcon, { className: "h-4 w-4" }) : void 0,
2620
+ persistentContent: persistentSummary,
2621
+ footer: footerActions,
2622
+ children: content ? /* @__PURE__ */ jsxRuntime.jsx(MarkdownContent, { content }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground italic", children: "Generating content..." })
2519
2623
  }
2520
- ) })
2521
- ] });
2522
- };
2624
+ );
2625
+ }
2626
+ });
2523
2627
  function Dialog({
2524
2628
  ...props
2525
2629
  }) {
@@ -2645,8 +2749,8 @@ function AvatarFallback({
2645
2749
  );
2646
2750
  }
2647
2751
  var useFileSrc = (file) => {
2648
- const [src, setSrc] = React.useState(void 0);
2649
- React.useEffect(() => {
2752
+ const [src, setSrc] = React2.useState(void 0);
2753
+ React2.useEffect(() => {
2650
2754
  if (!file) {
2651
2755
  setSrc(void 0);
2652
2756
  return;
@@ -2660,7 +2764,7 @@ var useFileSrc = (file) => {
2660
2764
  return src;
2661
2765
  };
2662
2766
  var useAttachmentSrc = () => {
2663
- const { file, src } = react.useAssistantState(
2767
+ const { file, src } = react$1.useAssistantState(
2664
2768
  shallow.useShallow(({ attachment }) => {
2665
2769
  if (attachment.type !== "image") return {};
2666
2770
  if (attachment.file) return { file: attachment.file };
@@ -2700,7 +2804,7 @@ var AttachmentPreviewDialog = ({ children }) => {
2700
2804
  ] });
2701
2805
  };
2702
2806
  var AttachmentThumb = () => {
2703
- const isImage = react.useAssistantState(
2807
+ const isImage = react$1.useAssistantState(
2704
2808
  ({ attachment }) => attachment.type === "image"
2705
2809
  );
2706
2810
  const src = useAttachmentSrc();
@@ -2717,12 +2821,12 @@ var AttachmentThumb = () => {
2717
2821
  ] });
2718
2822
  };
2719
2823
  var AttachmentUI = () => {
2720
- const api = react.useAssistantApi();
2824
+ const api = react$1.useAssistantApi();
2721
2825
  const isComposer = api.attachment.source === "composer";
2722
- const isImage = react.useAssistantState(
2826
+ const isImage = react$1.useAssistantState(
2723
2827
  ({ attachment }) => attachment.type === "image"
2724
2828
  );
2725
- const typeLabel = react.useAssistantState(({ attachment }) => {
2829
+ const typeLabel = react$1.useAssistantState(({ attachment }) => {
2726
2830
  const type = attachment.type;
2727
2831
  switch (type) {
2728
2832
  case "image":
@@ -2737,7 +2841,7 @@ var AttachmentUI = () => {
2737
2841
  });
2738
2842
  return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
2739
2843
  /* @__PURE__ */ jsxRuntime.jsxs(
2740
- react.AttachmentPrimitive.Root,
2844
+ react$1.AttachmentPrimitive.Root,
2741
2845
  {
2742
2846
  className: cn(
2743
2847
  "aui-attachment-root relative",
@@ -2761,11 +2865,11 @@ var AttachmentUI = () => {
2761
2865
  ]
2762
2866
  }
2763
2867
  ),
2764
- /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Name, {}) })
2868
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsxRuntime.jsx(react$1.AttachmentPrimitive.Name, {}) })
2765
2869
  ] });
2766
2870
  };
2767
2871
  var AttachmentRemove = () => {
2768
- return /* @__PURE__ */ jsxRuntime.jsx(react.AttachmentPrimitive.Remove, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
2872
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.AttachmentPrimitive.Remove, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
2769
2873
  TooltipIconButton,
2770
2874
  {
2771
2875
  tooltip: "Remove file",
@@ -2776,18 +2880,18 @@ var AttachmentRemove = () => {
2776
2880
  ) });
2777
2881
  };
2778
2882
  var UserMessageAttachments = () => {
2779
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aui-user-message-attachments-end col-span-full col-start-1 row-start-1 flex w-full flex-row justify-end gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(react.MessagePrimitive.Attachments, { components: { Attachment: AttachmentUI } }) });
2883
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aui-user-message-attachments-end col-span-full col-start-1 row-start-1 flex w-full flex-row justify-end gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(react$1.MessagePrimitive.Attachments, { components: { Attachment: AttachmentUI } }) });
2780
2884
  };
2781
2885
  var ComposerAttachments = () => {
2782
2886
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aui-composer-attachments mb-2 flex w-full flex-row items-center gap-2 overflow-x-auto px-1.5 pt-0.5 pb-1 empty:hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
2783
- react.ComposerPrimitive.Attachments,
2887
+ react$1.ComposerPrimitive.Attachments,
2784
2888
  {
2785
2889
  components: { Attachment: AttachmentUI }
2786
2890
  }
2787
2891
  ) });
2788
2892
  };
2789
2893
  var ComposerAddAttachment = () => {
2790
- return /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.AddAttachment, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
2894
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.ComposerPrimitive.AddAttachment, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
2791
2895
  TooltipIconButton,
2792
2896
  {
2793
2897
  tooltip: "Add Attachment",
@@ -2810,7 +2914,7 @@ var MarkdownTextImpl = () => {
2810
2914
  }
2811
2915
  );
2812
2916
  };
2813
- var MarkdownText = React.memo(MarkdownTextImpl);
2917
+ var MarkdownText = React2.memo(MarkdownTextImpl);
2814
2918
  var CodeHeader = ({ language, code }) => {
2815
2919
  const { isCopied, copyToClipboard } = useCopyToClipboard2();
2816
2920
  const onCopy = () => {
@@ -2828,7 +2932,7 @@ var CodeHeader = ({ language, code }) => {
2828
2932
  var useCopyToClipboard2 = ({
2829
2933
  copiedDuration = 3e3
2830
2934
  } = {}) => {
2831
- const [isCopied, setIsCopied] = React.useState(false);
2935
+ const [isCopied, setIsCopied] = React2.useState(false);
2832
2936
  const copyToClipboard = (value) => {
2833
2937
  if (!value) return;
2834
2938
  navigator.clipboard.writeText(value).then(() => {
@@ -3134,8 +3238,8 @@ var ContextMentionPopover = ({
3134
3238
  trigger,
3135
3239
  searchTerm
3136
3240
  }) => {
3137
- const activeItemRef = React.useRef(null);
3138
- React.useEffect(() => {
3241
+ const activeItemRef = React2.useRef(null);
3242
+ React2.useEffect(() => {
3139
3243
  if (isOpen && activeItemRef.current) {
3140
3244
  activeItemRef.current.scrollIntoView({
3141
3245
  block: "nearest",
@@ -3224,7 +3328,7 @@ function getTypeIconSvg(type) {
3224
3328
  return TYPE_ICON_SVGS[type] || TYPE_ICON_SVGS.attachment;
3225
3329
  }
3226
3330
  var ZERO_WIDTH_SPACE = "\u200B";
3227
- var MentionComposerInput = React.forwardRef(
3331
+ var MentionComposerInput = React2.forwardRef(
3228
3332
  ({
3229
3333
  placeholder = "Ask, search, or make anything...",
3230
3334
  className,
@@ -3236,12 +3340,12 @@ var MentionComposerInput = React.forwardRef(
3236
3340
  onTriggerDismissed,
3237
3341
  onSubmit
3238
3342
  }, ref) => {
3239
- const editorRef = React.useRef(null);
3240
- const composerRuntime = react.useComposerRuntime();
3241
- const [isEmpty, setIsEmpty] = React.useState(true);
3242
- const [inlineMentions, setInlineMentions] = React.useState([]);
3243
- const triggerPositionRef = React.useRef(null);
3244
- const getPlainText = React.useCallback(() => {
3343
+ const editorRef = React2.useRef(null);
3344
+ const composerRuntime = react$1.useComposerRuntime();
3345
+ const [isEmpty, setIsEmpty] = React2.useState(true);
3346
+ const [inlineMentions, setInlineMentions] = React2.useState([]);
3347
+ const triggerPositionRef = React2.useRef(null);
3348
+ const getPlainText = React2.useCallback(() => {
3245
3349
  const editor = editorRef.current;
3246
3350
  if (!editor) return "";
3247
3351
  let text = "";
@@ -3264,7 +3368,7 @@ var MentionComposerInput = React.forwardRef(
3264
3368
  editor.childNodes.forEach(walkNodes);
3265
3369
  return text.trim();
3266
3370
  }, []);
3267
- const getCursorPosition = React.useCallback(() => {
3371
+ const getCursorPosition = React2.useCallback(() => {
3268
3372
  const selection = window.getSelection();
3269
3373
  if (!selection || !selection.rangeCount) return 0;
3270
3374
  const range = selection.getRangeAt(0);
@@ -3304,12 +3408,12 @@ var MentionComposerInput = React.forwardRef(
3304
3408
  }
3305
3409
  return position2;
3306
3410
  }, []);
3307
- const syncToRuntime = React.useCallback(() => {
3411
+ const syncToRuntime = React2.useCallback(() => {
3308
3412
  const text = getPlainText();
3309
3413
  composerRuntime.setText(text);
3310
3414
  setIsEmpty(text.length === 0);
3311
3415
  }, [composerRuntime, getPlainText]);
3312
- const handleInput = React.useCallback(() => {
3416
+ const handleInput = React2.useCallback(() => {
3313
3417
  syncToRuntime();
3314
3418
  const text = getPlainText();
3315
3419
  const cursorPos = getCursorPosition();
@@ -3364,7 +3468,7 @@ var MentionComposerInput = React.forwardRef(
3364
3468
  onTriggerDismissed?.();
3365
3469
  }
3366
3470
  }, [syncToRuntime, getPlainText, getCursorPosition, onInput, onTriggerDetected, onTriggerDismissed]);
3367
- const handleKeyDown = React.useCallback(
3471
+ const handleKeyDown = React2.useCallback(
3368
3472
  (e) => {
3369
3473
  if (e.key === "Enter" && !e.shiftKey) {
3370
3474
  if (onKeyDown) {
@@ -3421,7 +3525,7 @@ var MentionComposerInput = React.forwardRef(
3421
3525
  },
3422
3526
  [onKeyDown, onMentionRemove, syncToRuntime, onSubmit, getPlainText]
3423
3527
  );
3424
- const insertMention = React.useCallback(
3528
+ const insertMention = React2.useCallback(
3425
3529
  (mention) => {
3426
3530
  const editor = editorRef.current;
3427
3531
  if (!editor) return;
@@ -3503,7 +3607,7 @@ var MentionComposerInput = React.forwardRef(
3503
3607
  },
3504
3608
  [syncToRuntime]
3505
3609
  );
3506
- React.useImperativeHandle(
3610
+ React2.useImperativeHandle(
3507
3611
  ref,
3508
3612
  () => ({
3509
3613
  focus: () => editorRef.current?.focus(),
@@ -3513,12 +3617,12 @@ var MentionComposerInput = React.forwardRef(
3513
3617
  }),
3514
3618
  [getPlainText, insertMention, inlineMentions]
3515
3619
  );
3516
- React.useEffect(() => {
3620
+ React2.useEffect(() => {
3517
3621
  if (autoFocus) {
3518
3622
  editorRef.current?.focus();
3519
3623
  }
3520
3624
  }, [autoFocus]);
3521
- React.useEffect(() => {
3625
+ React2.useEffect(() => {
3522
3626
  const unsubscribe = composerRuntime.subscribe(() => {
3523
3627
  const composerState = composerRuntime.getState();
3524
3628
  if (composerState.text === "" && editorRef.current) {
@@ -3529,7 +3633,7 @@ var MentionComposerInput = React.forwardRef(
3529
3633
  });
3530
3634
  return unsubscribe;
3531
3635
  }, [composerRuntime]);
3532
- const handlePaste = React.useCallback((e) => {
3636
+ const handlePaste = React2.useCallback((e) => {
3533
3637
  e.preventDefault();
3534
3638
  const text = e.clipboardData.getData("text/plain");
3535
3639
  document.execCommand("insertText", false, text);
@@ -3617,8 +3721,8 @@ function parseMessageContent(text) {
3617
3721
  return parts;
3618
3722
  }
3619
3723
  var UserMessageContent = () => {
3620
- const message = react.useMessage();
3621
- const renderedContent = React.useMemo(() => {
3724
+ const message = react$1.useMessage();
3725
+ const renderedContent = React2.useMemo(() => {
3622
3726
  const textParts = message.content?.filter(
3623
3727
  (part) => part.type === "text"
3624
3728
  );
@@ -3650,22 +3754,22 @@ var CATEGORY_LABELS = {
3650
3754
  };
3651
3755
  function useContextMention(options = {}) {
3652
3756
  const { onInsertMention } = options;
3653
- const widgetContext = React.useContext(WidgetContext);
3757
+ const widgetContext = React2.useContext(WidgetContext);
3654
3758
  if (!widgetContext) {
3655
3759
  throw new Error("useContextMention must be used within a WidgetProvider");
3656
3760
  }
3657
3761
  const { client } = widgetContext;
3658
3762
  const { selectedContext: selectedItems, addContextItem, removeContextItem, clearContext } = useMessageContext();
3659
- const [isOpen, setIsOpen] = React.useState(false);
3660
- const [searchTerm, setSearchTerm] = React.useState("");
3661
- const [activeIndex, setActiveIndex] = React.useState(0);
3662
- const [isLoading, setIsLoading] = React.useState(false);
3663
- const [categories, setCategories] = React.useState([]);
3664
- const [hasMore, setHasMore] = React.useState(false);
3763
+ const [isOpen, setIsOpen] = React2.useState(false);
3764
+ const [searchTerm, setSearchTerm] = React2.useState("");
3765
+ const [activeIndex, setActiveIndex] = React2.useState(0);
3766
+ const [isLoading, setIsLoading] = React2.useState(false);
3767
+ const [categories, setCategories] = React2.useState([]);
3768
+ const [hasMore, setHasMore] = React2.useState(false);
3665
3769
  const config = client.getConfig();
3666
3770
  const baseUrl = config.baseUrl || "http://localhost:3000";
3667
3771
  const assistantId = config.apiKey;
3668
- const fetchContextItems = React.useCallback(
3772
+ const fetchContextItems = React2.useCallback(
3669
3773
  async (search = "", limit = 10) => {
3670
3774
  setIsLoading(true);
3671
3775
  try {
@@ -3699,18 +3803,18 @@ function useContextMention(options = {}) {
3699
3803
  },
3700
3804
  [baseUrl, assistantId]
3701
3805
  );
3702
- const openPopover = React.useCallback(() => {
3806
+ const openPopover = React2.useCallback(() => {
3703
3807
  setIsOpen(true);
3704
3808
  setSearchTerm("");
3705
3809
  setActiveIndex(0);
3706
3810
  fetchContextItems();
3707
3811
  }, [fetchContextItems]);
3708
- const closePopover = React.useCallback(() => {
3812
+ const closePopover = React2.useCallback(() => {
3709
3813
  setIsOpen(false);
3710
3814
  setSearchTerm("");
3711
3815
  setActiveIndex(0);
3712
3816
  }, []);
3713
- const updateSearch = React.useCallback(
3817
+ const updateSearch = React2.useCallback(
3714
3818
  (term) => {
3715
3819
  setSearchTerm(term);
3716
3820
  setActiveIndex(0);
@@ -3718,18 +3822,18 @@ function useContextMention(options = {}) {
3718
3822
  },
3719
3823
  [fetchContextItems]
3720
3824
  );
3721
- const flattenedItems = React.useMemo(() => {
3825
+ const flattenedItems = React2.useMemo(() => {
3722
3826
  return categories.flatMap((category) => category.items);
3723
3827
  }, [categories]);
3724
- const navigateDown = React.useCallback(() => {
3828
+ const navigateDown = React2.useCallback(() => {
3725
3829
  setActiveIndex(
3726
3830
  (prev2) => prev2 < flattenedItems.length - 1 ? prev2 + 1 : prev2
3727
3831
  );
3728
3832
  }, [flattenedItems.length]);
3729
- const navigateUp = React.useCallback(() => {
3833
+ const navigateUp = React2.useCallback(() => {
3730
3834
  setActiveIndex((prev2) => prev2 > 0 ? prev2 - 1 : 0);
3731
3835
  }, []);
3732
- const selectActiveItem = React.useCallback(() => {
3836
+ const selectActiveItem = React2.useCallback(() => {
3733
3837
  const item = flattenedItems[activeIndex];
3734
3838
  if (item) {
3735
3839
  addContextItem(item);
@@ -3737,7 +3841,7 @@ function useContextMention(options = {}) {
3737
3841
  onInsertMention?.(item);
3738
3842
  }
3739
3843
  }, [flattenedItems, activeIndex, addContextItem, closePopover, onInsertMention]);
3740
- const selectItem = React.useCallback(
3844
+ const selectItem = React2.useCallback(
3741
3845
  (item) => {
3742
3846
  addContextItem(item);
3743
3847
  closePopover();
@@ -3745,13 +3849,13 @@ function useContextMention(options = {}) {
3745
3849
  },
3746
3850
  [addContextItem, closePopover, onInsertMention]
3747
3851
  );
3748
- const removeItem = React.useCallback((itemId) => {
3852
+ const removeItem = React2.useCallback((itemId) => {
3749
3853
  removeContextItem(itemId);
3750
3854
  }, [removeContextItem]);
3751
- const clearAll = React.useCallback(() => {
3855
+ const clearAll = React2.useCallback(() => {
3752
3856
  clearContext();
3753
3857
  }, [clearContext]);
3754
- const handleKeyDown = React.useCallback(
3858
+ const handleKeyDown = React2.useCallback(
3755
3859
  (event) => {
3756
3860
  if (!isOpen) return;
3757
3861
  switch (event.key) {
@@ -3775,7 +3879,7 @@ function useContextMention(options = {}) {
3775
3879
  },
3776
3880
  [isOpen, navigateDown, navigateUp, selectActiveItem, closePopover]
3777
3881
  );
3778
- const getCategoryLabel = React.useCallback((type) => {
3882
+ const getCategoryLabel = React2.useCallback((type) => {
3779
3883
  return CATEGORY_LABELS[type] || type;
3780
3884
  }, []);
3781
3885
  return {
@@ -3809,20 +3913,20 @@ function useContextMention(options = {}) {
3809
3913
  }
3810
3914
  var Thread = () => {
3811
3915
  return /* @__PURE__ */ jsxRuntime.jsx(
3812
- react.ThreadPrimitive.Root,
3916
+ react$1.ThreadPrimitive.Root,
3813
3917
  {
3814
3918
  className: "aui-thread-root @container flex h-full flex-col bg-background",
3815
3919
  style: {
3816
3920
  ["--thread-max-width"]: "44rem"
3817
3921
  },
3818
3922
  children: /* @__PURE__ */ jsxRuntime.jsxs(
3819
- react.ThreadPrimitive.Viewport,
3923
+ react$1.ThreadPrimitive.Viewport,
3820
3924
  {
3821
3925
  className: "aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4",
3822
3926
  children: [
3823
- /* @__PURE__ */ jsxRuntime.jsx(react.AssistantIf, { condition: ({ thread }) => thread.isEmpty, children: /* @__PURE__ */ jsxRuntime.jsx(ThreadWelcome, {}) }),
3927
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.AssistantIf, { condition: ({ thread }) => thread.isEmpty, children: /* @__PURE__ */ jsxRuntime.jsx(ThreadWelcome, {}) }),
3824
3928
  /* @__PURE__ */ jsxRuntime.jsx(
3825
- react.ThreadPrimitive.Messages,
3929
+ react$1.ThreadPrimitive.Messages,
3826
3930
  {
3827
3931
  components: {
3828
3932
  UserMessage,
@@ -3831,7 +3935,7 @@ var Thread = () => {
3831
3935
  }
3832
3936
  }
3833
3937
  ),
3834
- /* @__PURE__ */ jsxRuntime.jsxs(react.ThreadPrimitive.ViewportFooter, { className: "aui-thread-viewport-footer sticky bottom-0 mx-auto mt-auto flex w-full max-w-(--thread-max-width) flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4", children: [
3938
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.ThreadPrimitive.ViewportFooter, { className: "aui-thread-viewport-footer sticky bottom-0 mx-auto mt-auto flex w-full max-w-(--thread-max-width) flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4", children: [
3835
3939
  /* @__PURE__ */ jsxRuntime.jsx(ThreadScrollToBottom, {}),
3836
3940
  /* @__PURE__ */ jsxRuntime.jsx(Composer, {})
3837
3941
  ] })
@@ -3842,7 +3946,7 @@ var Thread = () => {
3842
3946
  );
3843
3947
  };
3844
3948
  var ThreadScrollToBottom = () => {
3845
- return /* @__PURE__ */ jsxRuntime.jsx(react.ThreadPrimitive.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3949
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadPrimitive.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3846
3950
  TooltipIconButton,
3847
3951
  {
3848
3952
  tooltip: "Scroll to bottom",
@@ -3906,8 +4010,8 @@ var ThreadSuggestions = () => {
3906
4010
  {
3907
4011
  className: "fade-in slide-in-from-bottom-2 animate-in fill-mode-both duration-200",
3908
4012
  style: { animationDelay: `${200 + index * 50}ms` },
3909
- children: /* @__PURE__ */ jsxRuntime.jsx(react.ThreadPrimitive.Suggestion, { prompt: suggestion.prompt, send: true, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3910
- Button,
4013
+ children: /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadPrimitive.Suggestion, { prompt: suggestion.prompt, send: true, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4014
+ Button2,
3911
4015
  {
3912
4016
  variant: "ghost",
3913
4017
  className: "aui-thread-welcome-suggestion h-auto w-full @md:flex-col flex-wrap items-start justify-start gap-1 rounded-2xl border text-left text-sm transition-colors hover:bg-muted hover:text-primary",
@@ -3928,12 +4032,12 @@ var ThreadSuggestions = () => {
3928
4032
  }) });
3929
4033
  };
3930
4034
  var Composer = () => {
3931
- const inputRef = React.useRef(null);
3932
- const composerRuntime = react.useComposerRuntime();
3933
- const handleSubmit = React.useCallback(() => {
4035
+ const inputRef = React2.useRef(null);
4036
+ const composerRuntime = react$1.useComposerRuntime();
4037
+ const handleSubmit = React2.useCallback(() => {
3934
4038
  composerRuntime.send();
3935
4039
  }, [composerRuntime]);
3936
- const handleInsertMention = React.useCallback((item) => {
4040
+ const handleInsertMention = React2.useCallback((item) => {
3937
4041
  inputRef.current?.insertMention({
3938
4042
  id: item.id,
3939
4043
  title: item.title,
@@ -3960,7 +4064,7 @@ var Composer = () => {
3960
4064
  updateSearch
3961
4065
  } = useContextMention({ onInsertMention: handleInsertMention });
3962
4066
  const { selectedContext, removeContextItem } = useMessageContext();
3963
- const handleTriggerDetected = React.useCallback(
4067
+ const handleTriggerDetected = React2.useCallback(
3964
4068
  (searchText) => {
3965
4069
  if (!isOpen) {
3966
4070
  openPopover();
@@ -3969,12 +4073,12 @@ var Composer = () => {
3969
4073
  },
3970
4074
  [isOpen, openPopover, updateSearch]
3971
4075
  );
3972
- const handleTriggerDismissed = React.useCallback(() => {
4076
+ const handleTriggerDismissed = React2.useCallback(() => {
3973
4077
  if (isOpen) {
3974
4078
  closePopover();
3975
4079
  }
3976
4080
  }, [isOpen, closePopover]);
3977
- const handleComposerKeyDown = React.useCallback(
4081
+ const handleComposerKeyDown = React2.useCallback(
3978
4082
  (e) => {
3979
4083
  if (isOpen) {
3980
4084
  if (["ArrowUp", "ArrowDown", "Enter", "Escape"].includes(e.key)) {
@@ -3990,13 +4094,13 @@ var Composer = () => {
3990
4094
  },
3991
4095
  [isOpen, handleKeyDown]
3992
4096
  );
3993
- const handleMentionRemove = React.useCallback(
4097
+ const handleMentionRemove = React2.useCallback(
3994
4098
  (mentionId) => {
3995
4099
  removeContextItem(mentionId);
3996
4100
  },
3997
4101
  [removeContextItem]
3998
4102
  );
3999
- return /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Root, { className: "aui-composer-root relative flex w-full flex-col", children: /* @__PURE__ */ jsxRuntime.jsxs(react.ComposerPrimitive.AttachmentDropzone, { className: "aui-composer-attachment-dropzone flex w-full flex-col rounded-2xl border border-input bg-background px-1 pt-2 outline-none transition-shadow has-[[contenteditable]:focus-visible]:border-ring has-[[contenteditable]:focus-visible]:ring-2 has-[[contenteditable]:focus-visible]:ring-ring/20 data-[dragging=true]:border-ring data-[dragging=true]:border-dashed data-[dragging=true]:bg-accent/50", children: [
4103
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.ComposerPrimitive.Root, { className: "aui-composer-root relative flex w-full flex-col", children: /* @__PURE__ */ jsxRuntime.jsxs(react$1.ComposerPrimitive.AttachmentDropzone, { className: "aui-composer-attachment-dropzone flex w-full flex-col rounded-2xl border border-input bg-background px-1 pt-2 outline-none transition-shadow has-[[contenteditable]:focus-visible]:border-ring has-[[contenteditable]:focus-visible]:ring-2 has-[[contenteditable]:focus-visible]:ring-ring/20 data-[dragging=true]:border-ring data-[dragging=true]:border-dashed data-[dragging=true]:bg-accent/50", children: [
4000
4104
  /* @__PURE__ */ jsxRuntime.jsx(
4001
4105
  ComposerContextUI,
4002
4106
  {
@@ -4100,7 +4204,7 @@ var ComposerAction = () => {
4100
4204
  }
4101
4205
  )
4102
4206
  ] }),
4103
- /* @__PURE__ */ jsxRuntime.jsx(react.AssistantIf, { condition: ({ thread }) => !thread.isRunning, children: /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Send, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4207
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.AssistantIf, { condition: ({ thread }) => !thread.isRunning, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.ComposerPrimitive.Send, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4104
4208
  TooltipIconButton,
4105
4209
  {
4106
4210
  tooltip: "Send message",
@@ -4112,8 +4216,8 @@ var ComposerAction = () => {
4112
4216
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpIcon, { className: "aui-composer-send-icon size-4" })
4113
4217
  }
4114
4218
  ) }) }),
4115
- /* @__PURE__ */ jsxRuntime.jsx(react.AssistantIf, { condition: ({ thread }) => thread.isRunning, children: /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4116
- Button,
4219
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.AssistantIf, { condition: ({ thread }) => thread.isRunning, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4220
+ Button2,
4117
4221
  {
4118
4222
  type: "button",
4119
4223
  variant: "default",
@@ -4126,18 +4230,18 @@ var ComposerAction = () => {
4126
4230
  ] });
4127
4231
  };
4128
4232
  var MessageError = () => {
4129
- return /* @__PURE__ */ jsxRuntime.jsx(react.MessagePrimitive.Error, { children: /* @__PURE__ */ jsxRuntime.jsx(react.ErrorPrimitive.Root, { className: "aui-message-error-root mt-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm dark:bg-destructive/5 dark:text-red-200", children: /* @__PURE__ */ jsxRuntime.jsx(react.ErrorPrimitive.Message, { className: "aui-message-error-message line-clamp-2" }) }) });
4233
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.MessagePrimitive.Error, { children: /* @__PURE__ */ jsxRuntime.jsx(react$1.ErrorPrimitive.Root, { className: "aui-message-error-root mt-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm dark:bg-destructive/5 dark:text-red-200", children: /* @__PURE__ */ jsxRuntime.jsx(react$1.ErrorPrimitive.Message, { className: "aui-message-error-message line-clamp-2" }) }) });
4130
4234
  };
4131
4235
  var AssistantMessage = () => {
4132
4236
  return /* @__PURE__ */ jsxRuntime.jsxs(
4133
- react.MessagePrimitive.Root,
4237
+ react$1.MessagePrimitive.Root,
4134
4238
  {
4135
4239
  className: "aui-assistant-message-root fade-in slide-in-from-bottom-1 relative mx-auto w-full max-w-(--thread-max-width) animate-in py-3 duration-150",
4136
4240
  "data-role": "assistant",
4137
4241
  children: [
4138
4242
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aui-assistant-message-content wrap-break-word px-2 text-foreground leading-relaxed", children: [
4139
4243
  /* @__PURE__ */ jsxRuntime.jsx(
4140
- react.MessagePrimitive.Parts,
4244
+ react$1.MessagePrimitive.Parts,
4141
4245
  {
4142
4246
  components: {
4143
4247
  Text: MarkdownText,
@@ -4157,26 +4261,26 @@ var AssistantMessage = () => {
4157
4261
  };
4158
4262
  var AssistantActionBar = () => {
4159
4263
  return /* @__PURE__ */ jsxRuntime.jsxs(
4160
- react.ActionBarPrimitive.Root,
4264
+ react$1.ActionBarPrimitive.Root,
4161
4265
  {
4162
4266
  hideWhenRunning: true,
4163
4267
  autohide: "not-last",
4164
4268
  autohideFloat: "single-branch",
4165
4269
  className: "aui-assistant-action-bar-root col-start-3 row-start-2 -ml-1 flex gap-1 text-muted-foreground data-floating:absolute data-floating:rounded-md data-floating:border data-floating:bg-background data-floating:p-1 data-floating:shadow-sm",
4166
4270
  children: [
4167
- /* @__PURE__ */ jsxRuntime.jsx(react.ActionBarPrimitive.Copy, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(TooltipIconButton, { tooltip: "Copy", children: [
4168
- /* @__PURE__ */ jsxRuntime.jsx(react.AssistantIf, { condition: ({ message }) => message.isCopied, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, {}) }),
4169
- /* @__PURE__ */ jsxRuntime.jsx(react.AssistantIf, { condition: ({ message }) => !message.isCopied, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CopyIcon, {}) })
4271
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ActionBarPrimitive.Copy, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(TooltipIconButton, { tooltip: "Copy", children: [
4272
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.AssistantIf, { condition: ({ message }) => message.isCopied, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, {}) }),
4273
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.AssistantIf, { condition: ({ message }) => !message.isCopied, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CopyIcon, {}) })
4170
4274
  ] }) }),
4171
- /* @__PURE__ */ jsxRuntime.jsx(react.ActionBarPrimitive.ExportMarkdown, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIconButton, { tooltip: "Export as Markdown", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DownloadIcon, {}) }) }),
4172
- /* @__PURE__ */ jsxRuntime.jsx(react.ActionBarPrimitive.Reload, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIconButton, { tooltip: "Refresh", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCwIcon, {}) }) })
4275
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ActionBarPrimitive.ExportMarkdown, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIconButton, { tooltip: "Export as Markdown", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DownloadIcon, {}) }) }),
4276
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ActionBarPrimitive.Reload, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIconButton, { tooltip: "Refresh", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCwIcon, {}) }) })
4173
4277
  ]
4174
4278
  }
4175
4279
  );
4176
4280
  };
4177
4281
  var MessageContextIndicator = () => {
4178
- const [isExpanded, setIsExpanded] = React.useState(false);
4179
- const contextItems = react.useMessage((state) => {
4282
+ const [isExpanded, setIsExpanded] = React2.useState(false);
4283
+ const contextItems = react$1.useMessage((state) => {
4180
4284
  console.log("[MessageContextIndicator] Message state:", state);
4181
4285
  const metadata = state.metadata;
4182
4286
  const context = metadata?.context || metadata?.custom?.context;
@@ -4221,7 +4325,7 @@ var MessageContextIndicator = () => {
4221
4325
  };
4222
4326
  var UserMessage = () => {
4223
4327
  return /* @__PURE__ */ jsxRuntime.jsxs(
4224
- react.MessagePrimitive.Root,
4328
+ react$1.MessagePrimitive.Root,
4225
4329
  {
4226
4330
  className: "aui-user-message-root fade-in slide-in-from-bottom-1 mx-auto grid w-full max-w-(--thread-max-width) animate-in auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] content-start gap-y-2 px-2 py-3 duration-150 [&:where(>*)]:col-start-2",
4227
4331
  "data-role": "user",
@@ -4239,27 +4343,27 @@ var UserMessage = () => {
4239
4343
  };
4240
4344
  var UserActionBar = () => {
4241
4345
  return /* @__PURE__ */ jsxRuntime.jsx(
4242
- react.ActionBarPrimitive.Root,
4346
+ react$1.ActionBarPrimitive.Root,
4243
4347
  {
4244
4348
  hideWhenRunning: true,
4245
4349
  autohide: "not-last",
4246
4350
  className: "aui-user-action-bar-root flex flex-col items-end",
4247
- children: /* @__PURE__ */ jsxRuntime.jsx(react.ActionBarPrimitive.Edit, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIconButton, { tooltip: "Edit", className: "aui-user-action-edit p-4", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PencilIcon, {}) }) })
4351
+ children: /* @__PURE__ */ jsxRuntime.jsx(react$1.ActionBarPrimitive.Edit, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIconButton, { tooltip: "Edit", className: "aui-user-action-edit p-4", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PencilIcon, {}) }) })
4248
4352
  }
4249
4353
  );
4250
4354
  };
4251
4355
  var EditComposer = () => {
4252
- return /* @__PURE__ */ jsxRuntime.jsx(react.MessagePrimitive.Root, { className: "aui-edit-composer-wrapper mx-auto flex w-full max-w-(--thread-max-width) flex-col px-2 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs(react.ComposerPrimitive.Root, { className: "aui-edit-composer-root ml-auto flex w-full max-w-[85%] flex-col rounded-2xl bg-muted", children: [
4356
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.MessagePrimitive.Root, { className: "aui-edit-composer-wrapper mx-auto flex w-full max-w-(--thread-max-width) flex-col px-2 py-3", children: /* @__PURE__ */ jsxRuntime.jsxs(react$1.ComposerPrimitive.Root, { className: "aui-edit-composer-root ml-auto flex w-full max-w-[85%] flex-col rounded-2xl bg-muted", children: [
4253
4357
  /* @__PURE__ */ jsxRuntime.jsx(
4254
- react.ComposerPrimitive.Input,
4358
+ react$1.ComposerPrimitive.Input,
4255
4359
  {
4256
4360
  className: "aui-edit-composer-input min-h-14 w-full resize-none bg-transparent p-4 text-foreground text-sm outline-none",
4257
4361
  autoFocus: true
4258
4362
  }
4259
4363
  ),
4260
4364
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end", children: [
4261
- /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", children: "Cancel" }) }),
4262
- /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Send, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", children: "Update" }) })
4365
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Button2, { variant: "ghost", size: "sm", children: "Cancel" }) }),
4366
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ComposerPrimitive.Send, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Button2, { size: "sm", children: "Update" }) })
4263
4367
  ] })
4264
4368
  ] }) });
4265
4369
  };
@@ -4268,7 +4372,7 @@ var BranchPicker = ({
4268
4372
  ...rest
4269
4373
  }) => {
4270
4374
  return /* @__PURE__ */ jsxRuntime.jsxs(
4271
- react.BranchPickerPrimitive.Root,
4375
+ react$1.BranchPickerPrimitive.Root,
4272
4376
  {
4273
4377
  hideWhenSingleBranch: true,
4274
4378
  className: cn(
@@ -4277,22 +4381,22 @@ var BranchPicker = ({
4277
4381
  ),
4278
4382
  ...rest,
4279
4383
  children: [
4280
- /* @__PURE__ */ jsxRuntime.jsx(react.BranchPickerPrimitive.Previous, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIconButton, { tooltip: "Previous", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, {}) }) }),
4384
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.BranchPickerPrimitive.Previous, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIconButton, { tooltip: "Previous", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, {}) }) }),
4281
4385
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "aui-branch-picker-state font-medium", children: [
4282
- /* @__PURE__ */ jsxRuntime.jsx(react.BranchPickerPrimitive.Number, {}),
4386
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.BranchPickerPrimitive.Number, {}),
4283
4387
  " / ",
4284
- /* @__PURE__ */ jsxRuntime.jsx(react.BranchPickerPrimitive.Count, {})
4388
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.BranchPickerPrimitive.Count, {})
4285
4389
  ] }),
4286
- /* @__PURE__ */ jsxRuntime.jsx(react.BranchPickerPrimitive.Next, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIconButton, { tooltip: "Next", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, {}) }) })
4390
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.BranchPickerPrimitive.Next, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIconButton, { tooltip: "Next", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, {}) }) })
4287
4391
  ]
4288
4392
  }
4289
4393
  );
4290
4394
  };
4291
4395
  var ThreadList = () => {
4292
- return /* @__PURE__ */ jsxRuntime.jsxs(react.ThreadListPrimitive.Root, { className: "aui-thread-list-root flex flex-col", children: [
4396
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.ThreadListPrimitive.Root, { className: "aui-thread-list-root flex flex-col", children: [
4293
4397
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-b border-border px-3 py-2", children: [
4294
4398
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-foreground", children: "Chats" }),
4295
- /* @__PURE__ */ jsxRuntime.jsx(react.ThreadListPrimitive.New, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4399
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadListPrimitive.New, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4296
4400
  TooltipIconButton,
4297
4401
  {
4298
4402
  tooltip: "New chat",
@@ -4305,7 +4409,7 @@ var ThreadList = () => {
4305
4409
  ] }),
4306
4410
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto", children: [
4307
4411
  /* @__PURE__ */ jsxRuntime.jsx(
4308
- react.ThreadListPrimitive.Items,
4412
+ react$1.ThreadListPrimitive.Items,
4309
4413
  {
4310
4414
  components: {
4311
4415
  ThreadListItem: ThreadListItem2
@@ -4314,7 +4418,7 @@ var ThreadList = () => {
4314
4418
  ),
4315
4419
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Archived" }) }),
4316
4420
  /* @__PURE__ */ jsxRuntime.jsx(
4317
- react.ThreadListPrimitive.Items,
4421
+ react$1.ThreadListPrimitive.Items,
4318
4422
  {
4319
4423
  archived: true,
4320
4424
  components: {
@@ -4326,13 +4430,13 @@ var ThreadList = () => {
4326
4430
  ] });
4327
4431
  };
4328
4432
  var ThreadListItem2 = () => {
4329
- return /* @__PURE__ */ jsxRuntime.jsxs(react.ThreadListItemPrimitive.Root, { className: "aui-thread-list-item group relative flex items-center gap-2 px-3 py-2 hover:bg-muted/50 data-[active]:bg-muted cursor-pointer transition-colors", children: [
4330
- /* @__PURE__ */ jsxRuntime.jsxs(react.ThreadListItemPrimitive.Trigger, { className: "flex flex-1 items-center gap-2 min-w-0", children: [
4433
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.ThreadListItemPrimitive.Root, { className: "aui-thread-list-item group relative flex items-center gap-2 px-3 py-2 hover:bg-muted/50 data-[active]:bg-muted cursor-pointer transition-colors", children: [
4434
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.ThreadListItemPrimitive.Trigger, { className: "flex flex-1 items-center gap-2 min-w-0", children: [
4331
4435
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquareIcon, { className: "h-4 w-4 flex-shrink-0 text-muted-foreground" }),
4332
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm font-medium text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(react.ThreadListItemPrimitive.Title, { fallback: "New Chat" }) }) })
4436
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm font-medium text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadListItemPrimitive.Title, { fallback: "New Chat" }) }) })
4333
4437
  ] }),
4334
4438
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity", children: [
4335
- /* @__PURE__ */ jsxRuntime.jsx(react.ThreadListItemPrimitive.Archive, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4439
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadListItemPrimitive.Archive, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4336
4440
  TooltipIconButton,
4337
4441
  {
4338
4442
  tooltip: "Archive",
@@ -4342,7 +4446,7 @@ var ThreadListItem2 = () => {
4342
4446
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArchiveIcon, { className: "h-3.5 w-3.5" })
4343
4447
  }
4344
4448
  ) }),
4345
- /* @__PURE__ */ jsxRuntime.jsx(react.ThreadListItemPrimitive.Delete, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4449
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadListItemPrimitive.Delete, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4346
4450
  TooltipIconButton,
4347
4451
  {
4348
4452
  tooltip: "Delete",
@@ -4356,13 +4460,13 @@ var ThreadListItem2 = () => {
4356
4460
  ] });
4357
4461
  };
4358
4462
  var ArchivedThreadListItem = () => {
4359
- return /* @__PURE__ */ jsxRuntime.jsxs(react.ThreadListItemPrimitive.Root, { className: "aui-thread-list-item-archived group relative flex items-center gap-2 px-3 py-2 hover:bg-muted/50 data-[active]:bg-muted cursor-pointer transition-colors opacity-70", children: [
4360
- /* @__PURE__ */ jsxRuntime.jsxs(react.ThreadListItemPrimitive.Trigger, { className: "flex flex-1 items-center gap-2 min-w-0", children: [
4463
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.ThreadListItemPrimitive.Root, { className: "aui-thread-list-item-archived group relative flex items-center gap-2 px-3 py-2 hover:bg-muted/50 data-[active]:bg-muted cursor-pointer transition-colors opacity-70", children: [
4464
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.ThreadListItemPrimitive.Trigger, { className: "flex flex-1 items-center gap-2 min-w-0", children: [
4361
4465
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArchiveIcon, { className: "h-4 w-4 flex-shrink-0 text-muted-foreground" }),
4362
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(react.ThreadListItemPrimitive.Title, { fallback: "Archived Chat" }) }) })
4466
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadListItemPrimitive.Title, { fallback: "Archived Chat" }) }) })
4363
4467
  ] }),
4364
4468
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity", children: [
4365
- /* @__PURE__ */ jsxRuntime.jsx(react.ThreadListItemPrimitive.Unarchive, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4469
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadListItemPrimitive.Unarchive, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4366
4470
  TooltipIconButton,
4367
4471
  {
4368
4472
  tooltip: "Unarchive",
@@ -4372,7 +4476,7 @@ var ArchivedThreadListItem = () => {
4372
4476
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArchiveRestoreIcon, { className: "h-3.5 w-3.5" })
4373
4477
  }
4374
4478
  ) }),
4375
- /* @__PURE__ */ jsxRuntime.jsx(react.ThreadListItemPrimitive.Delete, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4479
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadListItemPrimitive.Delete, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4376
4480
  TooltipIconButton,
4377
4481
  {
4378
4482
  tooltip: "Delete",
@@ -4385,118 +4489,17 @@ var ArchivedThreadListItem = () => {
4385
4489
  ] })
4386
4490
  ] });
4387
4491
  };
4388
- var categoryIcons = {
4389
- audio: lucideReact.HeadphonesIcon,
4390
- "audio-overview": lucideReact.HeadphonesIcon,
4391
- "video-overview": lucideReact.VideoIcon,
4392
- "mind-map": lucideReact.NetworkIcon,
4393
- reports: lucideReact.FileTextIcon,
4394
- flashcards: lucideReact.LayersIcon,
4395
- quiz: lucideReact.HelpCircleIcon,
4396
- "slide-deck": lucideReact.PresentationIcon,
4397
- infographic: lucideReact.BarChart3Icon
4398
- };
4399
- var categoryColors = {
4400
- audio: "bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300",
4401
- "audio-overview": "bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300",
4402
- "video-overview": "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-300",
4403
- "mind-map": "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300",
4404
- reports: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300",
4405
- flashcards: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-300",
4406
- quiz: "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300",
4407
- "slide-deck": "bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-300",
4408
- infographic: "bg-teal-100 text-teal-700 dark:bg-teal-900/30 dark:text-teal-300"
4409
- };
4410
- var categoryLabels = {
4411
- audio: "Audio",
4412
- "audio-overview": "Audio Overview",
4413
- "video-overview": "Video Overview",
4414
- "mind-map": "Mind Map",
4415
- reports: "Report",
4416
- flashcards: "Flashcards",
4417
- quiz: "Quiz",
4418
- "slide-deck": "Slide Deck",
4419
- infographic: "Infographic"
4420
- };
4421
- var ArtifactCard = ({
4422
- category,
4423
- title,
4424
- content,
4425
- isLoading,
4426
- children
4427
- }) => {
4428
- const Icon = categoryIcons[category];
4429
- const colorClass = categoryColors[category];
4430
- const label = categoryLabels[category];
4431
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-3 overflow-hidden rounded-xl border border-border bg-card shadow-sm", children: [
4432
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-3 px-4 py-3", colorClass), children: [
4433
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-white/50 dark:bg-black/20", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2Icon, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4" }) }),
4434
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
4435
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium opacity-80", children: label }),
4436
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "truncate font-semibold text-sm", children: title })
4437
- ] })
4438
- ] }),
4439
- content && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-3 text-sm text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "line-clamp-4 whitespace-pre-wrap", children: content }) }),
4440
- children,
4441
- !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-2 border-t border-border px-4 py-2", children: [
4442
- /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium text-muted-foreground hover:bg-muted transition-colors", children: [
4443
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DownloadIcon, { className: "h-3 w-3" }),
4444
- "Export"
4445
- ] }),
4446
- /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium text-muted-foreground hover:bg-muted transition-colors", children: [
4447
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLinkIcon, { className: "h-3 w-3" }),
4448
- "Open"
4449
- ] })
4450
- ] })
4451
- ] });
4452
- };
4453
- function createArtifactToolUI(category) {
4454
- return react.makeAssistantToolUI({
4455
- toolName: `create_${category.replace(/-/g, "_")}`,
4456
- render: ({ args, result, status }) => {
4457
- const isLoading = status.type === "running";
4458
- return /* @__PURE__ */ jsxRuntime.jsx(
4459
- ArtifactCard,
4460
- {
4461
- category,
4462
- title: args.title || "Generating...",
4463
- content: result?.content || args.content,
4464
- isLoading
4465
- }
4466
- );
4467
- }
4468
- });
4469
- }
4470
- var AudioOverviewToolUI = createArtifactToolUI("audio-overview");
4471
- var VideoOverviewToolUI = createArtifactToolUI("video-overview");
4472
- var MindMapToolUI = createArtifactToolUI("mind-map");
4473
- var ReportsToolUI = createArtifactToolUI("reports");
4474
- var FlashcardsToolUI = createArtifactToolUI("flashcards");
4475
- var QuizToolUI = createArtifactToolUI("quiz");
4476
- var SlideDeckToolUI = createArtifactToolUI("slide-deck");
4477
- var InfographicToolUI = createArtifactToolUI("infographic");
4478
- var ArtifactToolUIs = () => {
4479
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4480
- /* @__PURE__ */ jsxRuntime.jsx(AudioOverviewToolUI, {}),
4481
- /* @__PURE__ */ jsxRuntime.jsx(VideoOverviewToolUI, {}),
4482
- /* @__PURE__ */ jsxRuntime.jsx(MindMapToolUI, {}),
4483
- /* @__PURE__ */ jsxRuntime.jsx(ReportsToolUI, {}),
4484
- /* @__PURE__ */ jsxRuntime.jsx(FlashcardsToolUI, {}),
4485
- /* @__PURE__ */ jsxRuntime.jsx(QuizToolUI, {}),
4486
- /* @__PURE__ */ jsxRuntime.jsx(SlideDeckToolUI, {}),
4487
- /* @__PURE__ */ jsxRuntime.jsx(InfographicToolUI, {})
4488
- ] });
4489
- };
4490
4492
  var ChatWidget = ({
4491
4493
  sidebarOpen = false,
4492
4494
  onSidebarClose
4493
4495
  }) => {
4494
4496
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-1 h-full w-full overflow-hidden bg-background", children: [
4495
4497
  /* @__PURE__ */ jsxRuntime.jsx(ArtifactToolUIs, {}),
4498
+ /* @__PURE__ */ jsxRuntime.jsx(DetailedAnswerToolUI, {}),
4496
4499
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden relative", children: /* @__PURE__ */ jsxRuntime.jsx(Thread, {}) }) }),
4497
- /* @__PURE__ */ jsxRuntime.jsx(react$1.AnimatePresence, { children: sidebarOpen && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4500
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: sidebarOpen && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4498
4501
  /* @__PURE__ */ jsxRuntime.jsx(
4499
- react$1.motion.div,
4502
+ react.motion.div,
4500
4503
  {
4501
4504
  initial: { opacity: 0 },
4502
4505
  animate: { opacity: 1 },
@@ -4507,7 +4510,7 @@ var ChatWidget = ({
4507
4510
  }
4508
4511
  ),
4509
4512
  /* @__PURE__ */ jsxRuntime.jsx(
4510
- react$1.motion.div,
4513
+ react.motion.div,
4511
4514
  {
4512
4515
  initial: { x: -256 },
4513
4516
  animate: { x: 0 },
@@ -4568,12 +4571,12 @@ function WidgetContainer({
4568
4571
  defaultOpen = false,
4569
4572
  position: position2 = "bottom-right"
4570
4573
  }) {
4571
- const [isOpen, setIsOpen] = React.useState(defaultOpen);
4572
- const [sidebarOpen, setSidebarOpen] = React.useState(false);
4573
- const [chatHistoryOpen, setChatHistoryOpen] = React.useState(false);
4574
- const [layoutOpen, setLayoutOpen] = React.useState(false);
4575
- const [layout, setLayout] = React.useState("floating");
4576
- React.useEffect(() => {
4574
+ const [isOpen, setIsOpen] = React2.useState(defaultOpen);
4575
+ const [sidebarOpen, setSidebarOpen] = React2.useState(false);
4576
+ const [chatHistoryOpen, setChatHistoryOpen] = React2.useState(false);
4577
+ const [layoutOpen, setLayoutOpen] = React2.useState(false);
4578
+ const [layout, setLayout] = React2.useState("floating");
4579
+ React2.useEffect(() => {
4577
4580
  const savedLayout = localStorage.getItem(LAYOUT_STORAGE_KEY);
4578
4581
  if (savedLayout && ["floating", "fullscreen", "sidebar"].includes(savedLayout)) {
4579
4582
  setLayout(savedLayout);
@@ -4584,7 +4587,7 @@ function WidgetContainer({
4584
4587
  localStorage.setItem(LAYOUT_STORAGE_KEY, newLayout);
4585
4588
  setLayoutOpen(false);
4586
4589
  };
4587
- const threadTitle = react.useAssistantState(
4590
+ const threadTitle = react$1.useAssistantState(
4588
4591
  ({ threadListItem }) => threadListItem?.title ?? "New AI chat"
4589
4592
  );
4590
4593
  const handleMinimize = () => {
@@ -4633,7 +4636,7 @@ function WidgetContainer({
4633
4636
  }
4634
4637
  };
4635
4638
  return /* @__PURE__ */ jsxRuntime.jsxs(WidgetRoot, { position: position2, children: [
4636
- /* @__PURE__ */ jsxRuntime.jsx(react$1.AnimatePresence, { children: isOpen && /* @__PURE__ */ jsxRuntime.jsxs(
4639
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: isOpen && /* @__PURE__ */ jsxRuntime.jsxs(
4637
4640
  WidgetPanel,
4638
4641
  {
4639
4642
  initial: { opacity: 0, scale: 0, y: 0 },
@@ -4702,7 +4705,7 @@ function WidgetContainer({
4702
4705
  )
4703
4706
  ] }),
4704
4707
  /* @__PURE__ */ jsxRuntime.jsxs(Flex, { align: "center", gap: "xs", style: { flexShrink: 0 }, children: [
4705
- /* @__PURE__ */ jsxRuntime.jsx(react.ThreadListPrimitive.New, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(IconButton, { "aria-label": "New chat", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.EditIcon, { size: 18 }) }) }),
4708
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadListPrimitive.New, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(IconButton, { "aria-label": "New chat", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.EditIcon, { size: 18 }) }) }),
4706
4709
  /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: layoutOpen, onOpenChange: setLayoutOpen, children: [
4707
4710
  /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4708
4711
  IconButton,
@@ -4751,7 +4754,7 @@ function WidgetContainer({
4751
4754
  ]
4752
4755
  }
4753
4756
  ) }),
4754
- /* @__PURE__ */ jsxRuntime.jsx(react$1.AnimatePresence, { children: !isOpen && /* @__PURE__ */ jsxRuntime.jsx(
4757
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: !isOpen && /* @__PURE__ */ jsxRuntime.jsx(
4755
4758
  Flex,
4756
4759
  {
4757
4760
  justify: position2 === "bottom-right" ? "flex-end" : "flex-start",
@@ -4775,20 +4778,20 @@ function WidgetContainer({
4775
4778
  }
4776
4779
  var ReadOnlyThread = () => {
4777
4780
  return /* @__PURE__ */ jsxRuntime.jsx(
4778
- react.ThreadPrimitive.Root,
4781
+ react$1.ThreadPrimitive.Root,
4779
4782
  {
4780
4783
  className: "aui-thread-root @container flex h-full flex-col bg-background",
4781
4784
  style: {
4782
4785
  ["--thread-max-width"]: "44rem"
4783
4786
  },
4784
4787
  children: /* @__PURE__ */ jsxRuntime.jsxs(
4785
- react.ThreadPrimitive.Viewport,
4788
+ react$1.ThreadPrimitive.Viewport,
4786
4789
  {
4787
4790
  turnAnchor: "top",
4788
4791
  className: "aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4 pb-4",
4789
4792
  children: [
4790
4793
  /* @__PURE__ */ jsxRuntime.jsx(
4791
- react.ThreadPrimitive.Messages,
4794
+ react$1.ThreadPrimitive.Messages,
4792
4795
  {
4793
4796
  components: {
4794
4797
  UserMessage: ReadOnlyUserMessage,
@@ -4798,7 +4801,7 @@ var ReadOnlyThread = () => {
4798
4801
  }
4799
4802
  }
4800
4803
  ),
4801
- /* @__PURE__ */ jsxRuntime.jsx(react.ThreadPrimitive.Empty, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center text-muted-foreground", children: "No messages in this conversation." }) })
4804
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadPrimitive.Empty, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center text-muted-foreground", children: "No messages in this conversation." }) })
4802
4805
  ]
4803
4806
  }
4804
4807
  )
@@ -4807,13 +4810,13 @@ var ReadOnlyThread = () => {
4807
4810
  };
4808
4811
  var ReadOnlyAssistantMessage = () => {
4809
4812
  return /* @__PURE__ */ jsxRuntime.jsx(
4810
- react.MessagePrimitive.Root,
4813
+ react$1.MessagePrimitive.Root,
4811
4814
  {
4812
4815
  className: "aui-assistant-message-root fade-in slide-in-from-bottom-1 relative mx-auto w-full max-w-(--thread-max-width) animate-in py-3 duration-150",
4813
4816
  "data-role": "assistant",
4814
4817
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aui-assistant-message-content wrap-break-word px-2 text-foreground leading-relaxed", children: [
4815
4818
  /* @__PURE__ */ jsxRuntime.jsx(
4816
- react.MessagePrimitive.Parts,
4819
+ react$1.MessagePrimitive.Parts,
4817
4820
  {
4818
4821
  components: {
4819
4822
  Text: MarkdownText,
@@ -4821,14 +4824,14 @@ var ReadOnlyAssistantMessage = () => {
4821
4824
  }
4822
4825
  }
4823
4826
  ),
4824
- /* @__PURE__ */ jsxRuntime.jsx(react.MessagePrimitive.Error, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm", children: /* @__PURE__ */ jsxRuntime.jsx(react.MessagePrimitive.Error, {}) }) })
4827
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.MessagePrimitive.Error, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm", children: /* @__PURE__ */ jsxRuntime.jsx(react$1.MessagePrimitive.Error, {}) }) })
4825
4828
  ] })
4826
4829
  }
4827
4830
  );
4828
4831
  };
4829
4832
  var ReadOnlyUserMessage = () => {
4830
4833
  return /* @__PURE__ */ jsxRuntime.jsxs(
4831
- react.MessagePrimitive.Root,
4834
+ react$1.MessagePrimitive.Root,
4832
4835
  {
4833
4836
  className: "aui-user-message-root fade-in slide-in-from-bottom-1 mx-auto grid w-full max-w-(--thread-max-width) animate-in auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] content-start gap-y-2 px-2 py-3 duration-150 [&:where(>*)]:col-start-2",
4834
4837
  "data-role": "user",