@copilotkitnext/react 0.0.11 → 0.0.13-alpha.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/index.mjs CHANGED
@@ -1,17 +1,11 @@
1
1
  // src/components/chat/CopilotChatInput.tsx
2
- import {
3
- useState,
4
- useRef as useRef2,
5
- useEffect as useEffect2,
6
- forwardRef as forwardRef2,
7
- useImperativeHandle as useImperativeHandle2
8
- } from "react";
2
+ import { useState as useState2, useRef as useRef2, useEffect as useEffect2, forwardRef as forwardRef2, useImperativeHandle as useImperativeHandle2 } from "react";
9
3
  import { twMerge as twMerge3 } from "tailwind-merge";
10
4
  import { Plus, Settings2, Mic, ArrowUp, X, Check } from "lucide-react";
11
5
 
12
6
  // src/providers/CopilotChatConfigurationProvider.tsx
13
- import { createContext, useContext } from "react";
14
- import { DEFAULT_AGENT_ID } from "@copilotkitnext/shared";
7
+ import { createContext, useContext, useMemo, useState } from "react";
8
+ import { DEFAULT_AGENT_ID, randomUUID } from "@copilotkitnext/shared";
15
9
  import { jsx } from "react/jsx-runtime";
16
10
  var CopilotChatDefaultLabels = {
17
11
  chatInputPlaceholder: "Type a message...",
@@ -29,33 +23,60 @@ var CopilotChatDefaultLabels = {
29
23
  assistantMessageToolbarRegenerateLabel: "Regenerate",
30
24
  userMessageToolbarCopyMessageLabel: "Copy",
31
25
  userMessageToolbarEditMessageLabel: "Edit",
32
- chatDisclaimerText: "AI can make mistakes. Please verify important information."
26
+ chatDisclaimerText: "AI can make mistakes. Please verify important information.",
27
+ chatToggleOpenLabel: "Open chat",
28
+ chatToggleCloseLabel: "Close chat",
29
+ modalHeaderTitle: "CopilotKit Chat"
33
30
  };
34
31
  var CopilotChatConfiguration = createContext(null);
35
- var CopilotChatConfigurationProvider = ({
36
- children,
37
- labels = {},
38
- agentId,
39
- threadId
40
- }) => {
41
- const mergedLabels = {
42
- ...CopilotChatDefaultLabels,
43
- ...labels
44
- };
45
- const configurationValue = {
46
- labels: mergedLabels,
47
- agentId: agentId ?? DEFAULT_AGENT_ID,
48
- threadId
49
- };
32
+ var CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, isModalDefaultOpen }) => {
33
+ const parentConfig = useContext(CopilotChatConfiguration);
34
+ const mergedLabels = useMemo(
35
+ () => ({
36
+ ...CopilotChatDefaultLabels,
37
+ ...parentConfig?.labels ?? {},
38
+ ...labels ?? {}
39
+ }),
40
+ [labels, parentConfig?.labels]
41
+ );
42
+ const resolvedAgentId = agentId ?? parentConfig?.agentId ?? DEFAULT_AGENT_ID;
43
+ const resolvedThreadId = useMemo(() => {
44
+ if (threadId) {
45
+ return threadId;
46
+ }
47
+ if (parentConfig?.threadId) {
48
+ return parentConfig.threadId;
49
+ }
50
+ return randomUUID();
51
+ }, [threadId, parentConfig?.threadId]);
52
+ const resolvedDefaultOpen = isModalDefaultOpen ?? parentConfig?.isModalDefaultOpen ?? true;
53
+ const [internalModalOpen, setInternalModalOpen] = useState(
54
+ parentConfig?.isModalOpen ?? resolvedDefaultOpen
55
+ );
56
+ const resolvedIsModalOpen = parentConfig?.isModalOpen ?? internalModalOpen;
57
+ const resolvedSetModalOpen = parentConfig?.setModalOpen ?? setInternalModalOpen;
58
+ const configurationValue = useMemo(
59
+ () => ({
60
+ labels: mergedLabels,
61
+ agentId: resolvedAgentId,
62
+ threadId: resolvedThreadId,
63
+ isModalOpen: resolvedIsModalOpen,
64
+ setModalOpen: resolvedSetModalOpen,
65
+ isModalDefaultOpen: resolvedDefaultOpen
66
+ }),
67
+ [
68
+ mergedLabels,
69
+ resolvedAgentId,
70
+ resolvedThreadId,
71
+ resolvedIsModalOpen,
72
+ resolvedSetModalOpen,
73
+ resolvedDefaultOpen
74
+ ]
75
+ );
50
76
  return /* @__PURE__ */ jsx(CopilotChatConfiguration.Provider, { value: configurationValue, children });
51
77
  };
52
78
  var useCopilotChatConfiguration = () => {
53
79
  const configuration = useContext(CopilotChatConfiguration);
54
- if (!configuration) {
55
- throw new Error(
56
- "useCopilotChatConfiguration must be used within CopilotChatConfigurationProvider"
57
- );
58
- }
59
80
  return configuration;
60
81
  };
61
82
 
