@aigentyc/chat-sdk 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/AGENTS.md +24 -1
  2. package/claude-skill/aigentyc-chat-sdk/SKILL.md +1 -1
  3. package/context7.json +1 -1
  4. package/dist/{ChatInterface-f8ftS56n.d.ts → ChatInterface-2MN5cpYB.d.ts} +1 -1
  5. package/dist/{ChatInterface-B0zbA3Lm.d.cts → ChatInterface-BnVyOUG5.d.cts} +1 -1
  6. package/dist/{SlotsContext-BjiX1mRx.d.ts → SlotsContext-BZBi51ZT.d.ts} +89 -4
  7. package/dist/{SlotsContext-CEOBjzfh.d.cts → SlotsContext-D_C7zlUA.d.cts} +89 -4
  8. package/dist/ai-elements.cjs +163 -566
  9. package/dist/ai-elements.cjs.map +1 -1
  10. package/dist/ai-elements.d.cts +10 -2
  11. package/dist/ai-elements.d.ts +10 -2
  12. package/dist/ai-elements.js +16 -461
  13. package/dist/ai-elements.js.map +1 -1
  14. package/dist/{chunk-M4YRNNGB.js → chunk-3H4CX3MS.js} +29 -6
  15. package/dist/chunk-3H4CX3MS.js.map +1 -0
  16. package/dist/{chunk-BPV66QNM.cjs → chunk-52ZHMTAA.cjs} +30 -8
  17. package/dist/chunk-52ZHMTAA.cjs.map +1 -0
  18. package/dist/{chunk-B27JIQ4Z.js → chunk-5XF3NEFB.js} +576 -6
  19. package/dist/chunk-5XF3NEFB.js.map +1 -0
  20. package/dist/{chunk-5XF7KH6B.cjs → chunk-7ESWDFF5.cjs} +94 -60
  21. package/dist/chunk-7ESWDFF5.cjs.map +1 -0
  22. package/dist/{chunk-YG2COKFR.js → chunk-BWWN5LSE.js} +65 -31
  23. package/dist/chunk-BWWN5LSE.js.map +1 -0
  24. package/dist/chunk-BYTPAQ7F.js +70 -0
  25. package/dist/chunk-BYTPAQ7F.js.map +1 -0
  26. package/dist/{chunk-FPQ3UCCJ.js → chunk-D75TDRBH.js} +30 -8
  27. package/dist/chunk-D75TDRBH.js.map +1 -0
  28. package/dist/chunk-DDATCJ3O.cjs +75 -0
  29. package/dist/chunk-DDATCJ3O.cjs.map +1 -0
  30. package/dist/{chunk-NYQSM3EB.cjs → chunk-DVWX2UGY.cjs} +16 -2
  31. package/dist/chunk-DVWX2UGY.cjs.map +1 -0
  32. package/dist/{chunk-TZ7EM3EG.cjs → chunk-EMVZ7HWM.cjs} +44 -2
  33. package/dist/chunk-EMVZ7HWM.cjs.map +1 -0
  34. package/dist/{chunk-AD6XWKWB.js → chunk-FJZL33KP.js} +3 -3
  35. package/dist/{chunk-AD6XWKWB.js.map → chunk-FJZL33KP.js.map} +1 -1
  36. package/dist/{chunk-JHWSG5IB.js → chunk-JAOD6CNW.js} +38 -3
  37. package/dist/chunk-JAOD6CNW.js.map +1 -0
  38. package/dist/{chunk-4WOBNRRB.cjs → chunk-KTYYLZN7.cjs} +592 -8
  39. package/dist/chunk-KTYYLZN7.cjs.map +1 -0
  40. package/dist/{chunk-3HGOLNGG.cjs → chunk-NBZDBH4M.cjs} +29 -6
  41. package/dist/chunk-NBZDBH4M.cjs.map +1 -0
  42. package/dist/{chunk-5F3O3ZJH.js → chunk-P7UR37HP.js} +17 -4
  43. package/dist/chunk-P7UR37HP.js.map +1 -0
  44. package/dist/{chunk-7IFBPXT3.cjs → chunk-Q3UJEIBN.cjs} +6 -6
  45. package/dist/{chunk-7IFBPXT3.cjs.map → chunk-Q3UJEIBN.cjs.map} +1 -1
  46. package/dist/{chunk-3KSMOHNY.js → chunk-R3TYC66R.js} +46 -81
  47. package/dist/chunk-R3TYC66R.js.map +1 -0
  48. package/dist/{chunk-OU5OZKYH.cjs → chunk-Y4B45DW4.cjs} +48 -90
  49. package/dist/chunk-Y4B45DW4.cjs.map +1 -0
  50. package/dist/components.cjs +18 -18
  51. package/dist/components.d.cts +3 -3
  52. package/dist/components.d.ts +3 -3
  53. package/dist/components.js +7 -7
  54. package/dist/core.d.cts +2 -2
  55. package/dist/core.d.ts +2 -2
  56. package/dist/hooks.cjs +31 -10
  57. package/dist/hooks.cjs.map +1 -1
  58. package/dist/hooks.d.cts +2 -2
  59. package/dist/hooks.d.ts +2 -2
  60. package/dist/hooks.js +4 -3
  61. package/dist/hooks.js.map +1 -1
  62. package/dist/i18n.d.cts +1 -1
  63. package/dist/i18n.d.ts +1 -1
  64. package/dist/index.cjs +64 -32
  65. package/dist/index.cjs.map +1 -1
  66. package/dist/index.d.cts +4 -4
  67. package/dist/index.d.ts +4 -4
  68. package/dist/index.js +23 -11
  69. package/dist/index.js.map +1 -1
  70. package/dist/llms-full.txt +34 -11
  71. package/dist/styles.css +1 -1
  72. package/dist/theme.d.cts +1 -1
  73. package/dist/theme.d.ts +1 -1
  74. package/dist/tools.cjs +5 -5
  75. package/dist/tools.d.cts +2 -2
  76. package/dist/tools.d.ts +2 -2
  77. package/dist/tools.js +2 -2
  78. package/dist/{types-DlNwk-bG.d.ts → types-bsR_-fq8.d.cts} +43 -2
  79. package/dist/{types-DlNwk-bG.d.cts → types-bsR_-fq8.d.ts} +43 -2
  80. package/dist/ui.cjs +52 -52
  81. package/dist/ui.js +2 -2
  82. package/llms.txt +1 -1
  83. package/package.json +1 -1
  84. package/dist/chunk-3HGOLNGG.cjs.map +0 -1
  85. package/dist/chunk-3KSMOHNY.js.map +0 -1
  86. package/dist/chunk-4WOBNRRB.cjs.map +0 -1
  87. package/dist/chunk-5F3O3ZJH.js.map +0 -1
  88. package/dist/chunk-5XF7KH6B.cjs.map +0 -1
  89. package/dist/chunk-B27JIQ4Z.js.map +0 -1
  90. package/dist/chunk-BPV66QNM.cjs.map +0 -1
  91. package/dist/chunk-FPQ3UCCJ.js.map +0 -1
  92. package/dist/chunk-JHWSG5IB.js.map +0 -1
  93. package/dist/chunk-M4YRNNGB.js.map +0 -1
  94. package/dist/chunk-NYQSM3EB.cjs.map +0 -1
  95. package/dist/chunk-OU5OZKYH.cjs.map +0 -1
  96. package/dist/chunk-TZ7EM3EG.cjs.map +0 -1
  97. package/dist/chunk-YG2COKFR.js.map +0 -1
