@yourgpt/copilot-sdk 2.0.1 → 2.0.2-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/README.md +42 -0
  2. package/dist/{ThreadManager-JT0sqSSD.d.ts → ThreadManager-Dkp_eLty.d.ts} +1 -1
  3. package/dist/{ThreadManager-CUq5Ocu2.d.cts → ThreadManager-LfFRhr4e.d.cts} +1 -1
  4. package/dist/anthropic-6F5GRE3B.js +4 -0
  5. package/dist/anthropic-6F5GRE3B.js.map +1 -0
  6. package/dist/anthropic-DGalr_Fw.d.cts +17 -0
  7. package/dist/anthropic-DkCEDYOt.d.ts +17 -0
  8. package/dist/anthropic-NMTRABEH.cjs +21 -0
  9. package/dist/anthropic-NMTRABEH.cjs.map +1 -0
  10. package/dist/brave-DdnWb7Gb.d.cts +17 -0
  11. package/dist/brave-DsI9n7Wr.d.ts +17 -0
  12. package/dist/brave-OYKCOZEM.cjs +21 -0
  13. package/dist/brave-OYKCOZEM.cjs.map +1 -0
  14. package/dist/brave-XSASGGH2.js +4 -0
  15. package/dist/brave-XSASGGH2.js.map +1 -0
  16. package/dist/chunk-2FAWEBZS.cjs +88 -0
  17. package/dist/chunk-2FAWEBZS.cjs.map +1 -0
  18. package/dist/chunk-53UGJNHN.js +92 -0
  19. package/dist/chunk-53UGJNHN.js.map +1 -0
  20. package/dist/chunk-6T5XXJEP.cjs +80 -0
  21. package/dist/chunk-6T5XXJEP.cjs.map +1 -0
  22. package/dist/chunk-7K7HZMP4.cjs +1170 -0
  23. package/dist/chunk-7K7HZMP4.cjs.map +1 -0
  24. package/dist/chunk-7W7QLZNC.js +72 -0
  25. package/dist/chunk-7W7QLZNC.js.map +1 -0
  26. package/dist/{chunk-JM7PB2LP.js → chunk-7XFFRV7D.js} +10 -66
  27. package/dist/chunk-7XFFRV7D.js.map +1 -0
  28. package/dist/chunk-ASV6JLYG.cjs +99 -0
  29. package/dist/chunk-ASV6JLYG.cjs.map +1 -0
  30. package/dist/chunk-BH7MNDWW.js +1152 -0
  31. package/dist/chunk-BH7MNDWW.js.map +1 -0
  32. package/dist/chunk-BKO7DSPU.js +67 -0
  33. package/dist/chunk-BKO7DSPU.js.map +1 -0
  34. package/dist/chunk-CBAHCI4R.cjs +76 -0
  35. package/dist/chunk-CBAHCI4R.cjs.map +1 -0
  36. package/dist/chunk-CEKAYA2Q.cjs +74 -0
  37. package/dist/chunk-CEKAYA2Q.cjs.map +1 -0
  38. package/dist/chunk-CEOMTQTP.js +85 -0
  39. package/dist/chunk-CEOMTQTP.js.map +1 -0
  40. package/dist/chunk-DABZYCVX.js +84 -0
  41. package/dist/chunk-DABZYCVX.js.map +1 -0
  42. package/dist/chunk-DGUM43GV.js +10 -0
  43. package/dist/chunk-DGUM43GV.js.map +1 -0
  44. package/dist/chunk-G4SF2PNQ.js +33 -0
  45. package/dist/chunk-G4SF2PNQ.js.map +1 -0
  46. package/dist/chunk-GANCV72Z.cjs +110 -0
  47. package/dist/chunk-GANCV72Z.cjs.map +1 -0
  48. package/dist/{chunk-BLSI67J6.cjs → chunk-H5XMKBBA.cjs} +425 -30
  49. package/dist/chunk-H5XMKBBA.cjs.map +1 -0
  50. package/dist/{chunk-CJ7UWN2Y.js → chunk-IXFV6AW6.js} +397 -7
  51. package/dist/chunk-IXFV6AW6.js.map +1 -0
  52. package/dist/chunk-JEQ2X3Z6.cjs +12 -0
  53. package/dist/chunk-JEQ2X3Z6.cjs.map +1 -0
  54. package/dist/chunk-JO4BHPAD.cjs +40 -0
  55. package/dist/chunk-JO4BHPAD.cjs.map +1 -0
  56. package/dist/chunk-MEBXW75C.cjs +89 -0
  57. package/dist/chunk-MEBXW75C.cjs.map +1 -0
  58. package/dist/chunk-MNDGIW47.js +76 -0
  59. package/dist/chunk-MNDGIW47.js.map +1 -0
  60. package/dist/chunk-PPFHA6IL.js +83 -0
  61. package/dist/chunk-PPFHA6IL.js.map +1 -0
  62. package/dist/chunk-RQ74USYU.js +128 -0
  63. package/dist/chunk-RQ74USYU.js.map +1 -0
  64. package/dist/chunk-TXLIY7GF.cjs +132 -0
  65. package/dist/chunk-TXLIY7GF.cjs.map +1 -0
  66. package/dist/chunk-UIWFYMAO.cjs +82 -0
  67. package/dist/chunk-UIWFYMAO.cjs.map +1 -0
  68. package/dist/{chunk-4PRWNAXQ.cjs → chunk-UOWLKFXK.cjs} +27 -89
  69. package/dist/chunk-UOWLKFXK.cjs.map +1 -0
  70. package/dist/chunk-VD74IPKB.js +106 -0
  71. package/dist/chunk-VD74IPKB.js.map +1 -0
  72. package/dist/chunk-W73FBYIH.cjs +87 -0
  73. package/dist/chunk-W73FBYIH.cjs.map +1 -0
  74. package/dist/chunk-XGITAEXU.js +93 -0
  75. package/dist/chunk-XGITAEXU.js.map +1 -0
  76. package/dist/chunk-XWOHNY3F.cjs +96 -0
  77. package/dist/chunk-XWOHNY3F.cjs.map +1 -0
  78. package/dist/chunk-ZPYQDMUX.js +79 -0
  79. package/dist/chunk-ZPYQDMUX.js.map +1 -0
  80. package/dist/core/index.cjs +156 -84
  81. package/dist/core/index.d.cts +16 -4
  82. package/dist/core/index.d.ts +16 -4
  83. package/dist/core/index.js +13 -1
  84. package/dist/exa-72KFY5A7.cjs +21 -0
  85. package/dist/exa-72KFY5A7.cjs.map +1 -0
  86. package/dist/exa-Dp9U-WTc.d.ts +17 -0
  87. package/dist/exa-NNVPBC2M.js +4 -0
  88. package/dist/exa-NNVPBC2M.js.map +1 -0
  89. package/dist/exa-jJSPhyUW.d.cts +17 -0
  90. package/dist/google-CHU2yycE.d.cts +17 -0
  91. package/dist/google-CTEK6SV2.js +4 -0
  92. package/dist/google-CTEK6SV2.js.map +1 -0
  93. package/dist/google-Da8IQxaI.d.ts +17 -0
  94. package/dist/google-IIUXFFVF.cjs +21 -0
  95. package/dist/google-IIUXFFVF.cjs.map +1 -0
  96. package/dist/index-2VtgKM8S.d.cts +206 -0
  97. package/dist/index-pWEH7pUE.d.ts +206 -0
  98. package/dist/mcp/index.cjs +670 -0
  99. package/dist/mcp/index.cjs.map +1 -0
  100. package/dist/mcp/index.d.cts +779 -0
  101. package/dist/mcp/index.d.ts +779 -0
  102. package/dist/mcp/index.js +574 -0
  103. package/dist/mcp/index.js.map +1 -0
  104. package/dist/openai-6KTCQ7PZ.cjs +21 -0
  105. package/dist/openai-6KTCQ7PZ.cjs.map +1 -0
  106. package/dist/openai-7W2PCNW5.js +4 -0
  107. package/dist/openai-7W2PCNW5.js.map +1 -0
  108. package/dist/openai-Cam8hF4f.d.ts +17 -0
  109. package/dist/openai-HVSCuXgO.d.cts +17 -0
  110. package/dist/react/index.cjs +75 -42
  111. package/dist/react/index.d.cts +270 -45
  112. package/dist/react/index.d.ts +270 -45
  113. package/dist/react/index.js +15 -2
  114. package/dist/searxng-AXLVGY7Z.js +4 -0
  115. package/dist/searxng-AXLVGY7Z.js.map +1 -0
  116. package/dist/searxng-EJKNY236.cjs +21 -0
  117. package/dist/searxng-EJKNY236.cjs.map +1 -0
  118. package/dist/searxng-K0qtY9vp.d.ts +17 -0
  119. package/dist/searxng-QGOte_Gq.d.cts +17 -0
  120. package/dist/serper-3JYJHJX6.js +4 -0
  121. package/dist/serper-3JYJHJX6.js.map +1 -0
  122. package/dist/serper-63FT4AOL.cjs +21 -0
  123. package/dist/serper-63FT4AOL.cjs.map +1 -0
  124. package/dist/serper-7Czya3PW.d.ts +17 -0
  125. package/dist/serper-JzdaSnS9.d.cts +17 -0
  126. package/dist/styles.css +38 -0
  127. package/dist/tavily-AWFP4RM7.cjs +21 -0
  128. package/dist/tavily-AWFP4RM7.cjs.map +1 -0
  129. package/dist/tavily-C8cXXojE.d.cts +17 -0
  130. package/dist/tavily-CIWAAZPH.js +4 -0
  131. package/dist/tavily-CIWAAZPH.js.map +1 -0
  132. package/dist/tavily-DdSGVgkE.d.ts +17 -0
  133. package/dist/themes/catppuccin.css +2 -0
  134. package/dist/themes/claude.css +2 -0
  135. package/dist/themes/linear.css +2 -0
  136. package/dist/themes/modern-minimal.css +2 -0
  137. package/dist/themes/posthog.css +2 -0
  138. package/dist/themes/supabase.css +2 -0
  139. package/dist/themes/twitter.css +2 -0
  140. package/dist/themes/vercel.css +2 -0
  141. package/dist/tools/anthropic/index.cjs +61 -0
  142. package/dist/tools/anthropic/index.cjs.map +1 -0
  143. package/dist/tools/anthropic/index.d.cts +67 -0
  144. package/dist/tools/anthropic/index.d.ts +67 -0
  145. package/dist/tools/anthropic/index.js +56 -0
  146. package/dist/tools/anthropic/index.js.map +1 -0
  147. package/dist/tools/brave/index.cjs +85 -0
  148. package/dist/tools/brave/index.cjs.map +1 -0
  149. package/dist/tools/brave/index.d.cts +91 -0
  150. package/dist/tools/brave/index.d.ts +91 -0
  151. package/dist/tools/brave/index.js +80 -0
  152. package/dist/tools/brave/index.js.map +1 -0
  153. package/dist/tools/exa/index.cjs +90 -0
  154. package/dist/tools/exa/index.cjs.map +1 -0
  155. package/dist/tools/exa/index.d.cts +92 -0
  156. package/dist/tools/exa/index.d.ts +92 -0
  157. package/dist/tools/exa/index.js +85 -0
  158. package/dist/tools/exa/index.js.map +1 -0
  159. package/dist/tools/google/index.cjs +81 -0
  160. package/dist/tools/google/index.cjs.map +1 -0
  161. package/dist/tools/google/index.d.cts +81 -0
  162. package/dist/tools/google/index.d.ts +81 -0
  163. package/dist/tools/google/index.js +76 -0
  164. package/dist/tools/google/index.js.map +1 -0
  165. package/dist/tools/openai/index.cjs +83 -0
  166. package/dist/tools/openai/index.cjs.map +1 -0
  167. package/dist/tools/openai/index.d.cts +84 -0
  168. package/dist/tools/openai/index.d.ts +84 -0
  169. package/dist/tools/openai/index.js +78 -0
  170. package/dist/tools/openai/index.js.map +1 -0
  171. package/dist/tools/searxng/index.cjs +85 -0
  172. package/dist/tools/searxng/index.cjs.map +1 -0
  173. package/dist/tools/searxng/index.d.cts +91 -0
  174. package/dist/tools/searxng/index.d.ts +91 -0
  175. package/dist/tools/searxng/index.js +80 -0
  176. package/dist/tools/searxng/index.js.map +1 -0
  177. package/dist/tools/serper/index.cjs +85 -0
  178. package/dist/tools/serper/index.cjs.map +1 -0
  179. package/dist/tools/serper/index.d.cts +91 -0
  180. package/dist/tools/serper/index.d.ts +91 -0
  181. package/dist/tools/serper/index.js +80 -0
  182. package/dist/tools/serper/index.js.map +1 -0
  183. package/dist/tools/tavily/index.cjs +91 -0
  184. package/dist/tools/tavily/index.cjs.map +1 -0
  185. package/dist/tools/tavily/index.d.cts +95 -0
  186. package/dist/tools/tavily/index.d.ts +95 -0
  187. package/dist/tools/tavily/index.js +86 -0
  188. package/dist/tools/tavily/index.js.map +1 -0
  189. package/dist/tools/web-search/index.cjs +31 -0
  190. package/dist/tools/web-search/index.cjs.map +1 -0
  191. package/dist/tools/web-search/index.d.cts +3 -0
  192. package/dist/tools/web-search/index.d.ts +3 -0
  193. package/dist/tools/web-search/index.js +14 -0
  194. package/dist/tools/web-search/index.js.map +1 -0
  195. package/dist/{types-BtAaOV07.d.cts → tools-DDWrco4h.d.cts} +43 -367
  196. package/dist/{types-BtAaOV07.d.ts → tools-DDWrco4h.d.ts} +43 -367
  197. package/dist/types-B20VCJXL.d.cts +347 -0
  198. package/dist/types-B20VCJXL.d.ts +347 -0
  199. package/dist/types-Cizh9K_f.d.ts +441 -0
  200. package/dist/types-DG2ya08y.d.cts +367 -0
  201. package/dist/types-DG2ya08y.d.ts +367 -0
  202. package/dist/types-DjSfYNKj.d.cts +441 -0
  203. package/dist/types-ZguuKEs_.d.cts +127 -0
  204. package/dist/types-ZguuKEs_.d.ts +127 -0
  205. package/dist/ui/index.cjs +1075 -148
  206. package/dist/ui/index.cjs.map +1 -1
  207. package/dist/ui/index.d.cts +410 -4
  208. package/dist/ui/index.d.ts +410 -4
  209. package/dist/ui/index.js +1007 -96
  210. package/dist/ui/index.js.map +1 -1
  211. package/package.json +52 -2
  212. package/dist/chunk-4PRWNAXQ.cjs.map +0 -1
  213. package/dist/chunk-BLSI67J6.cjs.map +0 -1
  214. package/dist/chunk-CJ7UWN2Y.js.map +0 -1
  215. package/dist/chunk-JM7PB2LP.js.map +0 -1
