@yourgpt/copilot-sdk 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ui/index.cjs CHANGED
@@ -5,7 +5,7 @@ var chunkMTFU6EHR_cjs = require('../chunk-MTFU6EHR.cjs');
5
5
  var clsx = require('clsx');
6
6
  var tailwindMerge = require('tailwind-merge');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
- var React7 = require('react');
8
+ var React18 = require('react');
9
9
  var streamdown = require('streamdown');
10
10
  var code = require('@streamdown/code');
11
11
  var reactSlot = require('@radix-ui/react-slot');
@@ -34,7 +34,7 @@ function _interopNamespace(e) {
34
34
  return Object.freeze(n);
35
35
  }
36
36
 
37
- var React7__namespace = /*#__PURE__*/_interopNamespace(React7);
37
+ var React18__namespace = /*#__PURE__*/_interopNamespace(React18);
38
38
  var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
39
39
  var HoverCardPrimitive__namespace = /*#__PURE__*/_interopNamespace(HoverCardPrimitive);
40
40
 
@@ -468,7 +468,7 @@ function MarkdownComponent({
468
468
  }
469
469
  ) });
470
470
  }
471
- var Markdown = React7.memo(MarkdownComponent);
471
+ var Markdown = React18.memo(MarkdownComponent);
472
472
  Markdown.displayName = "Markdown";
473
473
  function CodeBlock({ children, className, ...props }) {
474
474
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -509,7 +509,7 @@ var buttonVariants = classVarianceAuthority.cva(
509
509
  }
510
510
  }
511
511
  );
512
- var Button = React7__namespace.forwardRef(
512
+ var Button = React18__namespace.forwardRef(
513
513
  ({ className, variant, size, asChild = false, ...props }, ref) => {
514
514
  const Comp = asChild ? reactSlot.Slot : "button";
515
515
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -750,7 +750,7 @@ function TooltipTrigger({
750
750
  disabled,
751
751
  ...props
752
752
  }) {
753
- if (asChild && React7__namespace.default.isValidElement(children)) {
753
+ if (asChild && React18__namespace.default.isValidElement(children)) {
754
754
  return /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Trigger, { disabled, render: children, ...props });
755
755
  }
756
756
  return /* @__PURE__ */ jsxRuntime.jsx(tooltip.Tooltip.Trigger, { disabled, ...props, children });
@@ -779,7 +779,7 @@ function TooltipContent({
779
779
  }
780
780
  ) }) });
781
781
  }
782
- var Avatar = React7__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
782
+ var Avatar = React18__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
783
783
  AvatarPrimitive__namespace.Root,
784
784
  {
785
785
  ref,
@@ -791,7 +791,7 @@ var Avatar = React7__namespace.forwardRef(({ className, ...props }, ref) => /* @
791
791
  }
792
792
  ));
793
793
  Avatar.displayName = AvatarPrimitive__namespace.Root.displayName;
794
- var AvatarImage = React7__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
794
+ var AvatarImage = React18__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
795
795
  AvatarPrimitive__namespace.Image,
796
796
  {
797
797
  ref,
@@ -800,7 +800,7 @@ var AvatarImage = React7__namespace.forwardRef(({ className, ...props }, ref) =>
800
800
  }
801
801
  ));
802
802
  AvatarImage.displayName = AvatarPrimitive__namespace.Image.displayName;
803
- var AvatarFallback = React7__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
803
+ var AvatarFallback = React18__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
804
804
  AvatarPrimitive__namespace.Fallback,
805
805
  {
806
806
  ref,
@@ -854,7 +854,7 @@ var MessageContent = ({
854
854
  );
855
855
  return markdown ? /* @__PURE__ */ jsxRuntime.jsx(Markdown, { className: classNames, ...props, children }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames, ...props, children });
856
856
  };
