@yourgpt/copilot-sdk 2.1.5-alpha.1 → 2.1.5-alpha.3

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 (76) hide show
  1. package/dist/{chunk-4QXY2PBG.js → chunk-3AONOZLY.js} +2 -2
  2. package/dist/{chunk-4QXY2PBG.js.map → chunk-3AONOZLY.js.map} +1 -1
  3. package/dist/{chunk-JKGFQUHJ.cjs → chunk-MDS23G2S.cjs} +5 -5
  4. package/dist/{chunk-JKGFQUHJ.cjs.map → chunk-MDS23G2S.cjs.map} +1 -1
  5. package/dist/{chunk-5Q72LZ5H.js → chunk-PT2TOHG5.js} +7 -3
  6. package/dist/chunk-PT2TOHG5.js.map +1 -0
  7. package/dist/{chunk-ENFWM3EY.js → chunk-RKGRQRZU.js} +3 -3
  8. package/dist/{chunk-ENFWM3EY.js.map → chunk-RKGRQRZU.js.map} +1 -1
  9. package/dist/{chunk-IXWNDR7H.cjs → chunk-TCPAT3WG.cjs} +35 -31
  10. package/dist/chunk-TCPAT3WG.cjs.map +1 -0
  11. package/dist/{chunk-246B6X5D.cjs → chunk-TPB7XED6.cjs} +2 -2
  12. package/dist/{chunk-246B6X5D.cjs.map → chunk-TPB7XED6.cjs.map} +1 -1
  13. package/dist/{chunk-I3SQUNTT.cjs → chunk-WIXFZUEZ.cjs} +23 -23
  14. package/dist/{chunk-I3SQUNTT.cjs.map → chunk-WIXFZUEZ.cjs.map} +1 -1
  15. package/dist/{chunk-UXJ6LIZB.js → chunk-WZ2TOZ7M.js} +4 -4
  16. package/dist/{chunk-UXJ6LIZB.js.map → chunk-WZ2TOZ7M.js.map} +1 -1
  17. package/dist/core/index.cjs +82 -82
  18. package/dist/core/index.d.cts +3 -3
  19. package/dist/core/index.d.ts +3 -3
  20. package/dist/core/index.js +3 -3
  21. package/dist/{index-CiExk87c.d.cts → index-CzJB8Ddo.d.cts} +1 -1
  22. package/dist/{index-Dwrcf-CP.d.ts → index-D7169xuR.d.ts} +1 -1
  23. package/dist/mcp/index.d.cts +3 -3
  24. package/dist/mcp/index.d.ts +3 -3
  25. package/dist/react/index.cjs +65 -65
  26. package/dist/react/index.d.cts +8 -4
  27. package/dist/react/index.d.ts +8 -4
  28. package/dist/react/index.js +4 -4
  29. package/dist/styles.css +43 -0
  30. package/dist/tools/anthropic/index.d.cts +1 -1
  31. package/dist/tools/anthropic/index.d.ts +1 -1
  32. package/dist/tools/brave/index.cjs +2 -2
  33. package/dist/tools/brave/index.d.cts +1 -1
  34. package/dist/tools/brave/index.d.ts +1 -1
  35. package/dist/tools/brave/index.js +1 -1
  36. package/dist/tools/exa/index.cjs +2 -2
  37. package/dist/tools/exa/index.d.cts +1 -1
  38. package/dist/tools/exa/index.d.ts +1 -1
  39. package/dist/tools/exa/index.js +1 -1
  40. package/dist/tools/google/index.cjs +2 -2
  41. package/dist/tools/google/index.d.cts +1 -1
  42. package/dist/tools/google/index.d.ts +1 -1
  43. package/dist/tools/google/index.js +1 -1
  44. package/dist/tools/openai/index.cjs +2 -2
  45. package/dist/tools/openai/index.d.cts +1 -1
  46. package/dist/tools/openai/index.d.ts +1 -1
  47. package/dist/tools/openai/index.js +1 -1
  48. package/dist/tools/searxng/index.cjs +2 -2
  49. package/dist/tools/searxng/index.d.cts +1 -1
  50. package/dist/tools/searxng/index.d.ts +1 -1
  51. package/dist/tools/searxng/index.js +1 -1
  52. package/dist/tools/serper/index.cjs +2 -2
  53. package/dist/tools/serper/index.d.cts +1 -1
  54. package/dist/tools/serper/index.d.ts +1 -1
  55. package/dist/tools/serper/index.js +1 -1
  56. package/dist/tools/tavily/index.cjs +2 -2
  57. package/dist/tools/tavily/index.d.cts +1 -1
  58. package/dist/tools/tavily/index.d.ts +1 -1
  59. package/dist/tools/tavily/index.js +1 -1
  60. package/dist/tools/web-search/index.cjs +3 -3
  61. package/dist/tools/web-search/index.d.cts +2 -2
  62. package/dist/tools/web-search/index.d.ts +2 -2
  63. package/dist/tools/web-search/index.js +2 -2
  64. package/dist/{tools-DHZhF5km.d.cts → tools-tmksfhUo.d.cts} +9 -0
  65. package/dist/{tools-DHZhF5km.d.ts → tools-tmksfhUo.d.ts} +9 -0
  66. package/dist/{types-BdX7uPj0.d.cts → types-BLw7mxtW.d.cts} +1 -1
  67. package/dist/{types-BTyJu0WD.d.ts → types-BqwW3Baj.d.ts} +1 -1
  68. package/dist/ui/index.cjs +798 -417
  69. package/dist/ui/index.cjs.map +1 -1
  70. package/dist/ui/index.d.cts +337 -108
  71. package/dist/ui/index.d.ts +337 -108
  72. package/dist/ui/index.js +745 -365
  73. package/dist/ui/index.js.map +1 -1
  74. package/package.json +1 -1
  75. package/dist/chunk-5Q72LZ5H.js.map +0 -1
  76. package/dist/chunk-IXWNDR7H.cjs.map +0 -1
package/dist/ui/index.cjs CHANGED
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var chunkIXWNDR7H_cjs = require('../chunk-IXWNDR7H.cjs');
4
- var chunkI3SQUNTT_cjs = require('../chunk-I3SQUNTT.cjs');
3
+ var chunkTCPAT3WG_cjs = require('../chunk-TCPAT3WG.cjs');
4
+ var chunkWIXFZUEZ_cjs = require('../chunk-WIXFZUEZ.cjs');
5
5
  var chunkJO4BHPAD_cjs = require('../chunk-JO4BHPAD.cjs');
6
6
  require('../chunk-JGPDQDY4.cjs');
7
7
  require('../chunk-BJYA5NDL.cjs');
8
- require('../chunk-JKGFQUHJ.cjs');
9
- require('../chunk-246B6X5D.cjs');
8
+ require('../chunk-MDS23G2S.cjs');
9
+ require('../chunk-TPB7XED6.cjs');
10
10
  require('../chunk-NUXLAZOE.cjs');
11
11
  require('../chunk-TXLIY7GF.cjs');
12
12
  require('../chunk-CBAHCI4R.cjs');
@@ -20,7 +20,7 @@ require('../chunk-JEQ2X3Z6.cjs');
20
20
  var clsx = require('clsx');
21
21
  var tailwindMerge = require('tailwind-merge');
22
22
  var jsxRuntime = require('react/jsx-runtime');
23
- var React18 = require('react');
23
+ var React19 = require('react');
24
24
  var streamdown = require('streamdown');
25
25
  var code = require('@streamdown/code');
26
26
  var reactSlot = require('@radix-ui/react-slot');
@@ -50,7 +50,7 @@ function _interopNamespace(e) {
50
50
  return Object.freeze(n);
51
51
  }
52
52
 
53
- var React18__namespace = /*#__PURE__*/_interopNamespace(React18);
53
+ var React19__namespace = /*#__PURE__*/_interopNamespace(React19);
54
54
  var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
55
55
  var HoverCardPrimitive__namespace = /*#__PURE__*/_interopNamespace(HoverCardPrimitive);
56
56
 
@@ -366,7 +366,7 @@ function MarkdownComponent({
366
366
  }
367
367
  ) });
368
368
  }
369
- var Markdown = React18.memo(MarkdownComponent);
369
+ var Markdown = React19.memo(MarkdownComponent);
370
370
  Markdown.displayName = "Markdown";
371
371
  function CodeBlock({ children, className, ...props }) {
372
372
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -407,7 +407,7 @@ var buttonVariants = classVarianceAuthority.cva(
407
407
  }
408
408
  }
409
409
  );
410
- var Button = React18__namespace.forwardRef(
410
+ var Button = React19__namespace.forwardRef(
411
411
  ({ className, variant, size, asChild = false, ...props }, ref) => {
412
412
  const Comp = asChild ? reactSlot.Slot : "button";
413
413
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -648,7 +648,7 @@ function TooltipTrigger({
648
648
  disabled,
649
649
  ...props
650
650
  }) {
651
- if (asChild && React18__namespace.default.isValidElement(children)) {
651
+ if (asChild && React19__namespace.default.isValidElement(children)) {
652
652
  return /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Trigger, { disabled, render: children, ...props });
653
653
  }
654
654
  return /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Trigger, { disabled, ...props, children });
@@ -677,7 +677,7 @@ function TooltipContent({
677
677
  }
678
678
  ) }) });
679
679
  }
680
- var Avatar = React18__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
680
+ var Avatar = React19__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
681
681
  AvatarPrimitive__namespace.Root,
682
682
  {
683
683
  ref,
@@ -689,7 +689,7 @@ var Avatar = React18__namespace.forwardRef(({ className, ...props }, ref) => /*
689
689
  }
690
690
  ));
691
691
  Avatar.displayName = AvatarPrimitive__namespace.Root.displayName;
692
- var AvatarImage = React18__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
692
+ var AvatarImage = React19__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
693
693
  AvatarPrimitive__namespace.Image,
694
694
  {
695
695
  ref,
@@ -698,7 +698,7 @@ var AvatarImage = React18__namespace.forwardRef(({ className, ...props }, ref) =
698
698
  }
699
699
  ));
700
700
  AvatarImage.displayName = AvatarPrimitive__namespace.Image.displayName;
701
- var AvatarFallback = React18__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
701
+ var AvatarFallback = React19__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
702
702
  AvatarPrimitive__namespace.Fallback,
703
703
  {
704
704
  ref,
@@ -758,7 +758,34 @@ var MessageContent = ({
758
758
  );
759
759
  return markdown ? /* @__PURE__ */ jsxRuntime.jsx(Markdown, { className: classNames, ...props, children }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames, ...props, children });
760
760
  };