package/dist/ui/index.cjs CHANGED
@@ -1,11 +1,25 @@
1
1
  'use strict';
2
2
 
3
- var chunkBLSI67J6_cjs = require('../chunk-BLSI67J6.cjs');
4
- var chunk4PRWNAXQ_cjs = require('../chunk-4PRWNAXQ.cjs');
3
+ var chunkH5XMKBBA_cjs = require('../chunk-H5XMKBBA.cjs');
4
+ var chunkUOWLKFXK_cjs = require('../chunk-UOWLKFXK.cjs');
5
+ var chunkJO4BHPAD_cjs = require('../chunk-JO4BHPAD.cjs');
6
+ require('../chunk-7K7HZMP4.cjs');
7
+ require('../chunk-UIWFYMAO.cjs');
8
+ require('../chunk-CEKAYA2Q.cjs');
9
+ require('../chunk-ASV6JLYG.cjs');
10
+ require('../chunk-CBAHCI4R.cjs');
11
+ require('../chunk-MEBXW75C.cjs');
12
+ require('../chunk-W73FBYIH.cjs');
13
+ require('../chunk-2FAWEBZS.cjs');
14
+ require('../chunk-6T5XXJEP.cjs');
15
+ require('../chunk-GANCV72Z.cjs');
16
+ require('../chunk-XWOHNY3F.cjs');
17
+ require('../chunk-TXLIY7GF.cjs');
18
+ require('../chunk-JEQ2X3Z6.cjs');
5
19
  var clsx = require('clsx');
6
20
  var tailwindMerge = require('tailwind-merge');
7
21
  var jsxRuntime = require('react/jsx-runtime');
8
- var React18 = require('react');
22
+ var React20 = require('react');
9
23
  var streamdown = require('streamdown');
10
24
  var code = require('@streamdown/code');
11
25
  var reactSlot = require('@radix-ui/react-slot');
@@ -14,6 +28,7 @@ var useStickToBottom = require('use-stick-to-bottom');
14
28
  var tooltip = require('@base-ui/react/tooltip');
15
29
  var AvatarPrimitive = require('@radix-ui/react-avatar');
16
30
  var HoverCardPrimitive = require('@radix-ui/react-hover-card');
31
+ var lucideReact = require('lucide-react');
17
32
  var popover = require('@base-ui/react/popover');
18
33
 
19
34
  function _interopNamespace(e) {
@@ -34,7 +49,7 @@ function _interopNamespace(e) {
34
49
  return Object.freeze(n);
35
50
  }
36
51
 
37
- var React18__namespace = /*#__PURE__*/_interopNamespace(React18);
52
+ var React20__namespace = /*#__PURE__*/_interopNamespace(React20);
38
53
  var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
39
54
  var HoverCardPrimitive__namespace = /*#__PURE__*/_interopNamespace(HoverCardPrimitive);
40
55
 
@@ -348,7 +363,7 @@ function MarkdownComponent({
348
363
  }
349
364
  ) });
350
365
  }
351
- var Markdown = React18.memo(MarkdownComponent);
366
+ var Markdown = React20.memo(MarkdownComponent);
352
367
  Markdown.displayName = "Markdown";
353
368
  function CodeBlock({ children, className, ...props }) {
354
369
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -389,7 +404,7 @@ var buttonVariants = classVarianceAuthority.cva(
389
404
  }
390
405
  }
391
406
  );