857
- var Textarea = React7__namespace.forwardRef(({ className, ...props }, ref) => {
857
+ var Textarea = React18__namespace.forwardRef(({ className, ...props }, ref) => {
858
858
  return /* @__PURE__ */ jsxRuntime.jsx(
859
859
  "textarea",
860
860
  {
@@ -868,7 +868,7 @@ var Textarea = React7__namespace.forwardRef(({ className, ...props }, ref) => {
868
868
  );
869
869
  });
870
870
  Textarea.displayName = "Textarea";
871
- var PromptInputContext = React7.createContext({
871
+ var PromptInputContext = React18.createContext({
872
872
  isLoading: false,
873
873
  value: "",
874
874
  setValue: () => {
@@ -879,7 +879,7 @@ var PromptInputContext = React7.createContext({
879
879
  textareaRef: { current: null }
880
880
  });
881
881
  function usePromptInput() {
882
- return React7.useContext(PromptInputContext);
882
+ return React18.useContext(PromptInputContext);
883
883
  }
884
884
  function PromptInput({
885
885
  className,
@@ -893,8 +893,8 @@ function PromptInput({
893
893
  onClick,
894
894
  ...props
895
895
  }) {
896
- const [internalValue, setInternalValue] = React7.useState(value || "");
897
- const textareaRef = React7.useRef(null);
896
+ const [internalValue, setInternalValue] = React18.useState(value || "");
897
+ const textareaRef = React18.useRef(null);
898
898
  const handleChange = (newValue) => {
899
899
  setInternalValue(newValue);
900
900
  onValueChange?.(newValue);
@@ -951,7 +951,7 @@ function PromptInputTextarea({
951
951
  textareaRef.current = el;
952
952
  adjustHeight(el);
953
953
  };
954
- React7.useLayoutEffect(() => {
954
+ React18.useLayoutEffect(() => {
955
955
  if (!textareaRef.current || disableAutosize) return;
956
956
  const el = textareaRef.current;
957
957
  el.style.height = "auto";
@@ -1018,7 +1018,7 @@ function PromptInputAction({
1018
1018
  }
1019
1019
  var HoverCard = HoverCardPrimitive__namespace.Root;
1020
1020
  var HoverCardTrigger = HoverCardPrimitive__namespace.Trigger;
1021
- var HoverCardContent = React7__namespace.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1021
+ var HoverCardContent = React18__namespace.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1022
1022
  HoverCardPrimitive__namespace.Content,
1023
1023
  {
1024
1024
  ref,
@@ -1032,9 +1032,9 @@ var HoverCardContent = React7__namespace.forwardRef(({ className, align = "cente
1032
1032
  }
1033
1033
  ));
1034
1034
  HoverCardContent.displayName = HoverCardPrimitive__namespace.Content.displayName;
1035
- var SourceContext = React7.createContext(null);
1035
+ var SourceContext = React18.createContext(null);
1036
1036
  function useSourceContext() {
1037
- const ctx = React7.useContext(SourceContext);
1037
+ const ctx = React18.useContext(SourceContext);
1038
1038
  if (!ctx) throw new Error("Source.* must be used inside <Source>");
1039
1039
  return ctx;
1040
1040
  }
@@ -1118,11 +1118,11 @@ function SourceContent({
1118
1118
  }
1119
1119
  ) });
1120
1120
  }
1121
- var ReasoningContext = React7__namespace.createContext(
1121
+ var ReasoningContext = React18__namespace.createContext(
1122
1122
  null
1123
1123
  );
1124
1124
  function useReasoningContext() {
1125
- const context = React7__namespace.useContext(ReasoningContext);
1125
+ const context = React18__namespace.useContext(ReasoningContext);
1126
1126
  if (!context) {
1127
1127
  throw new Error(
1128
1128
  "Reasoning components must be used within a Reasoning provider"
@@ -1138,11 +1138,11 @@ function Reasoning({
1138
1138
  defaultOpen = false,
1139
1139
  className
1140
1140
  }) {
1141
- const [uncontrolledOpen, setUncontrolledOpen] = React7__namespace.useState(defaultOpen);
1142
- const prevStreamingRef = React7__namespace.useRef(isStreaming);
1141
+ const [uncontrolledOpen, setUncontrolledOpen] = React18__namespace.useState(defaultOpen);
1142
+ const prevStreamingRef = React18__namespace.useRef(isStreaming);
1143
1143
  const isControlled = controlledOpen !== void 0;
1144
1144
  const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
1145
- const setIsOpen = React7__namespace.useCallback(
1145
+ const setIsOpen = React18__namespace.useCallback(
1146
1146
  (open) => {
1147
1147
  if (onOpenChange) {
1148
1148
  onOpenChange(open);
@@ -1153,7 +1153,7 @@ function Reasoning({
1153
1153
  },
1154
1154
  [isControlled, onOpenChange]
1155
1155
  );
1156
- React7__namespace.useEffect(() => {
1156
+ React18__namespace.useEffect(() => {
1157
1157
  if (isStreaming && !prevStreamingRef.current) {
1158
1158
  setIsOpen(true);
1159
1159
  } else if (!isStreaming && prevStreamingRef.current) {
@@ -1209,9 +1209,9 @@ function ReasoningContent({
1209
1209
  className
1210
1210
  }) {
1211
1211
  const { isOpen } = useReasoningContext();
1212
- const contentRef = React7__namespace.useRef(null);
1213
- const [height, setHeight] = React7__namespace.useState(0);
1214
- React7__namespace.useEffect(() => {
1212
+ const contentRef = React18__namespace.useRef(null);
1213
+ const [height, setHeight] = React18__namespace.useState(0);
1214
+ React18__namespace.useEffect(() => {
1215
1215
  if (contentRef.current) {
1216
1216
  const resizeObserver = new ResizeObserver((entries) => {
1217
1217
  for (const entry of entries) {
@@ -1260,11 +1260,11 @@ function SimpleReasoning({
1260
1260
  /* @__PURE__ */ jsxRuntime.jsx(ReasoningContent, { markdown, children: content })
1261
1261
  ] });
1262
1262
  }
1263
- var CopilotUIContext = React7__namespace.createContext(
1263
+ var CopilotUIContext = React18__namespace.createContext(
1264
1264
  null
1265
1265
  );
1266
1266
  function useCopilotUI() {
1267
- const context = React7__namespace.useContext(CopilotUIContext);
1267
+ const context = React18__namespace.useContext(CopilotUIContext);
1268
1268
  if (!context) {
1269
1269
  return {
1270
1270
  debug: false,
@@ -1279,7 +1279,7 @@ function CopilotUIProvider({
1279
1279
  debug = false,
1280
1280
  defaultDebugExpanded = false
1281
1281
  }) {
1282
- const value = React7__namespace.useMemo(
1282
+ const value = React18__namespace.useMemo(
1283
1283
  () => ({
1284
1284
  debug,
1285
1285
  defaultDebugExpanded,
@@ -1421,7 +1421,7 @@ function ToolStep({
1421
1421
  }) {
1422
1422
  const { isDebug, defaultDebugExpanded } = useCopilotUI();
1423
1423
  const debug = debugProp ?? isDebug;
1424
- const [expanded, setExpanded] = React7__namespace.useState(
1424
+ const [expanded, setExpanded] = React18__namespace.useState(
1425
1425
  defaultExpanded ?? defaultDebugExpanded ?? false
1426
1426
  );
1427
1427
  const displayTitle = getDisplayTitle(step);
@@ -1644,6 +1644,22 @@ function ChevronUpIcon({ className }) {
1644
1644
  }
1645
1645
  );
1646
1646
  }
1647
+ function ChevronLeftIcon({ className }) {
1648
+ return /* @__PURE__ */ jsxRuntime.jsx(
1649
+ "svg",
1650
+ {
1651
+ xmlns: "http://www.w3.org/2000/svg",
1652
+ viewBox: "0 0 24 24",
1653
+ fill: "none",
1654
+ stroke: "currentColor",
1655
+ strokeWidth: "2",
1656
+ strokeLinecap: "round",
1657
+ strokeLinejoin: "round",
1658
+ className,
1659
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m15 18-6-6 6-6" })
1660
+ }
1661
+ );
1662
+ }
1647
1663
  function CopyIcon({ className }) {
1648
1664
  return /* @__PURE__ */ jsxRuntime.jsxs(
1649
1665
  "svg",
@@ -1886,9 +1902,9 @@ function ArrowUpRightIcon({ className }) {
1886
1902
  }
1887
1903
  );
1888
1904
  }
1889
- var ConfirmationContext = React7__namespace.createContext(null);
1905
+ var ConfirmationContext = React18__namespace.createContext(null);
1890
1906
  function useConfirmationContext() {
1891
- const context = React7__namespace.useContext(ConfirmationContext);
1907
+ const context = React18__namespace.useContext(ConfirmationContext);
1892
1908
  if (!context) {
1893
1909
  throw new Error(
1894
1910
  "Confirmation components must be used within a Confirmation provider"
@@ -2060,8 +2076,8 @@ function PermissionConfirmation({
2060
2076
  permissionOptions = DEFAULT_PERMISSION_OPTIONS,
2061
2077
  className
2062
2078
  }) {
2063
- const [selectedPermission, setSelectedPermission] = React7__namespace.useState("ask");
2064
- const [showOptions, setShowOptions] = React7__namespace.useState(false);
2079
+ const [selectedPermission, setSelectedPermission] = React18__namespace.useState("ask");
2080
+ const [showOptions, setShowOptions] = React18__namespace.useState(false);
2065
2081
  const handleApprove = () => {
2066
2082
  onApprove?.(selectedPermission);
2067
2083
  };
@@ -2191,7 +2207,7 @@ function CompactPermissionConfirmation({
2191
2207
  onReject,
2192
2208
  className
2193
2209
  }) {
2194
- const [rememberChoice, setRememberChoice] = React7__namespace.useState(false);
2210
+ const [rememberChoice, setRememberChoice] = React18__namespace.useState(false);
2195
2211
  const handleApprove = () => {
2196
2212
  onApprove?.(rememberChoice ? "allow_always" : "ask");
2197
2213
  };
@@ -2308,8 +2324,8 @@ function DevLogger({
2308
2324
  position = "bottom-right",
2309
2325
  className
2310
2326
  }) {
2311
- const [isOpen, setIsOpen] = React7.useState(false);
2312
- const [activeTab, setActiveTab] = React7.useState("chat");
2327
+ const [isOpen, setIsOpen] = React18.useState(false);
2328
+ const [activeTab, setActiveTab] = React18.useState("chat");
2313
2329
  const positionClasses = {
2314
2330
  "bottom-left": "bottom-4 left-4",
2315
2331
  "bottom-right": "bottom-4 right-4",
@@ -2734,9 +2750,9 @@ function ModelSelector({
2734
2750
  showCapabilities = true,
2735
2751
  className
2736
2752
  }) {
2737
- const [isOpen, setIsOpen] = React7__namespace.useState(false);
2738
- const containerRef = React7__namespace.useRef(null);
2739
- React7__namespace.useEffect(() => {
2753
+ const [isOpen, setIsOpen] = React18__namespace.useState(false);
2754
+ const containerRef = React18__namespace.useRef(null);
2755
+ React18__namespace.useEffect(() => {
2740
2756
  function handleClickOutside(event) {
2741
2757
  if (containerRef.current && !containerRef.current.contains(event.target)) {
2742
2758
  setIsOpen(false);
@@ -2745,7 +2761,7 @@ function ModelSelector({
2745
2761
  document.addEventListener("mousedown", handleClickOutside);
2746
2762
  return () => document.removeEventListener("mousedown", handleClickOutside);
2747
2763
  }, []);
2748
- const selectedModel = React7__namespace.useMemo(() => {
2764
+ const selectedModel = React18__namespace.useMemo(() => {
2749
2765
  if (!value) return null;
2750
2766
  if (providers) {
2751
2767
  for (const provider of providers) {
@@ -2971,7 +2987,7 @@ function PopoverTrigger({
2971
2987
  className,
2972
2988
  ...props
2973
2989
  }) {
2974
- if (asChild && React7__namespace.isValidElement(children)) {
2990
+ if (asChild && React18__namespace.isValidElement(children)) {
2975
2991
  return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Trigger, { render: children, className, ...props });
2976
2992
  }
2977
2993
  return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Trigger, { className, ...props, children });
@@ -3106,8 +3122,8 @@ function ThreadPicker({
3106
3122
  itemClassName,
3107
3123
  newButtonClassName
3108
3124
  }) {
3109
- const [isOpen, setIsOpen] = React7__namespace.useState(false);
3110
- const selectedThread = React7__namespace.useMemo(() => {
3125
+ const [isOpen, setIsOpen] = React18__namespace.useState(false);
3126
+ const selectedThread = React18__namespace.useMemo(() => {
3111
3127
  if (!value) return null;
3112
3128
  return threads.find((t) => t.id === value) ?? null;
3113
3129
  }, [value, threads]);
@@ -3313,7 +3329,7 @@ function ThreadCard({
3313
3329
  showDelete = true,
3314
3330
  className
3315
3331
  }) {
3316
- const [isHovered, setIsHovered] = React7__namespace.useState(false);
3332
+ const [isHovered, setIsHovered] = React18__namespace.useState(false);
3317
3333
  const handleDelete = (e) => {
3318
3334
  e.stopPropagation();
3319
3335
  onDelete?.();
@@ -3564,7 +3580,7 @@ function DefaultMessage({
3564
3580
  }) {
3565
3581
  const isUser = message.role === "user";
3566
3582
  const isStreaming = isLastMessage && isLoading;
3567
- const { cleanContent, followUps } = React7__namespace.useMemo(() => {
3583
+ const { cleanContent, followUps } = React18__namespace.useMemo(() => {
3568
3584
  if (isUser || !message.content) {
3569
3585
  return { cleanContent: message.content, followUps: [] };
3570
3586
  }
@@ -3703,7 +3719,7 @@ function DefaultMessage({
3703
3719
  toolName: exec.name
3704
3720
  };
3705
3721
  const output = toolDef.render(renderProps);
3706
- return /* @__PURE__ */ jsxRuntime.jsx(React7__namespace.Fragment, { children: output }, exec.id);
3722
+ return /* @__PURE__ */ jsxRuntime.jsx(React18__namespace.Fragment, { children: output }, exec.id);
3707
3723
  }
3708
3724
  return null;
3709
3725
  }) }),
@@ -3739,7 +3755,7 @@ function DefaultMessage({
3739
3755
  approval: approvalCallbacks
3740
3756
  };
3741
3757
  const output = toolDef.render(renderProps);
3742
- return /* @__PURE__ */ jsxRuntime.jsx(React7__namespace.Fragment, { children: output }, tool.id);
3758
+ return /* @__PURE__ */ jsxRuntime.jsx(React18__namespace.Fragment, { children: output }, tool.id);
3743
3759
  }
3744
3760
  return /* @__PURE__ */ jsxRuntime.jsx(
3745
3761
  PermissionConfirmation,
@@ -3771,7 +3787,7 @@ function DefaultMessage({
3771
3787
  ] });
3772
3788
  }
3773
3789
  function AttachmentPreview({ attachment }) {
3774
- const [expanded, setExpanded] = React7__namespace.useState(false);
3790
+ const [expanded, setExpanded] = React18__namespace.useState(false);
3775
3791
  if (attachment.type !== "image") {
3776
3792
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 rounded-lg border bg-muted/50 px-3 py-2 text-sm", children: [
3777
3793
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: attachment.type }),
@@ -3900,10 +3916,10 @@ function ChatWelcome({
3900
3916
  processAttachment: processAttachmentProp,
3901
3917
  classNames = {}
3902
3918
  }) {
3903
- const [input, setInput] = React7.useState("");
3904
- const [pendingAttachments, setPendingAttachments] = React7.useState([]);
3905
- const fileInputRef = React7.useRef(null);
3906
- const fileInputId = React7.useId();
3919
+ const [input, setInput] = React18.useState("");
3920
+ const [pendingAttachments, setPendingAttachments] = React18.useState([]);
3921
+ const fileInputRef = React18.useRef(null);
3922
+ const fileInputId = React18.useId();
3907
3923
  const title = config?.title ?? DEFAULT_TITLE;
3908
3924
  const subtitle = config?.subtitle ?? DEFAULT_SUBTITLE;
3909
3925
  const logo = config?.logo;
@@ -3912,7 +3928,7 @@ function ChatWelcome({
3912
3928
  config?.recentChatsLabel ?? DEFAULT_RECENT_CHATS_LABEL;
3913
3929
  const maxRecentChats = config?.maxRecentChats ?? DEFAULT_MAX_RECENT_CHATS;
3914
3930
  config?.viewMoreLabel ?? DEFAULT_VIEW_MORE_LABEL;
3915
- const isFileTypeAllowed = React7.useCallback(
3931
+ const isFileTypeAllowed = React18.useCallback(
3916
3932
  (file) => {
3917
3933
  for (const type of allowedFileTypes) {
3918
3934
  if (type.endsWith("/*")) {
@@ -3926,7 +3942,7 @@ function ChatWelcome({
3926
3942
  },
3927
3943
  [allowedFileTypes]
3928
3944
  );
3929
- const handleFileSelect = React7.useCallback(
3945
+ const handleFileSelect = React18.useCallback(
3930
3946
  async (files) => {
3931
3947
  if (!files || !attachmentsEnabled) return;
3932
3948
  for (const file of Array.from(files)) {
@@ -3989,7 +4005,7 @@ function ChatWelcome({
3989
4005
  },
3990
4006
  [attachmentsEnabled, maxFileSize, isFileTypeAllowed, processAttachmentProp]
3991
4007
  );
3992
- const handleInputChange = React7.useCallback(
4008
+ const handleInputChange = React18.useCallback(
3993
4009
  (e) => {
3994
4010
  handleFileSelect(e.target.files);
3995
4011
  if (fileInputRef.current) {
@@ -3998,7 +4014,7 @@ function ChatWelcome({
3998
4014
  },
3999
4015
  [handleFileSelect]
4000
4016
  );
4001
- const removePendingAttachment = React7.useCallback((id) => {
4017
+ const removePendingAttachment = React18.useCallback((id) => {
4002
4018
  setPendingAttachments((prev) => {
4003
4019
  const att = prev.find((a) => a.id === id);
4004
4020
  if (att) {
@@ -4007,7 +4023,7 @@ function ChatWelcome({
4007
4023
  return prev.filter((a) => a.id !== id);
4008
4024
  });
4009
4025
  }, []);
4010
- const handleSubmit = React7.useCallback(() => {
4026
+ const handleSubmit = React18.useCallback(() => {
4011
4027
  const hasContent = input.trim();
4012
4028
  const hasAttachments = pendingAttachments.some(
4013
4029
  (att) => att.status === "ready"
@@ -4019,7 +4035,7 @@ function ChatWelcome({
4019
4035
  setPendingAttachments([]);
4020
4036
  setInput("");
4021
4037
  }, [input, isLoading, onSendMessage, pendingAttachments]);
4022
- const handleSuggestionClick = React7.useCallback(
4038
+ const handleSuggestionClick = React18.useCallback(
4023
4039
  (suggestion) => {
4024
4040
  onSendMessage(suggestion);
4025
4041
  },
@@ -4191,6 +4207,199 @@ function ChatWelcome({
4191
4207
  }
4192
4208
  );
4193
4209
  }
4210
+ var CopilotChatContext = React18.createContext(
4211
+ null
4212
+ );
4213
+ var useCopilotChatContext = () => {
4214
+ const ctx = React18.useContext(CopilotChatContext);
4215
+ if (!ctx) {
4216
+ throw new Error(
4217
+ "useCopilotChatContext must be used within CopilotChat. Make sure you're using CopilotChat.Home, CopilotChat.Input, etc. inside <CopilotChat>"
4218
+ );
4219
+ }
4220
+ return ctx;
4221
+ };
4222
+ function HomeView({ children, className }) {
4223
+ const { view } = useCopilotChatContext();
4224
+ if (view !== "home") return null;
4225
+ return /* @__PURE__ */ jsxRuntime.jsx(
4226
+ "div",
4227
+ {
4228
+ className: cn(
4229
+ "csdk-chat-home-view flex flex-1 flex-col overflow-auto",
4230
+ className
4231
+ ),
4232
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-center my-auto w-full", children })
4233
+ }
4234
+ );
4235
+ }
4236
+ var Home = HomeView;
4237
+ function ChatView({ children, className }) {
4238
+ const { view } = useCopilotChatContext();
4239
+ if (view !== "chat") return null;
4240
+ if (children) {
4241
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("csdk-chat-view flex flex-col", className), children });
4242
+ }
4243
+ return null;
4244
+ }
4245
+ ChatView.displayName = "ChatView";
4246
+ function chatViewHasOnlyLayoutChildren(chatViewElement) {
4247
+ if (!chatViewElement?.props?.children) return false;
4248
+ const childArray = React18__namespace.default.Children.toArray(chatViewElement.props.children);
4249
+ if (childArray.length === 0) return false;
4250
+ return childArray.every(
4251
+ (child) => React18__namespace.default.isValidElement(child) && (child.type === Header || child.type === Footer)
4252
+ );
4253
+ }
4254
+ function Header({ children, className }) {
4255
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("csdk-chat-header", className), children });
4256
+ }
4257
+ function Footer({ children, className }) {
4258
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("csdk-chat-footer", className), children });
4259
+ }
4260
+ function Input({ placeholder: placeholderProp, className }) {
4261
+ const {
4262
+ send,
4263
+ isLoading,
4264
+ onStop,
4265
+ placeholder: defaultPlaceholder
4266
+ } = useCopilotChatContext();
4267
+ const [value, setValue] = React18.useState("");
4268
+ const handleSubmit = React18.useCallback(() => {
4269
+ if (value.trim() && !isLoading) {
4270
+ send(value.trim());
4271
+ setValue("");
4272
+ }
4273
+ }, [value, isLoading, send]);
4274
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4275
+ PromptInput,
4276
+ {
4277
+ value,
4278
+ onValueChange: setValue,
4279
+ isLoading,
4280
+ onSubmit: handleSubmit,
4281
+ className: cn("csdk-compound-input", className),
4282
+ children: [
4283
+ /* @__PURE__ */ jsxRuntime.jsx(
4284
+ PromptInputTextarea,
4285
+ {
4286
+ placeholder: placeholderProp ?? defaultPlaceholder
4287
+ }
4288
+ ),
4289
+ /* @__PURE__ */ jsxRuntime.jsx(PromptInputActions, { className: "justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(PromptInputAction, { tooltip: isLoading ? "Stop" : "Send", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(
4290
+ Button,
4291
+ {
4292
+ size: "sm",
4293
+ variant: "destructive",
4294
+ className: "csdk-button-stop rounded-full size-9",
4295
+ onClick: onStop,
4296
+ children: /* @__PURE__ */ jsxRuntime.jsx(StopIcon, { className: "h-4 w-4" })
4297
+ }
4298
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
4299
+ Button,
4300
+ {
4301
+ size: "sm",
4302
+ className: "csdk-button-send rounded-full size-9",
4303
+ onClick: handleSubmit,
4304
+ disabled: !value.trim(),
4305
+ children: /* @__PURE__ */ jsxRuntime.jsx(ArrowUpIcon, { className: "h-4 w-4" })
4306
+ }
4307
+ ) }) })
4308
+ ]
4309
+ }
4310
+ );
4311
+ }
4312
+ function SuggestionsCompound({
4313
+ items,
4314
+ label,
4315
+ className,
4316
+ buttonClassName
4317
+ }) {
4318
+ const { send } = useCopilotChatContext();
4319
+ if (items.length === 0) return null;
4320
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("csdk-compound-suggestions", className), children: [
4321
+ label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground mb-2 block", children: label }),
4322
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(
4323
+ "button",
4324
+ {
4325
+ onClick: () => send(item),
4326
+ className: cn(
4327
+ "csdk-followup-button px-3 py-1.5 text-sm rounded-full border",
4328
+ "bg-background hover:bg-accent transition-colors",
4329
+ buttonClassName
4330
+ ),
4331
+ children: item
4332
+ },
4333
+ i
4334
+ )) })
4335
+ ] });
4336
+ }
4337
+ function BackButton({
4338
+ className,
4339
+ children,
4340
+ disabled,
4341
+ "aria-label": ariaLabel = "Start new chat"
4342
+ }) {
4343
+ const { onNewChat, isThreadBusy } = useCopilotChatContext();
4344
+ if (!onNewChat) return null;
4345
+ return /* @__PURE__ */ jsxRuntime.jsx(
4346
+ "button",
4347
+ {
4348
+ type: "button",
4349
+ onClick: onNewChat,
4350
+ disabled: disabled || isThreadBusy,
4351
+ "aria-label": ariaLabel,
4352
+ className: cn(
4353
+ "csdk-back-button flex items-center gap-1 text-sm",
4354
+ "hover:bg-accent rounded px-2 py-1",
4355
+ "disabled:opacity-50 disabled:cursor-not-allowed",
4356
+ className
4357
+ ),
4358
+ children: children || /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4359
+ /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, { className: "h-4 w-4" }),
4360
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "New Chat" })
4361
+ ] })
4362
+ }
4363
+ );
4364
+ }
4365
+ function ThreadPickerCompound(props) {
4366
+ const {
4367
+ threads,
4368
+ currentThreadId,
4369
+ onSwitchThread,
4370
+ onNewChat,
4371
+ onDeleteThread,
4372
+ isThreadBusy
4373
+ } = useCopilotChatContext();
4374
+ if (!threads || !onSwitchThread) return null;
4375
+ return /* @__PURE__ */ jsxRuntime.jsx(
4376
+ ThreadPicker,
4377
+ {
4378
+ ...props,
4379
+ value: currentThreadId,
4380
+ threads,
4381
+ onSelect: onSwitchThread,
4382
+ onNewThread: onNewChat,
4383
+ onDeleteThread,
4384
+ disabled: isThreadBusy
4385
+ }
4386
+ );
4387
+ }
4388
+ function hasCompoundChild(children, ...components) {
4389
+ return React18__namespace.default.Children.toArray(children).some(
4390
+ (child) => React18__namespace.default.isValidElement(child) && components.includes(child.type)
4391
+ );
4392
+ }
4393
+ function findCompoundChild(children, component) {
4394
+ return React18__namespace.default.Children.toArray(children).find(
4395
+ (child) => React18__namespace.default.isValidElement(child) && child.type === component
4396
+ );
4397
+ }
4398
+ function filterCompoundChildren(children, ...components) {
4399
+ return React18__namespace.default.Children.toArray(children).filter(
4400
+ (child) => React18__namespace.default.isValidElement(child) && components.includes(child.type)
4401
+ );
4402
+ }
4194
4403
  var DEFAULT_MAX_FILE_SIZE2 = 5 * 1024 * 1024;
4195
4404
  var DEFAULT_ALLOWED_TYPES2 = ["image/*", "application/pdf"];
4196
4405
  function getAttachmentType2(mimeType) {
@@ -4216,12 +4425,14 @@ function fileToBase642(file) {
4216
4425
  function generateAttachmentId2() {
4217
4426
  return `att_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
4218
4427
  }
4219
- function Chat({
4428
+ function ChatComponent({
4220
4429
  // Core
4221
4430
  messages = [],
4222
4431
  onSendMessage,
4223
4432
  onStop,
4224
4433
  isLoading = false,
4434
+ // Compound children
4435
+ children,
4225
4436
  // Labels
4226
4437
  placeholder = "Type a message...",
4227
4438
  welcomeMessage,
@@ -4272,14 +4483,20 @@ function Chat({
4272
4483
  renderHeader,
4273
4484
  // Styling
4274
4485
  className,
4275
- classNames = {}
4486
+ classNames = {},
4487
+ // Thread management for compound components
4488
+ onNewChat,
4489
+ threads,
4490
+ currentThreadId,
4491
+ onSwitchThread,
4492
+ isThreadBusy
4276
4493
  }) {
4277
- const [input, setInput] = React7.useState("");
4278
- const [pendingAttachments, setPendingAttachments] = React7.useState([]);
4279
- const [isDragging, setIsDragging] = React7.useState(false);
4280
- const fileInputRef = React7.useRef(null);
4281
- const fileInputId = React7.useId();
4282
- const isFileTypeAllowed = React7.useCallback(
4494
+ const [input, setInput] = React18.useState("");
4495
+ const [pendingAttachments, setPendingAttachments] = React18.useState([]);
4496
+ const [isDragging, setIsDragging] = React18.useState(false);
4497
+ const fileInputRef = React18.useRef(null);
4498
+ const fileInputId = React18.useId();
4499
+ const isFileTypeAllowed = React18.useCallback(
4283
4500
  (file) => {
4284
4501
  for (const type of allowedFileTypes) {
4285
4502
  if (type.endsWith("/*")) {
@@ -4293,7 +4510,7 @@ function Chat({
4293
4510
  },
4294
4511
  [allowedFileTypes]
4295
4512
  );
4296
- const handleFileSelect = React7.useCallback(
4513
+ const handleFileSelect = React18.useCallback(
4297
4514
  async (files) => {
4298
4515
  if (!files || !attachmentsEnabled) return;
4299
4516
  for (const file of Array.from(files)) {
@@ -4356,7 +4573,7 @@ function Chat({
4356
4573
  },
4357
4574
  [attachmentsEnabled, maxFileSize, isFileTypeAllowed, processAttachmentProp]
4358
4575
  );
4359
- const handleInputChange = React7.useCallback(
4576
+ const handleInputChange = React18.useCallback(
4360
4577
  (e) => {
4361
4578
  handleFileSelect(e.target.files);
4362
4579
  if (fileInputRef.current) {
@@ -4365,7 +4582,7 @@ function Chat({
4365
4582
  },
4366
4583
  [handleFileSelect]
4367
4584
  );
4368
- const removePendingAttachment = React7.useCallback((id) => {
4585
+ const removePendingAttachment = React18.useCallback((id) => {
4369
4586
  setPendingAttachments((prev) => {
4370
4587
  const att = prev.find((a) => a.id === id);
4371
4588
  if (att) {
@@ -4374,7 +4591,7 @@ function Chat({
4374
4591
  return prev.filter((a) => a.id !== id);
4375
4592
  });
4376
4593
  }, []);
4377
- const handleDragOver = React7.useCallback(
4594
+ const handleDragOver = React18.useCallback(
4378
4595
  (e) => {
4379
4596
  e.preventDefault();
4380
4597
  e.stopPropagation();
@@ -4384,12 +4601,12 @@ function Chat({
4384
4601
  },
4385
4602
  [attachmentsEnabled]
4386
4603
  );
4387
- const handleDragLeave = React7.useCallback((e) => {
4604
+ const handleDragLeave = React18.useCallback((e) => {
4388
4605
  e.preventDefault();
4389
4606
  e.stopPropagation();
4390
4607
  setIsDragging(false);
4391
4608
  }, []);
4392
- const handleDrop = React7.useCallback(
4609
+ const handleDrop = React18.useCallback(
4393
4610
  (e) => {
4394
4611
  e.preventDefault();
4395
4612
  e.stopPropagation();
@@ -4400,7 +4617,7 @@ function Chat({
4400
4617
  },
4401
4618
  [attachmentsEnabled, handleFileSelect]
4402
4619
  );
4403
- const handleSubmit = React7.useCallback(() => {
4620
+ const handleSubmit = React18.useCallback(() => {
4404
4621
  const hasContent = input.trim();
4405
4622
  const hasAttachments = pendingAttachments.some(
4406
4623
  (att) => att.status === "ready"
@@ -4412,7 +4629,7 @@ function Chat({
4412
4629
  setPendingAttachments([]);
4413
4630
  setInput("");
4414
4631
  }, [input, isLoading, onSendMessage, pendingAttachments]);
4415
- const handleSuggestionClick = React7.useCallback(
4632
+ const handleSuggestionClick = React18.useCallback(
4416
4633
  (suggestion) => {
4417
4634
  if (onSuggestionClick) {
4418
4635
  onSuggestionClick(suggestion);
@@ -4423,9 +4640,60 @@ function Chat({
4423
4640
  [onSuggestionClick, onSendMessage]
4424
4641
  );
4425
4642
  const acceptString = allowedFileTypes.join(",");
4426
- const showWelcome = messages.length === 0 && welcome !== false;
4643
+ const view = messages.length === 0 ? "home" : "chat";
4644
+ const hasCustomHome = hasCompoundChild(children, Home, HomeView);
4645
+ const hasCustomChatView = hasCompoundChild(children, ChatView);
4646
+ const hasCustomLayout = hasCustomHome || hasCustomChatView;
4647
+ const rootHeader = findCompoundChild(children, Header);
4648
+ const rootFooter = findCompoundChild(children, Footer);
4649
+ const viewChildren = filterCompoundChildren(
4650
+ children,
4651
+ HomeView,
4652
+ Home,
4653
+ ChatView
4654
+ );
4655
+ const chatViewElement = findCompoundChild(children, ChatView);
4656
+ const chatViewNeedsDefault = chatViewElement && (!chatViewElement.props.children || chatViewHasOnlyLayoutChildren(chatViewElement));
4657
+ const showDefaultWelcome = view === "home" && !hasCustomHome && welcome !== false;
4427
4658
  const welcomeConfig = typeof welcome === "object" ? welcome : void 0;
4428
- return /* @__PURE__ */ jsxRuntime.jsxs(
4659
+ const send = React18.useCallback(
4660
+ (message, attachments) => {
4661
+ onSendMessage?.(message, attachments);
4662
+ },
4663
+ [onSendMessage]
4664
+ );
4665
+ const contextValue = React18__namespace.default.useMemo(
4666
+ () => ({
4667
+ view,
4668
+ send,
4669
+ isLoading,
4670
+ onStop,
4671
+ attachmentsEnabled,
4672
+ placeholder,
4673
+ // Thread management - passed from connected-chat
4674
+ onNewChat,
4675
+ threads,
4676
+ currentThreadId,
4677
+ onSwitchThread,
4678
+ onDeleteThread,
4679
+ isThreadBusy
4680
+ }),
4681
+ [
4682
+ view,
4683
+ send,
4684
+ isLoading,
4685
+ onStop,
4686
+ attachmentsEnabled,
4687
+ placeholder,
4688
+ onNewChat,
4689
+ threads,
4690
+ currentThreadId,
4691
+ onSwitchThread,
4692
+ onDeleteThread,
4693
+ isThreadBusy
4694
+ ]
4695
+ );
4696
+ return /* @__PURE__ */ jsxRuntime.jsx(CopilotChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
4429
4697
  "div",
4430
4698
  {
4431
4699
  className: cn(
@@ -4449,8 +4717,10 @@ function Chat({
4449
4717
  className: classNames.header
4450
4718
  }
4451
4719
  )),
4452
- showWelcome ? (
4453
- /* Welcome Screen (centered input) */
4720
+ rootHeader,
4721
+ hasCustomLayout && viewChildren,
4722
+ showDefaultWelcome ? (
4723
+ /* Default Welcome Screen (centered input) */
4454
4724
  /* @__PURE__ */ jsxRuntime.jsx(
4455
4725
  ChatWelcome,
4456
4726
  {
@@ -4471,249 +4741,265 @@ function Chat({
4471
4741
  processAttachment: processAttachmentProp
4472
4742
  }
4473
4743
  )
4474
- ) : (
4475
- /* Normal Chat UI (messages + input at bottom) */
4476
- /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4477
- /* @__PURE__ */ jsxRuntime.jsxs(
4478
- ChatContainerRoot,
4479
- {
4480
- className: cn("relative flex-1", classNames.container),
4481
- children: [
4482
- /* @__PURE__ */ jsxRuntime.jsxs(
4483
- ChatContainerContent,
4484
- {
4485
- className: cn("gap-4 p-4", classNames.messageList),
4486
- children: [
4487
- messages.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center text-muted-foreground", children: welcomeMessage || "Send a message to start the conversation" }),
4488
- messages.map((message, index) => {
4489
- const isLastMessage = index === messages.length - 1;
4490
- const isEmptyAssistant = message.role === "assistant" && !message.content?.trim();
4491
- const hasToolCalls = message.tool_calls && message.tool_calls.length > 0;
4492
- const hasToolExecutions = message.toolExecutions && message.toolExecutions.length > 0;
4493
- const hasPendingApprovals = message.toolExecutions?.some(
4494
- (exec) => exec.approvalStatus === "required"
4495
- );
4496
- if (isEmptyAssistant) {
4497
- if (hasToolCalls || hasToolExecutions) ; else if (isLastMessage && hasPendingApprovals) ; else if (isLastMessage && isLoading && !isProcessing) {
4498
- return /* @__PURE__ */ jsxRuntime.jsxs(Message, { className: "flex gap-2", children: [
4499
- /* @__PURE__ */ jsxRuntime.jsx(
4500
- MessageAvatar,
4501
- {
4502
- src: assistantAvatar.src || "",
4503
- alt: "Assistant",
4504
- fallback: assistantAvatar.fallback,
4505
- fallbackIcon: !assistantAvatar.src ? /* @__PURE__ */ jsxRuntime.jsx(copilot_sdk_logo_default, { className: "size-5" }) : void 0,
4506
- className: "bg-background"
4507
- }
4508
- ),
4509
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-muted px-4 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(Loader, { variant: loaderVariant, size: "sm" }) })
4510
- ] }, message.id);
4511
- } else {
4512
- return null;
4513
- }
4514
- }
4515
- const savedExecutions = message.metadata?.toolExecutions;
4516
- const messageToolExecutions = message.toolExecutions || savedExecutions;
4517
- const messageWithExecutions = messageToolExecutions ? { ...message, toolExecutions: messageToolExecutions } : message;
4518
- const handleFollowUpClick = (question) => {
4519
- if (onSuggestionClick) {
4520
- onSuggestionClick(question);
4521
- } else {
4522
- onSendMessage?.(question);
4523
- }
4524
- };
4525
- return renderMessage ? /* @__PURE__ */ jsxRuntime.jsx(React7__namespace.default.Fragment, { children: renderMessage(messageWithExecutions, index) }, message.id) : /* @__PURE__ */ jsxRuntime.jsx(
4526
- DefaultMessage,
4527
- {
4528
- message: messageWithExecutions,
4529
- userAvatar,
4530
- assistantAvatar,
4531
- showUserAvatar,
4532
- userMessageClassName: classNames.userMessage,
4533
- assistantMessageClassName: classNames.assistantMessage,
4534
- size: fontSize,
4535
- isLastMessage,
4536
- isLoading,
4537
- registeredTools,
4538
- toolRenderers,
4539
- onApproveToolExecution,
4540
- onRejectToolExecution,
4541
- showFollowUps,
4542
- onFollowUpClick: handleFollowUpClick,
4543
- followUpClassName,
4544
- followUpButtonClassName
4545
- },
4546
- message.id
4547
- );
4548
- }),
4549
- isProcessing && /* @__PURE__ */ jsxRuntime.jsxs(Message, { className: "flex gap-2", children: [
4550
- /* @__PURE__ */ jsxRuntime.jsx(
4551
- MessageAvatar,
4552
- {
4553
- src: assistantAvatar?.src || "",
4554
- alt: "Assistant",
4555
- fallback: assistantAvatar?.fallback || "AI",
4556
- fallbackIcon: !assistantAvatar?.src ? /* @__PURE__ */ jsxRuntime.jsx(copilot_sdk_logo_default, { className: "size-5" }) : void 0,
4557
- className: "bg-background"
4558
- }
4559
- ),
4560
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-muted px-4 py-2 flex items-center gap-2", children: [
4561
- /* @__PURE__ */ jsxRuntime.jsx(Loader, { variant: "dots", size: "sm" }),
4562
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Continuing..." })
4563
- ] })
4564
- ] }),
4565
- isLoading && !isProcessing && (() => {
4566
- const lastMessage = messages[messages.length - 1];
4567
- if (lastMessage?.role === "user") {
4744
+ ) : null,
4745
+ view === "chat" && (!hasCustomChatView || chatViewNeedsDefault) && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4746
+ /* @__PURE__ */ jsxRuntime.jsxs(
4747
+ ChatContainerRoot,
4748
+ {
4749
+ className: cn("relative flex-1", classNames.container),
4750
+ children: [
4751
+ /* @__PURE__ */ jsxRuntime.jsxs(
4752
+ ChatContainerContent,
4753
+ {
4754
+ className: cn("gap-4 p-4", classNames.messageList),
4755
+ children: [
4756
+ messages.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center text-muted-foreground", children: welcomeMessage || "Send a message to start the conversation" }),
4757
+ messages.map((message, index) => {
4758
+ const isLastMessage = index === messages.length - 1;
4759
+ const isEmptyAssistant = message.role === "assistant" && !message.content?.trim();
4760
+ const hasToolCalls = message.tool_calls && message.tool_calls.length > 0;
4761
+ const hasToolExecutions = message.toolExecutions && message.toolExecutions.length > 0;
4762
+ const hasPendingApprovals = message.toolExecutions?.some(
4763
+ (exec) => exec.approvalStatus === "required"
4764
+ );
4765
+ if (isEmptyAssistant) {
4766
+ if (hasToolCalls || hasToolExecutions) ; else if (isLastMessage && hasPendingApprovals) ; else if (isLastMessage && isLoading && !isProcessing) {
4568
4767
  return /* @__PURE__ */ jsxRuntime.jsxs(Message, { className: "flex gap-2", children: [
4569
4768
  /* @__PURE__ */ jsxRuntime.jsx(
4570
4769
  MessageAvatar,
4571
4770
  {
4572
- src: assistantAvatar?.src || "",
4771
+ src: assistantAvatar.src || "",
4573
4772
  alt: "Assistant",
4574
- fallback: assistantAvatar?.fallback || "AI",
4575
- fallbackIcon: !assistantAvatar?.src ? /* @__PURE__ */ jsxRuntime.jsx(copilot_sdk_logo_default, { className: "size-5" }) : void 0,
4773
+ fallback: assistantAvatar.fallback,
4774
+ fallbackIcon: !assistantAvatar.src ? /* @__PURE__ */ jsxRuntime.jsx(copilot_sdk_logo_default, { className: "size-5" }) : void 0,
4576
4775
  className: "bg-background"
4577
4776
  }
4578
4777
  ),
4579
4778
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-muted px-4 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(Loader, { variant: loaderVariant, size: "sm" }) })
4580
- ] });
4779
+ ] }, message.id);
4780
+ } else {
4781
+ return null;
4581
4782
  }
4582
- return null;
4583
- })(),
4584
- /* @__PURE__ */ jsxRuntime.jsx(ChatContainerScrollAnchor, {})
4585
- ]
4586
- }
4587
- ),
4588
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-4 bottom-4", children: /* @__PURE__ */ jsxRuntime.jsx(ScrollButton, { className: "shadow-sm" }) })
4589
- ]
4590
- }
4591
- ),
4592
- suggestions.length > 0 && !isLoading && /* @__PURE__ */ jsxRuntime.jsx(
4593
- Suggestions,
4594
- {
4595
- suggestions,
4596
- onSuggestionClick: handleSuggestionClick,
4597
- className: classNames.suggestions
4598
- }
4599
- ),
4600
- renderInput ? renderInput() : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("p-2 pt-0", classNames.input), children: [
4601
- pendingAttachments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2 p-2 mb-2 bg-muted/30 rounded-lg", children: pendingAttachments.map((att) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group", children: [
4602
- att.attachment.type === "image" ? /* @__PURE__ */ jsxRuntime.jsx(
4603
- "img",
4604
- {
4605
- src: att.previewUrl,
4606
- alt: att.file.name,
4607
- className: "w-16 h-16 object-cover rounded-lg border"
4608
- }
4609
- ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-16 h-16 bg-muted rounded-lg border flex flex-col items-center justify-center p-1", children: [
4610
- /* @__PURE__ */ jsxRuntime.jsx(
4611
- "svg",
4612
- {
4613
- className: "w-6 h-6 text-muted-foreground",
4614
- fill: "none",
4615
- viewBox: "0 0 24 24",
4616
- stroke: "currentColor",
4617
- children: /* @__PURE__ */ jsxRuntime.jsx(
4618
- "path",
4619
- {
4620
- strokeLinecap: "round",
4621
- strokeLinejoin: "round",
4622
- strokeWidth: 1.5,
4623
- d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
4624
4783
  }
4625
- )
4626
- }
4627
- ),
4628
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground truncate w-full text-center mt-1", children: att.file.name.length > 10 ? att.file.name.slice(0, 8) + "..." : att.file.name })
4629
- ] }),
4630
- att.status === "processing" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-background/80 rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(Loader, { variant: "dots", size: "sm" }) }),
4631
- att.status === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-destructive/20 rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive text-xs", children: "Error" }) }),
4784
+ const savedExecutions = message.metadata?.toolExecutions;
4785
+ const messageToolExecutions = message.toolExecutions || savedExecutions;
4786
+ const messageWithExecutions = messageToolExecutions ? { ...message, toolExecutions: messageToolExecutions } : message;
4787
+ const handleFollowUpClick = (question) => {
4788
+ if (onSuggestionClick) {
4789
+ onSuggestionClick(question);
4790
+ } else {
4791
+ onSendMessage?.(question);
4792
+ }
4793
+ };
4794
+ return renderMessage ? /* @__PURE__ */ jsxRuntime.jsx(React18__namespace.default.Fragment, { children: renderMessage(messageWithExecutions, index) }, message.id) : /* @__PURE__ */ jsxRuntime.jsx(
4795
+ DefaultMessage,
4796
+ {
4797
+ message: messageWithExecutions,
4798
+ userAvatar,
4799
+ assistantAvatar,
4800
+ showUserAvatar,
4801
+ userMessageClassName: classNames.userMessage,
4802
+ assistantMessageClassName: classNames.assistantMessage,
4803
+ size: fontSize,
4804
+ isLastMessage,
4805
+ isLoading,
4806
+ registeredTools,
4807
+ toolRenderers,
4808
+ onApproveToolExecution,
4809
+ onRejectToolExecution,
4810
+ showFollowUps,
4811
+ onFollowUpClick: handleFollowUpClick,
4812
+ followUpClassName,
4813
+ followUpButtonClassName
4814
+ },
4815
+ message.id
4816
+ );
4817
+ }),
4818
+ isProcessing && /* @__PURE__ */ jsxRuntime.jsxs(Message, { className: "flex gap-2", children: [
4819
+ /* @__PURE__ */ jsxRuntime.jsx(
4820
+ MessageAvatar,
4821
+ {
4822
+ src: assistantAvatar?.src || "",
4823
+ alt: "Assistant",
4824
+ fallback: assistantAvatar?.fallback || "AI",
4825
+ fallbackIcon: !assistantAvatar?.src ? /* @__PURE__ */ jsxRuntime.jsx(copilot_sdk_logo_default, { className: "size-5" }) : void 0,
4826
+ className: "bg-background"
4827
+ }
4828
+ ),
4829
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-muted px-4 py-2 flex items-center gap-2", children: [
4830
+ /* @__PURE__ */ jsxRuntime.jsx(Loader, { variant: "dots", size: "sm" }),
4831
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Continuing..." })
4832
+ ] })
4833
+ ] }),
4834
+ isLoading && !isProcessing && (() => {
4835
+ const lastMessage = messages[messages.length - 1];
4836
+ if (lastMessage?.role === "user") {
4837
+ return /* @__PURE__ */ jsxRuntime.jsxs(Message, { className: "flex gap-2", children: [
4838
+ /* @__PURE__ */ jsxRuntime.jsx(
4839
+ MessageAvatar,
4840
+ {
4841
+ src: assistantAvatar?.src || "",
4842
+ alt: "Assistant",
4843
+ fallback: assistantAvatar?.fallback || "AI",
4844
+ fallbackIcon: !assistantAvatar?.src ? /* @__PURE__ */ jsxRuntime.jsx(copilot_sdk_logo_default, { className: "size-5" }) : void 0,
4845
+ className: "bg-background"
4846
+ }
4847
+ ),
4848
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-muted px-4 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(Loader, { variant: loaderVariant, size: "sm" }) })
4849
+ ] });
4850
+ }
4851
+ return null;
4852
+ })(),
4853
+ /* @__PURE__ */ jsxRuntime.jsx(ChatContainerScrollAnchor, {})
4854
+ ]
4855
+ }
4856
+ ),
4857
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-4 bottom-4", children: /* @__PURE__ */ jsxRuntime.jsx(ScrollButton, { className: "shadow-sm" }) })
4858
+ ]
4859
+ }
4860
+ ),
4861
+ suggestions.length > 0 && !isLoading && /* @__PURE__ */ jsxRuntime.jsx(
4862
+ Suggestions,
4863
+ {
4864
+ suggestions,
4865
+ onSuggestionClick: handleSuggestionClick,
4866
+ className: classNames.suggestions
4867
+ }
4868
+ ),
4869
+ renderInput ? renderInput() : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("p-2 pt-0", classNames.input), children: [
4870
+ pendingAttachments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2 p-2 mb-2 bg-muted/30 rounded-lg", children: pendingAttachments.map((att) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group", children: [
4871
+ att.attachment.type === "image" ? /* @__PURE__ */ jsxRuntime.jsx(
4872
+ "img",
4873
+ {
4874
+ src: att.previewUrl,
4875
+ alt: att.file.name,
4876
+ className: "w-16 h-16 object-cover rounded-lg border"
4877
+ }
4878
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-16 h-16 bg-muted rounded-lg border flex flex-col items-center justify-center p-1", children: [
4632
4879
  /* @__PURE__ */ jsxRuntime.jsx(
4633
- "button",
4880
+ "svg",
4634
4881
  {
4635
- onClick: () => removePendingAttachment(att.id),
4636
- className: "absolute -top-1.5 -right-1.5 bg-destructive text-destructive-foreground rounded-full p-0.5 opacity-0 group-hover:opacity-100 transition-opacity",
4637
- type: "button",
4638
- children: /* @__PURE__ */ jsxRuntime.jsx(XIcon2, { className: "w-3 h-3" })
4882
+ className: "w-6 h-6 text-muted-foreground",
4883
+ fill: "none",
4884
+ viewBox: "0 0 24 24",
4885
+ stroke: "currentColor",
4886
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4887
+ "path",
4888
+ {
4889
+ strokeLinecap: "round",
4890
+ strokeLinejoin: "round",
4891
+ strokeWidth: 1.5,
4892
+ d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
4893
+ }
4894
+ )
4639
4895
  }
4640
- )
4641
- ] }, att.id)) }),
4642
- /* @__PURE__ */ jsxRuntime.jsxs(
4643
- PromptInput,
4896
+ ),
4897
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground truncate w-full text-center mt-1", children: att.file.name.length > 10 ? att.file.name.slice(0, 8) + "..." : att.file.name })
4898
+ ] }),
4899
+ att.status === "processing" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-background/80 rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(Loader, { variant: "dots", size: "sm" }) }),
4900
+ att.status === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-destructive/20 rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive text-xs", children: "Error" }) }),
4901
+ /* @__PURE__ */ jsxRuntime.jsx(
4902
+ "button",
4644
4903
  {
4645
- value: input,
4646
- onValueChange: setInput,
4647
- isLoading,
4648
- onSubmit: handleSubmit,
4649
- className: "",
4650
- children: [
4651
- /* @__PURE__ */ jsxRuntime.jsx(PromptInputTextarea, { placeholder }),
4652
- /* @__PURE__ */ jsxRuntime.jsxs(PromptInputActions, { className: "flex justify-between", children: [
4653
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
4654
- PromptInputAction,
4655
- {
4656
- tooltip: attachmentsEnabled ? "Attach files" : attachmentsDisabledTooltip,
4657
- children: /* @__PURE__ */ jsxRuntime.jsxs(
4658
- "label",
4659
- {
4660
- htmlFor: fileInputId,
4661
- className: cn(
4662
- "csdk-button-attach flex h-8 w-8 items-center justify-center rounded-2xl",
4663
- attachmentsEnabled ? "hover:bg-secondary-foreground/10 cursor-pointer" : "opacity-50 cursor-not-allowed"
4664
- ),
4665
- children: [
4666
- /* @__PURE__ */ jsxRuntime.jsx(
4667
- "input",
4668
- {
4669
- ref: fileInputRef,
4670
- type: "file",
4671
- multiple: true,
4672
- accept: acceptString,
4673
- onChange: handleInputChange,
4674
- className: "hidden",
4675
- id: fileInputId,
4676
- disabled: !attachmentsEnabled
4677
- }
4678
- ),
4679
- /* @__PURE__ */ jsxRuntime.jsx(PlusIcon, { className: "text-primary size-5" })
4680
- ]
4681
- }
4682
- )
4683
- }
4684
- ) }),
4685
- /* @__PURE__ */ jsxRuntime.jsx(PromptInputAction, { tooltip: isLoading ? "Stop" : "Send", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(
4686
- Button,
4687
- {
4688
- size: "sm",
4689
- variant: "destructive",
4690
- className: "csdk-button-stop rounded-full size-9",
4691
- onClick: onStop,
4692
- children: /* @__PURE__ */ jsxRuntime.jsx(StopIcon, { className: "h-4 w-4" })
4693
- }
4694
- ) : /* @__PURE__ */ jsxRuntime.jsx(
4695
- Button,
4696
- {
4697
- size: "sm",
4698
- className: "csdk-button-send rounded-full size-9",
4699
- onClick: handleSubmit,
4700
- disabled: !input.trim() && !pendingAttachments.some(
4701
- (att) => att.status === "ready"
4702
- ),
4703
- children: /* @__PURE__ */ jsxRuntime.jsx(ArrowUpIcon, { className: "h-4 w-4" })
4704
- }
4705
- ) })
4706
- ] })
4707
- ]
4904
+ onClick: () => removePendingAttachment(att.id),
4905
+ className: "absolute -top-1.5 -right-1.5 bg-destructive text-destructive-foreground rounded-full p-0.5 opacity-0 group-hover:opacity-100 transition-opacity",
4906
+ type: "button",
4907
+ children: /* @__PURE__ */ jsxRuntime.jsx(XIcon2, { className: "w-3 h-3" })
4708
4908
  }
4709
4909
  )
4710
- ] })
4910
+ ] }, att.id)) }),
4911
+ /* @__PURE__ */ jsxRuntime.jsxs(
4912
+ PromptInput,
4913
+ {
4914
+ value: input,
4915
+ onValueChange: setInput,
4916
+ isLoading,
4917
+ onSubmit: handleSubmit,
4918
+ className: "",
4919
+ children: [
4920
+ /* @__PURE__ */ jsxRuntime.jsx(PromptInputTextarea, { placeholder }),
4921
+ /* @__PURE__ */ jsxRuntime.jsxs(PromptInputActions, { className: "flex justify-between", children: [
4922
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
4923
+ PromptInputAction,
4924
+ {
4925
+ tooltip: attachmentsEnabled ? "Attach files" : attachmentsDisabledTooltip,
4926
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
4927
+ "label",
4928
+ {
4929
+ htmlFor: fileInputId,
4930
+ className: cn(
4931
+ "csdk-button-attach flex h-8 w-8 items-center justify-center rounded-2xl",
4932
+ attachmentsEnabled ? "hover:bg-secondary-foreground/10 cursor-pointer" : "opacity-50 cursor-not-allowed"
4933
+ ),
4934
+ children: [
4935
+ /* @__PURE__ */ jsxRuntime.jsx(
4936
+ "input",
4937
+ {
4938
+ ref: fileInputRef,
4939
+ type: "file",
4940
+ multiple: true,
4941
+ accept: acceptString,
4942
+ onChange: handleInputChange,
4943
+ className: "hidden",
4944
+ id: fileInputId,
4945
+ disabled: !attachmentsEnabled
4946
+ }
4947
+ ),
4948
+ /* @__PURE__ */ jsxRuntime.jsx(PlusIcon, { className: "text-primary size-5" })
4949
+ ]
4950
+ }
4951
+ )
4952
+ }
4953
+ ) }),
4954
+ /* @__PURE__ */ jsxRuntime.jsx(PromptInputAction, { tooltip: isLoading ? "Stop" : "Send", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(
4955
+ Button,
4956
+ {
4957
+ size: "sm",
4958
+ variant: "destructive",
4959
+ className: "csdk-button-stop rounded-full size-9",
4960
+ onClick: onStop,
4961
+ children: /* @__PURE__ */ jsxRuntime.jsx(StopIcon, { className: "h-4 w-4" })
4962
+ }
4963
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
4964
+ Button,
4965
+ {
4966
+ size: "sm",
4967
+ className: "csdk-button-send rounded-full size-9",
4968
+ onClick: handleSubmit,
4969
+ disabled: !input.trim() && !pendingAttachments.some(
4970
+ (att) => att.status === "ready"
4971
+ ),
4972
+ children: /* @__PURE__ */ jsxRuntime.jsx(ArrowUpIcon, { className: "h-4 w-4" })
4973
+ }
4974
+ ) })
4975
+ ] })
4976
+ ]
4977
+ }
4978
+ )
4711
4979
  ] })
4712
- )
4980
+ ] }),
4981
+ rootFooter
4713
4982
  ]
4714
4983
  }
4715
- );
4984
+ ) });
4716
4985
  }
4986
+ var Chat = Object.assign(ChatComponent, {
4987
+ Root: ChatComponent,
4988
+ // Alias for layout composition pattern
4989
+ Home,
4990
+ // Backward compat alias
4991
+ HomeView,
4992
+ // New name
4993
+ ChatView,
4994
+ Header,
4995
+ Footer,
4996
+ Input,
4997
+ Suggestions: SuggestionsCompound,
4998
+ BackButton,
4999
+ // Navigation: start new chat
5000
+ ThreadPicker: ThreadPickerCompound
5001
+ // Thread switching
5002
+ });
4717
5003
  function ToolExecutionMessage({
4718
5004
  executions,
4719
5005
  assistantAvatar = { fallback: "AI" },
@@ -4858,17 +5144,17 @@ function useInternalThreadManager(config = {}) {
4858
5144
  refreshThreads
4859
5145
  } = threadManager;
4860
5146
  const { messages, setMessages, status, isLoading } = chunk3427BQ4M_cjs.useCopilot();
4861
- const isLoadingMessagesRef = React7.useRef(false);
4862
- const savingToThreadRef = React7.useRef(null);
4863
- const lastSavedSnapshotRef = React7.useRef("");
4864
- const hasInitializedRef = React7.useRef(false);
4865
- const getMessageSnapshot = React7.useCallback((msgs) => {
5147
+ const isLoadingMessagesRef = React18.useRef(false);
5148
+ const savingToThreadRef = React18.useRef(null);
5149
+ const lastSavedSnapshotRef = React18.useRef("");
5150
+ const hasInitializedRef = React18.useRef(false);
5151
+ const getMessageSnapshot = React18.useCallback((msgs) => {
4866
5152
  return msgs.map((m) => {
4867
5153
  const contentPreview = (m.content ?? "").slice(0, 20);
4868
5154
  return `${m.id}:${contentPreview}:${m.content?.length ?? 0}`;
4869
5155
  }).join("|");
4870
5156
  }, []);
4871
- const convertToCore = React7.useCallback((msgs) => {
5157
+ const convertToCore = React18.useCallback((msgs) => {
4872
5158
  return msgs.map((m) => ({
4873
5159
  id: m.id,
4874
5160
  role: m.role,
@@ -4882,7 +5168,7 @@ function useInternalThreadManager(config = {}) {
4882
5168
  }
4883
5169
  }));
4884
5170
  }, []);
4885
- const handleSwitchThread = React7.useCallback(
5171
+ const handleSwitchThread = React18.useCallback(
4886
5172
  async (threadId) => {
4887
5173
  isLoadingMessagesRef.current = true;
4888
5174
  const thread = await switchThread(threadId);
@@ -4911,7 +5197,7 @@ function useInternalThreadManager(config = {}) {
4911
5197
  },
4912
5198
  [switchThread, setMessages, getMessageSnapshot, onThreadChange]
4913
5199
  );
4914
- const handleNewThread = React7.useCallback(async () => {
5200
+ const handleNewThread = React18.useCallback(async () => {
4915
5201
  isLoadingMessagesRef.current = true;
4916
5202
  clearCurrentThread();
4917
5203
  lastSavedSnapshotRef.current = "";
@@ -4922,7 +5208,7 @@ function useInternalThreadManager(config = {}) {
4922
5208
  isLoadingMessagesRef.current = false;
4923
5209
  });
4924
5210
  }, [clearCurrentThread, setMessages, onThreadChange]);
4925
- React7.useEffect(() => {
5211
+ React18.useEffect(() => {
4926
5212
  if (hasInitializedRef.current || !currentThread) {
4927
5213
  return;
4928
5214
  }
@@ -4950,7 +5236,7 @@ function useInternalThreadManager(config = {}) {
4950
5236
  isLoadingMessagesRef.current = false;
4951
5237
  });
4952
5238
  }, [currentThread, setMessages, getMessageSnapshot, onThreadChange]);
4953
- React7.useEffect(() => {
5239
+ React18.useEffect(() => {
4954
5240
  if (isLoadingMessagesRef.current) {
4955
5241
  return;
4956
5242
  }
@@ -5044,13 +5330,14 @@ function parsePersistenceConfig(persistence, onThreadChange) {
5044
5330
  onThreadChange
5045
5331
  };
5046
5332
  }
5047
- function CopilotChat(props) {
5333
+ function CopilotChatBase(props) {
5048
5334
  const {
5049
5335
  persistence,
5050
5336
  showThreadPicker = false,
5051
5337
  onThreadChange,
5052
5338
  classNames,
5053
5339
  header,
5340
+ children,
5054
5341
  ...chatProps
5055
5342
  } = props;
5056
5343
  const persistenceConfig = parsePersistenceConfig(persistence, onThreadChange);
@@ -5190,7 +5477,7 @@ function CopilotChat(props) {
5190
5477
  footer: classNames.footer
5191
5478
  } : void 0;
5192
5479
  const { threadManager, handleSwitchThread, handleNewThread, isBusy } = threadManagerResult;
5193
- const handleDeleteThread = React7__namespace.default.useCallback(
5480
+ const handleDeleteThread = React18__namespace.default.useCallback(
5194
5481
  (threadId) => {
5195
5482
  const isCurrentThread = threadManager.currentThreadId === threadId;
5196
5483
  threadManager.deleteThread(threadId);
@@ -5241,10 +5528,33 @@ function CopilotChat(props) {
5241
5528
  renderHeader: useCustomHeader ? chatProps.renderHeader : void 0,
5242
5529
  recentThreads: isPersistenceEnabled ? threadManager.threads : void 0,
5243
5530
  onSelectThread: isPersistenceEnabled ? handleSwitchThread : void 0,
5244
- onDeleteThread: isPersistenceEnabled ? handleDeleteThread : void 0
5531
+ onDeleteThread: isPersistenceEnabled ? handleDeleteThread : void 0,
5532
+ onNewChat: handleNewThread,
5533
+ threads: isPersistenceEnabled ? threadManager.threads : void 0,
5534
+ currentThreadId: threadManager.currentThreadId,
5535
+ onSwitchThread: isPersistenceEnabled ? handleSwitchThread : void 0,
5536
+ isThreadBusy: isBusy,
5537
+ children
5245
5538
  }
5246
5539
  );
5247
5540
  }
5541
+ var CopilotChat = Object.assign(CopilotChatBase, {
5542
+ Root: CopilotChatBase,
5543
+ // Alias for layout composition pattern
5544
+ Home: Chat.Home,
5545
+ // Backward compat alias
5546
+ HomeView: Chat.HomeView,
5547
+ // New name
5548
+ ChatView: Chat.ChatView,
5549
+ Header: Chat.Header,
5550
+ Footer: Chat.Footer,
5551
+ Input: Chat.Input,
5552
+ Suggestions: Chat.Suggestions,
5553
+ BackButton: Chat.BackButton,
5554
+ // Navigation: start new chat
5555
+ ThreadPicker: Chat.ThreadPicker
5556
+ // Thread switching
5557
+ });
5248
5558
  var ConnectedChat = CopilotChat;
5249
5559
  function YourGPTLogo({ className }) {
5250
5560
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -5304,6 +5614,7 @@ exports.ChatContainerScrollAnchor = ChatContainerScrollAnchor;
5304
5614
  exports.ChatWelcome = ChatWelcome;
5305
5615
  exports.CheckIcon = CheckIcon;
5306
5616
  exports.ChevronDownIcon = ChevronDownIcon2;
5617
+ exports.ChevronLeftIcon = ChevronLeftIcon;
5307
5618
  exports.ChevronUpIcon = ChevronUpIcon;
5308
5619
  exports.CloseIcon = CloseIcon;
5309
5620
  exports.CodeBlock = CodeBlock;
@@ -5365,6 +5676,7 @@ exports.XIcon = XIcon2;
5365
5676
  exports.cn = cn;
5366
5677
  exports.parseFollowUps = parseFollowUps;
5367
5678
  exports.useChatContainer = useChatContainer;
5679
+ exports.useCopilotChatContext = useCopilotChatContext;
5368
5680
  exports.useCopilotUI = useCopilotUI;
5369
5681
  //# sourceMappingURL=index.cjs.map
5370
5682
  //# sourceMappingURL=index.cjs.map