761
- var Textarea = React18__namespace.forwardRef(({ className, ...props }, ref) => {
761
+ var MessageActions = ({
762
+ children,
763
+ className,
764
+ ...props
765
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
766
+ "div",
767
+ {
768
+ className: cn(
769
+ "csdk-message-actions text-muted-foreground flex items-center gap-2",
770
+ className
771
+ ),
772
+ ...props,
773
+ children
774
+ }
775
+ );
776
+ var MessageAction = ({
777
+ tooltip,
778
+ children,
779
+ className,
780
+ side = "top",
781
+ ...props
782
+ }) => {
783
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { ...props, children: [
784
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children }),
785
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side, className, children: tooltip })
786
+ ] }) });
787
+ };
788
+ var Textarea = React19__namespace.forwardRef(({ className, ...props }, ref) => {
762
789
  return /* @__PURE__ */ jsxRuntime.jsx(
763
790
  "textarea",
764
791
  {
@@ -772,7 +799,7 @@ var Textarea = React18__namespace.forwardRef(({ className, ...props }, ref) => {
772
799
  );
773
800
  });
774
801
  Textarea.displayName = "Textarea";
775
- var PromptInputContext = React18.createContext({
802
+ var PromptInputContext = React19.createContext({
776
803
  isLoading: false,
777
804
  value: "",
778
805
  setValue: () => {
@@ -783,7 +810,7 @@ var PromptInputContext = React18.createContext({
783
810
  textareaRef: { current: null }
784
811
  });
785
812
  function usePromptInput() {
786
- return React18.useContext(PromptInputContext);
813
+ return React19.useContext(PromptInputContext);
787
814
  }
788
815
  function PromptInput({
789
816
  className,
@@ -797,8 +824,8 @@ function PromptInput({
797
824
  onClick,
798
825
  ...props
799
826
  }) {
800
- const [internalValue, setInternalValue] = React18.useState(value || "");
801
- const textareaRef = React18.useRef(null);
827
+ const [internalValue, setInternalValue] = React19.useState(value || "");
828
+ const textareaRef = React19.useRef(null);
802
829
  const handleChange = (newValue) => {
803
830
  setInternalValue(newValue);
804
831
  onValueChange?.(newValue);
@@ -855,7 +882,7 @@ function PromptInputTextarea({
855
882
  textareaRef.current = el;
856
883
  adjustHeight(el);
857
884
  };
858
- React18.useLayoutEffect(() => {
885
+ React19.useLayoutEffect(() => {
859
886
  if (!textareaRef.current || disableAutosize) return;
860
887
  const el = textareaRef.current;
861
888
  el.style.height = "auto";
@@ -922,7 +949,7 @@ function PromptInputAction({
922
949
  }
923
950
  var HoverCard = HoverCardPrimitive__namespace.Root;
924
951
  var HoverCardTrigger = HoverCardPrimitive__namespace.Trigger;
925
- var HoverCardContent = React18__namespace.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
952
+ var HoverCardContent = React19__namespace.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
926
953
  HoverCardPrimitive__namespace.Content,
927
954
  {
928
955
  ref,
@@ -936,9 +963,9 @@ var HoverCardContent = React18__namespace.forwardRef(({ className, align = "cent
936
963
  }
937
964
  ));
938
965
  HoverCardContent.displayName = HoverCardPrimitive__namespace.Content.displayName;
939
- var SourceContext = React18.createContext(null);
966
+ var SourceContext = React19.createContext(null);
940
967
  function useSourceContext() {
941
- const ctx = React18.useContext(SourceContext);
968
+ const ctx = React19.useContext(SourceContext);
942
969
  if (!ctx) throw new Error("Source.* must be used inside <Source>");
943
970
  return ctx;
944
971
  }
@@ -1465,7 +1492,7 @@ function SourcesCollapsible({
1465
1492
  defaultExpanded = false,
1466
1493
  className
1467
1494
  }) {
1468
- const [expanded, setExpanded] = React18__namespace.useState(defaultExpanded);
1495
+ const [expanded, setExpanded] = React19__namespace.useState(defaultExpanded);
1469
1496
  if (citations.length === 0) return null;
1470
1497
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("border rounded-lg", className), children: [
1471
1498
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1531,7 +1558,7 @@ function SourcesList({
1531
1558
  if (compact) {
1532
1559
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("text-xs text-muted-foreground", className), children: [
1533
1560
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Sources: " }),
1534
- citations.map((c, i) => /* @__PURE__ */ jsxRuntime.jsxs(React18__namespace.Fragment, { children: [
1561
+ citations.map((c, i) => /* @__PURE__ */ jsxRuntime.jsxs(React19__namespace.Fragment, { children: [
1535
1562
  /* @__PURE__ */ jsxRuntime.jsxs(
1536
1563
  "a",
1537
1564
  {
@@ -1609,11 +1636,11 @@ function resultsToCitations(results) {
1609
1636
  domain: result.domain || getDomain3(result.url)
1610
1637
  }));
1611
1638
  }
1612
- var ReasoningContext = React18__namespace.createContext(
1639
+ var ReasoningContext = React19__namespace.createContext(
1613
1640
  null
1614
1641
  );
1615
1642
  function useReasoningContext() {
1616
- const context = React18__namespace.useContext(ReasoningContext);
1643
+ const context = React19__namespace.useContext(ReasoningContext);
1617
1644
  if (!context) {
1618
1645
  throw new Error(
1619
1646
  "Reasoning components must be used within a Reasoning provider"
@@ -1629,11 +1656,11 @@ function Reasoning({
1629
1656
  defaultOpen = false,
1630
1657
  className
1631
1658
  }) {
1632
- const [uncontrolledOpen, setUncontrolledOpen] = React18__namespace.useState(defaultOpen);
1633
- const prevStreamingRef = React18__namespace.useRef(isStreaming);
1659
+ const [uncontrolledOpen, setUncontrolledOpen] = React19__namespace.useState(defaultOpen);
1660
+ const prevStreamingRef = React19__namespace.useRef(isStreaming);
1634
1661
  const isControlled = controlledOpen !== void 0;
1635
1662
  const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
1636
- const setIsOpen = React18__namespace.useCallback(
1663
+ const setIsOpen = React19__namespace.useCallback(
1637
1664
  (open) => {
1638
1665
  if (onOpenChange) {
1639
1666
  onOpenChange(open);
@@ -1644,7 +1671,7 @@ function Reasoning({
1644
1671
  },
1645
1672
  [isControlled, onOpenChange]
1646
1673
  );
1647
- React18__namespace.useEffect(() => {
1674
+ React19__namespace.useEffect(() => {
1648
1675
  if (isStreaming && !prevStreamingRef.current) {
1649
1676
  setIsOpen(true);
1650
1677
  } else if (!isStreaming && prevStreamingRef.current) {
@@ -1700,9 +1727,9 @@ function ReasoningContent({
1700
1727
  className
1701
1728
  }) {
1702
1729
  const { isOpen } = useReasoningContext();
1703
- const contentRef = React18__namespace.useRef(null);
1704
- const [height, setHeight] = React18__namespace.useState(0);
1705
- React18__namespace.useEffect(() => {
1730
+ const contentRef = React19__namespace.useRef(null);
1731
+ const [height, setHeight] = React19__namespace.useState(0);
1732
+ React19__namespace.useEffect(() => {
1706
1733
  if (contentRef.current) {
1707
1734
  const resizeObserver = new ResizeObserver((entries) => {
1708
1735
  for (const entry of entries) {
@@ -1751,11 +1778,11 @@ function SimpleReasoning({
1751
1778
  /* @__PURE__ */ jsxRuntime.jsx(ReasoningContent, { markdown, children: content })
1752
1779
  ] });
1753
1780
  }
1754
- var CopilotUIContext = React18__namespace.createContext(
1781
+ var CopilotUIContext = React19__namespace.createContext(
1755
1782
  null
1756
1783
  );
1757
1784
  function useCopilotUI() {
1758
- const context = React18__namespace.useContext(CopilotUIContext);
1785
+ const context = React19__namespace.useContext(CopilotUIContext);
1759
1786
  if (!context) {
1760
1787
  return {
1761
1788
  debug: false,
@@ -1770,7 +1797,7 @@ function CopilotUIProvider({
1770
1797
  debug = false,
1771
1798
  defaultDebugExpanded = false
1772
1799
  }) {
1773
- const value = React18__namespace.useMemo(
1800
+ const value = React19__namespace.useMemo(
1774
1801
  () => ({
1775
1802
  debug,
1776
1803
  defaultDebugExpanded,
@@ -1913,7 +1940,7 @@ function ToolStep({
1913
1940
  }) {
1914
1941
  const { isDebug, defaultDebugExpanded } = useCopilotUI();
1915
1942
  const debug = debugProp ?? isDebug;
1916
- const [expanded, setExpanded] = React18__namespace.useState(
1943
+ const [expanded, setExpanded] = React19__namespace.useState(
1917
1944
  defaultExpanded ?? defaultDebugExpanded ?? false
1918
1945
  );
1919
1946
  const displayTitle = getDisplayTitle(step);
@@ -2394,9 +2421,9 @@ function ArrowUpRightIcon({ className }) {
2394
2421
  }
2395
2422
  );
2396
2423
  }
2397
- var ConfirmationContext = React18__namespace.createContext(null);
2424
+ var ConfirmationContext = React19__namespace.createContext(null);
2398
2425
  function useConfirmationContext() {
2399
- const context = React18__namespace.useContext(ConfirmationContext);
2426
+ const context = React19__namespace.useContext(ConfirmationContext);
2400
2427
  if (!context) {
2401
2428
  throw new Error(
2402
2429
  "Confirmation components must be used within a Confirmation provider"
@@ -2564,30 +2591,27 @@ function PermissionConfirmation({
2564
2591
  message,
2565
2592
  onApprove,
2566
2593
  onReject,
2567
- showPermissionOptions = true,
2568
- permissionOptions = DEFAULT_PERMISSION_OPTIONS,
2569
2594
  className
2570
2595
  }) {
2571
- const [selectedPermission, setSelectedPermission] = React18__namespace.useState("ask");
2572
- const [showOptions, setShowOptions] = React18__namespace.useState(false);
2573
2596
  const handleApprove = () => {
2574
- onApprove?.(selectedPermission);
2597
+ onApprove?.("ask");
2575
2598
  };
2576
2599
  const handleReject = () => {
2577
- onReject?.(
2578
- selectedPermission === "deny_always" ? "deny_always" : void 0
2579
- );
2600
+ onReject?.(void 0);
2580
2601
  };
2581
2602
  if (state === "approved") {
2582
2603
  return /* @__PURE__ */ jsxRuntime.jsxs(
2583
2604
  "div",
2584
2605
  {
2585
2606
  className: cn(
2586
- "flex items-center gap-2 px-4 py-2 text-sm text-green-600 dark:text-green-400 rounded-lg border bg-green-50 dark:bg-green-950/20",
2607
+ "csdk-confirm-result",
2608
+ "inline-flex items-center gap-2 px-3 py-1.5 text-sm",
2609
+ "rounded-2xl border border-green-200/70 dark:border-green-900/40",
2610
+ "bg-green-50 dark:bg-green-950/20 text-green-700 dark:text-green-400",
2587
2611
  className
2588
2612
  ),
2589
2613
  children: [
2590
- /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "h-4 w-4" }),
2614
+ /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "h-3.5 w-3.5 shrink-0" }),
2591
2615
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Approved" })
2592
2616
  ]
2593
2617
  }
@@ -2598,11 +2622,14 @@ function PermissionConfirmation({
2598
2622
  "div",
2599
2623
  {
2600
2624
  className: cn(
2601
- "flex items-center gap-2 px-4 py-2 text-sm text-red-600 dark:text-red-400 rounded-lg border bg-red-50 dark:bg-red-950/20",
2625
+ "csdk-confirm-result",
2626
+ "inline-flex items-center gap-2 px-3 py-1.5 text-sm",
2627
+ "rounded-2xl border border-red-200/70 dark:border-red-900/40",
2628
+ "bg-red-50 dark:bg-red-950/20 text-red-700 dark:text-red-400",
2602
2629
  className
2603
2630
  ),
2604
2631
  children: [
2605
- /* @__PURE__ */ jsxRuntime.jsx(XIcon2, { className: "h-4 w-4" }),
2632
+ /* @__PURE__ */ jsxRuntime.jsx(XIcon2, { className: "h-3.5 w-3.5 shrink-0" }),
2606
2633
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Rejected" })
2607
2634
  ]
2608
2635
  }
@@ -2612,81 +2639,47 @@ function PermissionConfirmation({
2612
2639
  "div",
2613
2640
  {
2614
2641
  className: cn(
2615
- "rounded-lg border bg-card text-card-foreground p-4",
2642
+ "csdk-confirm-card",
2643
+ "w-full rounded-2xl border border-border/60 bg-card text-card-foreground shadow-sm overflow-hidden",
2616
2644
  className
2617
2645
  ),
2618
2646
  children: [
2619
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3 mb-3", children: [
2620
- /* @__PURE__ */ jsxRuntime.jsx(AlertTriangleIcon, { className: "mt-0.5 h-5 w-5 flex-shrink-0 text-amber-500" }),
2621
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
2622
- toolName && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-foreground", children: toolName }),
2623
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: message || "This tool requires your approval to execute." })
2647
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3 p-4", children: [
2648
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-amber-100 dark:bg-amber-950/50", children: /* @__PURE__ */ jsxRuntime.jsx(AlertTriangleIcon, { className: "h-3.5 w-3.5 text-amber-600 dark:text-amber-400" }) }),
2649
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 pt-0.5", children: [
2650
+ toolName && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase tracking-widest text-muted-foreground mb-1", children: toolName }),
2651
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground leading-snug", children: message || "This tool requires your approval to execute." })
2624
2652
  ] })
2625
2653
  ] }),
2626
- showPermissionOptions && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
2627
- /* @__PURE__ */ jsxRuntime.jsxs(
2654
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-2 px-4 pb-4", children: [
2655
+ /* @__PURE__ */ jsxRuntime.jsx(
2628
2656
  "button",
2629
2657
  {
2630
2658
  type: "button",
2631
- onClick: () => setShowOptions(!showOptions),
2632
- className: "flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors",
2633
- children: [
2634
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: permissionOptions.find((o) => o.value === selectedPermission)?.label }),
2635
- /* @__PURE__ */ jsxRuntime.jsx(
2636
- "svg",
2637
- {
2638
- className: cn(
2639
- "h-4 w-4 transition-transform",
2640
- showOptions && "rotate-180"
2641
- ),
2642
- fill: "none",
2643
- viewBox: "0 0 24 24",
2644
- stroke: "currentColor",
2645
- strokeWidth: 2,
2646
- children: /* @__PURE__ */ jsxRuntime.jsx(
2647
- "path",
2648
- {
2649
- strokeLinecap: "round",
2650
- strokeLinejoin: "round",
2651
- d: "M19 9l-7 7-7-7"
2652
- }
2653
- )
2654
- }
2655
- )
2656
- ]
2659
+ onClick: handleReject,
2660
+ className: cn(
2661
+ "csdk-confirm-btn",
2662
+ "px-4 py-1.5 text-sm font-medium rounded-xl",
2663
+ "border border-border bg-transparent text-muted-foreground",
2664
+ "hover:bg-muted/60 hover:text-foreground"
2665
+ ),
2666
+ children: "Deny"
2657
2667
  }
2658
2668
  ),
2659
- showOptions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 space-y-1 pl-1", children: permissionOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsxs(
2660
- "label",
2669
+ /* @__PURE__ */ jsxRuntime.jsx(
2670
+ "button",
2661
2671
  {
2672
+ type: "button",
2673
+ onClick: handleApprove,
2662
2674
  className: cn(
2663
- "flex items-start gap-2 p-2 rounded-md cursor-pointer transition-colors",
2664
- selectedPermission === option.value ? "bg-primary/10" : "hover:bg-muted/50"
2675
+ "csdk-confirm-btn",
2676
+ "px-4 py-1.5 text-sm font-medium rounded-xl",
2677
+ "bg-primary text-primary-foreground",
2678
+ "hover:opacity-90"
2665
2679
  ),
2666
- children: [
2667
- /* @__PURE__ */ jsxRuntime.jsx(
2668
- "input",
2669
- {
2670
- type: "radio",
2671
- name: "permission",
2672
- value: option.value,
2673
- checked: selectedPermission === option.value,
2674
- onChange: () => setSelectedPermission(option.value),
2675
- className: "mt-0.5"
2676
- }
2677
- ),
2678
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2679
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium", children: option.label }),
2680
- option.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: option.description })
2681
- ] })
2682
- ]
2683
- },
2684
- option.value
2685
- )) })
2686
- ] }),
2687
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
2688
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", size: "sm", onClick: handleReject, children: "Deny" }),
2689
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "default", size: "sm", onClick: handleApprove, children: "Allow" })
2680
+ children: "Allow"
2681
+ }
2682
+ )
2690
2683
  ] })
2691
2684
  ]
2692
2685
  }
@@ -2699,23 +2692,25 @@ function CompactPermissionConfirmation({
2699
2692
  onReject,
2700
2693
  className
2701
2694
  }) {
2702
- const [rememberChoice, setRememberChoice] = React18__namespace.useState(false);
2703
2695
  const handleApprove = () => {
2704
- onApprove?.(rememberChoice ? "allow_always" : "ask");
2696
+ onApprove?.("ask");
2705
2697
  };
2706
2698
  const handleReject = () => {
2707
- onReject?.(rememberChoice ? "deny_always" : void 0);
2699
+ onReject?.(void 0);
2708
2700
  };
2709
2701
  if (state === "approved") {
2710
2702
  return /* @__PURE__ */ jsxRuntime.jsxs(
2711
2703
  "div",
2712
2704
  {
2713
2705
  className: cn(
2714
- "flex items-center gap-2 px-4 py-2 text-sm text-green-600 dark:text-green-400",
2706
+ "csdk-confirm-result",
2707
+ "inline-flex items-center gap-2 px-3 py-1.5 text-sm",
2708
+ "rounded-2xl border border-green-200/70 dark:border-green-900/40",
2709
+ "bg-green-50 dark:bg-green-950/20 text-green-700 dark:text-green-400",
2715
2710
  className
2716
2711
  ),
2717
2712
  children: [
2718
- /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "h-4 w-4" }),
2713
+ /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "h-3.5 w-3.5 shrink-0" }),
2719
2714
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Approved" })
2720
2715
  ]
2721
2716
  }
@@ -2726,11 +2721,14 @@ function CompactPermissionConfirmation({
2726
2721
  "div",
2727
2722
  {
2728
2723
  className: cn(
2729
- "flex items-center gap-2 px-4 py-2 text-sm text-red-600 dark:text-red-400",
2724
+ "csdk-confirm-result",
2725
+ "inline-flex items-center gap-2 px-3 py-1.5 text-sm",
2726
+ "rounded-2xl border border-red-200/70 dark:border-red-900/40",
2727
+ "bg-red-50 dark:bg-red-950/20 text-red-700 dark:text-red-400",
2730
2728
  className
2731
2729
  ),
2732
2730
  children: [
2733
- /* @__PURE__ */ jsxRuntime.jsx(XIcon2, { className: "h-4 w-4" }),
2731
+ /* @__PURE__ */ jsxRuntime.jsx(XIcon2, { className: "h-3.5 w-3.5 shrink-0" }),
2734
2732
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Rejected" })
2735
2733
  ]
2736
2734
  }
@@ -2740,31 +2738,44 @@ function CompactPermissionConfirmation({
2740
2738
  "div",
2741
2739
  {
2742
2740
  className: cn(
2743
- "rounded-lg border bg-card text-card-foreground p-4",
2741
+ "csdk-confirm-card",
2742
+ "w-full rounded-2xl border border-border/60 bg-card text-card-foreground shadow-sm overflow-hidden",
2744
2743
  className
2745
2744
  ),
2746
2745
  children: [
2747
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3 mb-3", children: [
2748
- /* @__PURE__ */ jsxRuntime.jsx(AlertTriangleIcon, { className: "mt-0.5 h-5 w-5 flex-shrink-0 text-amber-500" }),
2749
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground", children: message || "This action requires your approval." })
2746
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3 p-4", children: [
2747
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-amber-100 dark:bg-amber-950/50", children: /* @__PURE__ */ jsxRuntime.jsx(AlertTriangleIcon, { className: "h-3.5 w-3.5 text-amber-600 dark:text-amber-400" }) }),
2748
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "flex-1 min-w-0 pt-0.5 text-sm text-foreground leading-snug", children: message || "This action requires your approval." })
2750
2749
  ] }),
2751
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2752
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-sm text-muted-foreground cursor-pointer", children: [
2753
- /* @__PURE__ */ jsxRuntime.jsx(
2754
- "input",
2755
- {
2756
- type: "checkbox",
2757
- checked: rememberChoice,
2758
- onChange: (e) => setRememberChoice(e.target.checked),
2759
- className: "rounded border-gray-300"
2760
- }
2761
- ),
2762
- "Don't ask again"
2763
- ] }),
2764
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
2765
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", size: "sm", onClick: handleReject, children: "Deny" }),
2766
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "default", size: "sm", onClick: handleApprove, children: "Allow" })
2767
- ] })
2750
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-2 px-4 pb-4", children: [
2751
+ /* @__PURE__ */ jsxRuntime.jsx(
2752
+ "button",
2753
+ {
2754
+ type: "button",
2755
+ onClick: handleReject,
2756
+ className: cn(
2757
+ "csdk-confirm-btn",
2758
+ "px-4 py-1.5 text-sm font-medium rounded-xl",
2759
+ "border border-border bg-transparent text-muted-foreground",
2760
+ "hover:bg-muted/60 hover:text-foreground"
2761
+ ),
2762
+ children: "Deny"
2763
+ }
2764
+ ),
2765
+ /* @__PURE__ */ jsxRuntime.jsx(
2766
+ "button",
2767
+ {
2768
+ type: "button",
2769
+ onClick: handleApprove,
2770
+ className: cn(
2771
+ "csdk-confirm-btn",
2772
+ "px-4 py-1.5 text-sm font-medium rounded-xl",
2773
+ "bg-primary text-primary-foreground",
2774
+ "hover:opacity-90"
2775
+ ),
2776
+ children: "Allow"
2777
+ }
2778
+ )
2768
2779
  ] })
2769
2780
  ]
2770
2781
  }
@@ -2896,8 +2907,8 @@ function DevLogger({
2896
2907
  position = "bottom-right",
2897
2908
  className
2898
2909
  }) {
2899
- const [isOpen, setIsOpen] = React18.useState(false);
2900
- const [activeTab, setActiveTab] = React18.useState("chat");
2910
+ const [isOpen, setIsOpen] = React19.useState(false);
2911
+ const [activeTab, setActiveTab] = React19.useState("chat");
2901
2912
  const positionClasses = {
2902
2913
  "bottom-left": "bottom-4 left-4",
2903
2914
  "bottom-right": "bottom-4 right-4",
@@ -3322,9 +3333,9 @@ function ModelSelector({
3322
3333
  showCapabilities = true,
3323
3334
  className
3324
3335
  }) {
3325
- const [isOpen, setIsOpen] = React18__namespace.useState(false);
3326
- const containerRef = React18__namespace.useRef(null);
3327
- React18__namespace.useEffect(() => {
3336
+ const [isOpen, setIsOpen] = React19__namespace.useState(false);
3337
+ const containerRef = React19__namespace.useRef(null);
3338
+ React19__namespace.useEffect(() => {
3328
3339
  function handleClickOutside(event) {
3329
3340
  if (containerRef.current && !containerRef.current.contains(event.target)) {
3330
3341
  setIsOpen(false);
@@ -3333,7 +3344,7 @@ function ModelSelector({
3333
3344
  document.addEventListener("mousedown", handleClickOutside);
3334
3345
  return () => document.removeEventListener("mousedown", handleClickOutside);
3335
3346
  }, []);
3336
- const selectedModel = React18__namespace.useMemo(() => {
3347
+ const selectedModel = React19__namespace.useMemo(() => {
3337
3348
  if (!value) return null;
3338
3349
  if (providers) {
3339
3350
  for (const provider of providers) {
@@ -3559,7 +3570,7 @@ function PopoverTrigger({
3559
3570
  className,
3560
3571
  ...props
3561
3572
  }) {
3562
- if (asChild && React18__namespace.isValidElement(children)) {
3573
+ if (asChild && React19__namespace.isValidElement(children)) {
3563
3574
  return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Trigger, { render: children, className, ...props });
3564
3575
  }
3565
3576
  return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Trigger, { className, ...props, children });
@@ -3694,8 +3705,8 @@ function ThreadPicker({
3694
3705
  itemClassName,
3695
3706
  newButtonClassName
3696
3707
  }) {
3697
- const [isOpen, setIsOpen] = React18__namespace.useState(false);
3698
- const selectedThread = React18__namespace.useMemo(() => {
3708
+ const [isOpen, setIsOpen] = React19__namespace.useState(false);
3709
+ const selectedThread = React19__namespace.useMemo(() => {
3699
3710
  if (!value) return null;
3700
3711
  return threads.find((t) => t.id === value) ?? null;
3701
3712
  }, [value, threads]);
@@ -3901,7 +3912,7 @@ function ThreadCard({
3901
3912
  showDelete = true,
3902
3913
  className
3903
3914
  }) {
3904
- const [isHovered, setIsHovered] = React18__namespace.useState(false);
3915
+ const [isHovered, setIsHovered] = React19__namespace.useState(false);
3905
3916
  const handleDelete = (e) => {
3906
3917
  e.stopPropagation();
3907
3918
  onDelete?.();
@@ -4142,10 +4153,10 @@ function MCPUIFrame({
4142
4153
  showLoading = true,
4143
4154
  testId
4144
4155
  }) {
4145
- const iframeRef = React18__namespace.useRef(null);
4146
- const [isLoading, setIsLoading] = React18__namespace.useState(true);
4147
- const [error, setError] = React18__namespace.useState(null);
4148
- React18__namespace.useEffect(() => {
4156
+ const iframeRef = React19__namespace.useRef(null);
4157
+ const [isLoading, setIsLoading] = React19__namespace.useState(true);
4158
+ const [error, setError] = React19__namespace.useState(null);
4159
+ React19__namespace.useEffect(() => {
4149
4160
  const handleMessage = (event) => {
4150
4161
  if (event.source !== iframeRef.current?.contentWindow) {
4151
4162
  return;
@@ -4158,17 +4169,17 @@ function MCPUIFrame({
4158
4169
  window.addEventListener("message", handleMessage);
4159
4170
  return () => window.removeEventListener("message", handleMessage);
4160
4171
  }, [onIntent]);
4161
- const handleLoad = React18__namespace.useCallback(() => {
4172
+ const handleLoad = React19__namespace.useCallback(() => {
4162
4173
  setIsLoading(false);
4163
4174
  onLoad?.();
4164
4175
  }, [onLoad]);
4165
- const handleError = React18__namespace.useCallback(() => {
4176
+ const handleError = React19__namespace.useCallback(() => {
4166
4177
  const err = new Error("Failed to load MCP UI content");
4167
4178
  setError(err);
4168
4179
  setIsLoading(false);
4169
4180
  onError?.(err);
4170
4181
  }, [onError]);
4171
- const { srcDoc, src } = React18__namespace.useMemo(() => {
4182
+ const { srcDoc, src } = React19__namespace.useMemo(() => {
4172
4183
  if (resource.mimeType === "text/html") {
4173
4184
  let content = resource.content || "";
4174
4185
  if (resource.blob && !resource.content) {
@@ -4318,6 +4329,284 @@ function MCPUIFrameList({
4318
4329
  `${resource.uri}-${index}`
4319
4330
  )) });
4320
4331
  }
4332
+ var MessageActionsContext = React19.createContext(
4333
+ null
4334
+ );
4335
+ function MessageActionsProvider({
4336
+ children
4337
+ }) {
4338
+ const [registry, setRegistry] = React19.useState(
4339
+ {}
4340
+ );
4341
+ const registerActions = React19.useCallback(
4342
+ (role, actions) => {
4343
+ setRegistry((prev) => ({ ...prev, [role]: actions }));
4344
+ },
4345
+ []
4346
+ );
4347
+ const clearActions = React19.useCallback((role) => {
4348
+ setRegistry((prev) => {
4349
+ const next = { ...prev };
4350
+ delete next[role];
4351
+ return next;
4352
+ });
4353
+ }, []);
4354
+ const getActions = React19.useCallback(
4355
+ (role) => registry[role] ?? [],
4356
+ [registry]
4357
+ );
4358
+ return /* @__PURE__ */ jsxRuntime.jsx(
4359
+ MessageActionsContext.Provider,
4360
+ {
4361
+ value: { getActions, registerActions, clearActions },
4362
+ children
4363
+ }
4364
+ );
4365
+ }
4366
+ function useMessageActionsContext() {
4367
+ return React19.useContext(MessageActionsContext);
4368
+ }
4369
+ React19.createContext(null);
4370
+ function CopyIcon2() {
4371
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4372
+ "svg",
4373
+ {
4374
+ width: "13",
4375
+ height: "13",
4376
+ viewBox: "0 0 24 24",
4377
+ fill: "none",
4378
+ stroke: "currentColor",
4379
+ strokeWidth: 2,
4380
+ strokeLinecap: "round",
4381
+ strokeLinejoin: "round",
4382
+ children: [
4383
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }),
4384
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
4385
+ ]
4386
+ }
4387
+ );
4388
+ }
4389
+ function CheckIcon3() {
4390
+ return /* @__PURE__ */ jsxRuntime.jsx(
4391
+ "svg",
4392
+ {
4393
+ width: "13",
4394
+ height: "13",
4395
+ viewBox: "0 0 24 24",
4396
+ fill: "none",
4397
+ stroke: "currentColor",
4398
+ strokeWidth: 2.5,
4399
+ strokeLinecap: "round",
4400
+ strokeLinejoin: "round",
4401
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6L9 17l-5-5" })
4402
+ }
4403
+ );
4404
+ }
4405
+ function EditIcon() {
4406
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4407
+ "svg",
4408
+ {
4409
+ width: "12",
4410
+ height: "12",
4411
+ viewBox: "0 0 24 24",
4412
+ fill: "none",
4413
+ stroke: "currentColor",
4414
+ strokeWidth: 2,
4415
+ strokeLinecap: "round",
4416
+ strokeLinejoin: "round",
4417
+ children: [
4418
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
4419
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
4420
+ ]
4421
+ }
4422
+ );
4423
+ }
4424
+ function ThumbsUpIcon3() {
4425
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4426
+ "svg",
4427
+ {
4428
+ width: "13",
4429
+ height: "13",
4430
+ viewBox: "0 0 24 24",
4431
+ fill: "none",
4432
+ stroke: "currentColor",
4433
+ strokeWidth: 2,
4434
+ strokeLinecap: "round",
4435
+ strokeLinejoin: "round",
4436
+ children: [
4437
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 10v12" }),
4438
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z" })
4439
+ ]
4440
+ }
4441
+ );
4442
+ }
4443
+ function ThumbsDownIcon3() {
4444
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4445
+ "svg",
4446
+ {
4447
+ width: "13",
4448
+ height: "13",
4449
+ viewBox: "0 0 24 24",
4450
+ fill: "none",
4451
+ stroke: "currentColor",
4452
+ strokeWidth: 2,
4453
+ strokeLinecap: "round",
4454
+ strokeLinejoin: "round",
4455
+ children: [
4456
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M17 14V2" }),
4457
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z" })
4458
+ ]
4459
+ }
4460
+ );
4461
+ }
4462
+ function CopyAction({ tooltip = "Copy", className }) {
4463
+ return null;
4464
+ }
4465
+ CopyAction.displayName = "CopyAction";
4466
+ function EditAction({ tooltip = "Edit", className }) {
4467
+ return null;
4468
+ }
4469
+ EditAction.displayName = "EditAction";
4470
+ function FeedbackAction({
4471
+ onFeedback,
4472
+ tooltip = "Feedback",
4473
+ className
4474
+ }) {
4475
+ return null;
4476
+ }
4477
+ FeedbackAction.displayName = "FeedbackAction";
4478
+ function Action({
4479
+ icon,
4480
+ tooltip,
4481
+ onClick,
4482
+ hidden,
4483
+ className
4484
+ }) {
4485
+ return null;
4486
+ }
4487
+ Action.displayName = "Action";
4488
+ function MessageActions2({ role, children }) {
4489
+ const ctx = useMessageActionsContext();
4490
+ const actions = React19.useMemo(() => {
4491
+ const result = [];
4492
+ React19__namespace.default.Children.forEach(children, (child) => {
4493
+ if (!React19__namespace.default.isValidElement(child)) return;
4494
+ const props = child.props;
4495
+ const type = child.type;
4496
+ if (type === CopyAction || child.type?.displayName === "CopyAction") {
4497
+ result.push({
4498
+ id: "copy",
4499
+ icon: /* @__PURE__ */ jsxRuntime.jsx(CopyIcon2, {}),
4500
+ tooltip: props.tooltip ?? "Copy",
4501
+ onClick: ({ message }) => {
4502
+ navigator.clipboard.writeText(message.content ?? "");
4503
+ },
4504
+ className: props.className
4505
+ });
4506
+ } else if (type === EditAction || child.type?.displayName === "EditAction") {
4507
+ result.push({
4508
+ id: "edit",
4509
+ icon: /* @__PURE__ */ jsxRuntime.jsx(EditIcon, {}),
4510
+ tooltip: props.tooltip ?? "Edit",
4511
+ onClick: () => {
4512
+ },
4513
+ // handled internally by DefaultMessage via onEditMessage
4514
+ className: props.className
4515
+ });
4516
+ } else if (type === FeedbackAction || child.type?.displayName === "FeedbackAction") {
4517
+ const onFeedback = props.onFeedback;
4518
+ result.push(
4519
+ {
4520
+ id: "feedback-up",
4521
+ icon: /* @__PURE__ */ jsxRuntime.jsx(ThumbsUpIcon3, {}),
4522
+ tooltip: "Helpful",
4523
+ onClick: ({ message }) => onFeedback?.(message, "helpful"),
4524
+ className: props.className
4525
+ },
4526
+ {
4527
+ id: "feedback-down",
4528
+ icon: /* @__PURE__ */ jsxRuntime.jsx(ThumbsDownIcon3, {}),
4529
+ tooltip: "Not helpful",
4530
+ onClick: ({ message }) => onFeedback?.(message, "not-helpful"),
4531
+ className: props.className
4532
+ }
4533
+ );
4534
+ } else if (type === Action || child.type?.displayName === "Action") {
4535
+ result.push({
4536
+ id: props.id ?? props.tooltip,
4537
+ icon: props.icon,
4538
+ tooltip: props.tooltip,
4539
+ onClick: props.onClick,
4540
+ hidden: props.hidden,
4541
+ className: props.className
4542
+ });
4543
+ }
4544
+ });
4545
+ return result;
4546
+ }, [children]);
4547
+ React19.useLayoutEffect(() => {
4548
+ if (!ctx) return;
4549
+ ctx.registerActions(role, actions);
4550
+ return () => ctx.clearActions(role);
4551
+ }, [ctx, role, actions]);
4552
+ return null;
4553
+ }
4554
+ function FloatingActions({
4555
+ message,
4556
+ role,
4557
+ align = "left",
4558
+ onEdit
4559
+ }) {
4560
+ const ctx = useMessageActionsContext();
4561
+ const [copiedId, setCopiedId] = React19__namespace.useState(null);
4562
+ if (!ctx) return null;
4563
+ const actions = ctx.getActions(role);
4564
+ if (actions.length === 0) return null;
4565
+ return /* @__PURE__ */ jsxRuntime.jsx(
4566
+ "div",
4567
+ {
4568
+ className: cn(
4569
+ "flex items-center gap-0.5 mt-1",
4570
+ "opacity-0 group-hover/message:opacity-100 transition-opacity duration-150",
4571
+ align === "right" ? "justify-end" : "justify-start"
4572
+ ),
4573
+ children: actions.map((action) => {
4574
+ const isHidden = typeof action.hidden === "function" ? action.hidden({ message }) : action.hidden;
4575
+ if (isHidden) return null;
4576
+ const isCopied = copiedId === action.id;
4577
+ return /* @__PURE__ */ jsxRuntime.jsx(
4578
+ "button",
4579
+ {
4580
+ type: "button",
4581
+ title: action.tooltip,
4582
+ "aria-label": action.tooltip,
4583
+ className: cn(
4584
+ "flex items-center justify-center size-6 rounded-md",
4585
+ "text-muted-foreground hover:text-foreground hover:bg-muted",
4586
+ "transition-colors",
4587
+ action.className
4588
+ ),
4589
+ onClick: () => {
4590
+ if (action.id === "edit" && onEdit) {
4591
+ onEdit();
4592
+ return;
4593
+ }
4594
+ if (action.id === "copy") {
4595
+ navigator.clipboard.writeText(message.content ?? "");
4596
+ setCopiedId("copy");
4597
+ setTimeout(() => setCopiedId(null), 1500);
4598
+ return;
4599
+ }
4600
+ action.onClick({ message });
4601
+ },
4602
+ children: action.id === "copy" && isCopied ? /* @__PURE__ */ jsxRuntime.jsx(CheckIcon3, {}) : action.icon
4603
+ },
4604
+ action.id
4605
+ );
4606
+ })
4607
+ }
4608
+ );
4609
+ }
4321
4610
  function DefaultMessage({
4322
4611
  message,
4323
4612
  userAvatar,
@@ -4348,24 +4637,24 @@ function DefaultMessage({
4348
4637
  const isUser = message.role === "user";
4349
4638
  const isCompactionMarker = message.role === "system" && message.metadata?.type === "compaction-marker";
4350
4639
  const isStreaming = isLastMessage && isLoading;
4351
- const [isEditing, setIsEditing] = React18__namespace.useState(false);
4352
- const [editValue, setEditValue] = React18__namespace.useState(message.content ?? "");
4353
- const editRef = React18__namespace.useRef(null);
4354
- const startEdit = React18__namespace.useCallback(() => {
4640
+ const [isEditing, setIsEditing] = React19__namespace.useState(false);
4641
+ const [editValue, setEditValue] = React19__namespace.useState(message.content ?? "");
4642
+ const editRef = React19__namespace.useRef(null);
4643
+ const startEdit = React19__namespace.useCallback(() => {
4355
4644
  setEditValue(message.content ?? "");
4356
4645
  setIsEditing(true);
4357
4646
  requestAnimationFrame(() => editRef.current?.focus());
4358
4647
  }, [message.content]);
4359
- const cancelEdit = React18__namespace.useCallback(() => {
4648
+ const cancelEdit = React19__namespace.useCallback(() => {
4360
4649
  setIsEditing(false);
4361
4650
  }, []);
4362
- const submitEdit = React18__namespace.useCallback(() => {
4651
+ const submitEdit = React19__namespace.useCallback(() => {
4363
4652
  const trimmed = editValue.trim();
4364
4653
  if (!trimmed || !onEditMessage) return;
4365
4654
  onEditMessage(message.id, trimmed);
4366
4655
  setIsEditing(false);
4367
4656
  }, [editValue, message.id, onEditMessage]);
4368
- const handleEditKeyDown = React18__namespace.useCallback(
4657
+ const handleEditKeyDown = React19__namespace.useCallback(
4369
4658
  (e) => {
4370
4659
  if (e.key === "Enter" && !e.shiftKey) {
4371
4660
  e.preventDefault();
@@ -4407,18 +4696,18 @@ function DefaultMessage({
4407
4696
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 h-px bg-border" })
4408
4697
  ] });
4409
4698
  }
4410
- const { cleanContent: contentWithoutFollowUps, followUps } = React18__namespace.useMemo(() => {
4699
+ const { cleanContent: contentWithoutFollowUps, followUps } = React19__namespace.useMemo(() => {
4411
4700
  if (isUser || !message.content) {
4412
4701
  return { cleanContent: message.content, followUps: [] };
4413
4702
  }
4414
4703
  return parseFollowUps(message.content);
4415
4704
  }, [message.content, isUser]);
4416
- const cleanContent = React18__namespace.useMemo(() => {
4705
+ const cleanContent = React19__namespace.useMemo(() => {
4417
4706
  if (!contentWithoutFollowUps) return contentWithoutFollowUps;
4418
4707
  return contentWithoutFollowUps.replace(/\n*\*{0,2}Sources:?\*{0,2}\s*(\[.+?\]\(.+?\)[,\s]*)+$/gi, "").trim();
4419
4708
  }, [contentWithoutFollowUps]);
4420
4709
  const shouldShowFollowUps = showFollowUps && !isUser && isLastMessage && !isLoading && followUps.length > 0 && onFollowUpClick;
4421
- const sources = React18__namespace.useMemo(() => {
4710
+ const sources = React19__namespace.useMemo(() => {
4422
4711
  if (isUser || !citations.enabled) return [];
4423
4712
  const extractedSources = [];
4424
4713
  const addSource = (url, title, description) => {
@@ -4472,121 +4761,136 @@ function DefaultMessage({
4472
4761
  const shouldShowSources = citations.enabled && sources.length > 0;
4473
4762
  if (isUser) {
4474
4763
  const hasAttachments = message.attachments && message.attachments.length > 0;
4475
- return /* @__PURE__ */ jsxRuntime.jsxs(Message, { className: cn("flex gap-2 group/user-msg justify-end"), children: [
4476
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-end max-w-[80%] min-w-0", children: isEditing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5 w-full min-w-[200px]", children: [
4477
- /* @__PURE__ */ jsxRuntime.jsx(
4478
- "textarea",
4479
- {
4480
- ref: editRef,
4481
- value: editValue,
4482
- onChange: (e) => setEditValue(e.target.value),
4483
- onKeyDown: handleEditKeyDown,
4484
- rows: Math.max(2, (editValue.match(/\n/g) || []).length + 1),
4485
- className: cn(
4486
- "csdk-edit-textarea w-full rounded-lg px-3 py-2 text-sm resize-none",
4487
- "bg-primary text-primary-foreground placeholder:text-primary-foreground/50",
4488
- "focus:outline-none focus:ring-2 focus:ring-primary-foreground/30",
4489
- userMessageClassName
4490
- )
4491
- }
4492
- ),
4493
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 justify-end", children: [
4494
- /* @__PURE__ */ jsxRuntime.jsx(
4495
- "button",
4496
- {
4497
- type: "button",
4498
- onClick: cancelEdit,
4499
- className: "csdk-edit-cancel px-3 py-1 text-xs rounded-md bg-muted text-muted-foreground hover:bg-muted/80 transition-colors",
4500
- children: "Cancel"
4501
- }
4502
- ),
4503
- /* @__PURE__ */ jsxRuntime.jsx(
4504
- "button",
4505
- {
4506
- type: "button",
4507
- onClick: submitEdit,
4508
- disabled: !editValue.trim(),
4509
- className: "csdk-edit-submit px-3 py-1 text-xs rounded-md bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 transition-colors",
4510
- children: "Send"
4511
- }
4512
- )
4513
- ] })
4514
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4515
- message.content && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
4516
- /* @__PURE__ */ jsxRuntime.jsx(
4517
- MessageContent,
4518
- {
4519
- className: cn(
4520
- "csdk-message-user rounded-lg px-4 py-2 bg-primary text-primary-foreground",
4521
- userMessageClassName
4764
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4765
+ Message,
4766
+ {
4767
+ className: cn("flex gap-2 group/user-msg group/message justify-end"),
4768
+ children: [
4769
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-end max-w-[80%] min-w-0", children: isEditing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5 w-full min-w-[200px]", children: [
4770
+ /* @__PURE__ */ jsxRuntime.jsx(
4771
+ "textarea",
4772
+ {
4773
+ ref: editRef,
4774
+ value: editValue,
4775
+ onChange: (e) => setEditValue(e.target.value),
4776
+ onKeyDown: handleEditKeyDown,
4777
+ rows: Math.max(2, (editValue.match(/\n/g) || []).length + 1),
4778
+ className: cn(
4779
+ "csdk-edit-textarea w-full rounded-lg px-3 py-2 text-sm resize-none",
4780
+ "bg-primary text-primary-foreground placeholder:text-primary-foreground/50",
4781
+ "focus:outline-none focus:ring-2 focus:ring-primary-foreground/30",
4782
+ userMessageClassName
4783
+ )
4784
+ }
4785
+ ),
4786
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 justify-end", children: [
4787
+ /* @__PURE__ */ jsxRuntime.jsx(
4788
+ "button",
4789
+ {
4790
+ type: "button",
4791
+ onClick: cancelEdit,
4792
+ className: "csdk-edit-cancel px-3 py-1 text-xs rounded-md bg-muted text-muted-foreground hover:bg-muted/80 transition-colors",
4793
+ children: "Cancel"
4794
+ }
4522
4795
  ),
4523
- markdown: true,
4524
- size,
4525
- children: message.content
4526
- }
4527
- ),
4528
- showEditBtn && /* @__PURE__ */ jsxRuntime.jsx(
4529
- "button",
4530
- {
4531
- type: "button",
4532
- onClick: startEdit,
4533
- "aria-label": "Edit message",
4534
- className: cn(
4535
- "csdk-edit-btn absolute -left-7 top-1/2 -translate-y-1/2",
4536
- "size-6 flex items-center justify-center rounded-full",
4537
- "text-muted-foreground bg-background border border-border shadow-sm",
4538
- "opacity-0 group-hover/user-msg:opacity-100 transition-opacity",
4539
- "hover:text-foreground hover:bg-muted"
4796
+ /* @__PURE__ */ jsxRuntime.jsx(
4797
+ "button",
4798
+ {
4799
+ type: "button",
4800
+ onClick: submitEdit,
4801
+ disabled: !editValue.trim(),
4802
+ className: "csdk-edit-submit px-3 py-1 text-xs rounded-md bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 transition-colors",
4803
+ children: "Send"
4804
+ }
4805
+ )
4806
+ ] })
4807
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4808
+ message.content && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
4809
+ /* @__PURE__ */ jsxRuntime.jsx(
4810
+ MessageContent,
4811
+ {
4812
+ className: cn(
4813
+ "csdk-message-user rounded-lg px-4 py-2 bg-primary text-primary-foreground",
4814
+ userMessageClassName
4815
+ ),
4816
+ markdown: true,
4817
+ size,
4818
+ children: message.content
4819
+ }
4540
4820
  ),
4541
- children: /* @__PURE__ */ jsxRuntime.jsxs(
4542
- "svg",
4821
+ showEditBtn && /* @__PURE__ */ jsxRuntime.jsx(
4822
+ "button",
4543
4823
  {
4544
- width: "12",
4545
- height: "12",
4546
- viewBox: "0 0 24 24",
4547
- fill: "none",
4548
- stroke: "currentColor",
4549
- strokeWidth: 2,
4550
- strokeLinecap: "round",
4551
- strokeLinejoin: "round",
4552
- children: [
4553
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
4554
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
4555
- ]
4824
+ type: "button",
4825
+ onClick: startEdit,
4826
+ "aria-label": "Edit message",
4827
+ className: cn(
4828
+ "csdk-edit-btn absolute -left-7 top-1/2 -translate-y-1/2",
4829
+ "size-6 flex items-center justify-center rounded-full",
4830
+ "text-muted-foreground bg-background border border-border shadow-sm",
4831
+ "opacity-0 group-hover/user-msg:opacity-100 transition-opacity",
4832
+ "hover:text-foreground hover:bg-muted"
4833
+ ),
4834
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
4835
+ "svg",
4836
+ {
4837
+ width: "12",
4838
+ height: "12",
4839
+ viewBox: "0 0 24 24",
4840
+ fill: "none",
4841
+ stroke: "currentColor",
4842
+ strokeWidth: 2,
4843
+ strokeLinecap: "round",
4844
+ strokeLinejoin: "round",
4845
+ children: [
4846
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
4847
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
4848
+ ]
4849
+ }
4850
+ )
4556
4851
  }
4557
4852
  )
4853
+ ] }),
4854
+ hasAttachments && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex flex-wrap gap-2 justify-end", children: message.attachments.map((attachment, index) => /* @__PURE__ */ jsxRuntime.jsx(AttachmentPreview, { attachment }, index)) }),
4855
+ showBranchNav && /* @__PURE__ */ jsxRuntime.jsx(
4856
+ BranchNavigator,
4857
+ {
4858
+ siblingIndex: branchInfo.siblingIndex,
4859
+ totalSiblings: branchInfo.totalSiblings,
4860
+ hasPrevious: branchInfo.hasPrevious,
4861
+ hasNext: branchInfo.hasNext,
4862
+ onPrevious: () => onSwitchBranch(
4863
+ branchInfo.siblingIds[branchInfo.siblingIndex - 1]
4864
+ ),
4865
+ onNext: () => onSwitchBranch(
4866
+ branchInfo.siblingIds[branchInfo.siblingIndex + 1]
4867
+ ),
4868
+ className: "mt-1"
4869
+ }
4870
+ ),
4871
+ /* @__PURE__ */ jsxRuntime.jsx(
4872
+ FloatingActions,
4873
+ {
4874
+ message,
4875
+ role: "user",
4876
+ align: "right",
4877
+ onEdit: onEditMessage ? startEdit : void 0
4878
+ }
4879
+ )
4880
+ ] }) }),
4881
+ showUserAvatar && /* @__PURE__ */ jsxRuntime.jsx(
4882
+ MessageAvatar,
4883
+ {
4884
+ src: userAvatar.src,
4885
+ alt: "User",
4886
+ fallback: userAvatar.fallback,
4887
+ className: userAvatar.className,
4888
+ children: userAvatar.component
4558
4889
  }
4559
4890
  )
4560
- ] }),
4561
- hasAttachments && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex flex-wrap gap-2 justify-end", children: message.attachments.map((attachment, index) => /* @__PURE__ */ jsxRuntime.jsx(AttachmentPreview, { attachment }, index)) }),
4562
- showBranchNav && /* @__PURE__ */ jsxRuntime.jsx(
4563
- BranchNavigator,
4564
- {
4565
- siblingIndex: branchInfo.siblingIndex,
4566
- totalSiblings: branchInfo.totalSiblings,
4567
- hasPrevious: branchInfo.hasPrevious,
4568
- hasNext: branchInfo.hasNext,
4569
- onPrevious: () => onSwitchBranch(
4570
- branchInfo.siblingIds[branchInfo.siblingIndex - 1]
4571
- ),
4572
- onNext: () => onSwitchBranch(
4573
- branchInfo.siblingIds[branchInfo.siblingIndex + 1]
4574
- ),
4575
- className: "mt-1"
4576
- }
4577
- )
4578
- ] }) }),
4579
- showUserAvatar && /* @__PURE__ */ jsxRuntime.jsx(
4580
- MessageAvatar,
4581
- {
4582
- src: userAvatar.src,
4583
- alt: "User",
4584
- fallback: userAvatar.fallback,
4585
- className: userAvatar.className,
4586
- children: userAvatar.component
4587
- }
4588
- )
4589
- ] });
4891
+ ]
4892
+ }
4893
+ );
4590
4894
  }
4591
4895
  const isToolHidden = (exec) => {
4592
4896
  if (exec.hidden === true) return true;
@@ -4623,7 +4927,7 @@ function DefaultMessage({
4623
4927
  result: exec.result,
4624
4928
  error: exec.error
4625
4929
  }));
4626
- return /* @__PURE__ */ jsxRuntime.jsxs(Message, { className: "flex gap-2", children: [
4930
+ return /* @__PURE__ */ jsxRuntime.jsxs(Message, { className: "flex gap-2 group/message", children: [
4627
4931
  /* @__PURE__ */ jsxRuntime.jsx(
4628
4932
  MessageAvatar,
4629
4933
  {
@@ -4681,7 +4985,7 @@ function DefaultMessage({
4681
4985
  renderProps
4682
4986
  );
4683
4987
  if (output != null) {
4684
- return /* @__PURE__ */ jsxRuntime.jsx(React18__namespace.Fragment, { children: output }, exec.id);
4988
+ return /* @__PURE__ */ jsxRuntime.jsx(React19__namespace.Fragment, { children: output }, exec.id);
4685
4989
  }
4686
4990
  }
4687
4991
  if (mcpToolRenderer && (exec.source === "mcp" || toolDef?.source === "mcp")) {
@@ -4797,13 +5101,13 @@ function DefaultMessage({
4797
5101
  const output = toolDef.render(
4798
5102
  renderProps
4799
5103
  );
4800
- return /* @__PURE__ */ jsxRuntime.jsx(React18__namespace.Fragment, { children: output }, tool.id);
5104
+ return /* @__PURE__ */ jsxRuntime.jsx(React19__namespace.Fragment, { children: output }, tool.id);
4801
5105
  }
4802
5106
  return /* @__PURE__ */ jsxRuntime.jsx(
4803
5107
  PermissionConfirmation,
4804
5108
  {
4805
5109
  state: "pending",
4806
- toolName: tool.name,
5110
+ toolName: tool.approvalTitle ?? tool.name,
4807
5111
  message: tool.approvalMessage || `This tool wants to execute. Do you approve?`,
4808
5112
  onApprove: (permissionLevel) => onApproveToolExecution?.(
4809
5113
  tool.id,
@@ -4839,14 +5143,15 @@ function DefaultMessage({
4839
5143
  className: followUpClassName,
4840
5144
  buttonClassName: followUpButtonClassName
4841
5145
  }
4842
- )
5146
+ ),
5147
+ /* @__PURE__ */ jsxRuntime.jsx(FloatingActions, { message, role: "assistant", align: "left" })
4843
5148
  ] })
4844
5149
  )
4845
5150
  ] })
4846
5151
  ] });
4847
5152
  }
4848
5153
  function AttachmentPreview({ attachment }) {
4849
- const [expanded, setExpanded] = React18__namespace.useState(false);
5154
+ const [expanded, setExpanded] = React19__namespace.useState(false);
4850
5155
  if (attachment.type !== "image") {
4851
5156
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 rounded-lg border bg-muted/50 px-3 py-2 text-sm", children: [
4852
5157
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: attachment.type }),
@@ -4975,10 +5280,10 @@ function ChatWelcome({
4975
5280
  processAttachment: processAttachmentProp,
4976
5281
  classNames = {}
4977
5282
  }) {
4978
- const [input, setInput] = React18.useState("");
4979
- const [pendingAttachments, setPendingAttachments] = React18.useState([]);
4980
- const fileInputRef = React18.useRef(null);
4981
- const fileInputId = React18.useId();
5283
+ const [input, setInput] = React19.useState("");
5284
+ const [pendingAttachments, setPendingAttachments] = React19.useState([]);
5285
+ const fileInputRef = React19.useRef(null);
5286
+ const fileInputId = React19.useId();
4982
5287
  const title = config?.title ?? DEFAULT_TITLE;
4983
5288
  const subtitle = config?.subtitle ?? DEFAULT_SUBTITLE;
4984
5289
  const logo = config?.logo;
@@ -4987,7 +5292,7 @@ function ChatWelcome({
4987
5292
  config?.recentChatsLabel ?? DEFAULT_RECENT_CHATS_LABEL;
4988
5293
  const maxRecentChats = config?.maxRecentChats ?? DEFAULT_MAX_RECENT_CHATS;
4989
5294
  config?.viewMoreLabel ?? DEFAULT_VIEW_MORE_LABEL;
4990
- const isFileTypeAllowed = React18.useCallback(
5295
+ const isFileTypeAllowed = React19.useCallback(
4991
5296
  (file) => {
4992
5297
  for (const type of allowedFileTypes) {
4993
5298
  if (type.endsWith("/*")) {
@@ -5001,7 +5306,7 @@ function ChatWelcome({
5001
5306
  },
5002
5307
  [allowedFileTypes]
5003
5308
  );
5004
- const handleFileSelect = React18.useCallback(
5309
+ const handleFileSelect = React19.useCallback(
5005
5310
  async (files) => {
5006
5311
  if (!files || !attachmentsEnabled) return;
5007
5312
  for (const file of Array.from(files)) {
@@ -5064,7 +5369,7 @@ function ChatWelcome({
5064
5369
  },
5065
5370
  [attachmentsEnabled, maxFileSize, isFileTypeAllowed, processAttachmentProp]
5066
5371
  );
5067
- const handleInputChange = React18.useCallback(
5372
+ const handleInputChange = React19.useCallback(
5068
5373
  (e) => {
5069
5374
  handleFileSelect(e.target.files);
5070
5375
  if (fileInputRef.current) {
@@ -5073,7 +5378,7 @@ function ChatWelcome({
5073
5378
  },
5074
5379
  [handleFileSelect]
5075
5380
  );
5076
- const removePendingAttachment = React18.useCallback((id) => {
5381
+ const removePendingAttachment = React19.useCallback((id) => {
5077
5382
  setPendingAttachments((prev) => {
5078
5383
  const att = prev.find((a) => a.id === id);
5079
5384
  if (att) {
@@ -5082,7 +5387,7 @@ function ChatWelcome({
5082
5387
  return prev.filter((a) => a.id !== id);
5083
5388
  });
5084
5389
  }, []);
5085
- const handleSubmit = React18.useCallback(() => {
5390
+ const handleSubmit = React19.useCallback(() => {
5086
5391
  const hasContent = input.trim();
5087
5392
  const hasAttachments = pendingAttachments.some(
5088
5393
  (att) => att.status === "ready"
@@ -5094,7 +5399,7 @@ function ChatWelcome({
5094
5399
  setPendingAttachments([]);
5095
5400
  setInput("");
5096
5401
  }, [input, isLoading, onSendMessage, pendingAttachments]);
5097
- const handleSuggestionClick = React18.useCallback(
5402
+ const handleSuggestionClick = React19.useCallback(
5098
5403
  (suggestion) => {
5099
5404
  onSendMessage(suggestion);
5100
5405
  },
@@ -5266,11 +5571,11 @@ function ChatWelcome({
5266
5571
  }
5267
5572
  );
5268
5573
  }
5269
- var CopilotChatContext = React18.createContext(
5574
+ var CopilotChatContext = React19.createContext(
5270
5575
  null
5271
5576
  );
5272
5577
  var useCopilotChatContext = () => {
5273
- const ctx = React18.useContext(CopilotChatContext);
5578
+ const ctx = React19.useContext(CopilotChatContext);
5274
5579
  if (!ctx) {
5275
5580
  throw new Error(
5276
5581
  "useCopilotChatContext must be used within CopilotChat. Make sure you're using CopilotChat.Home, CopilotChat.Input, etc. inside <CopilotChat>"
@@ -5304,10 +5609,10 @@ function ChatView({ children, className }) {
5304
5609
  ChatView.displayName = "ChatView";
5305
5610
  function chatViewHasOnlyLayoutChildren(chatViewElement) {
5306
5611
  if (!chatViewElement?.props?.children) return false;
5307
- const childArray = React18__namespace.default.Children.toArray(chatViewElement.props.children);
5612
+ const childArray = React19__namespace.default.Children.toArray(chatViewElement.props.children);
5308
5613
  if (childArray.length === 0) return false;
5309
5614
  return childArray.every(
5310
- (child) => React18__namespace.default.isValidElement(child) && (child.type === Header || child.type === Footer)
5615
+ (child) => React19__namespace.default.isValidElement(child) && (child.type === Header || child.type === Footer)
5311
5616
  );
5312
5617
  }
5313
5618
  function Header({ children, className }) {
@@ -5323,8 +5628,8 @@ function Input({ placeholder: placeholderProp, className }) {
5323
5628
  onStop,
5324
5629
  placeholder: defaultPlaceholder
5325
5630
  } = useCopilotChatContext();
5326
- const [value, setValue] = React18.useState("");
5327
- const handleSubmit = React18.useCallback(() => {
5631
+ const [value, setValue] = React19.useState("");
5632
+ const handleSubmit = React19.useCallback(() => {
5328
5633
  if (value.trim() && !isLoading) {
5329
5634
  send(value.trim());
5330
5635
  setValue("");
@@ -5445,18 +5750,18 @@ function ThreadPickerCompound(props) {
5445
5750
  );
5446
5751
  }
5447
5752
  function hasCompoundChild(children, ...components) {
5448
- return React18__namespace.default.Children.toArray(children).some(
5449
- (child) => React18__namespace.default.isValidElement(child) && components.includes(child.type)
5753
+ return React19__namespace.default.Children.toArray(children).some(
5754
+ (child) => React19__namespace.default.isValidElement(child) && components.includes(child.type)
5450
5755
  );
5451
5756
  }
5452
5757
  function findCompoundChild(children, component) {
5453
- return React18__namespace.default.Children.toArray(children).find(
5454
- (child) => React18__namespace.default.isValidElement(child) && child.type === component
5758
+ return React19__namespace.default.Children.toArray(children).find(
5759
+ (child) => React19__namespace.default.isValidElement(child) && child.type === component
5455
5760
  );
5456
5761
  }
5457
5762
  function filterCompoundChildren(children, ...components) {
5458
- return React18__namespace.default.Children.toArray(children).filter(
5459
- (child) => React18__namespace.default.isValidElement(child) && components.includes(child.type)
5763
+ return React19__namespace.default.Children.toArray(children).filter(
5764
+ (child) => React19__namespace.default.isValidElement(child) && components.includes(child.type)
5460
5765
  );
5461
5766
  }
5462
5767
  var DEFAULT_MAX_FILE_SIZE2 = 5 * 1024 * 1024;
@@ -5541,6 +5846,7 @@ function ChatComponent({
5541
5846
  // Citations/Sources
5542
5847
  citations,
5543
5848
  // Custom rendering
5849
+ messageView,
5544
5850
  renderMessage,
5545
5851
  renderInput,
5546
5852
  renderHeader,
@@ -5562,12 +5868,12 @@ function ChatComponent({
5562
5868
  }) {
5563
5869
  const userAvatar = { fallback: "U", ...userAvatarProp };
5564
5870
  const assistantAvatar = { fallback: "AI", ...assistantAvatarProp };
5565
- const [input, setInput] = React18.useState("");
5566
- const [pendingAttachments, setPendingAttachments] = React18.useState([]);
5567
- const [isDragging, setIsDragging] = React18.useState(false);
5568
- const fileInputRef = React18.useRef(null);
5569
- const fileInputId = React18.useId();
5570
- const isFileTypeAllowed = React18.useCallback(
5871
+ const [input, setInput] = React19.useState("");
5872
+ const [pendingAttachments, setPendingAttachments] = React19.useState([]);
5873
+ const [isDragging, setIsDragging] = React19.useState(false);
5874
+ const fileInputRef = React19.useRef(null);
5875
+ const fileInputId = React19.useId();
5876
+ const isFileTypeAllowed = React19.useCallback(
5571
5877
  (file) => {
5572
5878
  for (const type of allowedFileTypes) {
5573
5879
  if (type.endsWith("/*")) {
@@ -5581,7 +5887,7 @@ function ChatComponent({
5581
5887
  },
5582
5888
  [allowedFileTypes]
5583
5889
  );
5584
- const handleFileSelect = React18.useCallback(
5890
+ const handleFileSelect = React19.useCallback(
5585
5891
  async (files) => {
5586
5892
  if (!files || !attachmentsEnabled) return;
5587
5893
  for (const file of Array.from(files)) {
@@ -5644,7 +5950,7 @@ function ChatComponent({
5644
5950
  },
5645
5951
  [attachmentsEnabled, maxFileSize, isFileTypeAllowed, processAttachmentProp]
5646
5952
  );
5647
- const handleInputChange = React18.useCallback(
5953
+ const handleInputChange = React19.useCallback(
5648
5954
  (e) => {
5649
5955
  handleFileSelect(e.target.files);
5650
5956
  if (fileInputRef.current) {
@@ -5653,7 +5959,7 @@ function ChatComponent({
5653
5959
  },
5654
5960
  [handleFileSelect]
5655
5961
  );
5656
- const removePendingAttachment = React18.useCallback((id) => {
5962
+ const removePendingAttachment = React19.useCallback((id) => {
5657
5963
  setPendingAttachments((prev) => {
5658
5964
  const att = prev.find((a) => a.id === id);
5659
5965
  if (att) {
@@ -5662,7 +5968,7 @@ function ChatComponent({
5662
5968
  return prev.filter((a) => a.id !== id);
5663
5969
  });
5664
5970
  }, []);
5665
- const handleDragOver = React18.useCallback(
5971
+ const handleDragOver = React19.useCallback(
5666
5972
  (e) => {
5667
5973
  e.preventDefault();
5668
5974
  e.stopPropagation();
@@ -5672,12 +5978,12 @@ function ChatComponent({
5672
5978
  },
5673
5979
  [attachmentsEnabled]
5674
5980
  );
5675
- const handleDragLeave = React18.useCallback((e) => {
5981
+ const handleDragLeave = React19.useCallback((e) => {
5676
5982
  e.preventDefault();
5677
5983
  e.stopPropagation();
5678
5984
  setIsDragging(false);
5679
5985
  }, []);
5680
- const handleDrop = React18.useCallback(
5986
+ const handleDrop = React19.useCallback(
5681
5987
  (e) => {
5682
5988
  e.preventDefault();
5683
5989
  e.stopPropagation();
@@ -5688,7 +5994,7 @@ function ChatComponent({
5688
5994
  },
5689
5995
  [attachmentsEnabled, handleFileSelect]
5690
5996
  );
5691
- const handleSubmit = React18.useCallback(() => {
5997
+ const handleSubmit = React19.useCallback(() => {
5692
5998
  const hasContent = input.trim();
5693
5999
  const hasAttachments = pendingAttachments.some(
5694
6000
  (att) => att.status === "ready"
@@ -5700,7 +6006,7 @@ function ChatComponent({
5700
6006
  setPendingAttachments([]);
5701
6007
  setInput("");
5702
6008
  }, [input, isLoading, onSendMessage, pendingAttachments]);
5703
- const handleSuggestionClick = React18.useCallback(
6009
+ const handleSuggestionClick = React19.useCallback(
5704
6010
  (suggestion) => {
5705
6011
  if (onSuggestionClick) {
5706
6012
  onSuggestionClick(suggestion);
@@ -5727,13 +6033,13 @@ function ChatComponent({
5727
6033
  const chatViewNeedsDefault = chatViewElement && (!chatViewElement.props.children || chatViewHasOnlyLayoutChildren(chatViewElement));
5728
6034
  const showDefaultWelcome = view === "home" && !hasCustomHome && welcome !== false;
5729
6035
  const welcomeConfig = typeof welcome === "object" ? welcome : void 0;
5730
- const send = React18.useCallback(
6036
+ const send = React19.useCallback(
5731
6037
  (message, attachments) => {
5732
6038
  onSendMessage?.(message, attachments);
5733
6039
  },
5734
6040
  [onSendMessage]
5735
6041
  );
5736
- const contextValue = React18__namespace.default.useMemo(
6042
+ const contextValue = React19__namespace.default.useMemo(
5737
6043
  () => ({
5738
6044
  view,
5739
6045
  send,
@@ -5741,6 +6047,9 @@ function ChatComponent({
5741
6047
  onStop,
5742
6048
  attachmentsEnabled,
5743
6049
  placeholder,
6050
+ // Messages for Chat.MessageList primitive
6051
+ messages,
6052
+ registeredTools,
5744
6053
  // Thread management - passed from connected-chat
5745
6054
  onNewChat,
5746
6055
  threads,
@@ -5756,6 +6065,8 @@ function ChatComponent({
5756
6065
  onStop,
5757
6066
  attachmentsEnabled,
5758
6067
  placeholder,
6068
+ messages,
6069
+ registeredTools,
5759
6070
  onNewChat,
5760
6071
  threads,
5761
6072
  currentThreadId,
@@ -5764,7 +6075,7 @@ function ChatComponent({
5764
6075
  isThreadBusy
5765
6076
  ]
5766
6077
  );
5767
- return /* @__PURE__ */ jsxRuntime.jsx(CopilotChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
6078
+ return /* @__PURE__ */ jsxRuntime.jsx(MessageActionsProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(CopilotChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
5768
6079
  "div",
5769
6080
  {
5770
6081
  className: cn(
@@ -5825,84 +6136,90 @@ function ChatComponent({
5825
6136
  className: cn("gap-4 p-4", classNames.messageList),
5826
6137
  children: [
5827
6138
  messages.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center text-muted-foreground", children: welcomeMessage || "Send a message to start the conversation" }),
5828
- messages.map((message, index) => {
5829
- const isLastMessage = index === messages.length - 1;
5830
- const GROUP_THRESHOLD_MS = 5 * 60 * 1e3;
5831
- const shouldHideAvatar = (() => {
5832
- if (!groupConsecutiveMessages || index === 0)
5833
- return false;
5834
- let prevIdx = index - 1;
5835
- while (prevIdx >= 0) {
5836
- const prev = messages[prevIdx];
5837
- const isToolMsg = prev.role === "tool";
5838
- const isInvisibleSystem = prev.role === "system" && // eslint-disable-next-line @typescript-eslint/no-explicit-any
5839
- prev.metadata?.type !== "compaction-marker";
5840
- if (!isToolMsg && !isInvisibleSystem) break;
5841
- prevIdx--;
5842
- }
5843
- if (prevIdx < 0) return false;
5844
- const prevVisible = messages[prevIdx];
5845
- if (prevVisible.role !== message.role) return false;
5846
- const curTs = message.timestamp;
5847
- const prevTs = prevVisible.timestamp;
5848
- if (curTs && prevTs && curTs - prevTs > GROUP_THRESHOLD_MS)
5849
- return false;
5850
- return true;
5851
- })();
5852
- const isEmptyAssistant = message.role === "assistant" && !message.content?.trim();
5853
- const hasToolCalls = message.tool_calls && message.tool_calls.length > 0;
5854
- const hasToolExecutions = message.toolExecutions && message.toolExecutions.length > 0;
5855
- const hasPendingApprovals = message.toolExecutions?.some(
5856
- (exec) => exec.approvalStatus === "required"
5857
- );
5858
- if (isEmptyAssistant) {
5859
- const shouldShowMessage = hasToolCalls || hasToolExecutions || hasPendingApprovals || isLastMessage && (isLoading || isProcessing);
5860
- if (!shouldShowMessage) {
5861
- return null;
6139
+ (() => {
6140
+ const messageElements = messages.map((message, index) => {
6141
+ const isLastMessage = index === messages.length - 1;
6142
+ const GROUP_THRESHOLD_MS = 5 * 60 * 1e3;
6143
+ const shouldHideAvatar = (() => {
6144
+ if (!groupConsecutiveMessages || index === 0)
6145
+ return false;
6146
+ let prevIdx = index - 1;
6147
+ while (prevIdx >= 0) {
6148
+ const prev = messages[prevIdx];
6149
+ const isToolMsg = prev.role === "tool";
6150
+ const isInvisibleSystem = prev.role === "system" && // eslint-disable-next-line @typescript-eslint/no-explicit-any
6151
+ prev.metadata?.type !== "compaction-marker";
6152
+ if (!isToolMsg && !isInvisibleSystem) break;
6153
+ prevIdx--;
6154
+ }
6155
+ if (prevIdx < 0) return false;
6156
+ const prevVisible = messages[prevIdx];
6157
+ if (prevVisible.role !== message.role) return false;
6158
+ const curTs = message.timestamp;
6159
+ const prevTs = prevVisible.timestamp;
6160
+ if (curTs && prevTs && curTs - prevTs > GROUP_THRESHOLD_MS)
6161
+ return false;
6162
+ return true;
6163
+ })();
6164
+ const isEmptyAssistant = message.role === "assistant" && !message.content?.trim();
6165
+ const hasToolCalls = message.tool_calls && message.tool_calls.length > 0;
6166
+ const hasToolExecutions = message.toolExecutions && message.toolExecutions.length > 0;
6167
+ const hasPendingApprovals = message.toolExecutions?.some(
6168
+ (exec) => exec.approvalStatus === "required"
6169
+ );
6170
+ if (isEmptyAssistant) {
6171
+ const shouldShowMessage = hasToolCalls || hasToolExecutions || hasPendingApprovals || isLastMessage && (isLoading || isProcessing);
6172
+ if (!shouldShowMessage) {
6173
+ return null;
6174
+ }
5862
6175
  }
5863
- }
5864
- const savedExecutions = message.metadata?.toolExecutions;
5865
- const messageToolExecutions = message.toolExecutions || savedExecutions;
5866
- const messageWithExecutions = messageToolExecutions ? { ...message, toolExecutions: messageToolExecutions } : message;
5867
- const handleFollowUpClick = (question) => {
5868
- if (onSuggestionClick) {
5869
- onSuggestionClick(question);
5870
- } else {
5871
- onSendMessage?.(question);
5872
- }
5873
- };
5874
- return renderMessage ? /* @__PURE__ */ jsxRuntime.jsx(React18__namespace.default.Fragment, { children: renderMessage(messageWithExecutions, index) }, message.id) : /* @__PURE__ */ jsxRuntime.jsx(
5875
- DefaultMessage,
5876
- {
5877
- message: messageWithExecutions,
5878
- userAvatar: shouldHideAvatar && message.role === "user" ? { ...userAvatar, className: "invisible" } : userAvatar,
5879
- assistantAvatar: shouldHideAvatar && message.role === "assistant" ? { ...assistantAvatar, className: "invisible" } : assistantAvatar,
5880
- showUserAvatar,
5881
- userMessageClassName: classNames.userMessage,
5882
- assistantMessageClassName: classNames.assistantMessage,
5883
- size: fontSize,
5884
- isLastMessage,
5885
- isLoading,
5886
- isProcessing,
5887
- loaderVariant,
5888
- registeredTools,
5889
- toolRenderers,
5890
- mcpToolRenderer,
5891
- fallbackToolRenderer,
5892
- onApproveToolExecution,
5893
- onRejectToolExecution,
5894
- showFollowUps,
5895
- onFollowUpClick: handleFollowUpClick,
5896
- followUpClassName,
5897
- followUpButtonClassName,
5898
- citations: citations === false ? { enabled: false } : citations,
5899
- branchInfo: message.role === "user" ? getBranchInfo?.(message.id) ?? null : null,
5900
- onSwitchBranch,
5901
- onEditMessage
5902
- },
5903
- message.id
5904
- );
5905
- }),
6176
+ const savedExecutions = message.metadata?.toolExecutions;
6177
+ const messageToolExecutions = message.toolExecutions || savedExecutions;
6178
+ const messageWithExecutions = messageToolExecutions ? {
6179
+ ...message,
6180
+ toolExecutions: messageToolExecutions
6181
+ } : message;
6182
+ const handleFollowUpClick = (question) => {
6183
+ if (onSuggestionClick) {
6184
+ onSuggestionClick(question);
6185
+ } else {
6186
+ onSendMessage?.(question);
6187
+ }
6188
+ };
6189
+ return renderMessage ? /* @__PURE__ */ jsxRuntime.jsx(React19__namespace.default.Fragment, { children: renderMessage(messageWithExecutions, index) }, message.id) : /* @__PURE__ */ jsxRuntime.jsx(
6190
+ DefaultMessage,
6191
+ {
6192
+ message: messageWithExecutions,
6193
+ userAvatar: shouldHideAvatar && message.role === "user" ? { ...userAvatar, className: "invisible" } : userAvatar,
6194
+ assistantAvatar: shouldHideAvatar && message.role === "assistant" ? { ...assistantAvatar, className: "invisible" } : assistantAvatar,
6195
+ showUserAvatar,
6196
+ userMessageClassName: classNames.userMessage,
6197
+ assistantMessageClassName: classNames.assistantMessage,
6198
+ size: fontSize,
6199
+ isLastMessage,
6200
+ isLoading,
6201
+ isProcessing,
6202
+ loaderVariant,
6203
+ registeredTools,
6204
+ toolRenderers,
6205
+ mcpToolRenderer,
6206
+ fallbackToolRenderer,
6207
+ onApproveToolExecution,
6208
+ onRejectToolExecution,
6209
+ showFollowUps,
6210
+ onFollowUpClick: handleFollowUpClick,
6211
+ followUpClassName,
6212
+ followUpButtonClassName,
6213
+ citations: citations === false ? { enabled: false } : citations,
6214
+ branchInfo: message.role === "user" ? getBranchInfo?.(message.id) ?? null : null,
6215
+ onSwitchBranch,
6216
+ onEditMessage
6217
+ },
6218
+ message.id
6219
+ );
6220
+ });
6221
+ return messageView?.children ? messageView.children({ messages, messageElements }) : messageElements;
6222
+ })(),
5906
6223
  isLoading && !isProcessing && messages.length > 0 && messages[messages.length - 1]?.role === "user" && /* @__PURE__ */ jsxRuntime.jsx(
5907
6224
  DefaultMessage,
5908
6225
  {
@@ -6052,7 +6369,7 @@ function ChatComponent({
6052
6369
  rootFooter
6053
6370
  ]
6054
6371
  }
6055
- ) });
6372
+ ) }) });
6056
6373
  }
6057
6374
  var Chat = Object.assign(ChatComponent, {
6058
6375
  Root: ChatComponent,
@@ -6068,9 +6385,34 @@ var Chat = Object.assign(ChatComponent, {
6068
6385
  Suggestions: SuggestionsCompound,
6069
6386
  BackButton,
6070
6387
  // Navigation: start new chat
6071
- ThreadPicker: ThreadPickerCompound
6388
+ ThreadPicker: ThreadPickerCompound,
6072
6389
  // Thread switching
6390
+ // Message actions compound components
6391
+ MessageActions: MessageActions2,
6392
+ CopyAction,
6393
+ EditAction,
6394
+ FeedbackAction,
6395
+ Action
6073
6396
  });
6397
+ function MessageList({ children, className }) {
6398
+ const { messages, registeredTools } = useCopilotChatContext();
6399
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: messages.map((message, index) => {
6400
+ if (children) {
6401
+ return /* @__PURE__ */ jsxRuntime.jsx(React19__namespace.Fragment, { children: children(message, index) }, message.id);
6402
+ }
6403
+ return /* @__PURE__ */ jsxRuntime.jsx(
6404
+ DefaultMessage,
6405
+ {
6406
+ message,
6407
+ userAvatar: { fallback: "U" },
6408
+ assistantAvatar: { fallback: "AI" },
6409
+ registeredTools,
6410
+ isLastMessage: index === messages.length - 1
6411
+ },
6412
+ message.id
6413
+ );
6414
+ }) });
6415
+ }
6074
6416
  function ToolExecutionMessage({
6075
6417
  executions,
6076
6418
  assistantAvatar = { fallback: "AI" },
@@ -6214,14 +6556,15 @@ function useInternalThreadManager(config = {}) {
6214
6556
  adapter,
6215
6557
  saveDebounce = 1e3,
6216
6558
  autoRestoreLastThread = true,
6217
- onThreadChange
6559
+ onThreadChange,
6560
+ enabled = true
6218
6561
  } = config;
6219
6562
  const threadManagerConfig = {
6220
6563
  adapter,
6221
6564
  saveDebounce,
6222
6565
  autoRestoreLastThread
6223
6566
  };
6224
- const threadManager = chunkIXWNDR7H_cjs.useThreadManager(threadManagerConfig);
6567
+ const threadManager = chunkTCPAT3WG_cjs.useThreadManager(threadManagerConfig);
6225
6568
  const {
6226
6569
  currentThread,
6227
6570
  currentThreadId,
@@ -6231,18 +6574,18 @@ function useInternalThreadManager(config = {}) {
6231
6574
  clearCurrentThread,
6232
6575
  refreshThreads
6233
6576
  } = threadManager;
6234
- const { messages, setMessages, status, isLoading, getAllMessages } = chunkIXWNDR7H_cjs.useCopilot();
6235
- const isLoadingMessagesRef = React18.useRef(false);
6236
- const savingToThreadRef = React18.useRef(null);
6237
- const lastSavedSnapshotRef = React18.useRef("");
6238
- const hasInitializedRef = React18.useRef(false);
6239
- const getMessageSnapshot = React18.useCallback((msgs) => {
6577
+ const { messages, setMessages, status, isLoading, getAllMessages } = chunkTCPAT3WG_cjs.useCopilot();
6578
+ const isLoadingMessagesRef = React19.useRef(false);
6579
+ const savingToThreadRef = React19.useRef(null);
6580
+ const lastSavedSnapshotRef = React19.useRef("");
6581
+ const hasInitializedRef = React19.useRef(false);
6582
+ const getMessageSnapshot = React19.useCallback((msgs) => {
6240
6583
  return msgs.map((m) => {
6241
6584
  const contentPreview = (m.content ?? "").slice(0, 20);
6242
6585
  return `${m.id}:${contentPreview}:${m.content?.length ?? 0}`;
6243
6586
  }).join("|");
6244
6587
  }, []);
6245
- const convertToCore = React18.useCallback((msgs) => {
6588
+ const convertToCore = React19.useCallback((msgs) => {
6246
6589
  return msgs.map((m) => ({
6247
6590
  id: m.id,
6248
6591
  role: m.role,
@@ -6260,7 +6603,7 @@ function useInternalThreadManager(config = {}) {
6260
6603
  }
6261
6604
  }));
6262
6605
  }, []);
6263
- const handleSwitchThread = React18.useCallback(
6606
+ const handleSwitchThread = React19.useCallback(
6264
6607
  async (threadId) => {
6265
6608
  isLoadingMessagesRef.current = true;
6266
6609
  const thread = await switchThread(threadId);
@@ -6291,7 +6634,7 @@ function useInternalThreadManager(config = {}) {
6291
6634
  },
6292
6635
  [switchThread, setMessages, getMessageSnapshot, onThreadChange]
6293
6636
  );
6294
- const handleNewThread = React18.useCallback(async () => {
6637
+ const handleNewThread = React19.useCallback(async () => {
6295
6638
  isLoadingMessagesRef.current = true;
6296
6639
  clearCurrentThread();
6297
6640
  lastSavedSnapshotRef.current = "";
@@ -6302,7 +6645,8 @@ function useInternalThreadManager(config = {}) {
6302
6645
  isLoadingMessagesRef.current = false;
6303
6646
  });
6304
6647
  }, [clearCurrentThread, setMessages, onThreadChange]);
6305
- React18.useEffect(() => {
6648
+ React19.useEffect(() => {
6649
+ if (!enabled) return;
6306
6650
  if (hasInitializedRef.current || !currentThread) {
6307
6651
  return;
6308
6652
  }
@@ -6334,8 +6678,9 @@ function useInternalThreadManager(config = {}) {
6334
6678
  requestAnimationFrame(() => {
6335
6679
  isLoadingMessagesRef.current = false;
6336
6680
  });
6337
- }, [adapter, currentThread, setMessages, getMessageSnapshot, onThreadChange]);
6338
- React18.useEffect(() => {
6681
+ }, [enabled, adapter, currentThread, setMessages, getMessageSnapshot, onThreadChange]);
6682
+ React19.useEffect(() => {
6683
+ if (!enabled) return;
6339
6684
  if (isLoadingMessagesRef.current) {
6340
6685
  return;
6341
6686
  }
@@ -6368,6 +6713,7 @@ function useInternalThreadManager(config = {}) {
6368
6713
  updateCurrentThread({ messages: coreMessages });
6369
6714
  lastSavedSnapshotRef.current = currentSnapshot;
6370
6715
  }, [
6716
+ enabled,
6371
6717
  adapter,
6372
6718
  messages,
6373
6719
  currentThreadId,
@@ -6408,7 +6754,7 @@ function parsePersistenceConfig(persistence, onThreadChange) {
6408
6754
  };
6409
6755
  case "server":
6410
6756
  return {
6411
- adapter: chunkI3SQUNTT_cjs.createServerAdapter({
6757
+ adapter: chunkWIXFZUEZ_cjs.createServerAdapter({
6412
6758
  endpoint: persistence.endpoint,
6413
6759
  headers: persistence.headers
6414
6760
  }),
@@ -6446,7 +6792,7 @@ function CopilotChatBase(props) {
6446
6792
  } = props;
6447
6793
  const persistenceConfig = parsePersistenceConfig(persistence, onThreadChange);
6448
6794
  const threadManagerResult = useInternalThreadManager(
6449
- persistenceConfig ?? { autoRestoreLastThread: false }
6795
+ persistenceConfig ?? { autoRestoreLastThread: false, enabled: false }
6450
6796
  );
6451
6797
  const isPersistenceEnabled = !!persistence;
6452
6798
  const {
@@ -6461,7 +6807,7 @@ function CopilotChatBase(props) {
6461
6807
  switchBranch,
6462
6808
  getBranchInfo,
6463
6809
  editMessage
6464
- } = chunkIXWNDR7H_cjs.useCopilot();
6810
+ } = chunkTCPAT3WG_cjs.useCopilot();
6465
6811
  const toolExecutions = rawToolExecutions.map(
6466
6812
  (exec) => ({
6467
6813
  id: exec.id,
@@ -6472,6 +6818,8 @@ function CopilotChatBase(props) {
6472
6818
  error: exec.error,
6473
6819
  timestamp: exec.startedAt ? exec.startedAt.getTime() : Date.now(),
6474
6820
  approvalStatus: exec.approvalStatus,
6821
+ approvalTitle: exec.approvalTitle,
6822
+ approvalMessage: exec.approvalMessage,
6475
6823
  hidden: exec.hidden
6476
6824
  })
6477
6825
  );
@@ -6613,7 +6961,7 @@ function CopilotChatBase(props) {
6613
6961
  footer: classNames.footer
6614
6962
  } : void 0;
6615
6963
  const { threadManager, handleSwitchThread, handleNewThread, isBusy } = threadManagerResult;
6616
- const handleDeleteThread = React18__namespace.default.useCallback(
6964
+ const handleDeleteThread = React19__namespace.default.useCallback(
6617
6965
  (threadId) => {
6618
6966
  const isCurrentThread = threadManager.currentThreadId === threadId;
6619
6967
  threadManager.deleteThread(threadId);
@@ -6741,6 +7089,38 @@ function PoweredBy({ className, showLogo = true }) {
6741
7089
  );
6742
7090
  }
6743
7091
 
7092
+ // src/ui/index.ts
7093
+ var ChatPrimitives = {
7094
+ // ── List ──────────────────────────────────────────────
7095
+ /** Renders the message list via render-prop. Falls back to DefaultMessage if no children. */
7096
+ MessageList,
7097
+ // ── Messages ──────────────────────────────────────────
7098
+ /** Full SDK message bubble (user + assistant + tools). Use as fallback inside MessageList. */
7099
+ DefaultMessage,
7100
+ /** Low-level message row wrapper (flex layout + avatar slot) */
7101
+ Message,
7102
+ /** Message avatar — image with fallback text/icon */
7103
+ MessageAvatar,
7104
+ /** Message content bubble — supports markdown */
7105
+ MessageContent,
7106
+ /** Action bar below a message (copy, feedback, etc.) */
7107
+ MessageActions,
7108
+ /** Single action button with tooltip inside MessageActions */
7109
+ MessageAction,
7110
+ // ── Layout ────────────────────────────────────────────
7111
+ /** Chat header bar with title and controls */
7112
+ Header: ChatHeader,
7113
+ /** Welcome screen shown when there are no messages */
7114
+ Welcome: ChatWelcome,
7115
+ /** Chat input / composer */
7116
+ Input: PromptInput,
7117
+ /** Scroll anchor — keeps the view pinned to the latest message */
7118
+ ScrollAnchor: ChatContainerScrollAnchor,
7119
+ // ── Indicators ────────────────────────────────────────
7120
+ /** Loading / streaming indicator (dots, wave, typing variants) */
7121
+ Loader
7122
+ };
7123
+
6744
7124
  exports.AlertTriangleIcon = AlertTriangleIcon;
6745
7125
  exports.BotIcon = BotIcon;
6746
7126
  exports.BranchNavigator = BranchNavigator;
@@ -6751,6 +7131,7 @@ exports.Chat = Chat;
6751
7131
  exports.ChatContainerContent = ChatContainerContent;
6752
7132
  exports.ChatContainerRoot = ChatContainerRoot;
6753
7133
  exports.ChatContainerScrollAnchor = ChatContainerScrollAnchor;
7134
+ exports.ChatPrimitives = ChatPrimitives;
6754
7135
  exports.ChatWelcome = ChatWelcome;
6755
7136
  exports.CheckIcon = CheckIcon;
6756
7137
  exports.ChevronDownIcon = ChevronDownIcon2;