392
- var Button = React18__namespace.forwardRef(
407
+ var Button = React20__namespace.forwardRef(
393
408
  ({ className, variant, size, asChild = false, ...props }, ref) => {
394
409
  const Comp = asChild ? reactSlot.Slot : "button";
395
410
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -532,7 +547,7 @@ function ChatContainerRoot({
532
547
  return /* @__PURE__ */ jsxRuntime.jsx(
533
548
  StickToBottom,
534
549
  {
535
- className: cn("flex overflow-y-auto", className),
550
+ className: cn("min-h-0", className),
536
551
  resize: "smooth",
537
552
  initial: "instant",
538
553
  role: "log",
@@ -630,7 +645,7 @@ function TooltipTrigger({
630
645
  disabled,
631
646
  ...props
632
647
  }) {
633
- if (asChild && React18__namespace.default.isValidElement(children)) {
648
+ if (asChild && React20__namespace.default.isValidElement(children)) {
634
649
  return /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Trigger, { disabled, render: children, ...props });
635
650
  }
636
651
  return /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Trigger, { disabled, ...props, children });
@@ -659,7 +674,7 @@ function TooltipContent({
659
674
  }
660
675
  ) }) });
661
676
  }
662
- var Avatar = React18__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
677
+ var Avatar = React20__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
663
678
  AvatarPrimitive__namespace.Root,
664
679
  {
665
680
  ref,
@@ -671,7 +686,7 @@ var Avatar = React18__namespace.forwardRef(({ className, ...props }, ref) => /*
671
686
  }
672
687
  ));
673
688
  Avatar.displayName = AvatarPrimitive__namespace.Root.displayName;
674
- var AvatarImage = React18__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
689
+ var AvatarImage = React20__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
675
690
  AvatarPrimitive__namespace.Image,
676
691
  {
677
692
  ref,
@@ -680,7 +695,7 @@ var AvatarImage = React18__namespace.forwardRef(({ className, ...props }, ref) =
680
695
  }
681
696
  ));
682
697
  AvatarImage.displayName = AvatarPrimitive__namespace.Image.displayName;
683
- var AvatarFallback = React18__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
698
+ var AvatarFallback = React20__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
684
699
  AvatarPrimitive__namespace.Fallback,
685
700
  {
686
701
  ref,
@@ -723,7 +738,7 @@ var MessageContent = ({
723
738
  ...props
724
739
  }) => {
725
740
  const classNames = cn(
726
- "csdk-message-content rounded-lg p-2 break-words whitespace-normal max-w-none leading-relaxed",
741
+ "csdk-message-content rounded-lg p-2 break-words whitespace-normal max-w-full leading-relaxed overflow-x-auto overflow-y-hidden",
727
742
  // Typography - simple Tailwind utilities (no prose)
728
743
  "[&_p]:my-1 [&_p]:leading-relaxed",
729
744
  "[&_ul]:my-1 [&_ul]:pl-4 [&_ul]:list-disc [&_ul]:list-outside",
@@ -731,14 +746,16 @@ var MessageContent = ({
731
746
  "[&_li]:my-0.5 [&_li]:pl-0",
732
747
  "[&_pre]:my-2 [&_blockquote]:my-2 [&_blockquote]:pl-3 [&_blockquote]:border-l-2 [&_blockquote]:border-current/30",
733
748
  "[&_code]:bg-current/10 [&_code]:px-1 [&_code]:rounded [&_code]:text-[0.9em]",
734
- "[&_a]:underline",
749
+ "[&_a]:underline [&_a]:text-[var(--csdk-link-color)] [&_a]:[overflow-wrap:anywhere]",
750
+ "[&_button[data-streamdown='link']]:underline [&_button[data-streamdown='link']]:text-[var(--csdk-link-color)] [&_button[data-streamdown='link']]:[overflow-wrap:anywhere] [&_button[data-streamdown='link']]:font-medium",
751
+ "[&_.text-primary]:text-[var(--csdk-link-color)]",
735
752
  "[&_strong]:font-semibold",
736
753
  textSizeMap[size],
737
754
  className
738
755
  );
739
756
  return markdown ? /* @__PURE__ */ jsxRuntime.jsx(Markdown, { className: classNames, ...props, children }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames, ...props, children });
740
757
  };
741
- var Textarea = React18__namespace.forwardRef(({ className, ...props }, ref) => {
758
+ var Textarea = React20__namespace.forwardRef(({ className, ...props }, ref) => {
742
759
  return /* @__PURE__ */ jsxRuntime.jsx(
743
760
  "textarea",
744
761
  {
@@ -752,7 +769,7 @@ var Textarea = React18__namespace.forwardRef(({ className, ...props }, ref) => {
752
769
  );
753
770
  });
754
771
  Textarea.displayName = "Textarea";
755
- var PromptInputContext = React18.createContext({
772
+ var PromptInputContext = React20.createContext({
756
773
  isLoading: false,
757
774
  value: "",
758
775
  setValue: () => {
@@ -763,7 +780,7 @@ var PromptInputContext = React18.createContext({
763
780
  textareaRef: { current: null }
764
781
  });
765
782
  function usePromptInput() {
766
- return React18.useContext(PromptInputContext);
783
+ return React20.useContext(PromptInputContext);
767
784
  }
768
785
  function PromptInput({
769
786
  className,
@@ -777,8 +794,8 @@ function PromptInput({
777
794
  onClick,
778
795
  ...props
779
796
  }) {
780
- const [internalValue, setInternalValue] = React18.useState(value || "");
781
- const textareaRef = React18.useRef(null);
797
+ const [internalValue, setInternalValue] = React20.useState(value || "");
798
+ const textareaRef = React20.useRef(null);
782
799
  const handleChange = (newValue) => {
783
800
  setInternalValue(newValue);
784
801
  onValueChange?.(newValue);
@@ -835,7 +852,7 @@ function PromptInputTextarea({
835
852
  textareaRef.current = el;
836
853
  adjustHeight(el);
837
854
  };
838
- React18.useLayoutEffect(() => {
855
+ React20.useLayoutEffect(() => {
839
856
  if (!textareaRef.current || disableAutosize) return;
840
857
  const el = textareaRef.current;
841
858
  el.style.height = "auto";
@@ -902,23 +919,23 @@ function PromptInputAction({
902
919
  }
903
920
  var HoverCard = HoverCardPrimitive__namespace.Root;
904
921
  var HoverCardTrigger = HoverCardPrimitive__namespace.Trigger;
905
- var HoverCardContent = React18__namespace.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
922
+ var HoverCardContent = React20__namespace.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
906
923
  HoverCardPrimitive__namespace.Content,
907
924
  {
908
925
  ref,
909
926
  align,
910
927
  sideOffset,
911
928
  className: cn(
912
- "z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-hover-card-content-transform-origin]",
929
+ "z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
913
930
  className
914
931
  ),
915
932
  ...props
916
933
  }
917
934
  ));
918
935
  HoverCardContent.displayName = HoverCardPrimitive__namespace.Content.displayName;
919
- var SourceContext = React18.createContext(null);
936
+ var SourceContext = React20.createContext(null);
920
937
  function useSourceContext() {
921
- const ctx = React18.useContext(SourceContext);
938
+ const ctx = React20.useContext(SourceContext);
922
939
  if (!ctx) throw new Error("Source.* must be used inside <Source>");
923
940
  return ctx;
924
941
  }
@@ -945,8 +962,8 @@ function SourceTrigger({
945
962
  target: "_blank",
946
963
  rel: "noopener noreferrer",
947
964
  className: cn(
948
- "bg-muted text-muted-foreground hover:bg-muted-foreground/30 hover:text-primary inline-flex h-5 max-w-32 items-center gap-1 overflow-hidden rounded-full py-0 text-xs no-underline transition-colors duration-150",
949
- showFavicon ? "pr-2 pl-1" : "px-1",
965
+ "inline-flex h-7 items-center gap-1.5 rounded-full border border-border/50 bg-background px-2.5 text-xs text-foreground/80 no-underline shadow-sm transition-all duration-150",
966
+ "hover:bg-muted hover:border-border hover:shadow-md hover:text-foreground",
950
967
  className
951
968
  ),
952
969
  children: [
@@ -956,13 +973,13 @@ function SourceTrigger({
956
973
  src: `https://www.google.com/s2/favicons?sz=64&domain_url=${encodeURIComponent(
957
974
  href
958
975
  )}`,
959
- alt: "favicon",
960
- width: 14,
961
- height: 14,
962
- className: "size-3.5 rounded-full"
976
+ alt: "",
977
+ width: 16,
978
+ height: 16,
979
+ className: "size-4 rounded-full"
963
980
  }
964
981
  ),
965
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate tabular-nums text-center font-normal", children: labelToShow })
982
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate max-w-28 font-medium", children: labelToShow })
966
983
  ]
967
984
  }
968
985
  ) });
@@ -973,40 +990,627 @@ function SourceContent({
973
990
  className
974
991
  }) {
975
992
  const { href, domain } = useSourceContext();
976
- return /* @__PURE__ */ jsxRuntime.jsx(HoverCardContent, { className: cn("w-80 p-0 shadow-xs", className), children: /* @__PURE__ */ jsxRuntime.jsxs(
993
+ return /* @__PURE__ */ jsxRuntime.jsx(
994
+ HoverCardContent,
995
+ {
996
+ className: cn("w-80 p-0 shadow-lg border border-border/50", className),
997
+ sideOffset: 8,
998
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
999
+ "a",
1000
+ {
1001
+ href,
1002
+ target: "_blank",
1003
+ rel: "noopener noreferrer",
1004
+ className: "flex flex-col gap-2.5 p-4 hover:bg-muted/50 transition-colors rounded-lg",
1005
+ children: [
1006
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1007
+ /* @__PURE__ */ jsxRuntime.jsx(
1008
+ "img",
1009
+ {
1010
+ src: `https://www.google.com/s2/favicons?sz=64&domain_url=${encodeURIComponent(
1011
+ href
1012
+ )}`,
1013
+ alt: "",
1014
+ className: "size-5 rounded-full",
1015
+ width: 20,
1016
+ height: 20
1017
+ }
1018
+ ),
1019
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-foreground/70 truncate text-sm", children: domain.replace("www.", "") })
1020
+ ] }),
1021
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "line-clamp-2 text-sm font-semibold text-foreground", children: title }),
1022
+ description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground line-clamp-3 text-sm leading-relaxed", children: description })
1023
+ ]
1024
+ }
1025
+ )
1026
+ }
1027
+ );
1028
+ }
1029
+ function SourceGroup({
1030
+ sources,
1031
+ label,
1032
+ maxVisible = 5,
1033
+ showFavicon = true,
1034
+ numbered = false,
1035
+ className
1036
+ }) {
1037
+ if (!sources || sources.length === 0) return null;
1038
+ const visibleSources = sources.slice(0, maxVisible);
1039
+ const hiddenCount = sources.length - maxVisible;
1040
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-wrap items-center gap-2", className), children: [
1041
+ label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs font-medium", children: label }),
1042
+ visibleSources.map((source, index) => /* @__PURE__ */ jsxRuntime.jsxs(Source, { href: source.href, children: [
1043
+ /* @__PURE__ */ jsxRuntime.jsx(
1044
+ SourceTrigger,
1045
+ {
1046
+ label: numbered ? index + 1 : void 0,
1047
+ showFavicon
1048
+ }
1049
+ ),
1050
+ (source.title || source.description) && /* @__PURE__ */ jsxRuntime.jsx(
1051
+ SourceContent,
1052
+ {
1053
+ title: source.title || getDomain(source.href),
1054
+ description: source.description || source.href
1055
+ }
1056
+ )
1057
+ ] }, index)),
1058
+ hiddenCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground text-xs font-medium bg-muted px-2 py-1 rounded-full", children: [
1059
+ "+",
1060
+ hiddenCount,
1061
+ " more"
1062
+ ] })
1063
+ ] });
1064
+ }
1065
+ function SimpleSource({
1066
+ href,
1067
+ label,
1068
+ showFavicon = false,
1069
+ className
1070
+ }) {
1071
+ let domain = "";
1072
+ try {
1073
+ domain = new URL(href).hostname.replace("www.", "");
1074
+ } catch {
1075
+ domain = href;
1076
+ }
1077
+ const displayLabel = label ?? domain;
1078
+ return /* @__PURE__ */ jsxRuntime.jsxs(
977
1079
  "a",
978
1080
  {
979
1081
  href,
980
1082
  target: "_blank",
981
1083
  rel: "noopener noreferrer",
982
- className: "flex flex-col gap-2 p-3",
1084
+ className: cn(
1085
+ "bg-muted text-muted-foreground hover:bg-primary/20 hover:text-primary",
1086
+ "inline-flex h-5 items-center gap-1 rounded-full text-xs no-underline transition-colors",
1087
+ showFavicon ? "pr-2 pl-1" : "px-1.5",
1088
+ className
1089
+ ),
983
1090
  children: [
984
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
985
- /* @__PURE__ */ jsxRuntime.jsx(
986
- "img",
987
- {
988
- src: `https://www.google.com/s2/favicons?sz=64&domain_url=${encodeURIComponent(
989
- href
990
- )}`,
991
- alt: "favicon",
992
- className: "size-4 rounded-full",
993
- width: 16,
994
- height: 16
1091
+ showFavicon && /* @__PURE__ */ jsxRuntime.jsx(
1092
+ "img",
1093
+ {
1094
+ src: `https://www.google.com/s2/favicons?sz=64&domain_url=${encodeURIComponent(href)}`,
1095
+ alt: "",
1096
+ width: 14,
1097
+ height: 14,
1098
+ className: "size-3.5 rounded-full"
1099
+ }
1100
+ ),
1101
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate tabular-nums font-normal", children: displayLabel })
1102
+ ]
1103
+ }
1104
+ );
1105
+ }
1106
+ function getDomain(url) {
1107
+ try {
1108
+ return new URL(url).hostname.replace("www.", "");
1109
+ } catch {
1110
+ return url;
1111
+ }
1112
+ }
1113
+ function SearchResults({
1114
+ results,
1115
+ className,
1116
+ variant = "cards",
1117
+ maxResults,
1118
+ showScores = false,
1119
+ showDates = false
1120
+ }) {
1121
+ const displayResults = maxResults ? results.slice(0, maxResults) : results;
1122
+ if (displayResults.length === 0) {
1123
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-muted-foreground text-sm", className), children: "No results found" });
1124
+ }
1125
+ if (variant === "compact") {
1126
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-wrap gap-2", className), children: displayResults.map((result, i) => /* @__PURE__ */ jsxRuntime.jsx(SearchResultCompact, { result, index: i + 1 }, i)) });
1127
+ }
1128
+ if (variant === "list") {
1129
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", className), children: displayResults.map((result, i) => /* @__PURE__ */ jsxRuntime.jsx(
1130
+ SearchResultList,
1131
+ {
1132
+ result,
1133
+ index: i + 1,
1134
+ showScore: showScores,
1135
+ showDate: showDates
1136
+ },
1137
+ i
1138
+ )) });
1139
+ }
1140
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid gap-2", className), children: displayResults.map((result, i) => /* @__PURE__ */ jsxRuntime.jsx(
1141
+ SearchResultCard,
1142
+ {
1143
+ result,
1144
+ showScore: showScores,
1145
+ showDate: showDates
1146
+ },
1147
+ i
1148
+ )) });
1149
+ }
1150
+ function SearchResultCard({
1151
+ result,
1152
+ showScore,
1153
+ showDate
1154
+ }) {
1155
+ const domain = result.domain || getDomain2(result.url);
1156
+ return /* @__PURE__ */ jsxRuntime.jsx(
1157
+ "a",
1158
+ {
1159
+ href: result.url,
1160
+ target: "_blank",
1161
+ rel: "noopener noreferrer",
1162
+ className: "group block p-3 border rounded-lg hover:bg-muted/50 transition-colors",
1163
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
1164
+ /* @__PURE__ */ jsxRuntime.jsx(
1165
+ "img",
1166
+ {
1167
+ src: getFaviconUrl(result.url),
1168
+ alt: "",
1169
+ className: "w-5 h-5 mt-0.5 rounded-sm",
1170
+ width: 20,
1171
+ height: 20
1172
+ }
1173
+ ),
1174
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
1175
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-medium text-sm group-hover:text-primary truncate", children: result.title }),
1176
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-1 line-clamp-2", children: result.content }),
1177
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
1178
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground/60 truncate", children: domain }),
1179
+ showDate && result.publishedDate && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground/60", children: formatDate(result.publishedDate) }),
1180
+ showScore && result.score !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground/60", children: [
1181
+ (result.score * 100).toFixed(0),
1182
+ "% match"
1183
+ ] })
1184
+ ] })
1185
+ ] })
1186
+ ] })
1187
+ }
1188
+ );
1189
+ }
1190
+ function SearchResultList({
1191
+ result,
1192
+ index,
1193
+ showScore,
1194
+ showDate
1195
+ }) {
1196
+ const domain = result.domain || getDomain2(result.url);
1197
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1198
+ "a",
1199
+ {
1200
+ href: result.url,
1201
+ target: "_blank",
1202
+ rel: "noopener noreferrer",
1203
+ className: "group flex items-start gap-2 py-1.5 hover:bg-muted/30 rounded px-1 -mx-1 transition-colors",
1204
+ children: [
1205
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground/60 mt-0.5 w-4 text-right flex-shrink-0", children: [
1206
+ index,
1207
+ "."
1208
+ ] }),
1209
+ /* @__PURE__ */ jsxRuntime.jsx(
1210
+ "img",
1211
+ {
1212
+ src: getFaviconUrl(result.url),
1213
+ alt: "",
1214
+ className: "w-4 h-4 mt-0.5 rounded-sm flex-shrink-0",
1215
+ width: 16,
1216
+ height: 16
1217
+ }
1218
+ ),
1219
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
1220
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm group-hover:text-primary", children: result.title }),
1221
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground ml-2", children: domain }),
1222
+ showDate && result.publishedDate && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground/60 ml-2", children: formatDate(result.publishedDate) }),
1223
+ showScore && result.score !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground/60 ml-2", children: [
1224
+ "(",
1225
+ (result.score * 100).toFixed(0),
1226
+ "%)"
1227
+ ] })
1228
+ ] })
1229
+ ]
1230
+ }
1231
+ );
1232
+ }
1233
+ function SearchResultCompact({ result, index }) {
1234
+ const domain = result.domain || getDomain2(result.url);
1235
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1236
+ "a",
1237
+ {
1238
+ href: result.url,
1239
+ target: "_blank",
1240
+ rel: "noopener noreferrer",
1241
+ className: "inline-flex items-center gap-1.5 px-2 py-1 text-xs bg-muted hover:bg-muted/80 rounded-md transition-colors",
1242
+ title: result.title,
1243
+ children: [
1244
+ /* @__PURE__ */ jsxRuntime.jsx(
1245
+ "img",
1246
+ {
1247
+ src: getFaviconUrl(result.url),
1248
+ alt: "",
1249
+ className: "w-3.5 h-3.5 rounded-sm",
1250
+ width: 14,
1251
+ height: 14
1252
+ }
1253
+ ),
1254
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate max-w-[120px]", children: domain })
1255
+ ]
1256
+ }
1257
+ );
1258
+ }
1259
+ function SearchAnswer({ answer, className }) {
1260
+ return /* @__PURE__ */ jsxRuntime.jsx(
1261
+ "div",
1262
+ {
1263
+ className: cn(
1264
+ "p-3 bg-muted/50 rounded-lg border-l-2 border-primary/50",
1265
+ className
1266
+ ),
1267
+ children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: answer })
1268
+ }
1269
+ );
1270
+ }
1271
+ function SearchResultsWithAnswer({
1272
+ response,
1273
+ className,
1274
+ variant = "cards",
1275
+ showAnswer = true,
1276
+ maxResults
1277
+ }) {
1278
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-3", className), children: [
1279
+ showAnswer && response.answer && /* @__PURE__ */ jsxRuntime.jsx(SearchAnswer, { answer: response.answer }),
1280
+ /* @__PURE__ */ jsxRuntime.jsx(
1281
+ SearchResults,
1282
+ {
1283
+ results: response.results,
1284
+ variant,
1285
+ maxResults
1286
+ }
1287
+ ),
1288
+ response.searchTime && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground", children: [
1289
+ "Found ",
1290
+ response.results.length,
1291
+ " results in ",
1292
+ response.searchTime,
1293
+ "ms"
1294
+ ] })
1295
+ ] });
1296
+ }
1297
+ function getDomain2(url) {
1298
+ try {
1299
+ return new URL(url).hostname.replace("www.", "");
1300
+ } catch {
1301
+ return url;
1302
+ }
1303
+ }
1304
+ function getFaviconUrl(url) {
1305
+ try {
1306
+ const domain = new URL(url).hostname;
1307
+ return `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;
1308
+ } catch {
1309
+ return "";
1310
+ }
1311
+ }
1312
+ function formatDate(dateStr) {
1313
+ try {
1314
+ const date = new Date(dateStr);
1315
+ const now = /* @__PURE__ */ new Date();
1316
+ const diffMs = now.getTime() - date.getTime();
1317
+ const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
1318
+ if (diffDays === 0) return "Today";
1319
+ if (diffDays === 1) return "Yesterday";
1320
+ if (diffDays < 7) return `${diffDays} days ago`;
1321
+ if (diffDays < 30) return `${Math.floor(diffDays / 7)} weeks ago`;
1322
+ if (diffDays < 365) return `${Math.floor(diffDays / 30)} months ago`;
1323
+ return `${Math.floor(diffDays / 365)} years ago`;
1324
+ } catch {
1325
+ return dateStr;
1326
+ }
1327
+ }
1328
+ function CitationBadge({
1329
+ index,
1330
+ url,
1331
+ title,
1332
+ size = "sm",
1333
+ className,
1334
+ onClick
1335
+ }) {
1336
+ const sizeClasses = {
1337
+ sm: "text-[10px] min-w-[16px] h-4 px-1",
1338
+ md: "text-xs min-w-[20px] h-5 px-1.5"
1339
+ };
1340
+ const badge = /* @__PURE__ */ jsxRuntime.jsx(
1341
+ "span",
1342
+ {
1343
+ className: cn(
1344
+ "inline-flex items-center justify-center rounded font-medium",
1345
+ "bg-primary/10 text-primary hover:bg-primary/20",
1346
+ "cursor-pointer transition-colors",
1347
+ sizeClasses[size],
1348
+ className
1349
+ ),
1350
+ title,
1351
+ onClick,
1352
+ children: index
1353
+ }
1354
+ );
1355
+ if (url) {
1356
+ return /* @__PURE__ */ jsxRuntime.jsx(
1357
+ "a",
1358
+ {
1359
+ href: url,
1360
+ target: "_blank",
1361
+ rel: "noopener noreferrer",
1362
+ className: "inline-flex",
1363
+ children: badge
1364
+ }
1365
+ );
1366
+ }
1367
+ return badge;
1368
+ }
1369
+ function CitationSuperscript({
1370
+ index,
1371
+ url,
1372
+ title,
1373
+ className
1374
+ }) {
1375
+ const sup = /* @__PURE__ */ jsxRuntime.jsxs(
1376
+ "sup",
1377
+ {
1378
+ className: cn(
1379
+ "text-[10px] text-primary hover:underline cursor-pointer ml-0.5",
1380
+ className
1381
+ ),
1382
+ title,
1383
+ children: [
1384
+ "[",
1385
+ index,
1386
+ "]"
1387
+ ]
1388
+ }
1389
+ );
1390
+ if (url) {
1391
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href: url, target: "_blank", rel: "noopener noreferrer", children: sup });
1392
+ }
1393
+ return sup;
1394
+ }
1395
+ function SourcePill({
1396
+ citation,
1397
+ showIndex = true,
1398
+ className
1399
+ }) {
1400
+ const domain = citation.domain || getDomain3(citation.url);
1401
+ const favicon = citation.favicon || getFaviconUrl2(citation.url);
1402
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1403
+ "a",
1404
+ {
1405
+ href: citation.url,
1406
+ target: "_blank",
1407
+ rel: "noopener noreferrer",
1408
+ title: citation.title,
1409
+ className: cn(
1410
+ "inline-flex items-center gap-1.5 px-2 py-1 text-xs rounded-full",
1411
+ "bg-muted hover:bg-muted/80 transition-colors",
1412
+ "text-muted-foreground hover:text-foreground",
1413
+ className
1414
+ ),
1415
+ children: [
1416
+ showIndex && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-primary", children: citation.index }),
1417
+ /* @__PURE__ */ jsxRuntime.jsx(
1418
+ "img",
1419
+ {
1420
+ src: favicon,
1421
+ alt: "",
1422
+ className: "w-3.5 h-3.5 rounded-sm",
1423
+ width: 14,
1424
+ height: 14,
1425
+ onError: (e) => {
1426
+ e.target.style.display = "none";
995
1427
  }
996
- ),
997
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-primary truncate text-sm", children: domain.replace("www.", "") })
1428
+ }
1429
+ ),
1430
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate max-w-[100px]", children: domain })
1431
+ ]
1432
+ }
1433
+ );
1434
+ }
1435
+ function SourcesBar({
1436
+ citations,
1437
+ label = "Sources",
1438
+ maxVisible = 5,
1439
+ className
1440
+ }) {
1441
+ const visibleCitations = citations.slice(0, maxVisible);
1442
+ const hiddenCount = citations.length - maxVisible;
1443
+ if (citations.length === 0) return null;
1444
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-2", className), children: [
1445
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground flex items-center gap-1", children: [
1446
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { className: "w-3 h-3" }),
1447
+ label
1448
+ ] }),
1449
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 overflow-x-auto", children: [
1450
+ visibleCitations.map((citation) => /* @__PURE__ */ jsxRuntime.jsx(SourcePill, { citation }, citation.index)),
1451
+ hiddenCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground px-2", children: [
1452
+ "+",
1453
+ hiddenCount,
1454
+ " more"
1455
+ ] })
1456
+ ] })
1457
+ ] });
1458
+ }
1459
+ function SourcesCollapsible({
1460
+ citations,
1461
+ label = "Sources",
1462
+ defaultExpanded = false,
1463
+ className
1464
+ }) {
1465
+ const [expanded, setExpanded] = React20__namespace.useState(defaultExpanded);
1466
+ if (citations.length === 0) return null;
1467
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("border rounded-lg", className), children: [
1468
+ /* @__PURE__ */ jsxRuntime.jsxs(
1469
+ "button",
1470
+ {
1471
+ onClick: () => setExpanded(!expanded),
1472
+ className: "w-full flex items-center justify-between px-3 py-2 text-sm hover:bg-muted/50 transition-colors",
1473
+ children: [
1474
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2 text-muted-foreground", children: [
1475
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { className: "w-4 h-4" }),
1476
+ label,
1477
+ " (",
1478
+ citations.length,
1479
+ ")"
1480
+ ] }),
1481
+ expanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "w-4 h-4 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "w-4 h-4 text-muted-foreground" })
1482
+ ]
1483
+ }
1484
+ ),
1485
+ expanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pb-3 space-y-2", children: citations.map((citation) => /* @__PURE__ */ jsxRuntime.jsx(SourceItem, { citation }, citation.index)) })
1486
+ ] });
1487
+ }
1488
+ function SourceItem({ citation }) {
1489
+ const domain = citation.domain || getDomain3(citation.url);
1490
+ const favicon = citation.favicon || getFaviconUrl2(citation.url);
1491
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1492
+ "a",
1493
+ {
1494
+ href: citation.url,
1495
+ target: "_blank",
1496
+ rel: "noopener noreferrer",
1497
+ className: "flex items-start gap-3 p-2 rounded-md hover:bg-muted/50 transition-colors group",
1498
+ children: [
1499
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center justify-center w-5 h-5 rounded bg-primary/10 text-primary text-xs font-medium flex-shrink-0", children: citation.index }),
1500
+ /* @__PURE__ */ jsxRuntime.jsx(
1501
+ "img",
1502
+ {
1503
+ src: favicon,
1504
+ alt: "",
1505
+ className: "w-4 h-4 mt-0.5 rounded-sm flex-shrink-0",
1506
+ width: 16,
1507
+ height: 16,
1508
+ onError: (e) => {
1509
+ e.target.style.display = "none";
1510
+ }
1511
+ }
1512
+ ),
1513
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
1514
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium group-hover:text-primary truncate", children: citation.title }),
1515
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground truncate", children: domain })
998
1516
  ] }),
999
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "line-clamp-2 text-sm font-medium", children: title }),
1000
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground line-clamp-2 text-sm", children: description })
1517
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-3.5 h-3.5 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0" })
1001
1518
  ]
1002
1519
  }
1003
- ) });
1520
+ );
1004
1521
  }
1005
- var ReasoningContext = React18__namespace.createContext(
1522
+ function SourcesList({
1523
+ citations,
1524
+ className,
1525
+ compact = false
1526
+ }) {
1527
+ if (citations.length === 0) return null;
1528
+ if (compact) {
1529
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("text-xs text-muted-foreground", className), children: [
1530
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Sources: " }),
1531
+ citations.map((c, i) => /* @__PURE__ */ jsxRuntime.jsxs(React20__namespace.Fragment, { children: [
1532
+ /* @__PURE__ */ jsxRuntime.jsxs(
1533
+ "a",
1534
+ {
1535
+ href: c.url,
1536
+ target: "_blank",
1537
+ rel: "noopener noreferrer",
1538
+ className: "hover:text-primary hover:underline",
1539
+ children: [
1540
+ "[",
1541
+ c.index,
1542
+ "]"
1543
+ ]
1544
+ }
1545
+ ),
1546
+ i < citations.length - 1 && " "
1547
+ ] }, c.index))
1548
+ ] });
1549
+ }
1550
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-1", className), children: citations.map((citation) => /* @__PURE__ */ jsxRuntime.jsx(SourceItem, { citation }, citation.index)) });
1551
+ }
1552
+ function MessageWithCitations({
1553
+ children,
1554
+ citations,
1555
+ config = {},
1556
+ className
1557
+ }) {
1558
+ const { enabled = true, sourcesPosition = "bottom", maxVisible = 5 } = config;
1559
+ if (!enabled || citations.length === 0) {
1560
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children });
1561
+ }
1562
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-3", className), children: [
1563
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children }),
1564
+ sourcesPosition === "bottom" && /* @__PURE__ */ jsxRuntime.jsx(SourcesBar, { citations, maxVisible }),
1565
+ sourcesPosition === "collapsible" && /* @__PURE__ */ jsxRuntime.jsx(SourcesCollapsible, { citations })
1566
+ ] });
1567
+ }
1568
+ function getDomain3(url) {
1569
+ try {
1570
+ return new URL(url).hostname.replace("www.", "");
1571
+ } catch {
1572
+ return url;
1573
+ }
1574
+ }
1575
+ function getFaviconUrl2(url) {
1576
+ try {
1577
+ const domain = new URL(url).hostname;
1578
+ return `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;
1579
+ } catch {
1580
+ return "";
1581
+ }
1582
+ }
1583
+ function annotationsToCitations(annotations) {
1584
+ const seen = /* @__PURE__ */ new Set();
1585
+ const citations = [];
1586
+ for (const annotation of annotations) {
1587
+ if (annotation.type === "url_citation" && annotation.url) {
1588
+ if (!seen.has(annotation.url)) {
1589
+ seen.add(annotation.url);
1590
+ citations.push({
1591
+ index: citations.length + 1,
1592
+ url: annotation.url,
1593
+ title: annotation.title || getDomain3(annotation.url),
1594
+ domain: getDomain3(annotation.url)
1595
+ });
1596
+ }
1597
+ }
1598
+ }
1599
+ return citations;
1600
+ }
1601
+ function resultsToCitations(results) {
1602
+ return results.map((result, index) => ({
1603
+ index: index + 1,
1604
+ url: result.url,
1605
+ title: result.title,
1606
+ domain: result.domain || getDomain3(result.url)
1607
+ }));
1608
+ }
1609
+ var ReasoningContext = React20__namespace.createContext(
1006
1610
  null
1007
1611
  );
