@tinkrapp/widget 1.0.0 → 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,410 +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);
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"
2175
2281
  }
2176
2282
  },
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);
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",
2372
+ {
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" })
2380
+ }
2381
+ )
2382
+ ]
2186
2383
  }
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);
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
2197
2392
  }
2198
- },
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`,
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
2487
+ }
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
2497
+ }
2498
+ ),
2499
+ code: ({ className, ...props }) => {
2500
+ const isInline = !className?.includes("language-");
2501
+ return /* @__PURE__ */ jsxRuntime.jsx(
2502
+ "code",
2205
2503
  {
2206
- method: "POST",
2207
- headers,
2208
- body: JSON.stringify({ messages })
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
2209
2509
  }
2210
2510
  );
2211
- if (!response.ok) {
2212
- throw new Error(`Title generation failed: ${response.status}`);
2213
- }
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: [] };
2321
- }
2322
2511
  },
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);
2376
- }
2377
- return {
2378
- assistantId,
2379
- threadId,
2380
- ...contextIds.length > 0 && { contextIds, contextMetadata }
2381
- };
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
2382
2522
  }
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
- );
2396
- if (currentThreadId && messages.length > 0) {
2397
- saveMessages(
2398
- baseUrl,
2399
- userId,
2400
- assistantId,
2401
- currentThreadId,
2402
- messages
2403
- );
2523
+ ),
2524
+ hr: ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
2525
+ "hr",
2526
+ {
2527
+ className: cn("my-2 border-b border-white/20", className),
2528
+ ...props
2404
2529
  }
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);
2530
+ )
2531
+ },
2532
+ children: content
2430
2533
  }
2431
- return () => {
2432
- unsubscribe();
2433
- client.destroy();
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);
2549
+ }
2434
2550
  };
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();
2451
- }
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;
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();
2481
2590
  }
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);
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" })
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..." })
2489
2623
  }
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
- }
2624
+ );
2625
+ }
2626
+ });
2502
2627
  function Dialog({
2503
2628
  ...props
2504
2629
  }) {
@@ -2624,8 +2749,8 @@ function AvatarFallback({
2624
2749
  );
2625
2750
  }
2626
2751
  var useFileSrc = (file) => {
2627
- const [src, setSrc] = React.useState(void 0);
2628
- React.useEffect(() => {
2752
+ const [src, setSrc] = React2.useState(void 0);
2753
+ React2.useEffect(() => {
2629
2754
  if (!file) {
2630
2755
  setSrc(void 0);
2631
2756
  return;
@@ -2639,7 +2764,7 @@ var useFileSrc = (file) => {
2639
2764
  return src;
2640
2765
  };
2641
2766
  var useAttachmentSrc = () => {
2642
- const { file, src } = react.useAssistantState(
2767
+ const { file, src } = react$1.useAssistantState(
2643
2768
  shallow.useShallow(({ attachment }) => {
2644
2769
  if (attachment.type !== "image") return {};
2645
2770
  if (attachment.file) return { file: attachment.file };
@@ -2679,7 +2804,7 @@ var AttachmentPreviewDialog = ({ children }) => {
2679
2804
  ] });
2680
2805
  };
2681
2806
  var AttachmentThumb = () => {
2682
- const isImage = react.useAssistantState(
2807
+ const isImage = react$1.useAssistantState(
2683
2808
  ({ attachment }) => attachment.type === "image"
2684
2809
  );
2685
2810
  const src = useAttachmentSrc();
@@ -2696,12 +2821,12 @@ var AttachmentThumb = () => {
2696
2821
  ] });
2697
2822
  };
2698
2823
  var AttachmentUI = () => {
2699
- const api = react.useAssistantApi();
2824
+ const api = react$1.useAssistantApi();
2700
2825
  const isComposer = api.attachment.source === "composer";
2701
- const isImage = react.useAssistantState(
2826
+ const isImage = react$1.useAssistantState(
2702
2827
  ({ attachment }) => attachment.type === "image"
2703
2828
  );
2704
- const typeLabel = react.useAssistantState(({ attachment }) => {
2829
+ const typeLabel = react$1.useAssistantState(({ attachment }) => {
2705
2830
  const type = attachment.type;
2706
2831
  switch (type) {
2707
2832
  case "image":
@@ -2716,7 +2841,7 @@ var AttachmentUI = () => {
2716
2841
  });
2717
2842
  return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
2718
2843
  /* @__PURE__ */ jsxRuntime.jsxs(
2719
- react.AttachmentPrimitive.Root,
2844
+ react$1.AttachmentPrimitive.Root,
2720
2845
  {
2721
2846
  className: cn(
2722
2847
  "aui-attachment-root relative",
@@ -2740,11 +2865,11 @@ var AttachmentUI = () => {
2740
2865
  ]
2741
2866
  }
2742
2867
  ),
2743
- /* @__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, {}) })
2744
2869
  ] });
2745
2870
  };
2746
2871
  var AttachmentRemove = () => {
2747
- 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(
2748
2873
  TooltipIconButton,
2749
2874
  {
2750
2875
  tooltip: "Remove file",
@@ -2755,18 +2880,18 @@ var AttachmentRemove = () => {
2755
2880
  ) });
2756
2881
  };
2757
2882
  var UserMessageAttachments = () => {
2758
- 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 } }) });
2759
2884
  };
2760
2885
  var ComposerAttachments = () => {
2761
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(
2762
- react.ComposerPrimitive.Attachments,
2887
+ react$1.ComposerPrimitive.Attachments,
2763
2888
  {
2764
2889
  components: { Attachment: AttachmentUI }
2765
2890
  }
2766
2891
  ) });
2767
2892
  };
2768
2893
  var ComposerAddAttachment = () => {
2769
- 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(
2770
2895
  TooltipIconButton,
2771
2896
  {
2772
2897
  tooltip: "Add Attachment",
@@ -2789,7 +2914,7 @@ var MarkdownTextImpl = () => {
2789
2914
  }
2790
2915
  );
2791
2916
  };
2792
- var MarkdownText = React.memo(MarkdownTextImpl);
2917
+ var MarkdownText = React2.memo(MarkdownTextImpl);
2793
2918
  var CodeHeader = ({ language, code }) => {
2794
2919
  const { isCopied, copyToClipboard } = useCopyToClipboard2();
2795
2920
  const onCopy = () => {
@@ -2807,7 +2932,7 @@ var CodeHeader = ({ language, code }) => {
2807
2932
  var useCopyToClipboard2 = ({
2808
2933
  copiedDuration = 3e3
2809
2934
  } = {}) => {
2810
- const [isCopied, setIsCopied] = React.useState(false);
2935
+ const [isCopied, setIsCopied] = React2.useState(false);
2811
2936
  const copyToClipboard = (value) => {
2812
2937
  if (!value) return;
2813
2938
  navigator.clipboard.writeText(value).then(() => {
@@ -3113,8 +3238,8 @@ var ContextMentionPopover = ({
3113
3238
  trigger,
3114
3239
  searchTerm
3115
3240
  }) => {
3116
- const activeItemRef = React.useRef(null);
3117
- React.useEffect(() => {
3241
+ const activeItemRef = React2.useRef(null);
3242
+ React2.useEffect(() => {
3118
3243
  if (isOpen && activeItemRef.current) {
3119
3244
  activeItemRef.current.scrollIntoView({
3120
3245
  block: "nearest",
@@ -3203,7 +3328,7 @@ function getTypeIconSvg(type) {
3203
3328
  return TYPE_ICON_SVGS[type] || TYPE_ICON_SVGS.attachment;
3204
3329
  }
3205
3330
  var ZERO_WIDTH_SPACE = "\u200B";
3206
- var MentionComposerInput = React.forwardRef(
3331
+ var MentionComposerInput = React2.forwardRef(
3207
3332
  ({
3208
3333
  placeholder = "Ask, search, or make anything...",
3209
3334
  className,
@@ -3215,12 +3340,12 @@ var MentionComposerInput = React.forwardRef(
3215
3340
  onTriggerDismissed,
3216
3341
  onSubmit
3217
3342
  }, ref) => {
3218
- const editorRef = React.useRef(null);
3219
- const composerRuntime = react.useComposerRuntime();
3220
- const [isEmpty, setIsEmpty] = React.useState(true);
3221
- const [inlineMentions, setInlineMentions] = React.useState([]);
3222
- const triggerPositionRef = React.useRef(null);
3223
- 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(() => {
3224
3349
  const editor = editorRef.current;
3225
3350
  if (!editor) return "";
3226
3351
  let text = "";
@@ -3243,7 +3368,7 @@ var MentionComposerInput = React.forwardRef(
3243
3368
  editor.childNodes.forEach(walkNodes);
3244
3369
  return text.trim();
3245
3370
  }, []);
3246
- const getCursorPosition = React.useCallback(() => {
3371
+ const getCursorPosition = React2.useCallback(() => {
3247
3372
  const selection = window.getSelection();
3248
3373
  if (!selection || !selection.rangeCount) return 0;
3249
3374
  const range = selection.getRangeAt(0);
@@ -3283,12 +3408,12 @@ var MentionComposerInput = React.forwardRef(
3283
3408
  }
3284
3409
  return position2;
3285
3410
  }, []);
3286
- const syncToRuntime = React.useCallback(() => {
3411
+ const syncToRuntime = React2.useCallback(() => {
3287
3412
  const text = getPlainText();
3288
3413
  composerRuntime.setText(text);
3289
3414
  setIsEmpty(text.length === 0);
3290
3415
  }, [composerRuntime, getPlainText]);
3291
- const handleInput = React.useCallback(() => {
3416
+ const handleInput = React2.useCallback(() => {
3292
3417
  syncToRuntime();
3293
3418
  const text = getPlainText();
3294
3419
  const cursorPos = getCursorPosition();
@@ -3343,7 +3468,7 @@ var MentionComposerInput = React.forwardRef(
3343
3468
  onTriggerDismissed?.();
3344
3469
  }
3345
3470
  }, [syncToRuntime, getPlainText, getCursorPosition, onInput, onTriggerDetected, onTriggerDismissed]);
3346
- const handleKeyDown = React.useCallback(
3471
+ const handleKeyDown = React2.useCallback(
3347
3472
  (e) => {
3348
3473
  if (e.key === "Enter" && !e.shiftKey) {
3349
3474
  if (onKeyDown) {
@@ -3400,7 +3525,7 @@ var MentionComposerInput = React.forwardRef(
3400
3525
  },
3401
3526
  [onKeyDown, onMentionRemove, syncToRuntime, onSubmit, getPlainText]
3402
3527
  );
3403
- const insertMention = React.useCallback(
3528
+ const insertMention = React2.useCallback(
3404
3529
  (mention) => {
3405
3530
  const editor = editorRef.current;
3406
3531
  if (!editor) return;
@@ -3482,7 +3607,7 @@ var MentionComposerInput = React.forwardRef(
3482
3607
  },
3483
3608
  [syncToRuntime]
3484
3609
  );
3485
- React.useImperativeHandle(
3610
+ React2.useImperativeHandle(
3486
3611
  ref,
3487
3612
  () => ({
3488
3613
  focus: () => editorRef.current?.focus(),
@@ -3492,12 +3617,12 @@ var MentionComposerInput = React.forwardRef(
3492
3617
  }),
3493
3618
  [getPlainText, insertMention, inlineMentions]
3494
3619
  );
3495
- React.useEffect(() => {
3620
+ React2.useEffect(() => {
3496
3621
  if (autoFocus) {
3497
3622
  editorRef.current?.focus();
3498
3623
  }
3499
3624
  }, [autoFocus]);
3500
- React.useEffect(() => {
3625
+ React2.useEffect(() => {
3501
3626
  const unsubscribe = composerRuntime.subscribe(() => {
3502
3627
  const composerState = composerRuntime.getState();
3503
3628
  if (composerState.text === "" && editorRef.current) {
@@ -3508,7 +3633,7 @@ var MentionComposerInput = React.forwardRef(
3508
3633
  });
3509
3634
  return unsubscribe;
3510
3635
  }, [composerRuntime]);
3511
- const handlePaste = React.useCallback((e) => {
3636
+ const handlePaste = React2.useCallback((e) => {
3512
3637
  e.preventDefault();
3513
3638
  const text = e.clipboardData.getData("text/plain");
3514
3639
  document.execCommand("insertText", false, text);
@@ -3596,8 +3721,8 @@ function parseMessageContent(text) {
3596
3721
  return parts;
3597
3722
  }
3598
3723
  var UserMessageContent = () => {
3599
- const message = react.useMessage();
3600
- const renderedContent = React.useMemo(() => {
3724
+ const message = react$1.useMessage();
3725
+ const renderedContent = React2.useMemo(() => {
3601
3726
  const textParts = message.content?.filter(
3602
3727
  (part) => part.type === "text"
3603
3728
  );
@@ -3629,22 +3754,22 @@ var CATEGORY_LABELS = {
3629
3754
  };
3630
3755
  function useContextMention(options = {}) {
3631
3756
  const { onInsertMention } = options;
3632
- const widgetContext = React.useContext(WidgetContext);
3757
+ const widgetContext = React2.useContext(WidgetContext);
3633
3758
  if (!widgetContext) {
3634
3759
  throw new Error("useContextMention must be used within a WidgetProvider");
3635
3760
  }
3636
3761
  const { client } = widgetContext;
3637
3762
  const { selectedContext: selectedItems, addContextItem, removeContextItem, clearContext } = useMessageContext();
3638
- const [isOpen, setIsOpen] = React.useState(false);
3639
- const [searchTerm, setSearchTerm] = React.useState("");
3640
- const [activeIndex, setActiveIndex] = React.useState(0);
3641
- const [isLoading, setIsLoading] = React.useState(false);
3642
- const [categories, setCategories] = React.useState([]);
3643
- 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);
3644
3769
  const config = client.getConfig();
3645
3770
  const baseUrl = config.baseUrl || "http://localhost:3000";
3646
3771
  const assistantId = config.apiKey;
3647
- const fetchContextItems = React.useCallback(
3772
+ const fetchContextItems = React2.useCallback(
3648
3773
  async (search = "", limit = 10) => {
3649
3774
  setIsLoading(true);
3650
3775
  try {
@@ -3678,18 +3803,18 @@ function useContextMention(options = {}) {
3678
3803
  },
3679
3804
  [baseUrl, assistantId]
3680
3805
  );
3681
- const openPopover = React.useCallback(() => {
3806
+ const openPopover = React2.useCallback(() => {
3682
3807
  setIsOpen(true);
3683
3808
  setSearchTerm("");
3684
3809
  setActiveIndex(0);
3685
3810
  fetchContextItems();
3686
3811
  }, [fetchContextItems]);
3687
- const closePopover = React.useCallback(() => {
3812
+ const closePopover = React2.useCallback(() => {
3688
3813
  setIsOpen(false);
3689
3814
  setSearchTerm("");
3690
3815
  setActiveIndex(0);
3691
3816
  }, []);
3692
- const updateSearch = React.useCallback(
3817
+ const updateSearch = React2.useCallback(
3693
3818
  (term) => {
3694
3819
  setSearchTerm(term);
3695
3820
  setActiveIndex(0);
@@ -3697,18 +3822,18 @@ function useContextMention(options = {}) {
3697
3822
  },
3698
3823
  [fetchContextItems]
3699
3824
  );
3700
- const flattenedItems = React.useMemo(() => {
3825
+ const flattenedItems = React2.useMemo(() => {
3701
3826
  return categories.flatMap((category) => category.items);
3702
3827
  }, [categories]);
3703
- const navigateDown = React.useCallback(() => {
3828
+ const navigateDown = React2.useCallback(() => {
3704
3829
  setActiveIndex(
3705
3830
  (prev2) => prev2 < flattenedItems.length - 1 ? prev2 + 1 : prev2
3706
3831
  );
3707
3832
  }, [flattenedItems.length]);
3708
- const navigateUp = React.useCallback(() => {
3833
+ const navigateUp = React2.useCallback(() => {
3709
3834
  setActiveIndex((prev2) => prev2 > 0 ? prev2 - 1 : 0);
3710
3835
  }, []);
3711
- const selectActiveItem = React.useCallback(() => {
3836
+ const selectActiveItem = React2.useCallback(() => {
3712
3837
  const item = flattenedItems[activeIndex];
3713
3838
  if (item) {
3714
3839
  addContextItem(item);
@@ -3716,7 +3841,7 @@ function useContextMention(options = {}) {
3716
3841
  onInsertMention?.(item);
3717
3842
  }
3718
3843
  }, [flattenedItems, activeIndex, addContextItem, closePopover, onInsertMention]);
3719
- const selectItem = React.useCallback(
3844
+ const selectItem = React2.useCallback(
3720
3845
  (item) => {
3721
3846
  addContextItem(item);
3722
3847
  closePopover();
@@ -3724,13 +3849,13 @@ function useContextMention(options = {}) {
3724
3849
  },
3725
3850
  [addContextItem, closePopover, onInsertMention]
3726
3851
  );
3727
- const removeItem = React.useCallback((itemId) => {
3852
+ const removeItem = React2.useCallback((itemId) => {
3728
3853
  removeContextItem(itemId);
3729
3854
  }, [removeContextItem]);
3730
- const clearAll = React.useCallback(() => {
3855
+ const clearAll = React2.useCallback(() => {
3731
3856
  clearContext();
3732
3857
  }, [clearContext]);
3733
- const handleKeyDown = React.useCallback(
3858
+ const handleKeyDown = React2.useCallback(
3734
3859
  (event) => {
3735
3860
  if (!isOpen) return;
3736
3861
  switch (event.key) {
@@ -3754,7 +3879,7 @@ function useContextMention(options = {}) {
3754
3879
  },
3755
3880
  [isOpen, navigateDown, navigateUp, selectActiveItem, closePopover]
3756
3881
  );
3757
- const getCategoryLabel = React.useCallback((type) => {
3882
+ const getCategoryLabel = React2.useCallback((type) => {
3758
3883
  return CATEGORY_LABELS[type] || type;
3759
3884
  }, []);
3760
3885
  return {
@@ -3788,20 +3913,20 @@ function useContextMention(options = {}) {
3788
3913
  }
3789
3914
  var Thread = () => {
3790
3915
  return /* @__PURE__ */ jsxRuntime.jsx(
3791
- react.ThreadPrimitive.Root,
3916
+ react$1.ThreadPrimitive.Root,
3792
3917
  {
3793
3918
  className: "aui-thread-root @container flex h-full flex-col bg-background",
3794
3919
  style: {
3795
3920
  ["--thread-max-width"]: "44rem"
3796
3921
  },
3797
3922
  children: /* @__PURE__ */ jsxRuntime.jsxs(
3798
- react.ThreadPrimitive.Viewport,
3923
+ react$1.ThreadPrimitive.Viewport,
3799
3924
  {
3800
3925
  className: "aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4",
3801
3926
  children: [
3802
- /* @__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, {}) }),
3803
3928
  /* @__PURE__ */ jsxRuntime.jsx(
3804
- react.ThreadPrimitive.Messages,
3929
+ react$1.ThreadPrimitive.Messages,
3805
3930
  {
3806
3931
  components: {
3807
3932
  UserMessage,
@@ -3810,7 +3935,7 @@ var Thread = () => {
3810
3935
  }
3811
3936
  }
3812
3937
  ),
3813
- /* @__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: [
3814
3939
  /* @__PURE__ */ jsxRuntime.jsx(ThreadScrollToBottom, {}),
3815
3940
  /* @__PURE__ */ jsxRuntime.jsx(Composer, {})
3816
3941
  ] })
@@ -3821,7 +3946,7 @@ var Thread = () => {
3821
3946
  );
3822
3947
  };
3823
3948
  var ThreadScrollToBottom = () => {
3824
- 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(
3825
3950
  TooltipIconButton,
3826
3951
  {
3827
3952
  tooltip: "Scroll to bottom",
@@ -3885,8 +4010,8 @@ var ThreadSuggestions = () => {
3885
4010
  {
3886
4011
  className: "fade-in slide-in-from-bottom-2 animate-in fill-mode-both duration-200",
3887
4012
  style: { animationDelay: `${200 + index * 50}ms` },
3888
- children: /* @__PURE__ */ jsxRuntime.jsx(react.ThreadPrimitive.Suggestion, { prompt: suggestion.prompt, send: true, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3889
- Button,
4013
+ children: /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadPrimitive.Suggestion, { prompt: suggestion.prompt, send: true, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4014
+ Button2,
3890
4015
  {
3891
4016
  variant: "ghost",
3892
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",
@@ -3907,12 +4032,12 @@ var ThreadSuggestions = () => {
3907
4032
  }) });
3908
4033
  };
3909
4034
  var Composer = () => {
3910
- const inputRef = React.useRef(null);
3911
- const composerRuntime = react.useComposerRuntime();
3912
- const handleSubmit = React.useCallback(() => {
4035
+ const inputRef = React2.useRef(null);
4036
+ const composerRuntime = react$1.useComposerRuntime();
4037
+ const handleSubmit = React2.useCallback(() => {
3913
4038
  composerRuntime.send();
3914
4039
  }, [composerRuntime]);
3915
- const handleInsertMention = React.useCallback((item) => {
4040
+ const handleInsertMention = React2.useCallback((item) => {
3916
4041
  inputRef.current?.insertMention({
3917
4042
  id: item.id,
3918
4043
  title: item.title,
@@ -3939,7 +4064,7 @@ var Composer = () => {
3939
4064
  updateSearch
3940
4065
  } = useContextMention({ onInsertMention: handleInsertMention });
3941
4066
  const { selectedContext, removeContextItem } = useMessageContext();
3942
- const handleTriggerDetected = React.useCallback(
4067
+ const handleTriggerDetected = React2.useCallback(
3943
4068
  (searchText) => {
3944
4069
  if (!isOpen) {
3945
4070
  openPopover();
@@ -3948,12 +4073,12 @@ var Composer = () => {
3948
4073
  },
3949
4074
  [isOpen, openPopover, updateSearch]
3950
4075
  );
3951
- const handleTriggerDismissed = React.useCallback(() => {
4076
+ const handleTriggerDismissed = React2.useCallback(() => {
3952
4077
  if (isOpen) {
3953
4078
  closePopover();
3954
4079
  }
3955
4080
  }, [isOpen, closePopover]);
3956
- const handleComposerKeyDown = React.useCallback(
4081
+ const handleComposerKeyDown = React2.useCallback(
3957
4082
  (e) => {
3958
4083
  if (isOpen) {
3959
4084
  if (["ArrowUp", "ArrowDown", "Enter", "Escape"].includes(e.key)) {
@@ -3969,13 +4094,13 @@ var Composer = () => {
3969
4094
  },
3970
4095
  [isOpen, handleKeyDown]
3971
4096
  );
3972
- const handleMentionRemove = React.useCallback(
4097
+ const handleMentionRemove = React2.useCallback(
3973
4098
  (mentionId) => {
3974
4099
  removeContextItem(mentionId);
3975
4100
  },
3976
4101
  [removeContextItem]
3977
4102
  );
3978
- 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: [
3979
4104
  /* @__PURE__ */ jsxRuntime.jsx(
3980
4105
  ComposerContextUI,
3981
4106
  {
@@ -4079,7 +4204,7 @@ var ComposerAction = () => {
4079
4204
  }
4080
4205
  )
4081
4206
  ] }),
4082
- /* @__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(
4083
4208
  TooltipIconButton,
4084
4209
  {
4085
4210
  tooltip: "Send message",
@@ -4091,8 +4216,8 @@ var ComposerAction = () => {
4091
4216
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpIcon, { className: "aui-composer-send-icon size-4" })
4092
4217
  }
4093
4218
  ) }) }),
4094
- /* @__PURE__ */ jsxRuntime.jsx(react.AssistantIf, { condition: ({ thread }) => thread.isRunning, children: /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4095
- 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,
4096
4221
  {
4097
4222
  type: "button",
4098
4223
  variant: "default",
@@ -4105,18 +4230,18 @@ var ComposerAction = () => {
4105
4230
  ] });
4106
4231
  };
4107
4232
  var MessageError = () => {
4108
- 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" }) }) });
4109
4234
  };
4110
4235
  var AssistantMessage = () => {
4111
4236
  return /* @__PURE__ */ jsxRuntime.jsxs(
4112
- react.MessagePrimitive.Root,
4237
+ react$1.MessagePrimitive.Root,
4113
4238
  {
4114
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",
4115
4240
  "data-role": "assistant",
4116
4241
  children: [
4117
4242
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aui-assistant-message-content wrap-break-word px-2 text-foreground leading-relaxed", children: [
4118
4243
  /* @__PURE__ */ jsxRuntime.jsx(
4119
- react.MessagePrimitive.Parts,
4244
+ react$1.MessagePrimitive.Parts,
4120
4245
  {
4121
4246
  components: {
4122
4247
  Text: MarkdownText,
@@ -4136,26 +4261,26 @@ var AssistantMessage = () => {
4136
4261
  };
4137
4262
  var AssistantActionBar = () => {
4138
4263
  return /* @__PURE__ */ jsxRuntime.jsxs(
4139
- react.ActionBarPrimitive.Root,
4264
+ react$1.ActionBarPrimitive.Root,
4140
4265
  {
4141
4266
  hideWhenRunning: true,
4142
4267
  autohide: "not-last",
4143
4268
  autohideFloat: "single-branch",
4144
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",
4145
4270
  children: [
4146
- /* @__PURE__ */ jsxRuntime.jsx(react.ActionBarPrimitive.Copy, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(TooltipIconButton, { tooltip: "Copy", children: [
4147
- /* @__PURE__ */ jsxRuntime.jsx(react.AssistantIf, { condition: ({ message }) => message.isCopied, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, {}) }),
4148
- /* @__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, {}) })
4149
4274
  ] }) }),
4150
- /* @__PURE__ */ jsxRuntime.jsx(react.ActionBarPrimitive.ExportMarkdown, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipIconButton, { tooltip: "Export as Markdown", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DownloadIcon, {}) }) }),
4151
- /* @__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, {}) }) })
4152
4277
  ]
4153
4278
  }
4154
4279
  );
4155
4280
  };
4156
4281
  var MessageContextIndicator = () => {
4157
- const [isExpanded, setIsExpanded] = React.useState(false);
4158
- const contextItems = react.useMessage((state) => {
4282
+ const [isExpanded, setIsExpanded] = React2.useState(false);
4283
+ const contextItems = react$1.useMessage((state) => {
4159
4284
  console.log("[MessageContextIndicator] Message state:", state);
4160
4285
  const metadata = state.metadata;
4161
4286
  const context = metadata?.context || metadata?.custom?.context;
@@ -4200,7 +4325,7 @@ var MessageContextIndicator = () => {
4200
4325
  };
4201
4326
  var UserMessage = () => {
4202
4327
  return /* @__PURE__ */ jsxRuntime.jsxs(
4203
- react.MessagePrimitive.Root,
4328
+ react$1.MessagePrimitive.Root,
4204
4329
  {
4205
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",
4206
4331
  "data-role": "user",
@@ -4218,27 +4343,27 @@ var UserMessage = () => {
4218
4343
  };
4219
4344
  var UserActionBar = () => {
4220
4345
  return /* @__PURE__ */ jsxRuntime.jsx(
4221
- react.ActionBarPrimitive.Root,
4346
+ react$1.ActionBarPrimitive.Root,
4222
4347
  {
4223
4348
  hideWhenRunning: true,
4224
4349
  autohide: "not-last",
4225
4350
  className: "aui-user-action-bar-root flex flex-col items-end",
4226
- 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, {}) }) })
4227
4352
  }
4228
4353
  );
4229
4354
  };
4230
4355
  var EditComposer = () => {
4231
- 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: [
4232
4357
  /* @__PURE__ */ jsxRuntime.jsx(
4233
- react.ComposerPrimitive.Input,
4358
+ react$1.ComposerPrimitive.Input,
4234
4359
  {
4235
4360
  className: "aui-edit-composer-input min-h-14 w-full resize-none bg-transparent p-4 text-foreground text-sm outline-none",
4236
4361
  autoFocus: true
4237
4362
  }
4238
4363
  ),
4239
4364
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end", children: [
4240
- /* @__PURE__ */ jsxRuntime.jsx(react.ComposerPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", children: "Cancel" }) }),
4241
- /* @__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" }) })
4242
4367
  ] })
4243
4368
  ] }) });
4244
4369
  };
@@ -4247,7 +4372,7 @@ var BranchPicker = ({
4247
4372
  ...rest
4248
4373
  }) => {
4249
4374
  return /* @__PURE__ */ jsxRuntime.jsxs(
4250
- react.BranchPickerPrimitive.Root,
4375
+ react$1.BranchPickerPrimitive.Root,
4251
4376
  {
4252
4377
  hideWhenSingleBranch: true,
4253
4378
  className: cn(
@@ -4256,22 +4381,22 @@ var BranchPicker = ({
4256
4381
  ),
4257
4382
  ...rest,
4258
4383
  children: [
4259
- /* @__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, {}) }) }),
4260
4385
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "aui-branch-picker-state font-medium", children: [
4261
- /* @__PURE__ */ jsxRuntime.jsx(react.BranchPickerPrimitive.Number, {}),
4386
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.BranchPickerPrimitive.Number, {}),
4262
4387
  " / ",
4263
- /* @__PURE__ */ jsxRuntime.jsx(react.BranchPickerPrimitive.Count, {})
4388
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.BranchPickerPrimitive.Count, {})
4264
4389
  ] }),
4265
- /* @__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, {}) }) })
4266
4391
  ]
4267
4392
  }
4268
4393
  );
4269
4394
  };
4270
4395
  var ThreadList = () => {
4271
- 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: [
4272
4397
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-b border-border px-3 py-2", children: [
4273
4398
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-foreground", children: "Chats" }),
4274
- /* @__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(
4275
4400
  TooltipIconButton,
4276
4401
  {
4277
4402
  tooltip: "New chat",
@@ -4284,16 +4409,16 @@ var ThreadList = () => {
4284
4409
  ] }),
4285
4410
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto", children: [
4286
4411
  /* @__PURE__ */ jsxRuntime.jsx(
4287
- react.ThreadListPrimitive.Items,
4412
+ react$1.ThreadListPrimitive.Items,
4288
4413
  {
4289
4414
  components: {
4290
- ThreadListItem
4415
+ ThreadListItem: ThreadListItem2
4291
4416
  }
4292
4417
  }
4293
4418
  ),
4294
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" }) }),
4295
4420
  /* @__PURE__ */ jsxRuntime.jsx(
4296
- react.ThreadListPrimitive.Items,
4421
+ react$1.ThreadListPrimitive.Items,
4297
4422
  {
4298
4423
  archived: true,
4299
4424
  components: {
@@ -4304,14 +4429,14 @@ var ThreadList = () => {
4304
4429
  ] })
4305
4430
  ] });
4306
4431
  };
4307
- var ThreadListItem = () => {
4308
- 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: [
4309
- /* @__PURE__ */ jsxRuntime.jsxs(react.ThreadListItemPrimitive.Trigger, { className: "flex flex-1 items-center gap-2 min-w-0", children: [
4432
+ var ThreadListItem2 = () => {
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: [
4310
4435
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquareIcon, { className: "h-4 w-4 flex-shrink-0 text-muted-foreground" }),
4311
- /* @__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" }) }) })
4312
4437
  ] }),
4313
4438
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity", children: [
4314
- /* @__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(
4315
4440
  TooltipIconButton,
4316
4441
  {
4317
4442
  tooltip: "Archive",
@@ -4321,7 +4446,7 @@ var ThreadListItem = () => {
4321
4446
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArchiveIcon, { className: "h-3.5 w-3.5" })
4322
4447
  }
4323
4448
  ) }),
4324
- /* @__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(
4325
4450
  TooltipIconButton,
4326
4451
  {
4327
4452
  tooltip: "Delete",
@@ -4335,13 +4460,13 @@ var ThreadListItem = () => {
4335
4460
  ] });
4336
4461
  };
4337
4462
  var ArchivedThreadListItem = () => {
4338
- 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: [
4339
- /* @__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: [
4340
4465
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArchiveIcon, { className: "h-4 w-4 flex-shrink-0 text-muted-foreground" }),
4341
- /* @__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" }) }) })
4342
4467
  ] }),
4343
4468
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity", children: [
4344
- /* @__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(
4345
4470
  TooltipIconButton,
4346
4471
  {
4347
4472
  tooltip: "Unarchive",
@@ -4351,7 +4476,7 @@ var ArchivedThreadListItem = () => {
4351
4476
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArchiveRestoreIcon, { className: "h-3.5 w-3.5" })
4352
4477
  }
4353
4478
  ) }),
4354
- /* @__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(
4355
4480
  TooltipIconButton,
4356
4481
  {
4357
4482
  tooltip: "Delete",
@@ -4364,118 +4489,17 @@ var ArchivedThreadListItem = () => {
4364
4489
  ] })
4365
4490
  ] });
4366
4491
  };
4367
- var categoryIcons = {
4368
- audio: lucideReact.HeadphonesIcon,
4369
- "audio-overview": lucideReact.HeadphonesIcon,
4370
- "video-overview": lucideReact.VideoIcon,
4371
- "mind-map": lucideReact.NetworkIcon,
4372
- reports: lucideReact.FileTextIcon,
4373
- flashcards: lucideReact.LayersIcon,
4374
- quiz: lucideReact.HelpCircleIcon,
4375
- "slide-deck": lucideReact.PresentationIcon,
4376
- infographic: lucideReact.BarChart3Icon
4377
- };
4378
- var categoryColors = {
4379
- audio: "bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300",
4380
- "audio-overview": "bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300",
4381
- "video-overview": "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-300",
4382
- "mind-map": "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300",
4383
- reports: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300",
4384
- flashcards: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-300",
4385
- quiz: "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300",
4386
- "slide-deck": "bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-300",
4387
- infographic: "bg-teal-100 text-teal-700 dark:bg-teal-900/30 dark:text-teal-300"
4388
- };
4389
- var categoryLabels = {
4390
- audio: "Audio",
4391
- "audio-overview": "Audio Overview",
4392
- "video-overview": "Video Overview",
4393
- "mind-map": "Mind Map",
4394
- reports: "Report",
4395
- flashcards: "Flashcards",
4396
- quiz: "Quiz",
4397
- "slide-deck": "Slide Deck",
4398
- infographic: "Infographic"
4399
- };
4400
- var ArtifactCard = ({
4401
- category,
4402
- title,
4403
- content,
4404
- isLoading,
4405
- children
4406
- }) => {
4407
- const Icon = categoryIcons[category];
4408
- const colorClass = categoryColors[category];
4409
- const label = categoryLabels[category];
4410
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-3 overflow-hidden rounded-xl border border-border bg-card shadow-sm", children: [
4411
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-3 px-4 py-3", colorClass), children: [
4412
- /* @__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" }) }),
4413
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
4414
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium opacity-80", children: label }),
4415
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "truncate font-semibold text-sm", children: title })
4416
- ] })
4417
- ] }),
4418
- 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 }) }),
4419
- children,
4420
- !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-2 border-t border-border px-4 py-2", children: [
4421
- /* @__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: [
4422
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DownloadIcon, { className: "h-3 w-3" }),
4423
- "Export"
4424
- ] }),
4425
- /* @__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: [
4426
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLinkIcon, { className: "h-3 w-3" }),
4427
- "Open"
4428
- ] })
4429
- ] })
4430
- ] });
4431
- };
4432
- function createArtifactToolUI(category) {
4433
- return react.makeAssistantToolUI({
4434
- toolName: `create_${category.replace(/-/g, "_")}`,
4435
- render: ({ args, result, status }) => {
4436
- const isLoading = status.type === "running";
4437
- return /* @__PURE__ */ jsxRuntime.jsx(
4438
- ArtifactCard,
4439
- {
4440
- category,
4441
- title: args.title || "Generating...",
4442
- content: result?.content || args.content,
4443
- isLoading
4444
- }
4445
- );
4446
- }
4447
- });
4448
- }
4449
- var AudioOverviewToolUI = createArtifactToolUI("audio-overview");
4450
- var VideoOverviewToolUI = createArtifactToolUI("video-overview");
4451
- var MindMapToolUI = createArtifactToolUI("mind-map");
4452
- var ReportsToolUI = createArtifactToolUI("reports");
4453
- var FlashcardsToolUI = createArtifactToolUI("flashcards");
4454
- var QuizToolUI = createArtifactToolUI("quiz");
4455
- var SlideDeckToolUI = createArtifactToolUI("slide-deck");
4456
- var InfographicToolUI = createArtifactToolUI("infographic");
4457
- var ArtifactToolUIs = () => {
4458
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4459
- /* @__PURE__ */ jsxRuntime.jsx(AudioOverviewToolUI, {}),
4460
- /* @__PURE__ */ jsxRuntime.jsx(VideoOverviewToolUI, {}),
4461
- /* @__PURE__ */ jsxRuntime.jsx(MindMapToolUI, {}),
4462
- /* @__PURE__ */ jsxRuntime.jsx(ReportsToolUI, {}),
4463
- /* @__PURE__ */ jsxRuntime.jsx(FlashcardsToolUI, {}),
4464
- /* @__PURE__ */ jsxRuntime.jsx(QuizToolUI, {}),
4465
- /* @__PURE__ */ jsxRuntime.jsx(SlideDeckToolUI, {}),
4466
- /* @__PURE__ */ jsxRuntime.jsx(InfographicToolUI, {})
4467
- ] });
4468
- };
4469
4492
  var ChatWidget = ({
4470
4493
  sidebarOpen = false,
4471
4494
  onSidebarClose
4472
4495
  }) => {
4473
4496
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-1 h-full w-full overflow-hidden bg-background", children: [
4474
4497
  /* @__PURE__ */ jsxRuntime.jsx(ArtifactToolUIs, {}),
4498
+ /* @__PURE__ */ jsxRuntime.jsx(DetailedAnswerToolUI, {}),
4475
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, {}) }) }),
4476
- /* @__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: [
4477
4501
  /* @__PURE__ */ jsxRuntime.jsx(
4478
- react$1.motion.div,
4502
+ react.motion.div,
4479
4503
  {
4480
4504
  initial: { opacity: 0 },
4481
4505
  animate: { opacity: 1 },
@@ -4486,7 +4510,7 @@ var ChatWidget = ({
4486
4510
  }
4487
4511
  ),
4488
4512
  /* @__PURE__ */ jsxRuntime.jsx(
4489
- react$1.motion.div,
4513
+ react.motion.div,
4490
4514
  {
4491
4515
  initial: { x: -256 },
4492
4516
  animate: { x: 0 },
@@ -4501,27 +4525,6 @@ var ChatWidget = ({
4501
4525
  ] }) })
4502
4526
  ] });
4503
4527
  };
4504
- var ThreadListItem2 = () => {
4505
- 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" }) }) }) });
4506
- };
4507
- var ChatHistoryPopover = ({
4508
- onSelectThread
4509
- }) => {
4510
- const handleThreadSelect = () => {
4511
- onSelectThread?.();
4512
- };
4513
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", onClick: handleThreadSelect, children: [
4514
- /* @__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" }) }),
4515
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-[300px] overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
4516
- react.ThreadListPrimitive.Items,
4517
- {
4518
- components: {
4519
- ThreadListItem: ThreadListItem2
4520
- }
4521
- }
4522
- ) })
4523
- ] });
4524
- };
4525
4528
  var layoutOptions = [
4526
4529
  {
4527
4530
  value: "sidebar",
@@ -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",