@@ -1,11 +1,15 @@
1
1
  "use client";
2
2
  import { useI18n } from './chunk-QYCEHFAB.js';
3
- import { Button, Textarea, Collapsible, CollapsibleTrigger, CollapsibleContent } from './chunk-JHWSG5IB.js';
3
+ import { Button, Textarea, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, Collapsible, CollapsibleTrigger, CollapsibleContent } from './chunk-JAOD6CNW.js';
4
4
  import { cn } from './chunk-3RW7O444.js';
5
- import { ArrowDownIcon, Check, Copy, X, ChevronDownIcon, BookIcon } from 'lucide-react';
6
- import { useCallback, useState } from 'react';
5
+ import { ArrowDownIcon, Check, Copy, X, ChevronLeftIcon, ChevronRightIcon, XIcon, PaperclipIcon, ChevronDownIcon, BookIcon } from 'lucide-react';
6
+ import { createContext, memo, useCallback, useState, useEffect, useContext, useRef } from 'react';
7
7
  import { StickToBottom, useStickToBottomContext } from 'use-stick-to-bottom';
8
8
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
+ import { Slot } from '@radix-ui/react-slot';
10
+ import { cva } from 'class-variance-authority';
11
+ import { createPortal } from 'react-dom';
12
+ import { Streamdown } from 'streamdown';
9
13
 