1008
1612
  function useReasoningContext() {
1009
- const context = React18__namespace.useContext(ReasoningContext);
1613
+ const context = React20__namespace.useContext(ReasoningContext);
1010
1614
  if (!context) {
1011
1615
  throw new Error(
1012
1616
  "Reasoning components must be used within a Reasoning provider"
@@ -1022,11 +1626,11 @@ function Reasoning({
1022
1626
  defaultOpen = false,
1023
1627
  className
1024
1628
  }) {
1025
- const [uncontrolledOpen, setUncontrolledOpen] = React18__namespace.useState(defaultOpen);
1026
- const prevStreamingRef = React18__namespace.useRef(isStreaming);
1629
+ const [uncontrolledOpen, setUncontrolledOpen] = React20__namespace.useState(defaultOpen);
1630
+ const prevStreamingRef = React20__namespace.useRef(isStreaming);
1027
1631
  const isControlled = controlledOpen !== void 0;
1028
1632
  const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
1029
- const setIsOpen = React18__namespace.useCallback(
1633
+ const setIsOpen = React20__namespace.useCallback(
1030
1634
  (open) => {
1031
1635
  if (onOpenChange) {
1032
1636
  onOpenChange(open);
@@ -1037,7 +1641,7 @@ function Reasoning({
1037
1641
  },
1038
1642
  [isControlled, onOpenChange]
1039
1643
  );
1040
- React18__namespace.useEffect(() => {
1644
+ React20__namespace.useEffect(() => {
1041
1645
  if (isStreaming && !prevStreamingRef.current) {
1042
1646
  setIsOpen(true);
1043
1647
  } else if (!isStreaming && prevStreamingRef.current) {
@@ -1093,9 +1697,9 @@ function ReasoningContent({
1093
1697
  className
1094
1698
  }) {
1095
1699
  const { isOpen } = useReasoningContext();
1096
- const contentRef = React18__namespace.useRef(null);
1097
- const [height, setHeight] = React18__namespace.useState(0);
1098
- React18__namespace.useEffect(() => {
1700
+ const contentRef = React20__namespace.useRef(null);
1701
+ const [height, setHeight] = React20__namespace.useState(0);
1702
+ React20__namespace.useEffect(() => {
1099
1703
  if (contentRef.current) {
1100
1704
  const resizeObserver = new ResizeObserver((entries) => {
1101
1705
  for (const entry of entries) {
@@ -1144,11 +1748,11 @@ function SimpleReasoning({
1144
1748
  /* @__PURE__ */ jsxRuntime.jsx(ReasoningContent, { markdown, children: content })
1145
1749
  ] });
1146
1750
  }
1147
- var CopilotUIContext = React18__namespace.createContext(
1751
+ var CopilotUIContext = React20__namespace.createContext(
1148
1752
  null
1149
1753
  );
1150
1754
  function useCopilotUI() {
1151
- const context = React18__namespace.useContext(CopilotUIContext);
1755
+ const context = React20__namespace.useContext(CopilotUIContext);
1152
1756
  if (!context) {
1153
1757
  return {
1154
1758
  debug: false,
@@ -1163,7 +1767,7 @@ function CopilotUIProvider({
1163
1767
  debug = false,
1164
1768
  defaultDebugExpanded = false
1165
1769
  }) {
1166
- const value = React18__namespace.useMemo(
1770
+ const value = React20__namespace.useMemo(
1167
1771
  () => ({
1168
1772
  debug,
1169
1773
  defaultDebugExpanded,
@@ -1174,6 +1778,7 @@ function CopilotUIProvider({
1174
1778
  return /* @__PURE__ */ jsxRuntime.jsx(CopilotUIContext.Provider, { value, children });
1175
1779
  }
1176
1780
  function toolNameToTitle(name) {
1781
+ if (!name) return "Tool";
1177
1782
  let result = name.replace(/_/g, " ");
1178
1783
  result = result.replace(/([a-z])([A-Z])/g, "$1 $2");
1179
1784
  return result.charAt(0).toUpperCase() + result.slice(1).toLowerCase();
@@ -1305,7 +1910,7 @@ function ToolStep({
1305
1910
  }) {
1306
1911
  const { isDebug, defaultDebugExpanded } = useCopilotUI();
1307
1912
  const debug = debugProp ?? isDebug;
1308
- const [expanded, setExpanded] = React18__namespace.useState(
1913
+ const [expanded, setExpanded] = React20__namespace.useState(
1309
1914
  defaultExpanded ?? defaultDebugExpanded ?? false
1310
1915
  );
1311
1916
  const displayTitle = getDisplayTitle(step);
@@ -1786,9 +2391,9 @@ function ArrowUpRightIcon({ className }) {
1786
2391
  }
1787
2392
  );
1788
2393
  }
1789
- var ConfirmationContext = React18__namespace.createContext(null);
2394
+ var ConfirmationContext = React20__namespace.createContext(null);
1790
2395
  function useConfirmationContext() {
1791
- const context = React18__namespace.useContext(ConfirmationContext);
2396
+ const context = React20__namespace.useContext(ConfirmationContext);
1792
2397
  if (!context) {
1793
2398
  throw new Error(
1794
2399
  "Confirmation components must be used within a Confirmation provider"
@@ -1960,8 +2565,8 @@ function PermissionConfirmation({
1960
2565
  permissionOptions = DEFAULT_PERMISSION_OPTIONS,
1961
2566
  className
1962
2567
  }) {
1963
- const [selectedPermission, setSelectedPermission] = React18__namespace.useState("ask");
1964
- const [showOptions, setShowOptions] = React18__namespace.useState(false);
2568
+ const [selectedPermission, setSelectedPermission] = React20__namespace.useState("ask");
2569
+ const [showOptions, setShowOptions] = React20__namespace.useState(false);
1965
2570
  const handleApprove = () => {
1966
2571
  onApprove?.(selectedPermission);
1967
2572
  };
@@ -2091,7 +2696,7 @@ function CompactPermissionConfirmation({
2091
2696
  onReject,
2092
2697
  className
2093
2698
  }) {
2094
- const [rememberChoice, setRememberChoice] = React18__namespace.useState(false);
2699
+ const [rememberChoice, setRememberChoice] = React20__namespace.useState(false);
2095
2700
  const handleApprove = () => {
2096
2701
  onApprove?.(rememberChoice ? "allow_always" : "ask");
2097
2702
  };
@@ -2208,8 +2813,8 @@ function DevLogger({
2208
2813
  position = "bottom-right",
2209
2814
  className
2210
2815
  }) {
2211
- const [isOpen, setIsOpen] = React18.useState(false);
2212
- const [activeTab, setActiveTab] = React18.useState("chat");
2816
+ const [isOpen, setIsOpen] = React20.useState(false);
2817
+ const [activeTab, setActiveTab] = React20.useState("chat");
2213
2818
  const positionClasses = {
2214
2819
  "bottom-left": "bottom-4 left-4",
2215
2820
  "bottom-right": "bottom-4 right-4",
@@ -2634,9 +3239,9 @@ function ModelSelector({
2634
3239
  showCapabilities = true,
2635
3240
  className
2636
3241
  }) {
2637
- const [isOpen, setIsOpen] = React18__namespace.useState(false);
2638
- const containerRef = React18__namespace.useRef(null);
2639
- React18__namespace.useEffect(() => {
3242
+ const [isOpen, setIsOpen] = React20__namespace.useState(false);
3243
+ const containerRef = React20__namespace.useRef(null);
3244
+ React20__namespace.useEffect(() => {
2640
3245
  function handleClickOutside(event) {
2641
3246
  if (containerRef.current && !containerRef.current.contains(event.target)) {
2642
3247
  setIsOpen(false);
@@ -2645,7 +3250,7 @@ function ModelSelector({
2645
3250
  document.addEventListener("mousedown", handleClickOutside);
2646
3251
  return () => document.removeEventListener("mousedown", handleClickOutside);
2647
3252
  }, []);
2648
- const selectedModel = React18__namespace.useMemo(() => {
3253
+ const selectedModel = React20__namespace.useMemo(() => {
2649
3254
  if (!value) return null;
2650
3255
  if (providers) {
2651
3256
  for (const provider of providers) {
@@ -2871,7 +3476,7 @@ function PopoverTrigger({
2871
3476
  className,
2872
3477
  ...props
2873
3478
  }) {
2874
- if (asChild && React18__namespace.isValidElement(children)) {
3479
+ if (asChild && React20__namespace.isValidElement(children)) {
2875
3480
  return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Trigger, { render: children, className, ...props });
2876
3481
  }
2877
3482
  return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Trigger, { className, ...props, children });
@@ -2899,7 +3504,7 @@ function PopoverContent({
2899
3504
  }
2900
3505
  ) }) });
2901
3506
  }
2902
- function formatDate(date) {
3507
+ function formatDate2(date) {
2903
3508
  const now = /* @__PURE__ */ new Date();
2904
3509
  const diff = now.getTime() - date.getTime();
2905
3510
  if (diff < 60 * 1e3) {
@@ -3006,8 +3611,8 @@ function ThreadPicker({
3006
3611
  itemClassName,
3007
3612
  newButtonClassName
3008
3613
  }) {
3009
- const [isOpen, setIsOpen] = React18__namespace.useState(false);
3010
- const selectedThread = React18__namespace.useMemo(() => {
3614
+ const [isOpen, setIsOpen] = React20__namespace.useState(false);
3615
+ const selectedThread = React20__namespace.useMemo(() => {
3011
3616
  if (!value) return null;
3012
3617
  return threads.find((t) => t.id === value) ?? null;
3013
3618
  }, [value, threads]);
@@ -3096,7 +3701,7 @@ function ThreadPicker({
3096
3701
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-[11px] text-muted-foreground", children: [
3097
3702
  thread.preview && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate max-w-[180px]", children: thread.preview }),
3098
3703
  thread.preview && thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: "\xB7" }),
3099
- thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: formatDate(thread.updatedAt) })
3704
+ thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: formatDate2(thread.updatedAt) })
3100
3705
  ] })
3101
3706
  ]
3102
3707
  }
@@ -3123,7 +3728,7 @@ function ThreadPicker({
3123
3728
  )
3124
3729
  ] });
3125
3730
  }
3126
- function formatDate2(date) {
3731
+ function formatDate3(date) {
3127
3732
  const now = /* @__PURE__ */ new Date();
3128
3733
  const diff = now.getTime() - date.getTime();
3129
3734
  if (diff < 60 * 1e3) {
@@ -3213,7 +3818,7 @@ function ThreadCard({
3213
3818
  showDelete = true,
3214
3819
  className
3215
3820
  }) {
3216
- const [isHovered, setIsHovered] = React18__namespace.useState(false);
3821
+ const [isHovered, setIsHovered] = React20__namespace.useState(false);
3217
3822
  const handleDelete = (e) => {
3218
3823
  e.stopPropagation();
3219
3824
  onDelete?.();
@@ -3268,7 +3873,7 @@ function ThreadCard({
3268
3873
  " messages"
3269
3874
  ] }),
3270
3875
  thread.messageCount !== void 0 && thread.messageCount > 0 && thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\xB7" }),
3271
- thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDate2(thread.updatedAt) })
3876
+ thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDate3(thread.updatedAt) })
3272
3877
  ] })
3273
3878
  ] })
3274
3879
  ] })
@@ -3443,6 +4048,193 @@ function Suggestions({
3443
4048
  index
3444
4049
  )) });
3445
4050
  }
4051
+ function MCPUIFrame({
4052
+ resource,
4053
+ onIntent,
4054
+ onError,
4055
+ onLoad,
4056
+ className,
4057
+ style,
4058
+ sandbox = chunkJO4BHPAD_cjs.DEFAULT_MCP_UI_SANDBOX,
4059
+ showLoading = true,
4060
+ testId
4061
+ }) {
4062
+ const iframeRef = React20__namespace.useRef(null);
4063
+ const [isLoading, setIsLoading] = React20__namespace.useState(true);
4064
+ const [error, setError] = React20__namespace.useState(null);
4065
+ React20__namespace.useEffect(() => {
4066
+ const handleMessage = (event) => {
4067
+ if (event.source !== iframeRef.current?.contentWindow) {
4068
+ return;
4069
+ }
4070
+ const intent = chunkJO4BHPAD_cjs.parseMCPUIMessage(event.data);
4071
+ if (intent && onIntent) {
4072
+ onIntent(intent);
4073
+ }
4074
+ };
4075
+ window.addEventListener("message", handleMessage);
4076
+ return () => window.removeEventListener("message", handleMessage);
4077
+ }, [onIntent]);
4078
+ const handleLoad = React20__namespace.useCallback(() => {
4079
+ setIsLoading(false);
4080
+ onLoad?.();
4081
+ }, [onLoad]);
4082
+ const handleError = React20__namespace.useCallback(() => {
4083
+ const err = new Error("Failed to load MCP UI content");
4084
+ setError(err);
4085
+ setIsLoading(false);
4086
+ onError?.(err);
4087
+ }, [onError]);
4088
+ const { srcDoc, src } = React20__namespace.useMemo(() => {
4089
+ if (resource.mimeType === "text/html") {
4090
+ let content = resource.content || "";
4091
+ if (resource.blob && !resource.content) {
4092
+ try {
4093
+ content = atob(resource.blob);
4094
+ } catch {
4095
+ setError(new Error("Failed to decode MCP UI blob content"));
4096
+ }
4097
+ }
4098
+ const wrappedContent = `
4099
+ <!DOCTYPE html>
4100
+ <html>
4101
+ <head>
4102
+ <meta charset="utf-8">
4103
+ <meta name="viewport" content="width=device-width, initial-scale=1">
4104
+ <style>
4105
+ *, *::before, *::after { box-sizing: border-box; }
4106
+ body { margin: 0; padding: 8px; font-family: system-ui, -apple-system, sans-serif; }
4107
+ </style>
4108
+ </head>
4109
+ <body>
4110
+ ${content}
4111
+ <script>
4112
+ // Helper for sending intents to parent
4113
+ window.mcpUI = {
4114
+ sendIntent: function(intent) {
4115
+ window.parent.postMessage({ source: 'mcp-ui', intent: intent }, '*');
4116
+ },
4117
+ callTool: function(name, args) {
4118
+ this.sendIntent({ type: 'tool', name: name, arguments: args });
4119
+ },
4120
+ sendAction: function(action, data) {
4121
+ this.sendIntent({ type: 'intent', action: action, data: data });
4122
+ },
4123
+ prompt: function(text) {
4124
+ this.sendIntent({ type: 'prompt', text: text });
4125
+ },
4126
+ notify: function(message, level) {
4127
+ this.sendIntent({ type: 'notify', message: message, level: level || 'info' });
4128
+ },
4129
+ openLink: function(url, newTab) {
4130
+ this.sendIntent({ type: 'link', url: url, newTab: newTab !== false });
4131
+ }
4132
+ };
4133
+ </script>
4134
+ </body>
4135
+ </html>
4136
+ `;
4137
+ return { srcDoc: wrappedContent, src: void 0 };
4138
+ }
4139
+ if (resource.mimeType === "text/uri-list") {
4140
+ return { srcDoc: void 0, src: resource.content };
4141
+ }
4142
+ return { srcDoc: void 0, src: resource.content };
4143
+ }, [resource]);
4144
+ const frameStyle = {
4145
+ width: resource.metadata?.width || "100%",
4146
+ minHeight: resource.metadata?.height || "200px",
4147
+ ...style
4148
+ };
4149
+ if (error) {
4150
+ return /* @__PURE__ */ jsxRuntime.jsx(
4151
+ "div",
4152
+ {
4153
+ className: cn(
4154
+ "flex items-center justify-center rounded-lg border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive",
4155
+ className
4156
+ ),
4157
+ style: frameStyle,
4158
+ "data-testid": testId ? `${testId}-error` : void 0,
4159
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
4160
+ /* @__PURE__ */ jsxRuntime.jsx(
4161
+ "svg",
4162
+ {
4163
+ className: "size-4",
4164
+ fill: "none",
4165
+ viewBox: "0 0 24 24",
4166
+ stroke: "currentColor",
4167
+ strokeWidth: 2,
4168
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4169
+ "path",
4170
+ {
4171
+ strokeLinecap: "round",
4172
+ strokeLinejoin: "round",
4173
+ d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
4174
+ }
4175
+ )
4176
+ }
4177
+ ),
4178
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Failed to load interactive content" })
4179
+ ] })
4180
+ }
4181
+ );
4182
+ }
4183
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4184
+ "div",
4185
+ {
4186
+ className: cn("relative overflow-hidden rounded-lg border", className),
4187
+ "data-testid": testId,
4188
+ children: [
4189
+ resource.metadata?.title && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b bg-muted/50 px-3 py-1.5 text-xs font-medium text-muted-foreground", children: resource.metadata.title }),
4190
+ showLoading && isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-10 flex items-center justify-center bg-background/80", children: /* @__PURE__ */ jsxRuntime.jsx(Loader, { variant: "dots", size: "md" }) }),
4191
+ /* @__PURE__ */ jsxRuntime.jsx(
4192
+ "iframe",
4193
+ {
4194
+ ref: iframeRef,
4195
+ srcDoc,
4196
+ src,
4197
+ sandbox,
4198
+ onLoad: handleLoad,
4199
+ onError: handleError,
4200
+ className: "block w-full border-0",
4201
+ style: frameStyle,
4202
+ title: resource.metadata?.title || "MCP UI Content",
4203
+ "data-testid": testId ? `${testId}-iframe` : void 0
4204
+ }
4205
+ )
4206
+ ]
4207
+ }
4208
+ );
4209
+ }
4210
+ function MCPUIFrameList({
4211
+ resources,
4212
+ onIntent,
4213
+ onError,
4214
+ className,
4215
+ frameClassName,
4216
+ gap = "md"
4217
+ }) {
4218
+ if (!resources || resources.length === 0) {
4219
+ return null;
4220
+ }
4221
+ const gapClasses = {
4222
+ sm: "space-y-1",
4223
+ md: "space-y-2",
4224
+ lg: "space-y-4"
4225
+ };
4226
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(gapClasses[gap], className), children: resources.map((resource, index) => /* @__PURE__ */ jsxRuntime.jsx(
4227
+ MCPUIFrame,
4228
+ {
4229
+ resource,
4230
+ onIntent: (intent) => onIntent?.(intent, index),
4231
+ onError: (error) => onError?.(error, index),
4232
+ className: frameClassName,
4233
+ testId: `mcp-ui-frame-${index}`
4234
+ },
4235
+ `${resource.uri}-${index}`
4236
+ )) });
4237
+ }
3446
4238
  function DefaultMessage({
3447
4239
  message,
3448
4240
  userAvatar,
@@ -3462,17 +4254,74 @@ function DefaultMessage({
3462
4254
  showFollowUps = true,
3463
4255
  onFollowUpClick,
3464
4256
  followUpClassName,
3465
- followUpButtonClassName
4257
+ followUpButtonClassName,
4258
+ citations = { enabled: true }
3466
4259
  }) {
3467
4260
  const isUser = message.role === "user";
3468
4261
  const isStreaming = isLastMessage && isLoading;
3469
- const { cleanContent, followUps } = React18__namespace.useMemo(() => {
4262
+ const { cleanContent: contentWithoutFollowUps, followUps } = React20__namespace.useMemo(() => {
3470
4263
  if (isUser || !message.content) {
3471
4264
  return { cleanContent: message.content, followUps: [] };
3472
4265
  }
3473
4266
  return parseFollowUps(message.content);
3474
4267
  }, [message.content, isUser]);
4268
+ const cleanContent = React20__namespace.useMemo(() => {
4269
+ if (!contentWithoutFollowUps) return contentWithoutFollowUps;
4270
+ return contentWithoutFollowUps.replace(/\n*\*{0,2}Sources:?\*{0,2}\s*(\[.+?\]\(.+?\)[,\s]*)+$/gi, "").trim();
4271
+ }, [contentWithoutFollowUps]);
3475
4272
  const shouldShowFollowUps = showFollowUps && !isUser && isLastMessage && !isLoading && followUps.length > 0 && onFollowUpClick;
4273
+ const sources = React20__namespace.useMemo(() => {
4274
+ if (isUser || !citations.enabled) return [];
4275
+ const extractedSources = [];
4276
+ const addSource = (url, title, description) => {
4277
+ if (url && !extractedSources.find((s) => s.href === url)) {
4278
+ extractedSources.push({
4279
+ href: url,
4280
+ title: title || getDomainFromUrl(url),
4281
+ description
4282
+ });
4283
+ }
4284
+ };
4285
+ const nativeCitations = message.metadata?.citations;
4286
+ if (nativeCitations && Array.isArray(nativeCitations)) {
4287
+ nativeCitations.forEach((citation) => {
4288
+ addSource(citation.url, citation.title, citation.citedText);
4289
+ });
4290
+ }
4291
+ message.toolExecutions?.forEach((exec) => {
4292
+ if (exec.name === "web_search" && exec.status === "completed" && exec.result) {
4293
+ const result = exec.result;
4294
+ const dataObj = result.data;
4295
+ if (dataObj?.results && Array.isArray(dataObj.results)) {
4296
+ dataObj.results.forEach((r) => {
4297
+ addSource(r.url, r.title, r.content);
4298
+ });
4299
+ }
4300
+ if (result.results && Array.isArray(result.results)) {
4301
+ result.results.forEach((r) => {
4302
+ addSource(r.url, r.title, r.content);
4303
+ });
4304
+ }
4305
+ if (dataObj && !dataObj.results && dataObj.query) {
4306
+ const response = dataObj;
4307
+ if (response.results && Array.isArray(response.results)) {
4308
+ response.results.forEach((r) => {
4309
+ addSource(r.url, r.title, r.content);
4310
+ });
4311
+ }
4312
+ }
4313
+ }
4314
+ });
4315
+ return extractedSources;
4316
+ }, [message.metadata, message.toolExecutions, isUser, citations.enabled]);
4317
+ function getDomainFromUrl(url) {
4318
+ try {
4319
+ return new URL(url).hostname.replace("www.", "");
4320
+ } catch {
4321
+ return url;
4322
+ }
4323
+ }
4324
+ const shouldShowSources = citations.enabled && sources.length > 0;
3476
4325
  if (isUser) {
3477
4326
  const hasAttachments = message.attachments && message.attachments.length > 0;
3478
4327
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -3483,7 +4332,7 @@ function DefaultMessage({
3483
4332
  showUserAvatar ? "justify-end" : "justify-end"
3484
4333
  ),
3485
4334
  children: [
3486
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end max-w-[80%]", children: [
4335
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end max-w-[80%] min-w-0", children: [
3487
4336
  message.content && /* @__PURE__ */ jsxRuntime.jsx(
3488
4337
  MessageContent,
3489
4338
  {
@@ -3511,11 +4360,15 @@ function DefaultMessage({
3511
4360
  }
3512
4361
  );
3513
4362
  }
4363
+ const isToolHidden = (toolName) => {
4364
+ const toolDef = registeredTools?.find((t) => t.name === toolName);
4365
+ return toolDef?.hidden === true;
4366
+ };
3514
4367
  const pendingApprovalTools = message.toolExecutions?.filter(
3515
- (exec) => exec.approvalStatus === "required"
4368
+ (exec) => exec.approvalStatus === "required" && !isToolHidden(exec.name)
3516
4369
  );
3517
4370
  const completedTools = message.toolExecutions?.filter(
3518
- (exec) => exec.approvalStatus !== "required"
4371
+ (exec) => exec.approvalStatus !== "required" && !isToolHidden(exec.name)
3519
4372
  );
3520
4373
  const hasCustomRender = (toolName) => {
3521
4374
  if (toolRenderers?.[toolName]) return true;
@@ -3529,7 +4382,8 @@ function DefaultMessage({
3529
4382
  const toolsWithoutCustomRender = completedTools?.filter(
3530
4383
  (exec) => !hasCustomRender(exec.name)
3531
4384
  );
3532
- const toolSteps = toolsWithoutCustomRender?.map((exec) => ({
4385
+ const hasNativeCitations = !!message.metadata?.citations?.length;
4386
+ const toolSteps = toolsWithoutCustomRender?.filter((exec) => !(exec.name === "web_search" && hasNativeCitations)).map((exec) => ({
3533
4387
  id: exec.id,
3534
4388
  name: exec.name,
3535
4389
  args: exec.args,
@@ -3615,11 +4469,23 @@ function DefaultMessage({
3615
4469
  const output = toolDef.render(
3616
4470
  renderProps
3617
4471
  );
3618
- return /* @__PURE__ */ jsxRuntime.jsx(React18__namespace.Fragment, { children: output }, exec.id);
4472
+ return /* @__PURE__ */ jsxRuntime.jsx(React20__namespace.Fragment, { children: output }, exec.id);
3619
4473
  }
3620
4474
  return null;
3621
4475
  }) }),
3622
4476
  toolSteps && toolSteps.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 rounded-lg bg-muted/50 px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(ToolSteps, { steps: toolSteps }) }),
4477
+ message.toolExecutions?.filter((exec) => !isToolHidden(exec.name)).map((exec) => {
4478
+ const uiResources = exec.result?._uiResources;
4479
+ if (!uiResources || uiResources.length === 0) return null;
4480
+ return /* @__PURE__ */ jsxRuntime.jsx(
4481
+ MCPUIFrameList,
4482
+ {
4483
+ resources: uiResources,
4484
+ className: "mt-2"
4485
+ },
4486
+ `${exec.id}-ui`
4487
+ );
4488
+ }),
3623
4489
  pendingApprovalTools && pendingApprovalTools.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 space-y-2", children: pendingApprovalTools.map((tool) => {
3624
4490
  const approvalCallbacks = {
3625
4491
  onApprove: (extraData) => onApproveToolExecution?.(tool.id, extraData),
@@ -3653,7 +4519,7 @@ function DefaultMessage({
3653
4519
  const output = toolDef.render(
3654
4520
  renderProps
3655
4521
  );
3656
- return /* @__PURE__ */ jsxRuntime.jsx(React18__namespace.Fragment, { children: output }, tool.id);
4522
+ return /* @__PURE__ */ jsxRuntime.jsx(React20__namespace.Fragment, { children: output }, tool.id);
3657
4523
  }
3658
4524
  return /* @__PURE__ */ jsxRuntime.jsx(
3659
4525
  PermissionConfirmation,
@@ -3676,6 +4542,17 @@ function DefaultMessage({
3676
4542
  );
3677
4543
  }) }),
3678
4544
  message.attachments && message.attachments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex flex-wrap gap-2", children: message.attachments.map((attachment, index) => /* @__PURE__ */ jsxRuntime.jsx(AttachmentPreview, { attachment }, index)) }),
4545
+ shouldShowSources && /* @__PURE__ */ jsxRuntime.jsx(
4546
+ SourceGroup,
4547
+ {
4548
+ sources,
4549
+ label: citations.label,
4550
+ showFavicon: citations.showFavicon ?? true,
4551
+ numbered: citations.numbered ?? false,
4552
+ maxVisible: citations.maxVisible ?? 6,
4553
+ className: cn("mt-2", citations.className)
4554
+ }
4555
+ ),
3679
4556
  shouldShowFollowUps && /* @__PURE__ */ jsxRuntime.jsx(
3680
4557
  FollowUpQuestions,
3681
4558
  {
@@ -3691,7 +4568,7 @@ function DefaultMessage({
3691
4568
  ] });
3692
4569
  }
3693
4570
  function AttachmentPreview({ attachment }) {
3694
- const [expanded, setExpanded] = React18__namespace.useState(false);
4571
+ const [expanded, setExpanded] = React20__namespace.useState(false);
3695
4572
  if (attachment.type !== "image") {
3696
4573
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 rounded-lg border bg-muted/50 px-3 py-2 text-sm", children: [
3697
4574
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: attachment.type }),
@@ -3820,10 +4697,10 @@ function ChatWelcome({
3820
4697
  processAttachment: processAttachmentProp,
3821
4698
  classNames = {}
3822
4699
  }) {
3823
- const [input, setInput] = React18.useState("");
3824
- const [pendingAttachments, setPendingAttachments] = React18.useState([]);
3825
- const fileInputRef = React18.useRef(null);
3826
- const fileInputId = React18.useId();
4700
+ const [input, setInput] = React20.useState("");
4701
+ const [pendingAttachments, setPendingAttachments] = React20.useState([]);
4702
+ const fileInputRef = React20.useRef(null);
4703
+ const fileInputId = React20.useId();
3827
4704
  const title = config?.title ?? DEFAULT_TITLE;
3828
4705
  const subtitle = config?.subtitle ?? DEFAULT_SUBTITLE;
3829
4706
  const logo = config?.logo;
@@ -3832,7 +4709,7 @@ function ChatWelcome({
3832
4709
  config?.recentChatsLabel ?? DEFAULT_RECENT_CHATS_LABEL;
3833
4710
  const maxRecentChats = config?.maxRecentChats ?? DEFAULT_MAX_RECENT_CHATS;
3834
4711
  config?.viewMoreLabel ?? DEFAULT_VIEW_MORE_LABEL;
3835
- const isFileTypeAllowed = React18.useCallback(
4712
+ const isFileTypeAllowed = React20.useCallback(
3836
4713
  (file) => {
3837
4714
  for (const type of allowedFileTypes) {
3838
4715
  if (type.endsWith("/*")) {
@@ -3846,7 +4723,7 @@ function ChatWelcome({
3846
4723
  },
3847
4724
  [allowedFileTypes]
3848
4725
  );
3849
- const handleFileSelect = React18.useCallback(
4726
+ const handleFileSelect = React20.useCallback(
3850
4727
  async (files) => {
3851
4728
  if (!files || !attachmentsEnabled) return;
3852
4729
  for (const file of Array.from(files)) {
@@ -3909,7 +4786,7 @@ function ChatWelcome({
3909
4786
  },
3910
4787
  [attachmentsEnabled, maxFileSize, isFileTypeAllowed, processAttachmentProp]
3911
4788
  );
3912
- const handleInputChange = React18.useCallback(
4789
+ const handleInputChange = React20.useCallback(
3913
4790
  (e) => {
3914
4791
  handleFileSelect(e.target.files);
3915
4792
  if (fileInputRef.current) {
@@ -3918,7 +4795,7 @@ function ChatWelcome({
3918
4795
  },
3919
4796
  [handleFileSelect]
3920
4797
  );
3921
- const removePendingAttachment = React18.useCallback((id) => {
4798
+ const removePendingAttachment = React20.useCallback((id) => {
3922
4799
  setPendingAttachments((prev) => {
3923
4800
  const att = prev.find((a) => a.id === id);
3924
4801
  if (att) {
@@ -3927,7 +4804,7 @@ function ChatWelcome({
3927
4804
  return prev.filter((a) => a.id !== id);
3928
4805
  });
3929
4806
  }, []);
3930
- const handleSubmit = React18.useCallback(() => {
4807
+ const handleSubmit = React20.useCallback(() => {
3931
4808
  const hasContent = input.trim();
3932
4809
  const hasAttachments = pendingAttachments.some(
3933
4810
  (att) => att.status === "ready"
@@ -3939,7 +4816,7 @@ function ChatWelcome({
3939
4816
  setPendingAttachments([]);
3940
4817
  setInput("");
3941
4818
  }, [input, isLoading, onSendMessage, pendingAttachments]);
3942
- const handleSuggestionClick = React18.useCallback(
4819
+ const handleSuggestionClick = React20.useCallback(
3943
4820
  (suggestion) => {
3944
4821
  onSendMessage(suggestion);
3945
4822
  },
@@ -4111,11 +4988,11 @@ function ChatWelcome({
4111
4988
  }
4112
4989
  );
4113
4990
  }
4114
- var CopilotChatContext = React18.createContext(
4991
+ var CopilotChatContext = React20.createContext(
4115
4992
  null
4116
4993
  );
4117
4994
  var useCopilotChatContext = () => {
4118
- const ctx = React18.useContext(CopilotChatContext);
4995
+ const ctx = React20.useContext(CopilotChatContext);
4119
4996
  if (!ctx) {
4120
4997
  throw new Error(
4121
4998
  "useCopilotChatContext must be used within CopilotChat. Make sure you're using CopilotChat.Home, CopilotChat.Input, etc. inside <CopilotChat>"
@@ -4149,10 +5026,10 @@ function ChatView({ children, className }) {
4149
5026
  ChatView.displayName = "ChatView";
4150
5027
  function chatViewHasOnlyLayoutChildren(chatViewElement) {
4151
5028
  if (!chatViewElement?.props?.children) return false;
4152
- const childArray = React18__namespace.default.Children.toArray(chatViewElement.props.children);
5029
+ const childArray = React20__namespace.default.Children.toArray(chatViewElement.props.children);
4153
5030
  if (childArray.length === 0) return false;
4154
5031
  return childArray.every(
4155
- (child) => React18__namespace.default.isValidElement(child) && (child.type === Header || child.type === Footer)
5032
+ (child) => React20__namespace.default.isValidElement(child) && (child.type === Header || child.type === Footer)
4156
5033
  );
4157
5034
  }
4158
5035
  function Header({ children, className }) {
@@ -4168,8 +5045,8 @@ function Input({ placeholder: placeholderProp, className }) {
4168
5045
  onStop,
4169
5046
  placeholder: defaultPlaceholder
4170
5047
  } = useCopilotChatContext();
4171
- const [value, setValue] = React18.useState("");
4172
- const handleSubmit = React18.useCallback(() => {
5048
+ const [value, setValue] = React20.useState("");
5049
+ const handleSubmit = React20.useCallback(() => {
4173
5050
  if (value.trim() && !isLoading) {
4174
5051
  send(value.trim());
4175
5052
  setValue("");
@@ -4290,18 +5167,18 @@ function ThreadPickerCompound(props) {
4290
5167
  );
4291
5168
  }
4292
5169
  function hasCompoundChild(children, ...components) {
4293
- return React18__namespace.default.Children.toArray(children).some(
4294
- (child) => React18__namespace.default.isValidElement(child) && components.includes(child.type)
5170
+ return React20__namespace.default.Children.toArray(children).some(
5171
+ (child) => React20__namespace.default.isValidElement(child) && components.includes(child.type)
4295
5172
  );
4296
5173
  }
4297
5174
  function findCompoundChild(children, component) {
4298
- return React18__namespace.default.Children.toArray(children).find(
4299
- (child) => React18__namespace.default.isValidElement(child) && child.type === component
5175
+ return React20__namespace.default.Children.toArray(children).find(
5176
+ (child) => React20__namespace.default.isValidElement(child) && child.type === component
4300
5177
  );
4301
5178
  }
4302
5179
  function filterCompoundChildren(children, ...components) {
4303
- return React18__namespace.default.Children.toArray(children).filter(
4304
- (child) => React18__namespace.default.isValidElement(child) && components.includes(child.type)
5180
+ return React20__namespace.default.Children.toArray(children).filter(
5181
+ (child) => React20__namespace.default.isValidElement(child) && components.includes(child.type)
4305
5182
  );
4306
5183
  }
4307
5184
  var DEFAULT_MAX_FILE_SIZE2 = 5 * 1024 * 1024;
@@ -4381,6 +5258,8 @@ function ChatComponent({
4381
5258
  showFollowUps = true,
4382
5259
  followUpClassName,
4383
5260
  followUpButtonClassName,
5261
+ // Citations/Sources
5262
+ citations,
4384
5263
  // Custom rendering
4385
5264
  renderMessage,
4386
5265
  renderInput,
@@ -4397,12 +5276,12 @@ function ChatComponent({
4397
5276
  }) {
4398
5277
  const userAvatar = { fallback: "U", ...userAvatarProp };
4399
5278
  const assistantAvatar = { fallback: "AI", ...assistantAvatarProp };
4400
- const [input, setInput] = React18.useState("");
4401
- const [pendingAttachments, setPendingAttachments] = React18.useState([]);
4402
- const [isDragging, setIsDragging] = React18.useState(false);
4403
- const fileInputRef = React18.useRef(null);
4404
- const fileInputId = React18.useId();
4405
- const isFileTypeAllowed = React18.useCallback(
5279
+ const [input, setInput] = React20.useState("");
5280
+ const [pendingAttachments, setPendingAttachments] = React20.useState([]);
5281
+ const [isDragging, setIsDragging] = React20.useState(false);
5282
+ const fileInputRef = React20.useRef(null);
5283
+ const fileInputId = React20.useId();
5284
+ const isFileTypeAllowed = React20.useCallback(
4406
5285
  (file) => {
4407
5286
  for (const type of allowedFileTypes) {
4408
5287
  if (type.endsWith("/*")) {
@@ -4416,7 +5295,7 @@ function ChatComponent({
4416
5295
  },
4417
5296
  [allowedFileTypes]
4418
5297
  );
4419
- const handleFileSelect = React18.useCallback(
5298
+ const handleFileSelect = React20.useCallback(
4420
5299
  async (files) => {
4421
5300
  if (!files || !attachmentsEnabled) return;
4422
5301
  for (const file of Array.from(files)) {
@@ -4479,7 +5358,7 @@ function ChatComponent({
4479
5358
  },
4480
5359
  [attachmentsEnabled, maxFileSize, isFileTypeAllowed, processAttachmentProp]
4481
5360
  );
4482
- const handleInputChange = React18.useCallback(
5361
+ const handleInputChange = React20.useCallback(
4483
5362
  (e) => {
4484
5363
  handleFileSelect(e.target.files);
4485
5364
  if (fileInputRef.current) {
@@ -4488,7 +5367,7 @@ function ChatComponent({
4488
5367
  },
4489
5368
  [handleFileSelect]
4490
5369
  );
4491
- const removePendingAttachment = React18.useCallback((id) => {
5370
+ const removePendingAttachment = React20.useCallback((id) => {
4492
5371
  setPendingAttachments((prev) => {
4493
5372
  const att = prev.find((a) => a.id === id);
4494
5373
  if (att) {
@@ -4497,7 +5376,7 @@ function ChatComponent({
4497
5376
  return prev.filter((a) => a.id !== id);
4498
5377
  });
4499
5378
  }, []);
4500
- const handleDragOver = React18.useCallback(
5379
+ const handleDragOver = React20.useCallback(
4501
5380
  (e) => {
4502
5381
  e.preventDefault();
4503
5382
  e.stopPropagation();
@@ -4507,12 +5386,12 @@ function ChatComponent({
4507
5386
  },
4508
5387
  [attachmentsEnabled]
4509
5388
  );
4510
- const handleDragLeave = React18.useCallback((e) => {
5389
+ const handleDragLeave = React20.useCallback((e) => {
4511
5390
  e.preventDefault();
4512
5391
  e.stopPropagation();
4513
5392
  setIsDragging(false);
4514
5393
  }, []);
4515
- const handleDrop = React18.useCallback(
5394
+ const handleDrop = React20.useCallback(
4516
5395
  (e) => {
4517
5396
  e.preventDefault();
4518
5397
  e.stopPropagation();
@@ -4523,7 +5402,7 @@ function ChatComponent({
4523
5402
  },
4524
5403
  [attachmentsEnabled, handleFileSelect]
4525
5404
  );
4526
- const handleSubmit = React18.useCallback(() => {
5405
+ const handleSubmit = React20.useCallback(() => {
4527
5406
  const hasContent = input.trim();
4528
5407
  const hasAttachments = pendingAttachments.some(
4529
5408
  (att) => att.status === "ready"
@@ -4535,7 +5414,7 @@ function ChatComponent({
4535
5414
  setPendingAttachments([]);
4536
5415
  setInput("");
4537
5416
  }, [input, isLoading, onSendMessage, pendingAttachments]);
4538
- const handleSuggestionClick = React18.useCallback(
5417
+ const handleSuggestionClick = React20.useCallback(
4539
5418
  (suggestion) => {
4540
5419
  if (onSuggestionClick) {
4541
5420
  onSuggestionClick(suggestion);
@@ -4562,13 +5441,13 @@ function ChatComponent({
4562
5441
  const chatViewNeedsDefault = chatViewElement && (!chatViewElement.props.children || chatViewHasOnlyLayoutChildren(chatViewElement));
4563
5442
  const showDefaultWelcome = view === "home" && !hasCustomHome && welcome !== false;
4564
5443
  const welcomeConfig = typeof welcome === "object" ? welcome : void 0;
4565
- const send = React18.useCallback(
5444
+ const send = React20.useCallback(
4566
5445
  (message, attachments) => {
4567
5446
  onSendMessage?.(message, attachments);
4568
5447
  },
4569
5448
  [onSendMessage]
4570
5449
  );
4571
- const contextValue = React18__namespace.default.useMemo(
5450
+ const contextValue = React20__namespace.default.useMemo(
4572
5451
  () => ({
4573
5452
  view,
4574
5453
  send,
@@ -4684,7 +5563,7 @@ function ChatComponent({
4684
5563
  onSendMessage?.(question);
4685
5564
  }
4686
5565
  };
4687
- return renderMessage ? /* @__PURE__ */ jsxRuntime.jsx(React18__namespace.default.Fragment, { children: renderMessage(messageWithExecutions, index) }, message.id) : /* @__PURE__ */ jsxRuntime.jsx(
5566
+ return renderMessage ? /* @__PURE__ */ jsxRuntime.jsx(React20__namespace.default.Fragment, { children: renderMessage(messageWithExecutions, index) }, message.id) : /* @__PURE__ */ jsxRuntime.jsx(
4688
5567
  DefaultMessage,
4689
5568
  {
4690
5569
  message: messageWithExecutions,
@@ -4705,7 +5584,8 @@ function ChatComponent({
4705
5584
  showFollowUps,
4706
5585
  onFollowUpClick: handleFollowUpClick,
4707
5586
  followUpClassName,
4708
- followUpButtonClassName
5587
+ followUpButtonClassName,
5588
+ citations: citations === false ? { enabled: false } : citations
4709
5589
  },
4710
5590
  message.id
4711
5591
  );
@@ -4884,6 +5764,7 @@ function ToolExecutionMessage({
4884
5764
  onApprove,
4885
5765
  onReject,
4886
5766
  toolRenderers,
5767
+ onUIIntent,
4887
5768
  className
4888
5769
  }) {
4889
5770
  if (!executions || executions.length === 0) return null;
@@ -4995,7 +5876,23 @@ function ToolExecutionMessage({
4995
5876
  tool.id
4996
5877
  );
4997
5878
  }) }),
4998
- toolSteps.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border bg-card px-3 py-2.5 shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(ToolSteps, { steps: toolSteps }) })
5879
+ toolSteps.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border bg-card px-3 py-2.5 shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(ToolSteps, { steps: toolSteps }) }),
5880
+ otherExecutions.map((exec) => {
5881
+ const uiResources = exec.result?._uiResources;
5882
+ if (!uiResources || uiResources.length === 0) return null;
5883
+ return /* @__PURE__ */ jsxRuntime.jsx(
5884
+ MCPUIFrameList,
5885
+ {
5886
+ resources: uiResources,
5887
+ onIntent: (intent) => onUIIntent?.(intent, {
5888
+ toolName: exec.name,
5889
+ toolCallId: exec.id
5890
+ }),
5891
+ className: "mt-2"
5892
+ },
5893
+ `${exec.id}-ui`
5894
+ );
5895
+ })
4999
5896
  ] })
5000
5897
  ] });
5001
5898
  }
@@ -5011,7 +5908,7 @@ function useInternalThreadManager(config = {}) {
5011
5908
  saveDebounce,
5012
5909
  autoRestoreLastThread
5013
5910
  };
5014
- const threadManager = chunkBLSI67J6_cjs.useThreadManager(threadManagerConfig);
5911
+ const threadManager = chunkH5XMKBBA_cjs.useThreadManager(threadManagerConfig);
5015
5912
  const {
5016
5913
  currentThread,
5017
5914
  currentThreadId,
@@ -5021,18 +5918,18 @@ function useInternalThreadManager(config = {}) {
5021
5918
  clearCurrentThread,
5022
5919
  refreshThreads
5023
5920
  } = threadManager;
5024
- const { messages, setMessages, status, isLoading } = chunkBLSI67J6_cjs.useCopilot();
5025
- const isLoadingMessagesRef = React18.useRef(false);
5026
- const savingToThreadRef = React18.useRef(null);
5027
- const lastSavedSnapshotRef = React18.useRef("");
5028
- const hasInitializedRef = React18.useRef(false);
5029
- const getMessageSnapshot = React18.useCallback((msgs) => {
5921
+ const { messages, setMessages, status, isLoading } = chunkH5XMKBBA_cjs.useCopilot();
5922
+ const isLoadingMessagesRef = React20.useRef(false);
5923
+ const savingToThreadRef = React20.useRef(null);
5924
+ const lastSavedSnapshotRef = React20.useRef("");
5925
+ const hasInitializedRef = React20.useRef(false);
5926
+ const getMessageSnapshot = React20.useCallback((msgs) => {
5030
5927
  return msgs.map((m) => {
5031
5928
  const contentPreview = (m.content ?? "").slice(0, 20);
5032
5929
  return `${m.id}:${contentPreview}:${m.content?.length ?? 0}`;
5033
5930
  }).join("|");
5034
5931
  }, []);
5035
- const convertToCore = React18.useCallback((msgs) => {
5932
+ const convertToCore = React20.useCallback((msgs) => {
5036
5933
  return msgs.map((m) => ({
5037
5934
  id: m.id,
5038
5935
  role: m.role,
@@ -5040,13 +5937,15 @@ function useInternalThreadManager(config = {}) {
5040
5937
  created_at: m.createdAt,
5041
5938
  tool_calls: m.toolCalls,
5042
5939
  tool_call_id: m.toolCallId,
5940
+ // Preserve full metadata including citations, toolExecutions, etc.
5043
5941
  metadata: {
5942
+ ...m.metadata,
5044
5943
  attachments: m.attachments,
5045
5944
  thinking: m.thinking
5046
5945
  }
5047
5946
  }));
5048
5947
  }, []);
5049
- const handleSwitchThread = React18.useCallback(
5948
+ const handleSwitchThread = React20.useCallback(
5050
5949
  async (threadId) => {
5051
5950
  isLoadingMessagesRef.current = true;
5052
5951
  const thread = await switchThread(threadId);
@@ -5075,7 +5974,7 @@ function useInternalThreadManager(config = {}) {
5075
5974
  },
5076
5975
  [switchThread, setMessages, getMessageSnapshot, onThreadChange]
5077
5976
  );
5078
- const handleNewThread = React18.useCallback(async () => {
5977
+ const handleNewThread = React20.useCallback(async () => {
5079
5978
  isLoadingMessagesRef.current = true;
5080
5979
  clearCurrentThread();
5081
5980
  lastSavedSnapshotRef.current = "";
@@ -5086,7 +5985,10 @@ function useInternalThreadManager(config = {}) {
5086
5985
  isLoadingMessagesRef.current = false;
5087
5986
  });
5088
5987
  }, [clearCurrentThread, setMessages, onThreadChange]);
5089
- React18.useEffect(() => {
5988
+ React20.useEffect(() => {
5989
+ if (!adapter) {
5990
+ return;
5991
+ }
5090
5992
  if (hasInitializedRef.current || !currentThread) {
5091
5993
  return;
5092
5994
  }
@@ -5100,7 +6002,10 @@ function useInternalThreadManager(config = {}) {
5100
6002
  createdAt: m.created_at ?? /* @__PURE__ */ new Date(),
5101
6003
  toolCalls: m.tool_calls,
5102
6004
  toolCallId: m.tool_call_id,
5103
- attachments: m.metadata?.attachments
6005
+ attachments: m.metadata?.attachments,
6006
+ thinking: m.metadata?.thinking,
6007
+ // Preserve full metadata including citations, toolExecutions, etc.
6008
+ metadata: m.metadata
5104
6009
  }));
5105
6010
  lastSavedSnapshotRef.current = getMessageSnapshot(uiMessages);
5106
6011
  savingToThreadRef.current = currentThread.id;
@@ -5113,8 +6018,11 @@ function useInternalThreadManager(config = {}) {
5113
6018
  requestAnimationFrame(() => {
5114
6019
  isLoadingMessagesRef.current = false;
5115
6020
  });
5116
- }, [currentThread, setMessages, getMessageSnapshot, onThreadChange]);
5117
- React18.useEffect(() => {
6021
+ }, [adapter, currentThread, setMessages, getMessageSnapshot, onThreadChange]);
6022
+ React20.useEffect(() => {
6023
+ if (!adapter) {
6024
+ return;
6025
+ }
5118
6026
  if (isLoadingMessagesRef.current) {
5119
6027
  return;
5120
6028
  }
@@ -5144,6 +6052,7 @@ function useInternalThreadManager(config = {}) {
5144
6052
  updateCurrentThread({ messages: coreMessages });
5145
6053
  lastSavedSnapshotRef.current = currentSnapshot;
5146
6054
  }, [
6055
+ adapter,
5147
6056
  messages,
5148
6057
  currentThreadId,
5149
6058
  status,
@@ -5182,7 +6091,7 @@ function parsePersistenceConfig(persistence, onThreadChange) {
5182
6091
  };
5183
6092
  case "server":
5184
6093
  return {
5185
- adapter: chunk4PRWNAXQ_cjs.createServerAdapter({
6094
+ adapter: chunkUOWLKFXK_cjs.createServerAdapter({
5186
6095
  endpoint: persistence.endpoint,
5187
6096
  headers: persistence.headers
5188
6097
  }),
@@ -5232,7 +6141,7 @@ function CopilotChatBase(props) {
5232
6141
  approveToolExecution,
5233
6142
  rejectToolExecution,
5234
6143
  registeredTools
5235
- } = chunkBLSI67J6_cjs.useCopilot();
6144
+ } = chunkH5XMKBBA_cjs.useCopilot();
5236
6145
  const toolExecutions = rawToolExecutions.map(
5237
6146
  (exec) => ({
5238
6147
  id: exec.id,
@@ -5319,7 +6228,9 @@ function CopilotChatBase(props) {
5319
6228
  // Include tool_calls for assistant messages
5320
6229
  tool_calls: m.toolCalls,
5321
6230
  // Attach matched tool executions to assistant messages
5322
- toolExecutions: messageToolExecutions
6231
+ toolExecutions: messageToolExecutions,
6232
+ // Include metadata (citations from native web search, etc.)
6233
+ metadata: m.metadata
5323
6234
  };
5324
6235
  });
5325
6236
  const suggestions = visibleMessages.length === 0 && chatProps.suggestions?.length ? chatProps.suggestions : [];
@@ -5355,7 +6266,7 @@ function CopilotChatBase(props) {
5355
6266
  footer: classNames.footer
5356
6267
  } : void 0;
5357
6268
  const { threadManager, handleSwitchThread, handleNewThread, isBusy } = threadManagerResult;
5358
- const handleDeleteThread = React18__namespace.default.useCallback(
6269
+ const handleDeleteThread = React20__namespace.default.useCallback(
5359
6270
  (threadId) => {
5360
6271
  const isCurrentThread = threadManager.currentThreadId === threadId;
5361
6272
  threadManager.deleteThread(threadId);
@@ -5494,6 +6405,8 @@ exports.CheckIcon = CheckIcon;
5494
6405
  exports.ChevronDownIcon = ChevronDownIcon2;
5495
6406
  exports.ChevronLeftIcon = ChevronLeftIcon;
5496
6407
  exports.ChevronUpIcon = ChevronUpIcon;
6408
+ exports.CitationBadge = CitationBadge;
6409
+ exports.CitationSuperscript = CitationSuperscript;
5497
6410
  exports.CloseIcon = CloseIcon;
5498
6411
  exports.CodeBlock = CodeBlock;
5499
6412
  exports.CompactPermissionConfirmation = CompactPermissionConfirmation;
@@ -5513,10 +6426,13 @@ exports.FeedbackBar = FeedbackBar;
5513
6426
  exports.FollowUpQuestions = FollowUpQuestions;
5514
6427
  exports.InlineToolSteps = InlineToolSteps;
5515
6428
  exports.Loader = Loader;
6429
+ exports.MCPUIFrame = MCPUIFrame;
6430
+ exports.MCPUIFrameList = MCPUIFrameList;
5516
6431
  exports.Markdown = Markdown;
5517
6432
  exports.MessageAvatar = MessageAvatar;
5518
6433
  exports.MessageContent = MessageContent;
5519
6434
  exports.MessagePrimitive = Message;
6435
+ exports.MessageWithCitations = MessageWithCitations;
5520
6436
  exports.ModelSelector = ModelSelector;
5521
6437
  exports.PermissionConfirmation = PermissionConfirmation;
5522
6438
  exports.PoweredBy = PoweredBy;
@@ -5529,13 +6445,22 @@ exports.ReasoningContent = ReasoningContent;
5529
6445
  exports.ReasoningTrigger = ReasoningTrigger;
5530
6446
  exports.RefreshIcon = RefreshIcon;
5531
6447
  exports.ScrollButton = ScrollButton;
6448
+ exports.SearchAnswer = SearchAnswer;
6449
+ exports.SearchResults = SearchResults;
6450
+ exports.SearchResultsWithAnswer = SearchResultsWithAnswer;
5532
6451
  exports.SendIcon = SendIcon;
5533
6452
  exports.SimpleConfirmation = SimpleConfirmation;
5534
6453
  exports.SimpleModelSelector = SimpleModelSelector;
5535
6454
  exports.SimpleReasoning = SimpleReasoning;
6455
+ exports.SimpleSource = SimpleSource;
5536
6456
  exports.Source = Source;
5537
6457
  exports.SourceContent = SourceContent;
6458
+ exports.SourceGroup = SourceGroup;
6459
+ exports.SourcePill = SourcePill;
5538
6460
  exports.SourceTrigger = SourceTrigger;
6461
+ exports.SourcesBar = SourcesBar;
6462
+ exports.SourcesCollapsible = SourcesCollapsible;
6463
+ exports.SourcesList = SourcesList;
5539
6464
  exports.StopIcon = StopIcon;
5540
6465
  exports.ThreadCard = ThreadCard;
5541
6466
  exports.ThreadList = ThreadList;
@@ -5551,8 +6476,10 @@ exports.TooltipProvider = TooltipProvider;
5551
6476
  exports.TooltipTrigger = TooltipTrigger;
5552
6477
  exports.UserIcon = UserIcon;
5553
6478
  exports.XIcon = XIcon2;
6479
+ exports.annotationsToCitations = annotationsToCitations;
5554
6480
  exports.cn = cn;
5555
6481
  exports.parseFollowUps = parseFollowUps;
6482
+ exports.resultsToCitations = resultsToCitations;
5556
6483
  exports.useChatContainer = useChatContainer;
5557
6484
  exports.useCopilotChatContext = useCopilotChatContext;
5558
6485
  exports.useCopilotUI = useCopilotUI;