@@ -496,7 +517,7 @@ function CopilotChatInput({
496
517
  ...props
497
518
  }) {
498
519
  const isControlled = value !== void 0;
499
- const [internalValue, setInternalValue] = useState(() => value ?? "");
520
+ const [internalValue, setInternalValue] = useState2(() => value ?? "");
500
521
  useEffect2(() => {
501
522
  if (!isControlled && value !== void 0) {
502
523
  setInternalValue(value);
@@ -505,6 +526,18 @@ function CopilotChatInput({
505
526
  const resolvedValue = isControlled ? value ?? "" : internalValue;
506
527
  const inputRef = useRef2(null);
507
528
  const audioRecorderRef = useRef2(null);
529
+ const config = useCopilotChatConfiguration();
530
+ const previousModalStateRef = useRef2(void 0);
531
+ useEffect2(() => {
532
+ if (!autoFocus) {
533
+ previousModalStateRef.current = config?.isModalOpen;
534
+ return;
535
+ }
536
+ if (config?.isModalOpen && !previousModalStateRef.current) {
537
+ inputRef.current?.focus();
538
+ }
539
+ previousModalStateRef.current = config?.isModalOpen;
540
+ }, [config?.isModalOpen, autoFocus]);
508
541
  useEffect2(() => {
509
542
  const recorder = audioRecorderRef.current;
510
543
  if (!recorder) {
@@ -555,59 +588,32 @@ function CopilotChatInput({
555
588
  onKeyDown: handleKeyDown,
556
589
  autoFocus
557
590
  });
558
- const BoundAudioRecorder = renderSlot(
559
- audioRecorder,
560
- CopilotChatAudioRecorder,
561
- {
562
- ref: audioRecorderRef
563
- }
564
- );
591
+ const BoundAudioRecorder = renderSlot(audioRecorder, CopilotChatAudioRecorder, {
592
+ ref: audioRecorderRef
593
+ });
565
594
  const BoundSendButton = renderSlot(sendButton, CopilotChatInput.SendButton, {
566
595
  onClick: send,
567
596
  disabled: !resolvedValue.trim() || !onSubmitMessage
568
597
  });
569
- const BoundStartTranscribeButton = renderSlot(
570
- startTranscribeButton,
571
- CopilotChatInput.StartTranscribeButton,
572
- {
573
- onClick: onStartTranscribe
574
- }
575
- );
576
- const BoundCancelTranscribeButton = renderSlot(
577
- cancelTranscribeButton,
578
- CopilotChatInput.CancelTranscribeButton,
579
- {
580
- onClick: onCancelTranscribe
581
- }
582
- );
583
- const BoundFinishTranscribeButton = renderSlot(
584
- finishTranscribeButton,
585
- CopilotChatInput.FinishTranscribeButton,
586
- {
587
- onClick: onFinishTranscribe
588
- }
589
- );
590
- const BoundAddFileButton = renderSlot(
591
- addFileButton,
592
- CopilotChatInput.AddFileButton,
593
- {
594
- onClick: onAddFile,
595
- disabled: mode === "transcribe"
596
- }
597
- );
598
- const BoundToolsButton = renderSlot(
599
- toolsButton,
600
- CopilotChatInput.ToolsButton,
601
- {
602
- disabled: mode === "transcribe",
603
- toolsMenu
604
- }
605
- );
598
+ const BoundStartTranscribeButton = renderSlot(startTranscribeButton, CopilotChatInput.StartTranscribeButton, {
599
+ onClick: onStartTranscribe
600
+ });
601
+ const BoundCancelTranscribeButton = renderSlot(cancelTranscribeButton, CopilotChatInput.CancelTranscribeButton, {
602
+ onClick: onCancelTranscribe
603
+ });
604
+ const BoundFinishTranscribeButton = renderSlot(finishTranscribeButton, CopilotChatInput.FinishTranscribeButton, {
605
+ onClick: onFinishTranscribe
606
+ });
607
+ const BoundAddFileButton = renderSlot(addFileButton, CopilotChatInput.AddFileButton, {
608
+ onClick: onAddFile,
609
+ disabled: mode === "transcribe"
610
+ });
611
+ const BoundToolsButton = renderSlot(toolsButton, CopilotChatInput.ToolsButton, {
612
+ disabled: mode === "transcribe",
613
+ toolsMenu
614
+ });
606
615
  const BoundToolbar = renderSlot(
607
- typeof toolbar === "string" || toolbar === void 0 ? twMerge3(
608
- toolbar,
609
- "w-full h-[60px] bg-transparent flex items-center justify-between"
610
- ) : toolbar,
616
+ typeof toolbar === "string" || toolbar === void 0 ? twMerge3(toolbar, "w-full h-[60px] bg-transparent flex items-center justify-between") : toolbar,
611
617
  CopilotChatInput.Toolbar,
612
618
  {
613
619
  children: /* @__PURE__ */ jsxs3(Fragment, { children: [
@@ -648,6 +654,12 @@ function CopilotChatInput({
648
654
  additionalToolbarItems
649
655
  }) });
650
656
  }
657
+ const handleContainerClick = (e) => {
658
+ const target = e.target;
659
+ if (target.tagName !== "BUTTON" && !target.closest("button") && inputRef.current && mode === "input") {
660
+ inputRef.current.focus();
661
+ }
662
+ };
651
663
  return /* @__PURE__ */ jsxs3(
652
664
  "div",
653
665
  {
@@ -664,6 +676,7 @@ function CopilotChatInput({
664
676
  "shadow-[0_4px_4px_0_#0000000a,0_0_1px_0_#0000009e] rounded-[28px]",
665
677
  className
666
678
  ),
679
+ onClick: handleContainerClick,
667
680
  ...props,
668
681
  children: [
669
682
  mode === "transcribe" ? BoundAudioRecorder : BoundTextArea,
@@ -685,7 +698,8 @@ function CopilotChatInput({
685
698
  }
686
699
  ) });
687
700
  CopilotChatInput2.ToolbarButton = ({ icon, labelKey, defaultClassName, className, ...props }) => {
688
- const { labels } = useCopilotChatConfiguration();
701
+ const config = useCopilotChatConfiguration();
702
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
689
703
  return /* @__PURE__ */ jsxs3(Tooltip, { children: [
690
704
  /* @__PURE__ */ jsx6(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx6(
691
705
  Button,
@@ -738,7 +752,8 @@ function CopilotChatInput({
738
752
  }
739
753
  );
740
754
  CopilotChatInput2.ToolsButton = ({ className, toolsMenu, ...props }) => {
741
- const { labels } = useCopilotChatConfiguration();
755
+ const config = useCopilotChatConfiguration();
756
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
742
757
  const renderMenuItems = (items) => {
743
758
  return items.map((item, index) => {
744
759
  if (item === "-") {
@@ -774,99 +789,83 @@ function CopilotChatInput({
774
789
  /* @__PURE__ */ jsx6(DropdownMenuContent, { side: "top", align: "end", children: renderMenuItems(toolsMenu) })
775
790
  ] });
776
791
  };
777
- CopilotChatInput2.Toolbar = ({
778
- className,
779
- ...props
780
- }) => /* @__PURE__ */ jsx6(
781
- "div",
782
- {
783
- className: twMerge3(
784
- "w-full h-[60px] bg-transparent flex items-center",
785
- className
786
- ),
787
- ...props
788
- }
789
- );
790
- CopilotChatInput2.TextArea = forwardRef2(
791
- function TextArea2({ maxRows = 5, style, className, ...props }, ref) {
792
- const internalTextareaRef = useRef2(null);
793
- const [maxHeight, setMaxHeight] = useState(0);
794
- const { labels } = useCopilotChatConfiguration();
795
- useImperativeHandle2(
796
- ref,
797
- () => internalTextareaRef.current
798
- );
799
- const adjustHeight = () => {
792
+ CopilotChatInput2.Toolbar = ({ className, ...props }) => /* @__PURE__ */ jsx6("div", { className: twMerge3("w-full h-[60px] bg-transparent flex items-center", className), ...props });
793
+ CopilotChatInput2.TextArea = forwardRef2(function TextArea2({ maxRows = 5, style, className, ...props }, ref) {
794
+ const internalTextareaRef = useRef2(null);
795
+ const [maxHeight, setMaxHeight] = useState2(0);
796
+ const config = useCopilotChatConfiguration();
797
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
798
+ useImperativeHandle2(ref, () => internalTextareaRef.current);
799
+ const adjustHeight = () => {
800
+ const textarea = internalTextareaRef.current;
801
+ if (textarea && maxHeight > 0) {
802
+ textarea.style.height = "auto";
803
+ textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
804
+ }
805
+ };
806
+ useEffect2(() => {
807
+ const calculateMaxHeight = () => {
800
808
  const textarea = internalTextareaRef.current;
801
- if (textarea && maxHeight > 0) {
809
+ if (textarea) {
810
+ const currentValue = textarea.value;
811
+ textarea.value = "";
802
812
  textarea.style.height = "auto";
803
- textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
804
- }
805
- };
806
- useEffect2(() => {
807
- const calculateMaxHeight = () => {
808
- const textarea = internalTextareaRef.current;
809
- if (textarea) {
810
- const currentValue = textarea.value;
811
- textarea.value = "";
813
+ const computedStyle = window.getComputedStyle(textarea);
814
+ const paddingTop = parseFloat(computedStyle.paddingTop);
815
+ const paddingBottom = parseFloat(computedStyle.paddingBottom);
816
+ const contentHeight = textarea.scrollHeight - paddingTop - paddingBottom;
817
+ setMaxHeight(contentHeight * maxRows + paddingTop + paddingBottom);
818
+ textarea.value = currentValue;
819
+ if (currentValue) {
812
820
  textarea.style.height = "auto";
813
- const computedStyle = window.getComputedStyle(textarea);
814
- const paddingTop = parseFloat(computedStyle.paddingTop);
815
- const paddingBottom = parseFloat(computedStyle.paddingBottom);
816
- const contentHeight = textarea.scrollHeight - paddingTop - paddingBottom;
817
- setMaxHeight(contentHeight * maxRows + paddingTop + paddingBottom);
818
- textarea.value = currentValue;
819
- if (currentValue) {
820
- textarea.style.height = "auto";
821
- textarea.style.height = `${Math.min(textarea.scrollHeight, contentHeight * maxRows + paddingTop + paddingBottom)}px`;
822
- }
823
- if (props.autoFocus) {
824
- textarea.focus();
825
- }
821
+ textarea.style.height = `${Math.min(textarea.scrollHeight, contentHeight * maxRows + paddingTop + paddingBottom)}px`;
822
+ }
823
+ if (props.autoFocus) {
824
+ textarea.focus();
826
825
  }
827
- };
828
- calculateMaxHeight();
829
- }, [maxRows, props.autoFocus]);
830
- useEffect2(() => {
831
- adjustHeight();
832
- }, [props.value, maxHeight]);
833
- const handleInput = (e) => {
834
- adjustHeight();
835
- if (props.onChange) {
836
- props.onChange(e);
837
826
  }
838
827
  };
839
- return /* @__PURE__ */ jsx6(
840
- "textarea",
841
- {
842
- ref: internalTextareaRef,
843
- ...props,
844
- onChange: handleInput,
845
- style: {
846
- overflow: "auto",
847
- resize: "none",
848
- maxHeight: `${maxHeight}px`,
849
- ...style
850
- },
851
- placeholder: labels.chatInputPlaceholder,
852
- className: twMerge3(
853
- // Layout and sizing
854
- "w-full p-5 pb-0",
855
- // Behavior
856
- "outline-none resize-none",
857
- // Background
858
- "bg-transparent",
859
- // Typography
860
- "antialiased font-regular leading-relaxed text-[16px]",
861
- // Placeholder styles
862
- "placeholder:text-[#00000077] dark:placeholder:text-[#fffc]",
863
- className
864
- ),
865
- rows: 1
866
- }
867
- );
868
- }
869
- );
828
+ calculateMaxHeight();
829
+ }, [maxRows, props.autoFocus]);
830
+ useEffect2(() => {
831
+ adjustHeight();
832
+ }, [props.value, maxHeight]);
833
+ const handleInput = (e) => {
834
+ adjustHeight();
835
+ if (props.onChange) {
836
+ props.onChange(e);
837
+ }
838
+ };
839
+ return /* @__PURE__ */ jsx6(
840
+ "textarea",
841
+ {
842
+ ref: internalTextareaRef,
843
+ ...props,
844
+ onChange: handleInput,
845
+ style: {
846
+ overflow: "auto",
847
+ resize: "none",
848
+ maxHeight: `${maxHeight}px`,
849
+ ...style
850
+ },
851
+ placeholder: labels.chatInputPlaceholder,
852
+ className: twMerge3(
853
+ // Layout and sizing
854
+ "w-full p-5 pb-0",
855
+ // Behavior
856
+ "outline-none resize-none",
857
+ // Background
858
+ "bg-transparent",
859
+ // Typography
860
+ "antialiased font-regular leading-relaxed text-[16px]",
861
+ // Placeholder styles
862
+ "placeholder:text-[#00000077] dark:placeholder:text-[#fffc]",
863
+ className
864
+ ),
865
+ rows: 1
866
+ }
867
+ );
868
+ });
870
869
  CopilotChatInput2.AudioRecorder = CopilotChatAudioRecorder;
871
870
  })(CopilotChatInput || (CopilotChatInput = {}));
872
871
  CopilotChatInput.TextArea.displayName = "CopilotChatInput.TextArea";
@@ -886,7 +885,7 @@ import remarkGfm from "remark-gfm";
886
885
  import remarkMath from "remark-math";
887
886
  import rehypePrettyCode from "rehype-pretty-code";
888
887
  import rehypeKatex from "rehype-katex";
889
- import { useState as useState5 } from "react";
888
+ import { useState as useState7 } from "react";
890
889
  import {
891
890
  Copy,
892
891
  Check as Check2,
@@ -900,23 +899,13 @@ import "katex/dist/katex.min.css";
900
899
  import { completePartialMarkdown } from "@copilotkitnext/core";
901
900
 
902
901
  // src/hooks/use-render-tool-call.tsx
903
- import { useCallback, useEffect as useEffect4, useState as useState3 } from "react";
902
+ import { useCallback, useEffect as useEffect4, useState as useState4 } from "react";
904
903
  import { ToolCallStatus } from "@copilotkitnext/core";
905
904
 
906
905
  // src/providers/CopilotKitProvider.tsx
907
- import {
908
- createContext as createContext2,
909
- useContext as useContext2,
910
- useMemo,
911
- useEffect as useEffect3,
912
- useState as useState2,
913
- useReducer,
914
- useRef as useRef3
915
- } from "react";
906
+ import { createContext as createContext2, useContext as useContext2, useMemo as useMemo2, useEffect as useEffect3, useState as useState3, useReducer, useRef as useRef3 } from "react";
916
907
  import { z } from "zod";
917
- import {
918
- CopilotKitCore
919
- } from "@copilotkitnext/core";
908
+ import { CopilotKitCore } from "@copilotkitnext/core";
920
909
  import { jsx as jsx7 } from "react/jsx-runtime";
921
910
  var CopilotKitContext = createContext2({
922
911
  copilotkit: null,
@@ -926,7 +915,7 @@ var CopilotKitContext = createContext2({
926
915
  }
927
916
  });
928
917
  function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
929
- const empty = useMemo(() => [], []);
918
+ const empty = useMemo2(() => [], []);
930
919
  const value = prop ?? empty;
931
920
  const initial = useRef3(value);
932
921
  useEffect3(() => {
@@ -967,9 +956,9 @@ var CopilotKitProvider = ({
967
956
  humanInTheLoop,
968
957
  "humanInTheLoop must be a stable array. If you want to dynamically add or remove human-in-the-loop tools, use `useHumanInTheLoop` instead."
969
958
  );
970
- const initialRenderToolCalls = useMemo(() => renderToolCallsList, []);
971
- const [currentRenderToolCalls, setCurrentRenderToolCalls] = useState2([]);
972
- const processedHumanInTheLoopTools = useMemo(() => {
959
+ const initialRenderToolCalls = useMemo2(() => renderToolCallsList, []);
960
+ const [currentRenderToolCalls, setCurrentRenderToolCalls] = useState3([]);
961
+ const processedHumanInTheLoopTools = useMemo2(() => {
973
962
  const processedTools = [];
974
963
  const processedRenderToolCalls = [];
975
964
  humanInTheLoopList.forEach((tool) => {
@@ -981,9 +970,7 @@ var CopilotKitProvider = ({
981
970
  ...tool.agentId && { agentId: tool.agentId },
982
971
  handler: async () => {
983
972
  return new Promise((resolve) => {
984
- console.warn(
985
- `Human-in-the-loop tool '${tool.name}' called but no interactive handler is set up.`
986
- );
973
+ console.warn(`Human-in-the-loop tool '${tool.name}' called but no interactive handler is set up.`);
987
974
  resolve(void 0);
988
975
  });
989
976
  }
@@ -1000,13 +987,13 @@ var CopilotKitProvider = ({
1000
987
  });
1001
988
  return { tools: processedTools, renderToolCalls: processedRenderToolCalls };
1002
989
  }, [humanInTheLoopList]);
1003
- const allTools = useMemo(() => {
990
+ const allTools = useMemo2(() => {
1004
991
  const tools = [];
1005
992
  tools.push(...frontendToolsList);
1006
993
  tools.push(...processedHumanInTheLoopTools.tools);
1007
994
  return tools;
1008
995
  }, [frontendToolsList, processedHumanInTheLoopTools]);
1009
- const allRenderToolCalls = useMemo(() => {
996
+ const allRenderToolCalls = useMemo2(() => {
1010
997
  const combined = [...renderToolCallsList];
1011
998
  frontendToolsList.forEach((tool) => {
1012
999
  if (tool.render) {
@@ -1023,13 +1010,12 @@ var CopilotKitProvider = ({
1023
1010
  combined.push(...processedHumanInTheLoopTools.renderToolCalls);
1024
1011
  return combined;
1025
1012
  }, [renderToolCallsList, frontendToolsList, processedHumanInTheLoopTools]);
1026
- const copilotkit = useMemo(() => {
1013
+ const copilotkit = useMemo2(() => {
1027
1014
  const config = {
1028
- // Don't set runtimeUrl during initialization to prevent server-side fetching
1029
- runtimeUrl: void 0,
1015
+ runtimeUrl,
1030
1016
  headers,
1031
1017
  properties,
1032
- agents,
1018
+ agents__unsafe_dev_only: agents,
1033
1019
  tools: allTools
1034
1020
  };
1035
1021
  const copilotkit2 = new CopilotKitCore(config);
@@ -1065,7 +1051,7 @@ var CopilotKitProvider = ({
1065
1051
  copilotkit.setRuntimeUrl(runtimeUrl);
1066
1052
  copilotkit.setHeaders(headers);
1067
1053
  copilotkit.setProperties(properties);
1068
- copilotkit.setAgents(agents);
1054
+ copilotkit.setAgents__unsafe_dev_only(agents);
1069
1055
  }, [runtimeUrl, headers, properties, agents]);
1070
1056
  return /* @__PURE__ */ jsx7(
1071
1057
  CopilotKitContext.Provider,
@@ -1100,12 +1086,14 @@ var useCopilotKit = () => {
1100
1086
  };
1101
1087
 
1102
1088
  // src/hooks/use-render-tool-call.tsx
1089
+ import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID2 } from "@copilotkitnext/shared";
1103
1090
  import { partialJSONParse } from "@copilotkitnext/shared";
1104
1091
  import { jsx as jsx8 } from "react/jsx-runtime";
1105
1092
  function useRenderToolCall() {
1106
1093
  const { currentRenderToolCalls, copilotkit } = useCopilotKit();
1107
- const { agentId } = useCopilotChatConfiguration();
1108
- const [executingToolCallIds, setExecutingToolCallIds] = useState3(() => /* @__PURE__ */ new Set());
1094
+ const config = useCopilotChatConfiguration();
1095
+ const agentId = config?.agentId ?? DEFAULT_AGENT_ID2;
1096
+ const [executingToolCallIds, setExecutingToolCallIds] = useState4(() => /* @__PURE__ */ new Set());
1109
1097
  useEffect4(() => {
1110
1098
  const unsubscribe = copilotkit.subscribe({
1111
1099
  onToolExecutionStart: ({ toolCallId }) => {
@@ -1218,10 +1206,10 @@ function useFrontendTool(tool) {
1218
1206
  }
1219
1207
 
1220
1208
  // src/hooks/use-human-in-the-loop.tsx
1221
- import { useState as useState4, useCallback as useCallback2, useRef as useRef4, useEffect as useEffect6 } from "react";
1209
+ import { useState as useState5, useCallback as useCallback2, useRef as useRef4, useEffect as useEffect6 } from "react";
1222
1210
  import React6 from "react";
1223
1211
  function useHumanInTheLoop(tool) {
1224
- const [status, setStatus] = useState4(
1212
+ const [status, setStatus] = useState5(
1225
1213
  "inProgress"
1226
1214
  );
1227
1215
  const statusRef = useRef4(status);
@@ -1292,22 +1280,22 @@ function useHumanInTheLoop(tool) {
1292
1280
  }
1293
1281
 
1294
1282
  // src/hooks/use-agent.tsx
1295
- import { useMemo as useMemo2, useEffect as useEffect7, useReducer as useReducer2 } from "react";
1296
- import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID2 } from "@copilotkitnext/shared";
1283
+ import { useMemo as useMemo3, useEffect as useEffect7, useReducer as useReducer2 } from "react";
1284
+ import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID3 } from "@copilotkitnext/shared";
1297
1285
  var ALL_UPDATES = [
1298
1286
  "OnMessagesChanged" /* OnMessagesChanged */,
1299
1287
  "OnStateChanged" /* OnStateChanged */,
1300
1288
  "OnRunStatusChanged" /* OnRunStatusChanged */
1301
1289
  ];
1302
1290
  function useAgent({ agentId, updates } = {}) {
1303
- agentId ??= DEFAULT_AGENT_ID2;
1291
+ agentId ??= DEFAULT_AGENT_ID3;
1304
1292
  const { copilotkit } = useCopilotKit();
1305
1293
  const [, forceUpdate] = useReducer2((x) => x + 1, 0);
1306
- const updateFlags = useMemo2(
1294
+ const updateFlags = useMemo3(
1307
1295
  () => updates ?? ALL_UPDATES,
1308
1296
  [JSON.stringify(updates)]
1309
1297
  );
1310
- const agent = useMemo2(() => {
1298
+ const agent = useMemo3(() => {
1311
1299
  return copilotkit.getAgent(agentId);
1312
1300
  }, [
1313
1301
  agentId,
@@ -1366,6 +1354,190 @@ function useAgentContext(context) {
1366
1354
  }, [description, value, copilotkit]);
1367
1355
  }
1368
1356
 
1357
+ // src/hooks/use-suggestions.tsx
1358
+ import { useCallback as useCallback3, useEffect as useEffect9, useMemo as useMemo4, useState as useState6 } from "react";
1359
+ import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID4 } from "@copilotkitnext/shared";
1360
+ function useSuggestions({ agentId } = {}) {
1361
+ const { copilotkit } = useCopilotKit();
1362
+ const config = useCopilotChatConfiguration();
1363
+ const resolvedAgentId = useMemo4(() => agentId ?? config?.agentId ?? DEFAULT_AGENT_ID4, [agentId, config?.agentId]);
1364
+ const [suggestions, setSuggestions] = useState6(() => {
1365
+ const result = copilotkit.getSuggestions(resolvedAgentId);
1366
+ return result.suggestions;
1367
+ });
1368
+ const [isLoading, setIsLoading] = useState6(() => {
1369
+ const result = copilotkit.getSuggestions(resolvedAgentId);
1370
+ return result.isLoading;
1371
+ });
1372
+ useEffect9(() => {
1373
+ const result = copilotkit.getSuggestions(resolvedAgentId);
1374
+ setSuggestions(result.suggestions);
1375
+ setIsLoading(result.isLoading);
1376
+ }, [copilotkit, resolvedAgentId]);
1377
+ useEffect9(() => {
1378
+ const unsubscribe = copilotkit.subscribe({
1379
+ onSuggestionsChanged: ({ agentId: changedAgentId, suggestions: suggestions2 }) => {
1380
+ if (changedAgentId !== resolvedAgentId) {
1381
+ return;
1382
+ }
1383
+ setSuggestions(suggestions2);
1384
+ },
1385
+ onSuggestionsStartedLoading: ({ agentId: changedAgentId }) => {
1386
+ if (changedAgentId !== resolvedAgentId) {
1387
+ return;
1388
+ }
1389
+ setIsLoading(true);
1390
+ },
1391
+ onSuggestionsFinishedLoading: ({ agentId: changedAgentId }) => {
1392
+ if (changedAgentId !== resolvedAgentId) {
1393
+ return;
1394
+ }
1395
+ setIsLoading(false);
1396
+ },
1397
+ onSuggestionsConfigChanged: () => {
1398
+ const result = copilotkit.getSuggestions(resolvedAgentId);
1399
+ setSuggestions(result.suggestions);
1400
+ setIsLoading(result.isLoading);
1401
+ }
1402
+ });
1403
+ return () => {
1404
+ unsubscribe();
1405
+ };
1406
+ }, [copilotkit, resolvedAgentId]);
1407
+ const reloadSuggestions = useCallback3(() => {
1408
+ copilotkit.reloadSuggestions(resolvedAgentId);
1409
+ }, [copilotkit, resolvedAgentId]);
1410
+ const clearSuggestions = useCallback3(() => {
1411
+ copilotkit.clearSuggestions(resolvedAgentId);
1412
+ }, [copilotkit, resolvedAgentId]);
1413
+ return {
1414
+ suggestions,
1415
+ reloadSuggestions,
1416
+ clearSuggestions,
1417
+ isLoading
1418
+ };
1419
+ }
1420
+
1421
+ // src/hooks/use-configure-suggestions.tsx
1422
+ import { useCallback as useCallback4, useEffect as useEffect10, useMemo as useMemo5, useRef as useRef5 } from "react";
1423
+ import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID5 } from "@copilotkitnext/shared";
1424
+ var EMPTY_DEPS = [];
1425
+ function useConfigureSuggestions(config, options) {
1426
+ const { copilotkit } = useCopilotKit();
1427
+ const chatConfig = useCopilotChatConfiguration();
1428
+ const extraDeps = options?.deps ?? EMPTY_DEPS;
1429
+ const resolvedConsumerAgentId = useMemo5(() => chatConfig?.agentId ?? DEFAULT_AGENT_ID5, [chatConfig?.agentId]);
1430
+ const rawConsumerAgentId = useMemo5(() => config ? config.consumerAgentId : void 0, [config]);
1431
+ const normalizationCacheRef = useRef5({
1432
+ serialized: null,
1433
+ config: null
1434
+ });
1435
+ const { normalizedConfig, serializedConfig } = useMemo5(() => {
1436
+ if (!config) {
1437
+ normalizationCacheRef.current = { serialized: null, config: null };
1438
+ return { normalizedConfig: null, serializedConfig: null };
1439
+ }
1440
+ if (config.available === "disabled") {
1441
+ normalizationCacheRef.current = { serialized: null, config: null };
1442
+ return { normalizedConfig: null, serializedConfig: null };
1443
+ }
1444
+ let built;
1445
+ if (isDynamicConfig(config)) {
1446
+ built = {
1447
+ ...config
1448
+ };
1449
+ } else {
1450
+ const normalizedSuggestions = normalizeStaticSuggestions(config.suggestions);
1451
+ const baseConfig = {
1452
+ ...config,
1453
+ suggestions: normalizedSuggestions
1454
+ };
1455
+ built = baseConfig;
1456
+ }
1457
+ const serialized = JSON.stringify(built);
1458
+ const cache = normalizationCacheRef.current;
1459
+ if (cache.serialized === serialized && cache.config) {
1460
+ return { normalizedConfig: cache.config, serializedConfig: serialized };
1461
+ }
1462
+ normalizationCacheRef.current = { serialized, config: built };
1463
+ return { normalizedConfig: built, serializedConfig: serialized };
1464
+ }, [config, resolvedConsumerAgentId, ...extraDeps]);
1465
+ const latestConfigRef = useRef5(null);
1466
+ latestConfigRef.current = normalizedConfig;
1467
+ const previousSerializedConfigRef = useRef5(null);
1468
+ const targetAgentId = useMemo5(() => {
1469
+ if (!normalizedConfig) {
1470
+ return resolvedConsumerAgentId;
1471
+ }
1472
+ const consumer = normalizedConfig.consumerAgentId;
1473
+ if (!consumer || consumer === "*") {
1474
+ return resolvedConsumerAgentId;
1475
+ }
1476
+ return consumer;
1477
+ }, [normalizedConfig, resolvedConsumerAgentId]);
1478
+ const isGlobalConfig = rawConsumerAgentId === void 0 || rawConsumerAgentId === "*";
1479
+ const requestReload = useCallback4(() => {
1480
+ if (!normalizedConfig) {
1481
+ return;
1482
+ }
1483
+ if (isGlobalConfig) {
1484
+ const agents = Object.values(copilotkit.agents ?? {});
1485
+ for (const entry of agents) {
1486
+ const agentId = entry.agentId;
1487
+ if (!agentId) {
1488
+ continue;
1489
+ }
1490
+ if (!entry.isRunning) {
1491
+ copilotkit.reloadSuggestions(agentId);
1492
+ }
1493
+ }
1494
+ return;
1495
+ }
1496
+ if (!targetAgentId) {
1497
+ return;
1498
+ }
1499
+ copilotkit.reloadSuggestions(targetAgentId);
1500
+ }, [copilotkit, isGlobalConfig, normalizedConfig, targetAgentId]);
1501
+ useEffect10(() => {
1502
+ if (!serializedConfig || !latestConfigRef.current) {
1503
+ return;
1504
+ }
1505
+ const id = copilotkit.addSuggestionsConfig(latestConfigRef.current);
1506
+ requestReload();
1507
+ return () => {
1508
+ copilotkit.removeSuggestionsConfig(id);
1509
+ };
1510
+ }, [copilotkit, serializedConfig, requestReload]);
1511
+ useEffect10(() => {
1512
+ if (!normalizedConfig) {
1513
+ previousSerializedConfigRef.current = null;
1514
+ return;
1515
+ }
1516
+ if (serializedConfig && previousSerializedConfigRef.current === serializedConfig) {
1517
+ return;
1518
+ }
1519
+ if (serializedConfig) {
1520
+ previousSerializedConfigRef.current = serializedConfig;
1521
+ }
1522
+ requestReload();
1523
+ }, [normalizedConfig, requestReload, serializedConfig]);
1524
+ useEffect10(() => {
1525
+ if (!normalizedConfig || extraDeps.length === 0) {
1526
+ return;
1527
+ }
1528
+ requestReload();
1529
+ }, [extraDeps.length, normalizedConfig, requestReload, ...extraDeps]);
1530
+ }
1531
+ function isDynamicConfig(config) {
1532
+ return "instructions" in config;
1533
+ }
1534
+ function normalizeStaticSuggestions(suggestions) {
1535
+ return suggestions.map((suggestion) => ({
1536
+ ...suggestion,
1537
+ isLoading: suggestion.isLoading ?? false
1538
+ }));
1539
+ }
1540
+
1369
1541
  // src/components/chat/CopilotChatToolCallsView.tsx
1370
1542
  import React7 from "react";
1371
1543
  import { Fragment as Fragment2, jsx as jsx9 } from "react/jsx-runtime";
@@ -1540,8 +1712,9 @@ function CopilotChatAssistantMessage({
1540
1712
  );
1541
1713
  };
1542
1714
  const CodeBlock = ({ children, className, onClick, ...props }) => {
1543
- const { labels } = useCopilotChatConfiguration();
1544
- const [copied, setCopied] = useState5(false);
1715
+ const config = useCopilotChatConfiguration();
1716
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
1717
+ const [copied, setCopied] = useState7(false);
1545
1718
  const getCodeContent = (node) => {
1546
1719
  if (typeof node === "string") return node;
1547
1720
  if (Array.isArray(node)) return node.map(getCodeContent).join("");
@@ -1653,8 +1826,9 @@ function CopilotChatAssistantMessage({
1653
1826
  ] });
1654
1827
  };
1655
1828
  CopilotChatAssistantMessage2.CopyButton = ({ className, title, onClick, ...props }) => {
1656
- const { labels } = useCopilotChatConfiguration();
1657
- const [copied, setCopied] = useState5(false);
1829
+ const config = useCopilotChatConfiguration();
1830
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
1831
+ const [copied, setCopied] = useState7(false);
1658
1832
  const handleClick = (event) => {
1659
1833
  setCopied(true);
1660
1834
  setTimeout(() => setCopied(false), 2e3);
@@ -1674,7 +1848,8 @@ function CopilotChatAssistantMessage({
1674
1848
  );
1675
1849
  };
1676
1850
  CopilotChatAssistantMessage2.ThumbsUpButton = ({ title, ...props }) => {
1677
- const { labels } = useCopilotChatConfiguration();
1851
+ const config = useCopilotChatConfiguration();
1852
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
1678
1853
  return /* @__PURE__ */ jsx10(
1679
1854
  CopilotChatAssistantMessage2.ToolbarButton,
1680
1855
  {
@@ -1685,7 +1860,8 @@ function CopilotChatAssistantMessage({
1685
1860
  );
1686
1861
  };
1687
1862
  CopilotChatAssistantMessage2.ThumbsDownButton = ({ title, ...props }) => {
1688
- const { labels } = useCopilotChatConfiguration();
1863
+ const config = useCopilotChatConfiguration();
1864
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
1689
1865
  return /* @__PURE__ */ jsx10(
1690
1866
  CopilotChatAssistantMessage2.ToolbarButton,
1691
1867
  {
@@ -1696,7 +1872,8 @@ function CopilotChatAssistantMessage({
1696
1872
  );
1697
1873
  };
1698
1874
  CopilotChatAssistantMessage2.ReadAloudButton = ({ title, ...props }) => {
1699
- const { labels } = useCopilotChatConfiguration();
1875
+ const config = useCopilotChatConfiguration();
1876
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
1700
1877
  return /* @__PURE__ */ jsx10(
1701
1878
  CopilotChatAssistantMessage2.ToolbarButton,
1702
1879
  {
@@ -1707,7 +1884,8 @@ function CopilotChatAssistantMessage({
1707
1884
  );
1708
1885
  };
1709
1886
  CopilotChatAssistantMessage2.RegenerateButton = ({ title, ...props }) => {
1710
- const { labels } = useCopilotChatConfiguration();
1887
+ const config = useCopilotChatConfiguration();
1888
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
1711
1889
  return /* @__PURE__ */ jsx10(
1712
1890
  CopilotChatAssistantMessage2.ToolbarButton,
1713
1891
  {
@@ -1728,7 +1906,7 @@ CopilotChatAssistantMessage.RegenerateButton.displayName = "CopilotChatAssistant
1728
1906
  var CopilotChatAssistantMessage_default = CopilotChatAssistantMessage;
1729
1907
 
1730
1908
  // src/components/chat/CopilotChatUserMessage.tsx
1731
- import { useState as useState6 } from "react";
1909
+ import { useState as useState8 } from "react";
1732
1910
  import { Copy as Copy2, Check as Check3, Edit, ChevronLeft, ChevronRight } from "lucide-react";
1733
1911
  import { twMerge as twMerge5 } from "tailwind-merge";
1734
1912
  import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
@@ -1871,8 +2049,9 @@ function CopilotChatUserMessage({
1871
2049
  ] });
1872
2050
  };
1873
2051
  CopilotChatUserMessage2.CopyButton = ({ className, title, onClick, ...props }) => {
1874
- const { labels } = useCopilotChatConfiguration();
1875
- const [copied, setCopied] = useState6(false);
2052
+ const config = useCopilotChatConfiguration();
2053
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
2054
+ const [copied, setCopied] = useState8(false);
1876
2055
  const handleClick = (event) => {
1877
2056
  setCopied(true);
1878
2057
  setTimeout(() => setCopied(false), 2e3);
@@ -1892,7 +2071,8 @@ function CopilotChatUserMessage({
1892
2071
  );
1893
2072
  };
1894
2073
  CopilotChatUserMessage2.EditButton = ({ className, title, ...props }) => {
1895
- const { labels } = useCopilotChatConfiguration();
2074
+ const config = useCopilotChatConfiguration();
2075
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
1896
2076
  return /* @__PURE__ */ jsx11(
1897
2077
  CopilotChatUserMessage2.ToolbarButton,
1898
2078
  {
@@ -1964,9 +2144,118 @@ CopilotChatUserMessage.EditButton.displayName = "CopilotChatUserMessage.EditButt
1964
2144
  CopilotChatUserMessage.BranchNavigation.displayName = "CopilotChatUserMessage.BranchNavigation";
1965
2145
  var CopilotChatUserMessage_default = CopilotChatUserMessage;
1966
2146
 
2147
+ // src/components/chat/CopilotChatSuggestionPill.tsx
2148
+ import React8 from "react";
2149
+ import { Loader2 } from "lucide-react";
2150
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
2151
+ var baseClasses = "group inline-flex h-8 items-center gap-1.5 rounded-full border border-border/60 bg-background px-3 text-xs leading-none text-foreground transition-colors cursor-pointer hover:bg-accent/60 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:text-muted-foreground disabled:hover:bg-background disabled:hover:text-muted-foreground pointer-events-auto";
2152
+ var labelClasses = "whitespace-nowrap font-medium leading-none";
2153
+ var CopilotChatSuggestionPill = React8.forwardRef(function CopilotChatSuggestionPill2({ className, children, icon, isLoading, type, ...props }, ref) {
2154
+ const showIcon = !isLoading && icon;
2155
+ return /* @__PURE__ */ jsxs6(
2156
+ "button",
2157
+ {
2158
+ ref,
2159
+ "data-slot": "suggestion-pill",
2160
+ className: cn(baseClasses, className),
2161
+ type: type ?? "button",
2162
+ "aria-busy": isLoading || void 0,
2163
+ disabled: isLoading || props.disabled,
2164
+ ...props,
2165
+ children: [
2166
+ isLoading ? /* @__PURE__ */ jsx12("span", { className: "flex h-4 w-4 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx12(Loader2, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" }) }) : showIcon && /* @__PURE__ */ jsx12("span", { className: "flex h-4 w-4 items-center justify-center text-muted-foreground", children: icon }),
2167
+ /* @__PURE__ */ jsx12("span", { className: labelClasses, children })
2168
+ ]
2169
+ }
2170
+ );
2171
+ });
2172
+ CopilotChatSuggestionPill.displayName = "CopilotChatSuggestionPill";
2173
+ var CopilotChatSuggestionPill_default = CopilotChatSuggestionPill;
2174
+
2175
+ // src/components/chat/CopilotChatSuggestionView.tsx
2176
+ import React9 from "react";
2177
+ import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
2178
+ var DefaultContainer = React9.forwardRef(function DefaultContainer2({ className, ...props }, ref) {
2179
+ return /* @__PURE__ */ jsx13(
2180
+ "div",
2181
+ {
2182
+ ref,
2183
+ className: cn(
2184
+ "flex flex-wrap items-center gap-2 px-4 sm:px-0 pointer-events-none",
2185
+ className
2186
+ ),
2187
+ ...props
2188
+ }
2189
+ );
2190
+ });
2191
+ var CopilotChatSuggestionView = React9.forwardRef(function CopilotChatSuggestionView2({
2192
+ suggestions,
2193
+ onSelectSuggestion,
2194
+ loadingIndexes,
2195
+ container,
2196
+ suggestion: suggestionSlot,
2197
+ className,
2198
+ children,
2199
+ ...restProps
2200
+ }, ref) {
2201
+ const loadingSet = React9.useMemo(() => {
2202
+ if (!loadingIndexes || loadingIndexes.length === 0) {
2203
+ return /* @__PURE__ */ new Set();
2204
+ }
2205
+ return new Set(loadingIndexes);
2206
+ }, [loadingIndexes]);
2207
+ const ContainerElement = renderSlot(container, DefaultContainer, {
2208
+ ref,
2209
+ className,
2210
+ ...restProps
2211
+ });
2212
+ const suggestionElements = suggestions.map((suggestion, index) => {
2213
+ const isLoading = loadingSet.has(index) || suggestion.isLoading === true;
2214
+ const pill = renderSlot(suggestionSlot, CopilotChatSuggestionPill_default, {
2215
+ children: suggestion.title,
2216
+ isLoading,
2217
+ type: "button",
2218
+ onClick: () => onSelectSuggestion?.(suggestion, index)
2219
+ });
2220
+ return React9.cloneElement(pill, {
2221
+ key: `${suggestion.title}-${index}`
2222
+ });
2223
+ });
2224
+ const boundContainer = React9.cloneElement(
2225
+ ContainerElement,
2226
+ void 0,
2227
+ suggestionElements
2228
+ );
2229
+ if (typeof children === "function") {
2230
+ const sampleSuggestion = renderSlot(suggestionSlot, CopilotChatSuggestionPill_default, {
2231
+ children: suggestions[0]?.title ?? "",
2232
+ isLoading: suggestions.length > 0 ? loadingSet.has(0) || suggestions[0]?.isLoading === true : false,
2233
+ type: "button"
2234
+ });
2235
+ return /* @__PURE__ */ jsx13(Fragment5, { children: children({
2236
+ container: boundContainer,
2237
+ suggestion: sampleSuggestion,
2238
+ suggestions,
2239
+ onSelectSuggestion,
2240
+ loadingIndexes,
2241
+ className,
2242
+ ...restProps
2243
+ }) });
2244
+ }
2245
+ if (children) {
2246
+ return /* @__PURE__ */ jsxs7(Fragment5, { children: [
2247
+ boundContainer,
2248
+ children
2249
+ ] });
2250
+ }
2251
+ return boundContainer;
2252
+ });
2253
+ CopilotChatSuggestionView.displayName = "CopilotChatSuggestionView";
2254
+ var CopilotChatSuggestionView_default = CopilotChatSuggestionView;
2255
+
1967
2256
  // src/components/chat/CopilotChatMessageView.tsx
1968
2257
  import { twMerge as twMerge6 } from "tailwind-merge";
1969
- import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
2258
+ import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
1970
2259
  function CopilotChatMessageView({
1971
2260
  messages = [],
1972
2261
  assistantMessage,
@@ -1996,7 +2285,7 @@ function CopilotChatMessageView({
1996
2285
  if (children) {
1997
2286
  return children({ messageElements, messages, isRunning });
1998
2287
  }
1999
- return /* @__PURE__ */ jsxs6("div", { className: twMerge6("flex flex-col", className), ...props, children: [
2288
+ return /* @__PURE__ */ jsxs8("div", { className: twMerge6("flex flex-col", className), ...props, children: [
2000
2289
  messageElements,
2001
2290
  isRunning && renderSlot(cursor, CopilotChatMessageView.Cursor, {})
2002
2291
  ] });
@@ -2005,7 +2294,7 @@ CopilotChatMessageView.Cursor = function Cursor({
2005
2294
  className,
2006
2295
  ...props
2007
2296
  }) {
2008
- return /* @__PURE__ */ jsx12(
2297
+ return /* @__PURE__ */ jsx14(
2009
2298
  "div",
2010
2299
  {
2011
2300
  className: twMerge6(
@@ -2019,11 +2308,11 @@ CopilotChatMessageView.Cursor = function Cursor({
2019
2308
  var CopilotChatMessageView_default = CopilotChatMessageView;
2020
2309
 
2021
2310
  // src/components/chat/CopilotChatView.tsx
2022
- import React8, { useRef as useRef5, useState as useState7, useEffect as useEffect9 } from "react";
2311
+ import React10, { useRef as useRef6, useState as useState9, useEffect as useEffect11 } from "react";
2023
2312
  import { twMerge as twMerge7 } from "tailwind-merge";
2024
2313
  import { StickToBottom, useStickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
2025
2314
  import { ChevronDown } from "lucide-react";
2026
- import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
2315
+ import { Fragment as Fragment6, jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
2027
2316
  function CopilotChatView({
2028
2317
  messageView,
2029
2318
  input,
@@ -2032,19 +2321,23 @@ function CopilotChatView({
2032
2321
  feather,
2033
2322
  inputContainer,
2034
2323
  disclaimer,
2324
+ suggestionView,
2035
2325
  messages = [],
2036
2326
  autoScroll = true,
2037
2327
  inputProps,
2038
2328
  isRunning = false,
2329
+ suggestions,
2330
+ suggestionLoadingIndexes,
2331
+ onSelectSuggestion,
2039
2332
  children,
2040
2333
  className,
2041
2334
  ...props
2042
2335
  }) {
2043
- const inputContainerRef = useRef5(null);
2044
- const [inputContainerHeight, setInputContainerHeight] = useState7(0);
2045
- const [isResizing, setIsResizing] = useState7(false);
2046
- const resizeTimeoutRef = useRef5(null);
2047
- useEffect9(() => {
2336
+ const inputContainerRef = useRef6(null);
2337
+ const [inputContainerHeight, setInputContainerHeight] = useState9(0);
2338
+ const [isResizing, setIsResizing] = useState9(false);
2339
+ const resizeTimeoutRef = useRef6(null);
2340
+ useEffect11(() => {
2048
2341
  const element = inputContainerRef.current;
2049
2342
  if (!element) return;
2050
2343
  const resizeObserver = new ResizeObserver((entries) => {
@@ -2078,40 +2371,38 @@ function CopilotChatView({
2078
2371
  messages,
2079
2372
  isRunning
2080
2373
  });
2081
- const BoundInput = renderSlot(
2082
- input,
2083
- CopilotChatInput_default,
2084
- inputProps ?? {}
2085
- );
2374
+ const BoundInput = renderSlot(input, CopilotChatInput_default, inputProps ?? {});
2375
+ const hasSuggestions = Array.isArray(suggestions) && suggestions.length > 0;
2376
+ const BoundSuggestionView = hasSuggestions ? renderSlot(
2377
+ suggestionView,
2378
+ CopilotChatSuggestionView_default,
2379
+ {
2380
+ suggestions,
2381
+ loadingIndexes: suggestionLoadingIndexes,
2382
+ onSelectSuggestion,
2383
+ className: "mb-3 lg:ml-4 lg:mr-4 ml-0 mr-0"
2384
+ }
2385
+ ) : null;
2086
2386
  const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
2087
2387
  const BoundScrollView = renderSlot(scrollView, CopilotChatView.ScrollView, {
2088
2388
  autoScroll,
2089
2389
  scrollToBottomButton,
2090
2390
  inputContainerHeight,
2091
2391
  isResizing,
2092
- children: /* @__PURE__ */ jsx13("div", { style: { paddingBottom: `${inputContainerHeight + 32}px` }, children: /* @__PURE__ */ jsx13("div", { className: "max-w-3xl mx-auto", children: BoundMessageView }) })
2392
+ children: /* @__PURE__ */ jsx15("div", { style: { paddingBottom: `${inputContainerHeight + (hasSuggestions ? 4 : 32)}px` }, children: /* @__PURE__ */ jsxs9("div", { className: "max-w-3xl mx-auto", children: [
2393
+ BoundMessageView,
2394
+ hasSuggestions ? /* @__PURE__ */ jsx15("div", { className: "px-4 sm:px-0 mt-4", children: BoundSuggestionView }) : null
2395
+ ] }) })
2396
+ });
2397
+ const BoundScrollToBottomButton = renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, {});
2398
+ const BoundDisclaimer = renderSlot(disclaimer, CopilotChatView.Disclaimer, {});
2399
+ const BoundInputContainer = renderSlot(inputContainer, CopilotChatView.InputContainer, {
2400
+ ref: inputContainerRef,
2401
+ children: /* @__PURE__ */ jsxs9(Fragment6, { children: [
2402
+ /* @__PURE__ */ jsx15("div", { className: "max-w-3xl mx-auto py-0 px-4 sm:px-0 [div[data-sidebar-chat]_&]:px-8 pointer-events-auto", children: BoundInput }),
2403
+ BoundDisclaimer
2404
+ ] })
2093
2405
  });
2094
- const BoundScrollToBottomButton = renderSlot(
2095
- scrollToBottomButton,
2096
- CopilotChatView.ScrollToBottomButton,
2097
- {}
2098
- );
2099
- const BoundDisclaimer = renderSlot(
2100
- disclaimer,
2101
- CopilotChatView.Disclaimer,
2102
- {}
2103
- );
2104
- const BoundInputContainer = renderSlot(
2105
- inputContainer,
2106
- CopilotChatView.InputContainer,
2107
- {
2108
- ref: inputContainerRef,
2109
- children: /* @__PURE__ */ jsxs7(Fragment5, { children: [
2110
- /* @__PURE__ */ jsx13("div", { className: "max-w-3xl mx-auto py-0 px-4 sm:px-0", children: BoundInput }),
2111
- BoundDisclaimer
2112
- ] })
2113
- }
2114
- );
2115
2406
  if (children) {
2116
2407
  return children({
2117
2408
  messageView: BoundMessageView,
@@ -2120,10 +2411,11 @@ function CopilotChatView({
2120
2411
  scrollToBottomButton: BoundScrollToBottomButton,
2121
2412
  feather: BoundFeather,
2122
2413
  inputContainer: BoundInputContainer,
2123
- disclaimer: BoundDisclaimer
2414
+ disclaimer: BoundDisclaimer,
2415
+ suggestionView: BoundSuggestionView ?? /* @__PURE__ */ jsx15(Fragment6, {})
2124
2416
  });
2125
2417
  }
2126
- return /* @__PURE__ */ jsxs7("div", { className: twMerge7("relative h-full", className), ...props, children: [
2418
+ return /* @__PURE__ */ jsxs9("div", { className: twMerge7("relative h-full", className), ...props, children: [
2127
2419
  BoundScrollView,
2128
2420
  BoundFeather,
2129
2421
  BoundInputContainer
@@ -2132,22 +2424,18 @@ function CopilotChatView({
2132
2424
  ((CopilotChatView2) => {
2133
2425
  const ScrollContent = ({ children, scrollToBottomButton, inputContainerHeight, isResizing }) => {
2134
2426
  const { isAtBottom, scrollToBottom } = useStickToBottomContext();
2135
- return /* @__PURE__ */ jsxs7(Fragment5, { children: [
2136
- /* @__PURE__ */ jsx13(StickToBottom.Content, { className: "overflow-y-scroll overflow-x-hidden", children: /* @__PURE__ */ jsx13("div", { className: "px-4 sm:px-0", children }) }),
2137
- !isAtBottom && !isResizing && /* @__PURE__ */ jsx13(
2427
+ return /* @__PURE__ */ jsxs9(Fragment6, { children: [
2428
+ /* @__PURE__ */ jsx15(StickToBottom.Content, { className: "overflow-y-scroll overflow-x-hidden", children: /* @__PURE__ */ jsx15("div", { className: "px-4 sm:px-0 [div[data-sidebar-chat]_&]:px-8", children }) }),
2429
+ !isAtBottom && !isResizing && /* @__PURE__ */ jsx15(
2138
2430
  "div",
2139
2431
  {
2140
- className: "absolute inset-x-0 flex justify-center z-10",
2432
+ className: "absolute inset-x-0 flex justify-center z-10 pointer-events-none",
2141
2433
  style: {
2142
2434
  bottom: `${inputContainerHeight + 16}px`
2143
2435
  },
2144
- children: renderSlot(
2145
- scrollToBottomButton,
2146
- CopilotChatView2.ScrollToBottomButton,
2147
- {
2148
- onClick: () => scrollToBottom()
2149
- }
2150
- )
2436
+ children: renderSlot(scrollToBottomButton, CopilotChatView2.ScrollToBottomButton, {
2437
+ onClick: () => scrollToBottom()
2438
+ })
2151
2439
  }
2152
2440
  )
2153
2441
  ] });
@@ -2161,13 +2449,13 @@ function CopilotChatView({
2161
2449
  className,
2162
2450
  ...props
2163
2451
  }) => {
2164
- const [hasMounted, setHasMounted] = useState7(false);
2452
+ const [hasMounted, setHasMounted] = useState9(false);
2165
2453
  const { scrollRef, contentRef, scrollToBottom } = useStickToBottom();
2166
- const [showScrollButton, setShowScrollButton] = useState7(false);
2167
- useEffect9(() => {
2454
+ const [showScrollButton, setShowScrollButton] = useState9(false);
2455
+ useEffect11(() => {
2168
2456
  setHasMounted(true);
2169
2457
  }, []);
2170
- useEffect9(() => {
2458
+ useEffect11(() => {
2171
2459
  if (autoScroll) return;
2172
2460
  const scrollElement = scrollRef.current;
2173
2461
  if (!scrollElement) return;
@@ -2185,45 +2473,44 @@ function CopilotChatView({
2185
2473
  };
2186
2474
  }, [scrollRef, autoScroll]);
2187
2475
  if (!hasMounted) {
2188
- return /* @__PURE__ */ jsx13("div", { className: "h-full max-h-full flex flex-col min-h-0 overflow-y-scroll overflow-x-hidden", children: /* @__PURE__ */ jsx13("div", { className: "px-4 sm:px-0", children }) });
2476
+ return /* @__PURE__ */ jsx15("div", { className: "h-full max-h-full flex flex-col min-h-0 overflow-y-scroll overflow-x-hidden", children: /* @__PURE__ */ jsx15("div", { className: "px-4 sm:px-0 [div[data-sidebar-chat]_&]:px-8", children }) });
2189
2477
  }
2190
2478
  if (!autoScroll) {
2191
- return /* @__PURE__ */ jsxs7(
2479
+ return /* @__PURE__ */ jsxs9(
2192
2480
  "div",
2193
2481
  {
2194
2482
  ref: scrollRef,
2195
- className: cn("h-full max-h-full flex flex-col min-h-0 overflow-y-scroll overflow-x-hidden relative", className),
2483
+ className: cn(
2484
+ "h-full max-h-full flex flex-col min-h-0 overflow-y-scroll overflow-x-hidden relative",
2485
+ className
2486
+ ),
2196
2487
  ...props,
2197
2488
  children: [
2198
- /* @__PURE__ */ jsx13("div", { ref: contentRef, className: "px-4 sm:px-0", children }),
2199
- showScrollButton && !isResizing && /* @__PURE__ */ jsx13(
2489
+ /* @__PURE__ */ jsx15("div", { ref: contentRef, className: "px-4 sm:px-0 [div[data-sidebar-chat]_&]:px-8", children }),
2490
+ showScrollButton && !isResizing && /* @__PURE__ */ jsx15(
2200
2491
  "div",
2201
2492
  {
2202
- className: "absolute inset-x-0 flex justify-center z-10",
2493
+ className: "absolute inset-x-0 flex justify-center z-10 pointer-events-none",
2203
2494
  style: {
2204
2495
  bottom: `${inputContainerHeight + 16}px`
2205
2496
  },
2206
- children: renderSlot(
2207
- scrollToBottomButton,
2208
- CopilotChatView2.ScrollToBottomButton,
2209
- {
2210
- onClick: () => scrollToBottom()
2211
- }
2212
- )
2497
+ children: renderSlot(scrollToBottomButton, CopilotChatView2.ScrollToBottomButton, {
2498
+ onClick: () => scrollToBottom()
2499
+ })
2213
2500
  }
2214
2501
  )
2215
2502
  ]
2216
2503
  }
2217
2504
  );
2218
2505
  }
2219
- return /* @__PURE__ */ jsx13(
2506
+ return /* @__PURE__ */ jsx15(
2220
2507
  StickToBottom,
2221
2508
  {
2222
2509
  className: cn("h-full max-h-full flex flex-col min-h-0 relative", className),
2223
2510
  resize: "smooth",
2224
2511
  initial: "smooth",
2225
2512
  ...props,
2226
- children: /* @__PURE__ */ jsx13(
2513
+ children: /* @__PURE__ */ jsx15(
2227
2514
  ScrollContent,
2228
2515
  {
2229
2516
  scrollToBottomButton,
@@ -2235,13 +2522,16 @@ function CopilotChatView({
2235
2522
  }
2236
2523
  );
2237
2524
  };
2238
- CopilotChatView2.ScrollToBottomButton = ({ className, ...props }) => /* @__PURE__ */ jsx13(
2525
+ CopilotChatView2.ScrollToBottomButton = ({
2526
+ className,
2527
+ ...props
2528
+ }) => /* @__PURE__ */ jsx15(
2239
2529
  Button,
2240
2530
  {
2241
2531
  variant: "outline",
2242
2532
  size: "sm",
2243
2533
  className: twMerge7(
2244
- "rounded-full w-10 h-10 p-0",
2534
+ "rounded-full w-10 h-10 p-0 pointer-events-auto",
2245
2535
  "bg-white dark:bg-gray-900",
2246
2536
  "shadow-lg border border-gray-200 dark:border-gray-700",
2247
2537
  "hover:bg-gray-50 dark:hover:bg-gray-800",
@@ -2249,14 +2539,10 @@ function CopilotChatView({
2249
2539
  className
2250
2540
  ),
2251
2541
  ...props,
2252
- children: /* @__PURE__ */ jsx13(ChevronDown, { className: "w-4 h-4 text-gray-600 dark:text-white" })
2542
+ children: /* @__PURE__ */ jsx15(ChevronDown, { className: "w-4 h-4 text-gray-600 dark:text-white" })
2253
2543
  }
2254
2544
  );
2255
- CopilotChatView2.Feather = ({
2256
- className,
2257
- style,
2258
- ...props
2259
- }) => /* @__PURE__ */ jsx13(
2545
+ CopilotChatView2.Feather = ({ className, style, ...props }) => /* @__PURE__ */ jsx15(
2260
2546
  "div",
2261
2547
  {
2262
2548
  className: cn(
@@ -2269,28 +2555,15 @@ function CopilotChatView({
2269
2555
  ...props
2270
2556
  }
2271
2557
  );
2272
- CopilotChatView2.InputContainer = React8.forwardRef(({ children, className, ...props }, ref) => /* @__PURE__ */ jsx13(
2273
- "div",
2274
- {
2275
- ref,
2276
- className: cn("absolute bottom-0 left-0 right-0 z-20", className),
2277
- ...props,
2278
- children
2279
- }
2280
- ));
2558
+ CopilotChatView2.InputContainer = React10.forwardRef(({ children, className, ...props }, ref) => /* @__PURE__ */ jsx15("div", { ref, className: cn("absolute bottom-0 left-0 right-0 z-20 pointer-events-none", className), ...props, children }));
2281
2559
  CopilotChatView2.InputContainer.displayName = "CopilotChatView.InputContainer";
2282
- CopilotChatView2.Disclaimer = ({
2283
- className,
2284
- ...props
2285
- }) => {
2286
- const { labels } = useCopilotChatConfiguration();
2287
- return /* @__PURE__ */ jsx13(
2560
+ CopilotChatView2.Disclaimer = ({ className, ...props }) => {
2561
+ const config = useCopilotChatConfiguration();
2562
+ const labels = config?.labels ?? CopilotChatDefaultLabels;
2563
+ return /* @__PURE__ */ jsx15(
2288
2564
  "div",
2289
2565
  {
2290
- className: cn(
2291
- "text-center text-xs text-muted-foreground py-3 px-4 max-w-3xl mx-auto",
2292
- className
2293
- ),
2566
+ className: cn("text-center text-xs text-muted-foreground py-3 px-4 max-w-3xl mx-auto", className),
2294
2567
  ...props,
2295
2568
  children: labels.chatDisclaimerText
2296
2569
  }
@@ -2300,23 +2573,31 @@ function CopilotChatView({
2300
2573
  var CopilotChatView_default = CopilotChatView;
2301
2574
 
2302
2575
  // src/components/chat/CopilotChat.tsx
2303
- import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID3, randomUUID } from "@copilotkitnext/shared";
2304
- import { useCallback as useCallback3, useEffect as useEffect10, useMemo as useMemo3 } from "react";
2576
+ import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID6, randomUUID as randomUUID2 } from "@copilotkitnext/shared";
2577
+ import { useCallback as useCallback5, useEffect as useEffect12, useMemo as useMemo6 } from "react";
2305
2578
  import { merge } from "ts-deepmerge";
2306
2579
  import { AGUIConnectNotImplementedError } from "@ag-ui/client";
2307
- import { jsx as jsx14 } from "react/jsx-runtime";
2308
- function CopilotChat({
2309
- agentId = DEFAULT_AGENT_ID3,
2310
- threadId,
2311
- ...props
2312
- }) {
2313
- const { agent } = useAgent({ agentId });
2580
+ import { jsx as jsx16 } from "react/jsx-runtime";
2581
+ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen, ...props }) {
2582
+ const existingConfig = useCopilotChatConfiguration();
2583
+ const resolvedAgentId = agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID6;
2584
+ const resolvedThreadId = useMemo6(
2585
+ () => threadId ?? existingConfig?.threadId ?? randomUUID2(),
2586
+ [threadId, existingConfig?.threadId]
2587
+ );
2588
+ const { agent } = useAgent({ agentId: resolvedAgentId });
2314
2589
  const { copilotkit } = useCopilotKit();
2315
- const resolvedThreadId = useMemo3(() => threadId ?? randomUUID(), [threadId]);
2316
- useEffect10(() => {
2590
+ const { suggestions: autoSuggestions } = useSuggestions({ agentId: resolvedAgentId });
2591
+ const {
2592
+ inputProps: providedInputProps,
2593
+ messageView: providedMessageView,
2594
+ suggestionView: providedSuggestionView,
2595
+ ...restProps
2596
+ } = props;
2597
+ useEffect12(() => {
2317
2598
  const connect = async (agent2) => {
2318
2599
  try {
2319
- await copilotkit.connectAgent({ agent: agent2, agentId });
2600
+ await copilotkit.connectAgent({ agent: agent2 });
2320
2601
  } catch (error) {
2321
2602
  if (error instanceof AGUIConnectNotImplementedError) {
2322
2603
  } else {
@@ -2330,59 +2611,392 @@ function CopilotChat({
2330
2611
  }
2331
2612
  return () => {
2332
2613
  };
2333
- }, [resolvedThreadId, agent, copilotkit, agentId]);
2334
- const onSubmitInput = useCallback3(
2614
+ }, [resolvedThreadId, agent, copilotkit, resolvedAgentId]);
2615
+ const onSubmitInput = useCallback5(
2335
2616
  async (value) => {
2336
2617
  agent?.addMessage({
2337
- id: randomUUID(),
2618
+ id: randomUUID2(),
2338
2619
  role: "user",
2339
2620
  content: value
2340
2621
  });
2341
2622
  if (agent) {
2342
2623
  try {
2343
- await copilotkit.runAgent({ agent, agentId });
2624
+ await copilotkit.runAgent({ agent });
2344
2625
  } catch (error) {
2345
2626
  console.error("CopilotChat: runAgent failed", error);
2346
2627
  }
2347
2628
  }
2348
2629
  },
2349
- [agent, copilotkit, agentId]
2630
+ [agent, copilotkit]
2631
+ );
2632
+ const handleSelectSuggestion = useCallback5(
2633
+ async (suggestion) => {
2634
+ if (!agent) {
2635
+ return;
2636
+ }
2637
+ agent.addMessage({
2638
+ id: randomUUID2(),
2639
+ role: "user",
2640
+ content: suggestion.message
2641
+ });
2642
+ try {
2643
+ await copilotkit.runAgent({ agent });
2644
+ } catch (error) {
2645
+ console.error("CopilotChat: runAgent failed after selecting suggestion", error);
2646
+ }
2647
+ },
2648
+ [agent, copilotkit]
2350
2649
  );
2351
- const {
2352
- inputProps: providedInputProps,
2353
- messageView: providedMessageView,
2354
- ...restProps
2355
- } = props;
2356
2650
  const mergedProps = merge(
2357
2651
  {
2358
- isRunning: agent?.isRunning ?? false
2652
+ isRunning: agent?.isRunning ?? false,
2653
+ suggestions: autoSuggestions,
2654
+ onSelectSuggestion: handleSelectSuggestion,
2655
+ suggestionView: providedSuggestionView
2359
2656
  },
2360
2657
  {
2361
2658
  ...restProps,
2362
2659
  ...typeof providedMessageView === "string" ? { messageView: { className: providedMessageView } } : providedMessageView !== void 0 ? { messageView: providedMessageView } : {}
2363
2660
  }
2364
2661
  );
2365
- return /* @__PURE__ */ jsx14(
2662
+ const finalProps = merge(mergedProps, {
2663
+ messages: agent?.messages ?? [],
2664
+ inputProps: {
2665
+ onSubmitMessage: onSubmitInput,
2666
+ ...providedInputProps
2667
+ }
2668
+ });
2669
+ const RenderedChatView = renderSlot(chatView, CopilotChatView, finalProps);
2670
+ return /* @__PURE__ */ jsx16(
2366
2671
  CopilotChatConfigurationProvider,
2367
2672
  {
2368
- agentId,
2673
+ agentId: resolvedAgentId,
2369
2674
  threadId: resolvedThreadId,
2370
- children: /* @__PURE__ */ jsx14(
2371
- CopilotChatView,
2675
+ labels,
2676
+ isModalDefaultOpen,
2677
+ children: RenderedChatView
2678
+ }
2679
+ );
2680
+ }
2681
+ ((CopilotChat2) => {
2682
+ CopilotChat2.View = CopilotChatView;
2683
+ })(CopilotChat || (CopilotChat = {}));
2684
+
2685
+ // src/components/chat/CopilotChatToggleButton.tsx
2686
+ import React11, { useState as useState10 } from "react";
2687
+ import { MessageCircle, X as X2 } from "lucide-react";
2688
+ import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
2689
+ var DefaultOpenIcon = ({
2690
+ className,
2691
+ ...props
2692
+ }) => /* @__PURE__ */ jsx17(MessageCircle, { className: cn("h-6 w-6", className), strokeWidth: 1.75, fill: "currentColor", ...props });
2693
+ var DefaultCloseIcon = ({
2694
+ className,
2695
+ ...props
2696
+ }) => /* @__PURE__ */ jsx17(X2, { className: cn("h-6 w-6", className), strokeWidth: 1.75, ...props });
2697
+ DefaultOpenIcon.displayName = "CopilotChatToggleButton.OpenIcon";
2698
+ DefaultCloseIcon.displayName = "CopilotChatToggleButton.CloseIcon";
2699
+ var ICON_TRANSITION_STYLE = Object.freeze({
2700
+ transition: "opacity 120ms ease-out, transform 260ms cubic-bezier(0.22, 1, 0.36, 1)"
2701
+ });
2702
+ var ICON_WRAPPER_BASE = "pointer-events-none absolute inset-0 flex items-center justify-center will-change-transform";
2703
+ var BUTTON_BASE_CLASSES = cn(
2704
+ "fixed bottom-6 right-6 z-[1100] flex h-14 w-14 items-center justify-center",
2705
+ "rounded-full border border-primary bg-primary text-primary-foreground",
2706
+ "shadow-sm transition-all duration-200 ease-out",
2707
+ "hover:scale-[1.04] hover:shadow-md",
2708
+ "cursor-pointer",
2709
+ "active:scale-[0.96]",
2710
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
2711
+ "disabled:pointer-events-none disabled:opacity-60"
2712
+ );
2713
+ var CopilotChatToggleButton = React11.forwardRef(function CopilotChatToggleButton2({ openIcon, closeIcon, className, ...buttonProps }, ref) {
2714
+ const { onClick, type, disabled, ...restProps } = buttonProps;
2715
+ const configuration = useCopilotChatConfiguration();
2716
+ const labels = configuration?.labels ?? CopilotChatDefaultLabels;
2717
+ const [fallbackOpen, setFallbackOpen] = useState10(false);
2718
+ const isOpen = configuration?.isModalOpen ?? fallbackOpen;
2719
+ const setModalOpen = configuration?.setModalOpen ?? setFallbackOpen;
2720
+ const handleClick = (event) => {
2721
+ if (disabled) {
2722
+ return;
2723
+ }
2724
+ if (onClick) {
2725
+ onClick(event);
2726
+ }
2727
+ if (event.defaultPrevented) {
2728
+ return;
2729
+ }
2730
+ const nextOpen = !isOpen;
2731
+ setModalOpen(nextOpen);
2732
+ };
2733
+ const renderedOpenIcon = renderSlot(
2734
+ openIcon,
2735
+ DefaultOpenIcon,
2736
+ {
2737
+ className: "h-6 w-6",
2738
+ "aria-hidden": true,
2739
+ focusable: false
2740
+ }
2741
+ );
2742
+ const renderedCloseIcon = renderSlot(
2743
+ closeIcon,
2744
+ DefaultCloseIcon,
2745
+ {
2746
+ className: "h-6 w-6",
2747
+ "aria-hidden": true,
2748
+ focusable: false
2749
+ }
2750
+ );
2751
+ const openIconElement = /* @__PURE__ */ jsx17(
2752
+ "span",
2753
+ {
2754
+ "aria-hidden": "true",
2755
+ "data-slot": "chat-toggle-button-open-icon",
2756
+ className: ICON_WRAPPER_BASE,
2757
+ style: {
2758
+ ...ICON_TRANSITION_STYLE,
2759
+ opacity: isOpen ? 0 : 1,
2760
+ transform: `scale(${isOpen ? 0.75 : 1}) rotate(${isOpen ? 90 : 0}deg)`
2761
+ },
2762
+ children: renderedOpenIcon
2763
+ }
2764
+ );
2765
+ const closeIconElement = /* @__PURE__ */ jsx17(
2766
+ "span",
2767
+ {
2768
+ "aria-hidden": "true",
2769
+ "data-slot": "chat-toggle-button-close-icon",
2770
+ className: ICON_WRAPPER_BASE,
2771
+ style: {
2772
+ ...ICON_TRANSITION_STYLE,
2773
+ opacity: isOpen ? 1 : 0,
2774
+ transform: `scale(${isOpen ? 1 : 0.75}) rotate(${isOpen ? 0 : -90}deg)`
2775
+ },
2776
+ children: renderedCloseIcon
2777
+ }
2778
+ );
2779
+ return /* @__PURE__ */ jsxs10(
2780
+ "button",
2781
+ {
2782
+ ref,
2783
+ type: type ?? "button",
2784
+ "data-slot": "chat-toggle-button",
2785
+ "data-state": isOpen ? "open" : "closed",
2786
+ className: cn(BUTTON_BASE_CLASSES, className),
2787
+ "aria-label": isOpen ? labels.chatToggleCloseLabel : labels.chatToggleOpenLabel,
2788
+ "aria-pressed": isOpen,
2789
+ disabled,
2790
+ onClick: handleClick,
2791
+ ...restProps,
2792
+ children: [
2793
+ openIconElement,
2794
+ closeIconElement
2795
+ ]
2796
+ }
2797
+ );
2798
+ });
2799
+ CopilotChatToggleButton.displayName = "CopilotChatToggleButton";
2800
+ var CopilotChatToggleButton_default = CopilotChatToggleButton;
2801
+
2802
+ // src/components/chat/CopilotSidebarView.tsx
2803
+ import { useEffect as useEffect13, useRef as useRef7, useState as useState11 } from "react";
2804
+
2805
+ // src/components/chat/CopilotModalHeader.tsx
2806
+ import { useCallback as useCallback6 } from "react";
2807
+ import { X as X3 } from "lucide-react";
2808
+ import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
2809
+ function CopilotModalHeader({
2810
+ title,
2811
+ titleContent,
2812
+ closeButton,
2813
+ children,
2814
+ className,
2815
+ ...rest
2816
+ }) {
2817
+ const configuration = useCopilotChatConfiguration();
2818
+ const fallbackTitle = configuration?.labels.modalHeaderTitle ?? CopilotChatDefaultLabels.modalHeaderTitle;
2819
+ const resolvedTitle = title ?? fallbackTitle;
2820
+ const handleClose = useCallback6(() => {
2821
+ configuration?.setModalOpen(false);
2822
+ }, [configuration]);
2823
+ const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {
2824
+ children: resolvedTitle
2825
+ });
2826
+ const BoundCloseButton = renderSlot(closeButton, CopilotModalHeader.CloseButton, {
2827
+ onClick: handleClose
2828
+ });
2829
+ if (children) {
2830
+ return children({
2831
+ titleContent: BoundTitle,
2832
+ closeButton: BoundCloseButton,
2833
+ title: resolvedTitle,
2834
+ ...rest
2835
+ });
2836
+ }
2837
+ return /* @__PURE__ */ jsx18(
2838
+ "header",
2839
+ {
2840
+ "data-slot": "copilot-modal-header",
2841
+ className: cn(
2842
+ "flex items-center justify-between border-b border-border px-4 py-4",
2843
+ "bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80",
2844
+ className
2845
+ ),
2846
+ ...rest,
2847
+ children: /* @__PURE__ */ jsxs11("div", { className: "flex w-full items-center gap-2", children: [
2848
+ /* @__PURE__ */ jsx18("div", { className: "flex-1", "aria-hidden": "true" }),
2849
+ /* @__PURE__ */ jsx18("div", { className: "flex flex-1 justify-center text-center", children: BoundTitle }),
2850
+ /* @__PURE__ */ jsx18("div", { className: "flex flex-1 justify-end", children: BoundCloseButton })
2851
+ ] })
2852
+ }
2853
+ );
2854
+ }
2855
+ CopilotModalHeader.displayName = "CopilotModalHeader";
2856
+ ((CopilotModalHeader2) => {
2857
+ CopilotModalHeader2.Title = ({ children, className, ...props }) => /* @__PURE__ */ jsx18(
2858
+ "div",
2859
+ {
2860
+ className: cn(
2861
+ "w-full text-base font-medium leading-none tracking-tight text-foreground",
2862
+ className
2863
+ ),
2864
+ ...props,
2865
+ children
2866
+ }
2867
+ );
2868
+ CopilotModalHeader2.CloseButton = ({
2869
+ className,
2870
+ ...props
2871
+ }) => /* @__PURE__ */ jsx18(
2872
+ "button",
2873
+ {
2874
+ type: "button",
2875
+ className: cn(
2876
+ "inline-flex size-8 items-center justify-center rounded-full text-muted-foreground transition cursor-pointer",
2877
+ "hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2878
+ className
2879
+ ),
2880
+ "aria-label": "Close",
2881
+ ...props,
2882
+ children: /* @__PURE__ */ jsx18(X3, { className: "h-4 w-4", "aria-hidden": "true" })
2883
+ }
2884
+ );
2885
+ })(CopilotModalHeader || (CopilotModalHeader = {}));
2886
+ CopilotModalHeader.Title.displayName = "CopilotModalHeader.Title";
2887
+ CopilotModalHeader.CloseButton.displayName = "CopilotModalHeader.CloseButton";
2888
+
2889
+ // src/components/chat/CopilotSidebarView.tsx
2890
+ import { Fragment as Fragment7, jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
2891
+ var DEFAULT_SIDEBAR_WIDTH = 480;
2892
+ var SIDEBAR_TRANSITION_MS = 260;
2893
+ function CopilotSidebarView({ header, width, ...props }) {
2894
+ const configuration = useCopilotChatConfiguration();
2895
+ const isSidebarOpen = configuration?.isModalOpen ?? false;
2896
+ const sidebarRef = useRef7(null);
2897
+ const [sidebarWidth, setSidebarWidth] = useState11(width ?? DEFAULT_SIDEBAR_WIDTH);
2898
+ const widthToCss = (w) => {
2899
+ return typeof w === "number" ? `${w}px` : w;
2900
+ };
2901
+ const widthToMargin = (w) => {
2902
+ if (typeof w === "number") {
2903
+ return `${w}px`;
2904
+ }
2905
+ return w;
2906
+ };
2907
+ useEffect13(() => {
2908
+ if (width !== void 0) {
2909
+ return;
2910
+ }
2911
+ if (typeof window === "undefined") {
2912
+ return;
2913
+ }
2914
+ const element = sidebarRef.current;
2915
+ if (!element) {
2916
+ return;
2917
+ }
2918
+ const updateWidth = () => {
2919
+ const rect = element.getBoundingClientRect();
2920
+ if (rect.width > 0) {
2921
+ setSidebarWidth(rect.width);
2922
+ }
2923
+ };
2924
+ updateWidth();
2925
+ if (typeof ResizeObserver !== "undefined") {
2926
+ const observer = new ResizeObserver(() => updateWidth());
2927
+ observer.observe(element);
2928
+ return () => observer.disconnect();
2929
+ }
2930
+ window.addEventListener("resize", updateWidth);
2931
+ return () => window.removeEventListener("resize", updateWidth);
2932
+ }, [width]);
2933
+ const headerElement = renderSlot(header, CopilotModalHeader, {});
2934
+ return /* @__PURE__ */ jsxs12(Fragment7, { children: [
2935
+ isSidebarOpen && /* @__PURE__ */ jsx19(
2936
+ "style",
2937
+ {
2938
+ dangerouslySetInnerHTML: {
2939
+ __html: `body {
2940
+ margin-inline-end: ${widthToMargin(sidebarWidth)};
2941
+ transition: margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease;
2942
+ }`
2943
+ }
2944
+ }
2945
+ ),
2946
+ /* @__PURE__ */ jsx19(CopilotChatToggleButton_default, {}),
2947
+ /* @__PURE__ */ jsx19(
2948
+ "aside",
2949
+ {
2950
+ ref: sidebarRef,
2951
+ "data-copilot-sidebar": true,
2952
+ className: cn(
2953
+ "fixed right-0 top-0 z-[1200] flex h-dvh max-h-screen",
2954
+ "border-l border-border bg-background text-foreground shadow-xl",
2955
+ "transition-transform duration-300 ease-out",
2956
+ isSidebarOpen ? "translate-x-0" : "translate-x-full pointer-events-none"
2957
+ ),
2958
+ style: { width: widthToCss(sidebarWidth) },
2959
+ "aria-hidden": !isSidebarOpen,
2960
+ "aria-label": "Copilot chat sidebar",
2961
+ role: "complementary",
2962
+ children: /* @__PURE__ */ jsxs12("div", { className: "flex h-full w-full flex-col overflow-hidden", children: [
2963
+ headerElement,
2964
+ /* @__PURE__ */ jsx19("div", { className: "flex-1 overflow-hidden", "data-sidebar-chat": true, children: /* @__PURE__ */ jsx19(CopilotChatView_default, { ...props }) })
2965
+ ] })
2966
+ }
2967
+ )
2968
+ ] });
2969
+ }
2970
+ CopilotSidebarView.displayName = "CopilotSidebarView";
2971
+
2972
+ // src/components/chat/CopilotSidebar.tsx
2973
+ import { useMemo as useMemo7 } from "react";
2974
+ import { jsx as jsx20 } from "react/jsx-runtime";
2975
+ function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
2976
+ const SidebarViewOverride = useMemo7(() => {
2977
+ const Component = (viewProps) => {
2978
+ const { header: viewHeader, width: viewWidth, ...restProps } = viewProps;
2979
+ return /* @__PURE__ */ jsx20(
2980
+ CopilotSidebarView,
2372
2981
  {
2373
- ...{
2374
- messages: agent?.messages ?? [],
2375
- inputProps: {
2376
- onSubmitMessage: onSubmitInput,
2377
- ...providedInputProps
2378
- },
2379
- ...mergedProps
2380
- }
2982
+ ...restProps,
2983
+ header: header ?? viewHeader,
2984
+ width: width ?? viewWidth
2381
2985
  }
2382
- )
2986
+ );
2987
+ };
2988
+ return Object.assign(Component, CopilotChatView_default);
2989
+ }, [header, width]);
2990
+ return /* @__PURE__ */ jsx20(
2991
+ CopilotChat,
2992
+ {
2993
+ ...chatProps,
2994
+ chatView: SidebarViewOverride,
2995
+ isModalDefaultOpen: defaultOpen
2383
2996
  }
2384
2997
  );
2385
2998
  }
2999
+ CopilotSidebar.displayName = "CopilotSidebar";
2386
3000
 
2387
3001
  // src/types/defineToolCallRender.ts
2388
3002
  import { z as z2 } from "zod";
@@ -2397,25 +3011,25 @@ function defineToolCallRender(def) {
2397
3011
  }
2398
3012
 
2399
3013
  // src/components/WildcardToolCallRender.tsx
2400
- import { useState as useState8 } from "react";
2401
- import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
3014
+ import { useState as useState12 } from "react";
3015
+ import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
2402
3016
  var WildcardToolCallRender = defineToolCallRender({
2403
3017
  name: "*",
2404
3018
  render: ({ args, result, name, status }) => {
2405
- const [isExpanded, setIsExpanded] = useState8(false);
3019
+ const [isExpanded, setIsExpanded] = useState12(false);
2406
3020
  const statusString = String(status);
2407
3021
  const isActive = statusString === "inProgress" || statusString === "executing";
2408
3022
  const isComplete = statusString === "complete";
2409
3023
  const statusStyles = isActive ? "bg-amber-100 text-amber-800 dark:bg-amber-500/15 dark:text-amber-400" : isComplete ? "bg-emerald-100 text-emerald-800 dark:bg-emerald-500/15 dark:text-emerald-400" : "bg-zinc-100 text-zinc-800 dark:bg-zinc-700/40 dark:text-zinc-300";
2410
- return /* @__PURE__ */ jsx15("div", { className: "mt-2 pb-2", children: /* @__PURE__ */ jsxs8("div", { className: "rounded-xl border border-zinc-200/60 dark:border-zinc-800/60 bg-white/70 dark:bg-zinc-900/50 shadow-sm backdrop-blur p-4", children: [
2411
- /* @__PURE__ */ jsxs8(
3024
+ return /* @__PURE__ */ jsx21("div", { className: "mt-2 pb-2", children: /* @__PURE__ */ jsxs13("div", { className: "rounded-xl border border-zinc-200/60 dark:border-zinc-800/60 bg-white/70 dark:bg-zinc-900/50 shadow-sm backdrop-blur p-4", children: [
3025
+ /* @__PURE__ */ jsxs13(
2412
3026
  "div",
2413
3027
  {
2414
3028
  className: "flex items-center justify-between gap-3 cursor-pointer",
2415
3029
  onClick: () => setIsExpanded(!isExpanded),
2416
3030
  children: [
2417
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 min-w-0", children: [
2418
- /* @__PURE__ */ jsx15(
3031
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 min-w-0", children: [
3032
+ /* @__PURE__ */ jsx21(
2419
3033
  "svg",
2420
3034
  {
2421
3035
  className: `h-4 w-4 text-zinc-500 dark:text-zinc-400 transition-transform ${isExpanded ? "rotate-90" : ""}`,
@@ -2423,7 +3037,7 @@ var WildcardToolCallRender = defineToolCallRender({
2423
3037
  viewBox: "0 0 24 24",
2424
3038
  strokeWidth: 2,
2425
3039
  stroke: "currentColor",
2426
- children: /* @__PURE__ */ jsx15(
3040
+ children: /* @__PURE__ */ jsx21(
2427
3041
  "path",
2428
3042
  {
2429
3043
  strokeLinecap: "round",
@@ -2433,10 +3047,10 @@ var WildcardToolCallRender = defineToolCallRender({
2433
3047
  )
2434
3048
  }
2435
3049
  ),
2436
- /* @__PURE__ */ jsx15("span", { className: "inline-block h-2 w-2 rounded-full bg-blue-500" }),
2437
- /* @__PURE__ */ jsx15("span", { className: "truncate text-sm font-medium text-zinc-900 dark:text-zinc-100", children: name })
3050
+ /* @__PURE__ */ jsx21("span", { className: "inline-block h-2 w-2 rounded-full bg-blue-500" }),
3051
+ /* @__PURE__ */ jsx21("span", { className: "truncate text-sm font-medium text-zinc-900 dark:text-zinc-100", children: name })
2438
3052
  ] }),
2439
- /* @__PURE__ */ jsx15(
3053
+ /* @__PURE__ */ jsx21(
2440
3054
  "span",
2441
3055
  {
2442
3056
  className: `inline-flex items-center rounded-full px-2 py-1 text-xs font-medium ${statusStyles}`,
@@ -2446,14 +3060,14 @@ var WildcardToolCallRender = defineToolCallRender({
2446
3060
  ]
2447
3061
  }
2448
3062
  ),
2449
- isExpanded && /* @__PURE__ */ jsxs8("div", { className: "mt-3 grid gap-4", children: [
2450
- /* @__PURE__ */ jsxs8("div", { children: [
2451
- /* @__PURE__ */ jsx15("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Arguments" }),
2452
- /* @__PURE__ */ jsx15("pre", { className: "mt-2 max-h-64 overflow-auto rounded-md bg-zinc-50 dark:bg-zinc-800/60 p-3 text-xs leading-relaxed text-zinc-800 dark:text-zinc-200 whitespace-pre-wrap break-words", children: JSON.stringify(args ?? {}, null, 2) })
3063
+ isExpanded && /* @__PURE__ */ jsxs13("div", { className: "mt-3 grid gap-4", children: [
3064
+ /* @__PURE__ */ jsxs13("div", { children: [
3065
+ /* @__PURE__ */ jsx21("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Arguments" }),
3066
+ /* @__PURE__ */ jsx21("pre", { className: "mt-2 max-h-64 overflow-auto rounded-md bg-zinc-50 dark:bg-zinc-800/60 p-3 text-xs leading-relaxed text-zinc-800 dark:text-zinc-200 whitespace-pre-wrap break-words", children: JSON.stringify(args ?? {}, null, 2) })
2453
3067
  ] }),
2454
- result !== void 0 && /* @__PURE__ */ jsxs8("div", { children: [
2455
- /* @__PURE__ */ jsx15("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Result" }),
2456
- /* @__PURE__ */ jsx15("pre", { className: "mt-2 max-h-64 overflow-auto rounded-md bg-zinc-50 dark:bg-zinc-800/60 p-3 text-xs leading-relaxed text-zinc-800 dark:text-zinc-200 whitespace-pre-wrap break-words", children: typeof result === "string" ? result : JSON.stringify(result, null, 2) })
3068
+ result !== void 0 && /* @__PURE__ */ jsxs13("div", { children: [
3069
+ /* @__PURE__ */ jsx21("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Result" }),
3070
+ /* @__PURE__ */ jsx21("pre", { className: "mt-2 max-h-64 overflow-auto rounded-md bg-zinc-50 dark:bg-zinc-800/60 p-3 text-xs leading-relaxed text-zinc-800 dark:text-zinc-200 whitespace-pre-wrap break-words", children: typeof result === "string" ? result : JSON.stringify(result, null, 2) })
2457
3071
  ] })
2458
3072
  ] })
2459
3073
  ] }) });
@@ -2467,18 +3081,28 @@ export {
2467
3081
  CopilotChatConfigurationProvider,
2468
3082
  CopilotChatInput_default as CopilotChatInput,
2469
3083
  CopilotChatMessageView_default as CopilotChatMessageView,
3084
+ CopilotChatSuggestionPill_default as CopilotChatSuggestionPill,
3085
+ CopilotChatSuggestionView_default as CopilotChatSuggestionView,
3086
+ CopilotChatToggleButton,
3087
+ DefaultCloseIcon as CopilotChatToggleButtonCloseIcon,
3088
+ DefaultOpenIcon as CopilotChatToggleButtonOpenIcon,
2470
3089
  CopilotChatToolCallsView_default as CopilotChatToolCallsView,
2471
3090
  CopilotChatUserMessage_default as CopilotChatUserMessage,
2472
3091
  CopilotChatView_default as CopilotChatView,
2473
3092
  CopilotKitProvider,
3093
+ CopilotModalHeader,
3094
+ CopilotSidebar,
3095
+ CopilotSidebarView,
2474
3096
  WildcardToolCallRender,
2475
3097
  defineToolCallRender,
2476
3098
  useAgent,
2477
3099
  useAgentContext,
3100
+ useConfigureSuggestions,
2478
3101
  useCopilotChatConfiguration,
2479
3102
  useCopilotKit,
2480
3103
  useFrontendTool,
2481
3104
  useHumanInTheLoop,
2482
- useRenderToolCall
3105
+ useRenderToolCall,
3106
+ useSuggestions
2483
3107
  };
2484
3108
  //# sourceMappingURL=index.mjs.map