10
14
  var Conversation = ({ className, ...props }) => /* @__PURE__ */ jsx(
11
15
  StickToBottom,
@@ -383,6 +387,572 @@ function MessageFeedback({
383
387
  ` })
384
388
  ] });
385
389
  }
390
+ var buttonGroupVariants = cva(
391
+ "flex w-fit items-stretch has-[>[data-slot=button-group]]:gap-2 [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
392
+ {
393
+ variants: {
394
+ orientation: {
395
+ horizontal: "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none",
396
+ vertical: "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none"
397
+ }
398
+ },
399
+ defaultVariants: {
400
+ orientation: "horizontal"
401
+ }
402
+ }
403
+ );
404
+ function ButtonGroup({
405
+ className,
406
+ orientation,
407
+ ...props
408
+ }) {
409
+ return /* @__PURE__ */ jsx(
410
+ "div",
411
+ {
412
+ role: "group",
413
+ "data-slot": "button-group",
414
+ "data-orientation": orientation,
415
+ className: cn(buttonGroupVariants({ orientation }), className),
416
+ ...props
417
+ }
418
+ );
419
+ }
420
+ function ButtonGroupText({
421
+ className,
422
+ asChild = false,
423
+ ...props
424
+ }) {
425
+ const Comp = asChild ? Slot : "div";
426
+ return /* @__PURE__ */ jsx(
427
+ Comp,
428
+ {
429
+ className: cn(
430
+ "bg-muted shadow-xs flex items-center gap-2 rounded-md border px-4 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none",
431
+ className
432
+ ),
433
+ ...props
434
+ }
435
+ );
436
+ }
437
+ var Message = ({ className, from, fullWidth, ...props }) => /* @__PURE__ */ jsx(
438
+ "div",
439
+ {
440
+ className: cn(
441
+ "group flex w-full flex-col gap-2",
442
+ fullWidth ? "" : from === "assistant" ? "max-w-[var(--ac-assistant-max-width,95%)]" : "max-w-[95%]",
443
+ from === "user" ? "is-user justify-end" : "is-assistant",
444
+ className
445
+ ),
446
+ ...props
447
+ }
448
+ );
449
+ var MessageContent = ({
450
+ children,
451
+ className,
452
+ fullWidth,
453
+ ...props
454
+ }) => /* @__PURE__ */ jsx(
455
+ "div",
456
+ {
457
+ className: cn(
458
+ "flex min-w-0 flex-col gap-2 overflow-hidden",
459
+ fullWidth ? "w-full" : "w-fit max-w-full",
460
+ "group-[.is-user]:ml-auto group-[.is-user]:px-6 group-[.is-user]:py-4 group-[.is-user]:text-foreground group-[.is-user]:rounded-bl-[24px] group-[.is-user]:rounded-br-[24px] group-[.is-user]:rounded-tl-[4px] group-[.is-user]:rounded-tr-[24px] group-[.is-user]:bg-[var(--ac-user-bubble-bg,#f0f4f8)]",
461
+ "group-[.is-assistant]:text-foreground group-[.is-assistant]:w-full",
462
+ className
463
+ ),
464
+ ...props,
465
+ children
466
+ }
467
+ );
468
+ var MessageActions = ({
469
+ className,
470
+ children,
471
+ ...props
472
+ }) => /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-1", className), ...props, children });
473
+ var MessageAction = ({
474
+ tooltip,
475
+ children,
476
+ label,
477
+ variant = "ghost",
478
+ size = "icon-sm",
479
+ ...props
480
+ }) => {
481
+ const button = /* @__PURE__ */ jsxs(Button, { size, type: "button", variant, ...props, children: [
482
+ children,
483
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: label || tooltip })
484
+ ] });
485
+ if (tooltip) {
486
+ return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
487
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: button }),
488
+ /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: tooltip }) })
489
+ ] }) });
490
+ }
491
+ return button;
492
+ };
493
+ var MessageBranchContext = createContext(
494
+ null
495
+ );
496
+ var useMessageBranch = () => {
497
+ const context = useContext(MessageBranchContext);
498
+ if (!context) {
499
+ throw new Error(
500
+ "MessageBranch components must be used within MessageBranch"
501
+ );
502
+ }
503
+ return context;
504
+ };
505
+ var MessageBranch = ({
506
+ defaultBranch = 0,
507
+ onBranchChange,
508
+ className,
509
+ ...props
510
+ }) => {
511
+ const [currentBranch, setCurrentBranch] = useState(defaultBranch);
512
+ const [branches, setBranches] = useState([]);
513
+ const handleBranchChange = (newBranch) => {
514
+ setCurrentBranch(newBranch);
515
+ onBranchChange?.(newBranch);
516
+ };
517
+ const goToPrevious = () => {
518
+ const newBranch = currentBranch > 0 ? currentBranch - 1 : branches.length - 1;
519
+ handleBranchChange(newBranch);
520
+ };
521
+ const goToNext = () => {
522
+ const newBranch = currentBranch < branches.length - 1 ? currentBranch + 1 : 0;
523
+ handleBranchChange(newBranch);
524
+ };
525
+ const contextValue = {
526
+ currentBranch,
527
+ totalBranches: branches.length,
528
+ goToPrevious,
529
+ goToNext,
530
+ branches,
531
+ setBranches
532
+ };
533
+ return /* @__PURE__ */ jsx(MessageBranchContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
534
+ "div",
535
+ {
536
+ className: cn("grid w-full gap-2 [&>div]:pb-0", className),
537
+ ...props
538
+ }
539
+ ) });
540
+ };
541
+ var MessageBranchContent = ({
542
+ children,
543
+ ...props
544
+ }) => {
545
+ const { currentBranch, setBranches, branches } = useMessageBranch();
546
+ const childrenArray = Array.isArray(children) ? children : [children];
547
+ useEffect(() => {
548
+ if (branches.length !== childrenArray.length) {
549
+ setBranches(childrenArray);
550
+ }
551
+ }, [childrenArray, branches, setBranches]);
552
+ return childrenArray.map((branch, index) => /* @__PURE__ */ jsx(
553
+ "div",
554
+ {
555
+ className: cn(
556
+ "grid gap-2 overflow-hidden [&>div]:pb-0",
557
+ index === currentBranch ? "block" : "hidden"
558
+ ),
559
+ ...props,
560
+ children: branch
561
+ },
562
+ branch.key
563
+ ));
564
+ };
565
+ var MessageBranchSelector = ({
566
+ className,
567
+ from,
568
+ ...props
569
+ }) => {
570
+ const { totalBranches } = useMessageBranch();
571
+ if (totalBranches <= 1) {
572
+ return null;
573
+ }
574
+ return /* @__PURE__ */ jsx(
575
+ ButtonGroup,
576
+ {
577
+ className: "[&>*:not(:first-child)]:rounded-l-md [&>*:not(:last-child)]:rounded-r-md",
578
+ orientation: "horizontal",
579
+ ...props
580
+ }
581
+ );
582
+ };
583
+ var MessageBranchPrevious = ({
584
+ children,
585
+ ...props
586
+ }) => {
587
+ const { goToPrevious, totalBranches } = useMessageBranch();
588
+ return /* @__PURE__ */ jsx(
589
+ Button,
590
+ {
591
+ "aria-label": "Previous branch",
592
+ disabled: totalBranches <= 1,
593
+ onClick: goToPrevious,
594
+ size: "icon-sm",
595
+ type: "button",
596
+ variant: "ghost",
597
+ ...props,
598
+ children: children ?? /* @__PURE__ */ jsx(ChevronLeftIcon, { size: 14 })
599
+ }
600
+ );
601
+ };
602
+ var MessageBranchNext = ({
603
+ children,
604
+ className,
605
+ ...props
606
+ }) => {
607
+ const { goToNext, totalBranches } = useMessageBranch();
608
+ return /* @__PURE__ */ jsx(
609
+ Button,
610
+ {
611
+ "aria-label": "Next branch",
612
+ disabled: totalBranches <= 1,
613
+ onClick: goToNext,
614
+ size: "icon-sm",
615
+ type: "button",
616
+ variant: "ghost",
617
+ ...props,
618
+ children: children ?? /* @__PURE__ */ jsx(ChevronRightIcon, { size: 14 })
619
+ }
620
+ );
621
+ };
622
+ var MessageBranchPage = ({
623
+ className,
624
+ ...props
625
+ }) => {
626
+ const { currentBranch, totalBranches } = useMessageBranch();
627
+ return /* @__PURE__ */ jsxs(
628
+ ButtonGroupText,
629
+ {
630
+ className: cn(
631
+ "border-none bg-transparent text-muted-foreground shadow-none",
632
+ className
633
+ ),
634
+ ...props,
635
+ children: [
636
+ currentBranch + 1,
637
+ " of ",
638
+ totalBranches
639
+ ]
640
+ }
641
+ );
642
+ };
643
+ function addUtmParams(url) {
644
+ try {
645
+ const urlObj = new URL(url);
646
+ urlObj.searchParams.set("utm_source", "chat");
647
+ urlObj.searchParams.set("utm_medium", "referral");
648
+ return urlObj.toString();
649
+ } catch {
650
+ return url;
651
+ }
652
+ }
653
+ var CustomLink = ({ href, children, ...props }) => /* @__PURE__ */ jsx(
654
+ "a",
655
+ {
656
+ href: href ? addUtmParams(href) : href,
657
+ target: "_blank",
658
+ rel: "noopener noreferrer",
659
+ className: "hover:underline hover:opacity-80 transition-opacity font-medium",
660
+ ...props,
661
+ children
662
+ }
663
+ );
664
+ var CustomImage = ({ src, alt, ...props }) => /* @__PURE__ */ jsx(
665
+ "img",
666
+ {
667
+ src,
668
+ alt: alt || "",
669
+ loading: "lazy",
670
+ className: "rounded-xl max-w-full h-auto my-4",
671
+ ...props
672
+ }
673
+ );
674
+ var CustomTable = ({ children, ...props }) => /* @__PURE__ */ jsx("div", { className: "my-4 overflow-x-auto", children: /* @__PURE__ */ jsx(
675
+ "table",
676
+ {
677
+ className: "w-full text-sm rounded-xl border border-black/[0.08] overflow-hidden",
678
+ ...props,
679
+ children
680
+ }
681
+ ) });
682
+ var CustomThead = ({ children, ...props }) => /* @__PURE__ */ jsx("thead", { className: "bg-black/[0.04]", ...props, children });
683
+ var CustomTh = ({ children, ...props }) => /* @__PURE__ */ jsx(
684
+ "th",
685
+ {
686
+ className: "px-4 py-3 text-start text-xs font-medium uppercase tracking-wider opacity-60 border-b border-black/[0.08]",
687
+ ...props,
688
+ children
689
+ }
690
+ );
691
+ var CustomTd = ({ children, ...props }) => /* @__PURE__ */ jsx(
692
+ "td",
693
+ {
694
+ className: "px-4 py-3 border-b border-black/[0.08]",
695
+ ...props,
696
+ children
697
+ }
698
+ );
699
+ var CustomTr = ({ children, ...props }) => /* @__PURE__ */ jsx(
700
+ "tr",
701
+ {
702
+ className: "hover:bg-black/[0.02] transition-colors",
703
+ ...props,
704
+ children
705
+ }
706
+ );
707
+ var MessageResponse = memo(
708
+ ({ className, ...props }) => /* @__PURE__ */ jsx(
709
+ Streamdown,
710
+ {
711
+ className: cn(
712
+ "message-response size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0",
713
+ className
714
+ ),
715
+ components: {
716
+ a: CustomLink,
717
+ img: CustomImage,
718
+ table: CustomTable,
719
+ thead: CustomThead,
720
+ th: CustomTh,
721
+ td: CustomTd,
722
+ tr: CustomTr
723
+ },
724
+ linkSafety: { enabled: false },
725
+ ...props
726
+ }
727
+ ),
728
+ (prevProps, nextProps) => prevProps.children === nextProps.children
729
+ );
730
+ MessageResponse.displayName = "MessageResponse";
731
+ function MessageAttachmentLightbox({
732
+ url,
733
+ alt,
734
+ onClose
735
+ }) {
736
+ const [container, setContainer] = useState(
737
+ null
738
+ );
739
+ const anchorRef = useRef(null);
740
+ useEffect(() => {
741
+ const root = anchorRef.current?.getRootNode();
742
+ if (!root) return;
743
+ const host = root instanceof ShadowRoot ? root : root.body ?? null;
744
+ if (!host) return;
745
+ const node = document.createElement("div");
746
+ node.setAttribute("data-aigentyc-chat", "");
747
+ host.appendChild(node);
748
+ setContainer(node);
749
+ return () => {
750
+ node.remove();
751
+ };
752
+ }, []);
753
+ useEffect(() => {
754
+ const onKey = (e) => {
755
+ if (e.key === "Escape") onClose();
756
+ };
757
+ document.addEventListener("keydown", onKey);
758
+ return () => document.removeEventListener("keydown", onKey);
759
+ }, [onClose]);
760
+ const overlay = /* @__PURE__ */ jsxs(
761
+ "div",
762
+ {
763
+ "aria-label": alt,
764
+ "aria-modal": "true",
765
+ className: "ac-lightbox",
766
+ onClick: onClose,
767
+ role: "dialog",
768
+ style: {
769
+ position: "fixed",
770
+ inset: 0,
771
+ zIndex: 2147483001,
772
+ display: "flex",
773
+ alignItems: "center",
774
+ justifyContent: "center",
775
+ padding: 24,
776
+ background: "rgba(8, 12, 16, 0.82)",
777
+ pointerEvents: "auto",
778
+ cursor: "zoom-out"
779
+ },
780
+ children: [
781
+ /* @__PURE__ */ jsx(
782
+ "img",
783
+ {
784
+ alt,
785
+ onClick: (e) => e.stopPropagation(),
786
+ src: url,
787
+ style: {
788
+ maxWidth: "100%",
789
+ maxHeight: "100%",
790
+ objectFit: "contain",
791
+ borderRadius: 12,
792
+ boxShadow: "0 24px 64px rgba(0, 0, 0, 0.45)",
793
+ cursor: "default"
794
+ }
795
+ }
796
+ ),
797
+ /* @__PURE__ */ jsx(
798
+ "button",
799
+ {
800
+ "aria-label": "Close",
801
+ onClick: onClose,
802
+ style: {
803
+ position: "absolute",
804
+ top: 16,
805
+ insetInlineEnd: 16,
806
+ width: 36,
807
+ height: 36,
808
+ display: "flex",
809
+ alignItems: "center",
810
+ justifyContent: "center",
811
+ border: "none",
812
+ borderRadius: "50%",
813
+ background: "rgba(255, 255, 255, 0.14)",
814
+ color: "#fff",
815
+ cursor: "pointer"
816
+ },
817
+ type: "button",
818
+ children: /* @__PURE__ */ jsx(XIcon, { size: 18 })
819
+ }
820
+ )
821
+ ]
822
+ }
823
+ );
824
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
825
+ /* @__PURE__ */ jsx("span", { ref: anchorRef, style: { display: "none" } }),
826
+ container ? createPortal(overlay, container) : null
827
+ ] });
828
+ }
829
+ function MessageAttachment({
830
+ data,
831
+ className,
832
+ onRemove,
833
+ ...props
834
+ }) {
835
+ const [zoomed, setZoomed] = useState(false);
836
+ const filename = data.filename || "";
837
+ const mediaType = data.mediaType?.startsWith("image/") && data.url ? "image" : "file";
838
+ const isImage = mediaType === "image";
839
+ const attachmentLabel = filename || (isImage ? "Image" : "Attachment");
840
+ return /* @__PURE__ */ jsx(
841
+ "div",
842
+ {
843
+ className: cn(
844
+ "group relative size-24 overflow-hidden rounded-lg",
845
+ className
846
+ ),
847
+ ...props,
848
+ children: isImage ? /* @__PURE__ */ jsxs(Fragment, { children: [
849
+ /* @__PURE__ */ jsx(
850
+ "button",
851
+ {
852
+ "aria-label": `View ${attachmentLabel} full size`,
853
+ className: "block size-full cursor-zoom-in",
854
+ onClick: () => setZoomed(true),
855
+ title: "View full size",
856
+ type: "button",
857
+ children: /* @__PURE__ */ jsx(
858
+ "img",
859
+ {
860
+ alt: filename || "attachment",
861
+ className: "size-full object-cover transition-transform duration-200 group-hover:scale-105",
862
+ height: 100,
863
+ src: data.url,
864
+ width: 100
865
+ }
866
+ )
867
+ }
868
+ ),
869
+ zoomed && /* @__PURE__ */ jsx(
870
+ MessageAttachmentLightbox,
871
+ {
872
+ alt: attachmentLabel,
873
+ onClose: () => setZoomed(false),
874
+ url: data.url
875
+ }
876
+ ),
877
+ onRemove && /* @__PURE__ */ jsxs(
878
+ Button,
879
+ {
880
+ "aria-label": "Remove attachment",
881
+ className: "absolute top-2 right-2 size-6 rounded-full bg-background/80 p-0 opacity-0 backdrop-blur-sm transition-opacity hover:bg-background group-hover:opacity-100 [&>svg]:size-3",
882
+ onClick: (e) => {
883
+ e.stopPropagation();
884
+ onRemove();
885
+ },
886
+ type: "button",
887
+ variant: "ghost",
888
+ children: [
889
+ /* @__PURE__ */ jsx(XIcon, {}),
890
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Remove" })
891
+ ]
892
+ }
893
+ )
894
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
895
+ /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
896
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "flex size-full shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx(PaperclipIcon, { className: "size-4" }) }) }),
897
+ /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: attachmentLabel }) })
898
+ ] }) }),
899
+ onRemove && /* @__PURE__ */ jsxs(
900
+ Button,
901
+ {
902
+ "aria-label": "Remove attachment",
903
+ className: "size-6 shrink-0 rounded-full p-0 opacity-0 transition-opacity hover:bg-accent group-hover:opacity-100 [&>svg]:size-3",
904
+ onClick: (e) => {
905
+ e.stopPropagation();
906
+ onRemove();
907
+ },
908
+ type: "button",
909
+ variant: "ghost",
910
+ children: [
911
+ /* @__PURE__ */ jsx(XIcon, {}),
912
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Remove" })
913
+ ]
914
+ }
915
+ )
916
+ ] })
917
+ }
918
+ );
919
+ }
920
+ function MessageAttachments({
921
+ children,
922
+ className,
923
+ ...props
924
+ }) {
925
+ const isEmpty = !children || Array.isArray(children) && children.flat().filter(Boolean).length === 0;
926
+ if (isEmpty) {
927
+ return null;
928
+ }
929
+ return /* @__PURE__ */ jsx(
930
+ "div",
931
+ {
932
+ className: cn(
933
+ "ml-auto flex w-fit flex-wrap items-start gap-2",
934
+ className
935
+ ),
936
+ ...props,
937
+ children
938
+ }
939
+ );
940
+ }
941
+ var MessageToolbar = ({
942
+ className,
943
+ children,
944
+ ...props
945
+ }) => /* @__PURE__ */ jsx(
946
+ "div",
947
+ {
948
+ className: cn(
949
+ "mt-4 flex w-full items-center justify-between gap-4",
950
+ className
951
+ ),
952
+ ...props,
953
+ children
954
+ }
955
+ );
386
956
  var Loader = ({ className, text = "Thinking...", ...props }) => /* @__PURE__ */ jsxs(
387
957
  "div",
388
958
  {
@@ -523,6 +1093,6 @@ var Source = ({ href, title, children, ...props }) => /* @__PURE__ */ jsx(
523
1093
  }
524
1094
  );
525
1095
 
526
- export { Conversation, ConversationContent, ConversationEmptyState, ConversationScrollButton, Loader, MessageFeedback, Source, Sources, SourcesContent, SourcesTrigger, SpinnerLoader };
527
- //# sourceMappingURL=chunk-B27JIQ4Z.js.map
528
- //# sourceMappingURL=chunk-B27JIQ4Z.js.map
1096
+ export { Conversation, ConversationContent, ConversationEmptyState, ConversationScrollButton, Loader, Message, MessageAction, MessageActions, MessageAttachment, MessageAttachments, MessageBranch, MessageBranchContent, MessageBranchNext, MessageBranchPage, MessageBranchPrevious, MessageBranchSelector, MessageContent, MessageFeedback, MessageResponse, MessageToolbar, Source, Sources, SourcesContent, SourcesTrigger, SpinnerLoader };
1097
+ //# sourceMappingURL=chunk-5XF3NEFB.js.map
1098
+ //# sourceMappingURL=chunk-5XF3NEFB.js.map