@copilotkitnext/react 0.0.14 → 0.0.15
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.d.mts +41 -15
- package/dist/index.d.ts +41 -15
- package/dist/index.js +890 -195
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +920 -218
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/components/chat/CopilotChatInput.tsx
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
useState as useState2,
|
|
6
|
+
useRef as useRef2,
|
|
7
|
+
useEffect as useEffect2,
|
|
8
|
+
useLayoutEffect,
|
|
9
|
+
forwardRef as forwardRef2,
|
|
10
|
+
useImperativeHandle as useImperativeHandle2,
|
|
11
|
+
useCallback,
|
|
12
|
+
useMemo as useMemo2
|
|
13
|
+
} from "react";
|
|
5
14
|
import { twMerge as twMerge3 } from "tailwind-merge";
|
|
6
|
-
import { Plus,
|
|
15
|
+
import { Plus, Mic, ArrowUp, X, Check } from "lucide-react";
|
|
7
16
|
|
|
8
17
|
// src/providers/CopilotChatConfigurationProvider.tsx
|
|
9
18
|
import { createContext, useContext, useMemo, useState } from "react";
|
|
@@ -493,6 +502,8 @@ function renderSlot(slot, DefaultComponent, props) {
|
|
|
493
502
|
|
|
494
503
|
// src/components/chat/CopilotChatInput.tsx
|
|
495
504
|
import { Fragment, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
505
|
+
var SLASH_MENU_MAX_VISIBLE_ITEMS = 5;
|
|
506
|
+
var SLASH_MENU_ITEM_HEIGHT_PX = 40;
|
|
496
507
|
function CopilotChatInput({
|
|
497
508
|
mode = "input",
|
|
498
509
|
onSubmitMessage,
|
|
@@ -504,15 +515,12 @@ function CopilotChatInput({
|
|
|
504
515
|
value,
|
|
505
516
|
toolsMenu,
|
|
506
517
|
autoFocus = true,
|
|
507
|
-
additionalToolbarItems,
|
|
508
518
|
textArea,
|
|
509
519
|
sendButton,
|
|
510
520
|
startTranscribeButton,
|
|
511
521
|
cancelTranscribeButton,
|
|
512
522
|
finishTranscribeButton,
|
|
513
|
-
|
|
514
|
-
toolsButton,
|
|
515
|
-
toolbar,
|
|
523
|
+
addMenuButton,
|
|
516
524
|
audioRecorder,
|
|
517
525
|
children,
|
|
518
526
|
className,
|
|
@@ -526,10 +534,82 @@ function CopilotChatInput({
|
|
|
526
534
|
}
|
|
527
535
|
}, [isControlled, value]);
|
|
528
536
|
const resolvedValue = isControlled ? value ?? "" : internalValue;
|
|
537
|
+
const [layout, setLayout] = useState2("compact");
|
|
538
|
+
const ignoreResizeRef = useRef2(false);
|
|
539
|
+
const resizeEvaluationRafRef = useRef2(null);
|
|
540
|
+
const isExpanded = mode === "input" && layout === "expanded";
|
|
541
|
+
const [commandQuery, setCommandQuery] = useState2(null);
|
|
542
|
+
const [slashHighlightIndex, setSlashHighlightIndex] = useState2(0);
|
|
529
543
|
const inputRef = useRef2(null);
|
|
544
|
+
const gridRef = useRef2(null);
|
|
545
|
+
const addButtonContainerRef = useRef2(null);
|
|
546
|
+
const actionsContainerRef = useRef2(null);
|
|
530
547
|
const audioRecorderRef = useRef2(null);
|
|
548
|
+
const slashMenuRef = useRef2(null);
|
|
531
549
|
const config = useCopilotChatConfiguration();
|
|
550
|
+
const labels = config?.labels ?? CopilotChatDefaultLabels;
|
|
532
551
|
const previousModalStateRef = useRef2(void 0);
|
|
552
|
+
const measurementCanvasRef = useRef2(null);
|
|
553
|
+
const measurementsRef = useRef2({
|
|
554
|
+
singleLineHeight: 0,
|
|
555
|
+
maxHeight: 0,
|
|
556
|
+
paddingLeft: 0,
|
|
557
|
+
paddingRight: 0
|
|
558
|
+
});
|
|
559
|
+
const commandItems = useMemo2(() => {
|
|
560
|
+
const entries = [];
|
|
561
|
+
const seen = /* @__PURE__ */ new Set();
|
|
562
|
+
const pushItem = (item) => {
|
|
563
|
+
if (item === "-") {
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
if (item.items && item.items.length > 0) {
|
|
567
|
+
for (const nested of item.items) {
|
|
568
|
+
pushItem(nested);
|
|
569
|
+
}
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
if (!seen.has(item.label)) {
|
|
573
|
+
seen.add(item.label);
|
|
574
|
+
entries.push(item);
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
if (onAddFile) {
|
|
578
|
+
pushItem({
|
|
579
|
+
label: labels.chatInputToolbarAddButtonLabel,
|
|
580
|
+
action: onAddFile
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
if (toolsMenu && toolsMenu.length > 0) {
|
|
584
|
+
for (const item of toolsMenu) {
|
|
585
|
+
pushItem(item);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
return entries;
|
|
589
|
+
}, [labels.chatInputToolbarAddButtonLabel, onAddFile, toolsMenu]);
|
|
590
|
+
const filteredCommands = useMemo2(() => {
|
|
591
|
+
if (commandQuery === null) {
|
|
592
|
+
return [];
|
|
593
|
+
}
|
|
594
|
+
if (commandItems.length === 0) {
|
|
595
|
+
return [];
|
|
596
|
+
}
|
|
597
|
+
const query = commandQuery.trim().toLowerCase();
|
|
598
|
+
if (query.length === 0) {
|
|
599
|
+
return commandItems;
|
|
600
|
+
}
|
|
601
|
+
const startsWith = [];
|
|
602
|
+
const contains = [];
|
|
603
|
+
for (const item of commandItems) {
|
|
604
|
+
const label = item.label.toLowerCase();
|
|
605
|
+
if (label.startsWith(query)) {
|
|
606
|
+
startsWith.push(item);
|
|
607
|
+
} else if (label.includes(query)) {
|
|
608
|
+
contains.push(item);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
return [...startsWith, ...contains];
|
|
612
|
+
}, [commandItems, commandQuery]);
|
|
533
613
|
useEffect2(() => {
|
|
534
614
|
if (!autoFocus) {
|
|
535
615
|
previousModalStateRef.current = config?.isModalOpen;
|
|
@@ -540,6 +620,29 @@ function CopilotChatInput({
|
|
|
540
620
|
}
|
|
541
621
|
previousModalStateRef.current = config?.isModalOpen;
|
|
542
622
|
}, [config?.isModalOpen, autoFocus]);
|
|
623
|
+
useEffect2(() => {
|
|
624
|
+
if (commandItems.length === 0 && commandQuery !== null) {
|
|
625
|
+
setCommandQuery(null);
|
|
626
|
+
}
|
|
627
|
+
}, [commandItems.length, commandQuery]);
|
|
628
|
+
const previousCommandQueryRef = useRef2(null);
|
|
629
|
+
useEffect2(() => {
|
|
630
|
+
if (commandQuery !== null && commandQuery !== previousCommandQueryRef.current && filteredCommands.length > 0) {
|
|
631
|
+
setSlashHighlightIndex(0);
|
|
632
|
+
}
|
|
633
|
+
previousCommandQueryRef.current = commandQuery;
|
|
634
|
+
}, [commandQuery, filteredCommands.length]);
|
|
635
|
+
useEffect2(() => {
|
|
636
|
+
if (commandQuery === null) {
|
|
637
|
+
setSlashHighlightIndex(0);
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
if (filteredCommands.length === 0) {
|
|
641
|
+
setSlashHighlightIndex(-1);
|
|
642
|
+
} else if (slashHighlightIndex < 0 || slashHighlightIndex >= filteredCommands.length) {
|
|
643
|
+
setSlashHighlightIndex(0);
|
|
644
|
+
}
|
|
645
|
+
}, [commandQuery, filteredCommands, slashHighlightIndex]);
|
|
543
646
|
useEffect2(() => {
|
|
544
647
|
const recorder = audioRecorderRef.current;
|
|
545
648
|
if (!recorder) {
|
|
@@ -553,14 +656,103 @@ function CopilotChatInput({
|
|
|
553
656
|
}
|
|
554
657
|
}
|
|
555
658
|
}, [mode]);
|
|
659
|
+
useEffect2(() => {
|
|
660
|
+
if (mode !== "input") {
|
|
661
|
+
setLayout("compact");
|
|
662
|
+
setCommandQuery(null);
|
|
663
|
+
}
|
|
664
|
+
}, [mode]);
|
|
665
|
+
const updateSlashState = useCallback(
|
|
666
|
+
(value2) => {
|
|
667
|
+
if (commandItems.length === 0) {
|
|
668
|
+
setCommandQuery((prev) => prev === null ? prev : null);
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
if (value2.startsWith("/")) {
|
|
672
|
+
const firstLine = value2.split(/\r?\n/, 1)[0] ?? "";
|
|
673
|
+
const query = firstLine.slice(1);
|
|
674
|
+
setCommandQuery((prev) => prev === query ? prev : query);
|
|
675
|
+
} else {
|
|
676
|
+
setCommandQuery((prev) => prev === null ? prev : null);
|
|
677
|
+
}
|
|
678
|
+
},
|
|
679
|
+
[commandItems.length]
|
|
680
|
+
);
|
|
681
|
+
useEffect2(() => {
|
|
682
|
+
updateSlashState(resolvedValue);
|
|
683
|
+
}, [resolvedValue, updateSlashState]);
|
|
556
684
|
const handleChange = (e) => {
|
|
557
685
|
const nextValue = e.target.value;
|
|
558
686
|
if (!isControlled) {
|
|
559
687
|
setInternalValue(nextValue);
|
|
560
688
|
}
|
|
561
689
|
onChange?.(nextValue);
|
|
690
|
+
updateSlashState(nextValue);
|
|
562
691
|
};
|
|
692
|
+
const clearInputValue = useCallback(() => {
|
|
693
|
+
if (!isControlled) {
|
|
694
|
+
setInternalValue("");
|
|
695
|
+
}
|
|
696
|
+
if (onChange) {
|
|
697
|
+
onChange("");
|
|
698
|
+
}
|
|
699
|
+
}, [isControlled, onChange]);
|
|
700
|
+
const runCommand = useCallback(
|
|
701
|
+
(item) => {
|
|
702
|
+
clearInputValue();
|
|
703
|
+
item.action?.();
|
|
704
|
+
setCommandQuery(null);
|
|
705
|
+
setSlashHighlightIndex(0);
|
|
706
|
+
requestAnimationFrame(() => {
|
|
707
|
+
inputRef.current?.focus();
|
|
708
|
+
});
|
|
709
|
+
},
|
|
710
|
+
[clearInputValue]
|
|
711
|
+
);
|
|
563
712
|
const handleKeyDown = (e) => {
|
|
713
|
+
if (commandQuery !== null && mode === "input") {
|
|
714
|
+
if (e.key === "ArrowDown") {
|
|
715
|
+
if (filteredCommands.length > 0) {
|
|
716
|
+
e.preventDefault();
|
|
717
|
+
setSlashHighlightIndex((prev) => {
|
|
718
|
+
if (filteredCommands.length === 0) {
|
|
719
|
+
return prev;
|
|
720
|
+
}
|
|
721
|
+
const next = prev === -1 ? 0 : (prev + 1) % filteredCommands.length;
|
|
722
|
+
return next;
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
if (e.key === "ArrowUp") {
|
|
728
|
+
if (filteredCommands.length > 0) {
|
|
729
|
+
e.preventDefault();
|
|
730
|
+
setSlashHighlightIndex((prev) => {
|
|
731
|
+
if (filteredCommands.length === 0) {
|
|
732
|
+
return prev;
|
|
733
|
+
}
|
|
734
|
+
if (prev === -1) {
|
|
735
|
+
return filteredCommands.length - 1;
|
|
736
|
+
}
|
|
737
|
+
return prev <= 0 ? filteredCommands.length - 1 : prev - 1;
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
if (e.key === "Enter") {
|
|
743
|
+
const selected = slashHighlightIndex >= 0 ? filteredCommands[slashHighlightIndex] : void 0;
|
|
744
|
+
if (selected) {
|
|
745
|
+
e.preventDefault();
|
|
746
|
+
runCommand(selected);
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
if (e.key === "Escape") {
|
|
751
|
+
e.preventDefault();
|
|
752
|
+
setCommandQuery(null);
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
564
756
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
565
757
|
e.preventDefault();
|
|
566
758
|
send();
|
|
@@ -588,7 +780,11 @@ function CopilotChatInput({
|
|
|
588
780
|
value: resolvedValue,
|
|
589
781
|
onChange: handleChange,
|
|
590
782
|
onKeyDown: handleKeyDown,
|
|
591
|
-
autoFocus
|
|
783
|
+
autoFocus,
|
|
784
|
+
className: twMerge3(
|
|
785
|
+
"w-full py-3",
|
|
786
|
+
isExpanded ? "px-5" : "pr-5"
|
|
787
|
+
)
|
|
592
788
|
});
|
|
593
789
|
const BoundAudioRecorder = renderSlot(audioRecorder, CopilotChatAudioRecorder, {
|
|
594
790
|
ref: audioRecorderRef
|
|
@@ -606,45 +802,20 @@ function CopilotChatInput({
|
|
|
606
802
|
const BoundFinishTranscribeButton = renderSlot(finishTranscribeButton, CopilotChatInput.FinishTranscribeButton, {
|
|
607
803
|
onClick: onFinishTranscribe
|
|
608
804
|
});
|
|
609
|
-
const
|
|
610
|
-
onClick: onAddFile,
|
|
611
|
-
disabled: mode === "transcribe"
|
|
612
|
-
});
|
|
613
|
-
const BoundToolsButton = renderSlot(toolsButton, CopilotChatInput.ToolsButton, {
|
|
805
|
+
const BoundAddMenuButton = renderSlot(addMenuButton, CopilotChatInput.AddMenuButton, {
|
|
614
806
|
disabled: mode === "transcribe",
|
|
807
|
+
onAddFile,
|
|
615
808
|
toolsMenu
|
|
616
809
|
});
|
|
617
|
-
const BoundToolbar = renderSlot(
|
|
618
|
-
typeof toolbar === "string" || toolbar === void 0 ? twMerge3(toolbar, "w-full h-[60px] bg-transparent flex items-center justify-between") : toolbar,
|
|
619
|
-
CopilotChatInput.Toolbar,
|
|
620
|
-
{
|
|
621
|
-
children: /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
622
|
-
/* @__PURE__ */ jsxs3("div", { className: "flex items-center", children: [
|
|
623
|
-
onAddFile && BoundAddFileButton,
|
|
624
|
-
BoundToolsButton,
|
|
625
|
-
additionalToolbarItems
|
|
626
|
-
] }),
|
|
627
|
-
/* @__PURE__ */ jsx6("div", { className: "flex items-center", children: mode === "transcribe" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
628
|
-
onCancelTranscribe && BoundCancelTranscribeButton,
|
|
629
|
-
onFinishTranscribe && BoundFinishTranscribeButton
|
|
630
|
-
] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
631
|
-
onStartTranscribe && BoundStartTranscribeButton,
|
|
632
|
-
BoundSendButton
|
|
633
|
-
] }) })
|
|
634
|
-
] })
|
|
635
|
-
}
|
|
636
|
-
);
|
|
637
810
|
if (children) {
|
|
638
|
-
|
|
811
|
+
const childProps = {
|
|
639
812
|
textArea: BoundTextArea,
|
|
640
813
|
audioRecorder: BoundAudioRecorder,
|
|
641
814
|
sendButton: BoundSendButton,
|
|
642
815
|
startTranscribeButton: BoundStartTranscribeButton,
|
|
643
816
|
cancelTranscribeButton: BoundCancelTranscribeButton,
|
|
644
817
|
finishTranscribeButton: BoundFinishTranscribeButton,
|
|
645
|
-
|
|
646
|
-
toolsButton: BoundToolsButton,
|
|
647
|
-
toolbar: BoundToolbar,
|
|
818
|
+
addMenuButton: BoundAddMenuButton,
|
|
648
819
|
onSubmitMessage,
|
|
649
820
|
onStartTranscribe,
|
|
650
821
|
onCancelTranscribe,
|
|
@@ -652,9 +823,9 @@ function CopilotChatInput({
|
|
|
652
823
|
onAddFile,
|
|
653
824
|
mode,
|
|
654
825
|
toolsMenu,
|
|
655
|
-
autoFocus
|
|
656
|
-
|
|
657
|
-
|
|
826
|
+
autoFocus
|
|
827
|
+
};
|
|
828
|
+
return /* @__PURE__ */ jsx6(Fragment, { children: children(childProps) });
|
|
658
829
|
}
|
|
659
830
|
const handleContainerClick = (e) => {
|
|
660
831
|
const target = e.target;
|
|
@@ -662,7 +833,227 @@ function CopilotChatInput({
|
|
|
662
833
|
inputRef.current.focus();
|
|
663
834
|
}
|
|
664
835
|
};
|
|
665
|
-
|
|
836
|
+
const ensureMeasurements = useCallback(() => {
|
|
837
|
+
const textarea = inputRef.current;
|
|
838
|
+
if (!textarea) {
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
const previousValue = textarea.value;
|
|
842
|
+
const previousHeight = textarea.style.height;
|
|
843
|
+
textarea.style.height = "auto";
|
|
844
|
+
const computedStyle = window.getComputedStyle(textarea);
|
|
845
|
+
const paddingLeft = parseFloat(computedStyle.paddingLeft) || 0;
|
|
846
|
+
const paddingRight = parseFloat(computedStyle.paddingRight) || 0;
|
|
847
|
+
const paddingTop = parseFloat(computedStyle.paddingTop) || 0;
|
|
848
|
+
const paddingBottom = parseFloat(computedStyle.paddingBottom) || 0;
|
|
849
|
+
textarea.value = "";
|
|
850
|
+
const singleLineHeight = textarea.scrollHeight;
|
|
851
|
+
textarea.value = previousValue;
|
|
852
|
+
const contentHeight = singleLineHeight - paddingTop - paddingBottom;
|
|
853
|
+
const maxHeight = contentHeight * 5 + paddingTop + paddingBottom;
|
|
854
|
+
measurementsRef.current = {
|
|
855
|
+
singleLineHeight,
|
|
856
|
+
maxHeight,
|
|
857
|
+
paddingLeft,
|
|
858
|
+
paddingRight
|
|
859
|
+
};
|
|
860
|
+
textarea.style.height = previousHeight;
|
|
861
|
+
textarea.style.maxHeight = `${maxHeight}px`;
|
|
862
|
+
}, []);
|
|
863
|
+
const adjustTextareaHeight = useCallback(() => {
|
|
864
|
+
const textarea = inputRef.current;
|
|
865
|
+
if (!textarea) {
|
|
866
|
+
return 0;
|
|
867
|
+
}
|
|
868
|
+
if (measurementsRef.current.singleLineHeight === 0) {
|
|
869
|
+
ensureMeasurements();
|
|
870
|
+
}
|
|
871
|
+
const { maxHeight } = measurementsRef.current;
|
|
872
|
+
if (maxHeight) {
|
|
873
|
+
textarea.style.maxHeight = `${maxHeight}px`;
|
|
874
|
+
}
|
|
875
|
+
textarea.style.height = "auto";
|
|
876
|
+
const scrollHeight = textarea.scrollHeight;
|
|
877
|
+
if (maxHeight) {
|
|
878
|
+
textarea.style.height = `${Math.min(scrollHeight, maxHeight)}px`;
|
|
879
|
+
} else {
|
|
880
|
+
textarea.style.height = `${scrollHeight}px`;
|
|
881
|
+
}
|
|
882
|
+
return scrollHeight;
|
|
883
|
+
}, [ensureMeasurements]);
|
|
884
|
+
const updateLayout = useCallback((nextLayout) => {
|
|
885
|
+
setLayout((prev) => {
|
|
886
|
+
if (prev === nextLayout) {
|
|
887
|
+
return prev;
|
|
888
|
+
}
|
|
889
|
+
ignoreResizeRef.current = true;
|
|
890
|
+
return nextLayout;
|
|
891
|
+
});
|
|
892
|
+
}, []);
|
|
893
|
+
const evaluateLayout = useCallback(() => {
|
|
894
|
+
if (mode !== "input") {
|
|
895
|
+
updateLayout("compact");
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
|
|
899
|
+
const isMobileViewport = window.matchMedia("(max-width: 767px)").matches;
|
|
900
|
+
if (isMobileViewport) {
|
|
901
|
+
ensureMeasurements();
|
|
902
|
+
adjustTextareaHeight();
|
|
903
|
+
updateLayout("expanded");
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
const textarea = inputRef.current;
|
|
908
|
+
const grid = gridRef.current;
|
|
909
|
+
const addContainer = addButtonContainerRef.current;
|
|
910
|
+
const actionsContainer = actionsContainerRef.current;
|
|
911
|
+
if (!textarea || !grid || !addContainer || !actionsContainer) {
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
if (measurementsRef.current.singleLineHeight === 0) {
|
|
915
|
+
ensureMeasurements();
|
|
916
|
+
}
|
|
917
|
+
const scrollHeight = adjustTextareaHeight();
|
|
918
|
+
const baseline = measurementsRef.current.singleLineHeight;
|
|
919
|
+
const hasExplicitBreak = resolvedValue.includes("\n");
|
|
920
|
+
const renderedMultiline = baseline > 0 ? scrollHeight > baseline + 1 : false;
|
|
921
|
+
let shouldExpand = hasExplicitBreak || renderedMultiline;
|
|
922
|
+
if (!shouldExpand) {
|
|
923
|
+
const gridStyles = window.getComputedStyle(grid);
|
|
924
|
+
const paddingLeft = parseFloat(gridStyles.paddingLeft) || 0;
|
|
925
|
+
const paddingRight = parseFloat(gridStyles.paddingRight) || 0;
|
|
926
|
+
const columnGap = parseFloat(gridStyles.columnGap) || 0;
|
|
927
|
+
const gridAvailableWidth = grid.clientWidth - paddingLeft - paddingRight;
|
|
928
|
+
if (gridAvailableWidth > 0) {
|
|
929
|
+
const addWidth = addContainer.getBoundingClientRect().width;
|
|
930
|
+
const actionsWidth = actionsContainer.getBoundingClientRect().width;
|
|
931
|
+
const compactWidth = Math.max(gridAvailableWidth - addWidth - actionsWidth - columnGap * 2, 0);
|
|
932
|
+
const canvas = measurementCanvasRef.current ?? document.createElement("canvas");
|
|
933
|
+
if (!measurementCanvasRef.current) {
|
|
934
|
+
measurementCanvasRef.current = canvas;
|
|
935
|
+
}
|
|
936
|
+
const context = canvas.getContext("2d");
|
|
937
|
+
if (context) {
|
|
938
|
+
const textareaStyles = window.getComputedStyle(textarea);
|
|
939
|
+
const font = textareaStyles.font || `${textareaStyles.fontStyle} ${textareaStyles.fontVariant} ${textareaStyles.fontWeight} ${textareaStyles.fontSize}/${textareaStyles.lineHeight} ${textareaStyles.fontFamily}`;
|
|
940
|
+
context.font = font;
|
|
941
|
+
const compactInnerWidth = Math.max(
|
|
942
|
+
compactWidth - (measurementsRef.current.paddingLeft || 0) - (measurementsRef.current.paddingRight || 0),
|
|
943
|
+
0
|
|
944
|
+
);
|
|
945
|
+
if (compactInnerWidth > 0) {
|
|
946
|
+
const lines = resolvedValue.length > 0 ? resolvedValue.split("\n") : [""];
|
|
947
|
+
let longestWidth = 0;
|
|
948
|
+
for (const line of lines) {
|
|
949
|
+
const metrics = context.measureText(line || " ");
|
|
950
|
+
if (metrics.width > longestWidth) {
|
|
951
|
+
longestWidth = metrics.width;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
if (longestWidth > compactInnerWidth) {
|
|
955
|
+
shouldExpand = true;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
const nextLayout = shouldExpand ? "expanded" : "compact";
|
|
962
|
+
updateLayout(nextLayout);
|
|
963
|
+
}, [adjustTextareaHeight, ensureMeasurements, mode, resolvedValue, updateLayout]);
|
|
964
|
+
useLayoutEffect(() => {
|
|
965
|
+
evaluateLayout();
|
|
966
|
+
}, [evaluateLayout]);
|
|
967
|
+
useEffect2(() => {
|
|
968
|
+
if (typeof ResizeObserver === "undefined") {
|
|
969
|
+
return;
|
|
970
|
+
}
|
|
971
|
+
const textarea = inputRef.current;
|
|
972
|
+
const grid = gridRef.current;
|
|
973
|
+
const addContainer = addButtonContainerRef.current;
|
|
974
|
+
const actionsContainer = actionsContainerRef.current;
|
|
975
|
+
if (!textarea || !grid || !addContainer || !actionsContainer) {
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
const scheduleEvaluation = () => {
|
|
979
|
+
if (ignoreResizeRef.current) {
|
|
980
|
+
ignoreResizeRef.current = false;
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
if (typeof window === "undefined") {
|
|
984
|
+
evaluateLayout();
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
if (resizeEvaluationRafRef.current !== null) {
|
|
988
|
+
cancelAnimationFrame(resizeEvaluationRafRef.current);
|
|
989
|
+
}
|
|
990
|
+
resizeEvaluationRafRef.current = window.requestAnimationFrame(() => {
|
|
991
|
+
resizeEvaluationRafRef.current = null;
|
|
992
|
+
evaluateLayout();
|
|
993
|
+
});
|
|
994
|
+
};
|
|
995
|
+
const observer = new ResizeObserver(() => {
|
|
996
|
+
scheduleEvaluation();
|
|
997
|
+
});
|
|
998
|
+
observer.observe(grid);
|
|
999
|
+
observer.observe(addContainer);
|
|
1000
|
+
observer.observe(actionsContainer);
|
|
1001
|
+
observer.observe(textarea);
|
|
1002
|
+
return () => {
|
|
1003
|
+
observer.disconnect();
|
|
1004
|
+
if (typeof window !== "undefined" && resizeEvaluationRafRef.current !== null) {
|
|
1005
|
+
cancelAnimationFrame(resizeEvaluationRafRef.current);
|
|
1006
|
+
resizeEvaluationRafRef.current = null;
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
}, [evaluateLayout]);
|
|
1010
|
+
const slashMenuVisible = commandQuery !== null && commandItems.length > 0;
|
|
1011
|
+
useEffect2(() => {
|
|
1012
|
+
if (!slashMenuVisible || slashHighlightIndex < 0) {
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
const active = slashMenuRef.current?.querySelector(
|
|
1016
|
+
`[data-slash-index="${slashHighlightIndex}"]`
|
|
1017
|
+
);
|
|
1018
|
+
active?.scrollIntoView({ block: "nearest" });
|
|
1019
|
+
}, [slashMenuVisible, slashHighlightIndex]);
|
|
1020
|
+
const slashMenu = slashMenuVisible ? /* @__PURE__ */ jsx6(
|
|
1021
|
+
"div",
|
|
1022
|
+
{
|
|
1023
|
+
"data-testid": "copilot-slash-menu",
|
|
1024
|
+
role: "listbox",
|
|
1025
|
+
"aria-label": "Slash commands",
|
|
1026
|
+
ref: slashMenuRef,
|
|
1027
|
+
className: "absolute bottom-full left-0 right-0 z-30 mb-2 max-h-64 overflow-y-auto rounded-lg border border-border bg-white shadow-lg dark:border-[#3a3a3a] dark:bg-[#1f1f1f]",
|
|
1028
|
+
style: { maxHeight: `${SLASH_MENU_MAX_VISIBLE_ITEMS * SLASH_MENU_ITEM_HEIGHT_PX}px` },
|
|
1029
|
+
children: filteredCommands.length === 0 ? /* @__PURE__ */ jsx6("div", { className: "px-3 py-2 text-sm text-muted-foreground", children: "No commands found" }) : filteredCommands.map((item, index) => {
|
|
1030
|
+
const isActive = index === slashHighlightIndex;
|
|
1031
|
+
return /* @__PURE__ */ jsx6(
|
|
1032
|
+
"button",
|
|
1033
|
+
{
|
|
1034
|
+
type: "button",
|
|
1035
|
+
role: "option",
|
|
1036
|
+
"aria-selected": isActive,
|
|
1037
|
+
"data-active": isActive ? "true" : void 0,
|
|
1038
|
+
"data-slash-index": index,
|
|
1039
|
+
className: twMerge3(
|
|
1040
|
+
"w-full px-3 py-2 text-left text-sm transition-colors",
|
|
1041
|
+
"hover:bg-muted dark:hover:bg-[#2f2f2f]",
|
|
1042
|
+
isActive ? "bg-muted dark:bg-[#2f2f2f]" : "bg-transparent"
|
|
1043
|
+
),
|
|
1044
|
+
onMouseEnter: () => setSlashHighlightIndex(index),
|
|
1045
|
+
onMouseDown: (event) => {
|
|
1046
|
+
event.preventDefault();
|
|
1047
|
+
runCommand(item);
|
|
1048
|
+
},
|
|
1049
|
+
children: item.label
|
|
1050
|
+
},
|
|
1051
|
+
`${item.label}-${index}`
|
|
1052
|
+
);
|
|
1053
|
+
})
|
|
1054
|
+
}
|
|
1055
|
+
) : null;
|
|
1056
|
+
return /* @__PURE__ */ jsx6(
|
|
666
1057
|
"div",
|
|
667
1058
|
{
|
|
668
1059
|
className: twMerge3(
|
|
@@ -680,10 +1071,62 @@ function CopilotChatInput({
|
|
|
680
1071
|
),
|
|
681
1072
|
onClick: handleContainerClick,
|
|
682
1073
|
...props,
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
1074
|
+
"data-layout": isExpanded ? "expanded" : "compact",
|
|
1075
|
+
children: /* @__PURE__ */ jsxs3(
|
|
1076
|
+
"div",
|
|
1077
|
+
{
|
|
1078
|
+
ref: gridRef,
|
|
1079
|
+
className: twMerge3(
|
|
1080
|
+
"grid w-full gap-x-3 gap-y-3 px-3 py-2",
|
|
1081
|
+
isExpanded ? "grid-cols-[auto_minmax(0,1fr)_auto] grid-rows-[auto_auto]" : "grid-cols-[auto_minmax(0,1fr)_auto] items-center"
|
|
1082
|
+
),
|
|
1083
|
+
"data-layout": isExpanded ? "expanded" : "compact",
|
|
1084
|
+
children: [
|
|
1085
|
+
/* @__PURE__ */ jsx6(
|
|
1086
|
+
"div",
|
|
1087
|
+
{
|
|
1088
|
+
ref: addButtonContainerRef,
|
|
1089
|
+
className: twMerge3(
|
|
1090
|
+
"flex items-center",
|
|
1091
|
+
isExpanded ? "row-start-2" : "row-start-1",
|
|
1092
|
+
"col-start-1"
|
|
1093
|
+
),
|
|
1094
|
+
children: BoundAddMenuButton
|
|
1095
|
+
}
|
|
1096
|
+
),
|
|
1097
|
+
/* @__PURE__ */ jsx6(
|
|
1098
|
+
"div",
|
|
1099
|
+
{
|
|
1100
|
+
className: twMerge3(
|
|
1101
|
+
"relative flex min-w-0 flex-col",
|
|
1102
|
+
isExpanded ? "col-span-3 row-start-1" : "col-start-2 row-start-1"
|
|
1103
|
+
),
|
|
1104
|
+
children: mode === "transcribe" ? BoundAudioRecorder : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1105
|
+
BoundTextArea,
|
|
1106
|
+
slashMenu
|
|
1107
|
+
] })
|
|
1108
|
+
}
|
|
1109
|
+
),
|
|
1110
|
+
/* @__PURE__ */ jsx6(
|
|
1111
|
+
"div",
|
|
1112
|
+
{
|
|
1113
|
+
ref: actionsContainerRef,
|
|
1114
|
+
className: twMerge3(
|
|
1115
|
+
"flex items-center justify-end gap-2",
|
|
1116
|
+
isExpanded ? "col-start-3 row-start-2" : "col-start-3 row-start-1"
|
|
1117
|
+
),
|
|
1118
|
+
children: mode === "transcribe" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1119
|
+
onCancelTranscribe && BoundCancelTranscribeButton,
|
|
1120
|
+
onFinishTranscribe && BoundFinishTranscribeButton
|
|
1121
|
+
] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1122
|
+
onStartTranscribe && BoundStartTranscribeButton,
|
|
1123
|
+
BoundSendButton
|
|
1124
|
+
] })
|
|
1125
|
+
}
|
|
1126
|
+
)
|
|
1127
|
+
]
|
|
1128
|
+
}
|
|
1129
|
+
)
|
|
687
1130
|
}
|
|
688
1131
|
);
|
|
689
1132
|
}
|
|
@@ -744,124 +1187,110 @@ function CopilotChatInput({
|
|
|
744
1187
|
...props
|
|
745
1188
|
}
|
|
746
1189
|
);
|
|
747
|
-
CopilotChatInput2.
|
|
748
|
-
CopilotChatInput2.ToolbarButton,
|
|
749
|
-
{
|
|
750
|
-
icon: /* @__PURE__ */ jsx6(Plus, { className: "size-[20px]" }),
|
|
751
|
-
labelKey: "chatInputToolbarAddButtonLabel",
|
|
752
|
-
defaultClassName: "ml-2",
|
|
753
|
-
...props
|
|
754
|
-
}
|
|
755
|
-
);
|
|
756
|
-
CopilotChatInput2.ToolsButton = ({ className, toolsMenu, ...props }) => {
|
|
1190
|
+
CopilotChatInput2.AddMenuButton = ({ className, toolsMenu, onAddFile, disabled, ...props }) => {
|
|
757
1191
|
const config = useCopilotChatConfiguration();
|
|
758
1192
|
const labels = config?.labels ?? CopilotChatDefaultLabels;
|
|
759
|
-
const
|
|
760
|
-
|
|
1193
|
+
const menuItems = useMemo2(() => {
|
|
1194
|
+
const items = [];
|
|
1195
|
+
if (onAddFile) {
|
|
1196
|
+
items.push({
|
|
1197
|
+
label: labels.chatInputToolbarAddButtonLabel,
|
|
1198
|
+
action: onAddFile
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
if (toolsMenu && toolsMenu.length > 0) {
|
|
1202
|
+
if (items.length > 0) {
|
|
1203
|
+
items.push("-");
|
|
1204
|
+
}
|
|
1205
|
+
for (const item of toolsMenu) {
|
|
1206
|
+
if (item === "-") {
|
|
1207
|
+
if (items.length === 0 || items[items.length - 1] === "-") {
|
|
1208
|
+
continue;
|
|
1209
|
+
}
|
|
1210
|
+
items.push(item);
|
|
1211
|
+
} else {
|
|
1212
|
+
items.push(item);
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
while (items.length > 0 && items[items.length - 1] === "-") {
|
|
1216
|
+
items.pop();
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
return items;
|
|
1220
|
+
}, [onAddFile, toolsMenu, labels.chatInputToolbarAddButtonLabel]);
|
|
1221
|
+
const renderMenuItems = useCallback(
|
|
1222
|
+
(items) => items.map((item, index) => {
|
|
761
1223
|
if (item === "-") {
|
|
762
|
-
return /* @__PURE__ */ jsx6(DropdownMenuSeparator, {}, index);
|
|
763
|
-
}
|
|
1224
|
+
return /* @__PURE__ */ jsx6(DropdownMenuSeparator, {}, `separator-${index}`);
|
|
1225
|
+
}
|
|
1226
|
+
if (item.items && item.items.length > 0) {
|
|
764
1227
|
return /* @__PURE__ */ jsxs3(DropdownMenuSub, { children: [
|
|
765
1228
|
/* @__PURE__ */ jsx6(DropdownMenuSubTrigger, { children: item.label }),
|
|
766
1229
|
/* @__PURE__ */ jsx6(DropdownMenuSubContent, { children: renderMenuItems(item.items) })
|
|
767
|
-
] }, index);
|
|
768
|
-
} else {
|
|
769
|
-
return /* @__PURE__ */ jsx6(DropdownMenuItem, { onClick: item.action, children: item.label }, index);
|
|
1230
|
+
] }, `group-${index}`);
|
|
770
1231
|
}
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
1232
|
+
return /* @__PURE__ */ jsx6(DropdownMenuItem, { onClick: item.action, children: item.label }, `item-${index}`);
|
|
1233
|
+
}),
|
|
1234
|
+
[]
|
|
1235
|
+
);
|
|
1236
|
+
const hasMenuItems = menuItems.length > 0;
|
|
1237
|
+
const isDisabled = disabled || !hasMenuItems;
|
|
776
1238
|
return /* @__PURE__ */ jsxs3(DropdownMenu, { children: [
|
|
777
|
-
/* @__PURE__ */
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
/* @__PURE__ */ jsx6(
|
|
788
|
-
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
|
|
1239
|
+
/* @__PURE__ */ jsxs3(Tooltip, { children: [
|
|
1240
|
+
/* @__PURE__ */ jsx6(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx6(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx6(
|
|
1241
|
+
Button,
|
|
1242
|
+
{
|
|
1243
|
+
type: "button",
|
|
1244
|
+
variant: "chatInputToolbarSecondary",
|
|
1245
|
+
size: "chatInputToolbarIcon",
|
|
1246
|
+
className: twMerge3("ml-1", className),
|
|
1247
|
+
disabled: isDisabled,
|
|
1248
|
+
...props,
|
|
1249
|
+
children: /* @__PURE__ */ jsx6(Plus, { className: "size-[20px]" })
|
|
1250
|
+
}
|
|
1251
|
+
) }) }),
|
|
1252
|
+
/* @__PURE__ */ jsx6(TooltipContent, { side: "bottom", children: /* @__PURE__ */ jsxs3("p", { className: "flex items-center gap-1 text-xs font-medium", children: [
|
|
1253
|
+
/* @__PURE__ */ jsx6("span", { children: "Add files and more" }),
|
|
1254
|
+
/* @__PURE__ */ jsx6("code", { className: "rounded bg-[#4a4a4a] px-1 py-[1px] font-mono text-[11px] text-white dark:bg-[#e0e0e0] dark:text-black", children: "/" })
|
|
1255
|
+
] }) })
|
|
1256
|
+
] }),
|
|
1257
|
+
hasMenuItems && /* @__PURE__ */ jsx6(DropdownMenuContent, { side: "top", align: "start", children: renderMenuItems(menuItems) })
|
|
792
1258
|
] });
|
|
793
1259
|
};
|
|
794
|
-
CopilotChatInput2.
|
|
795
|
-
CopilotChatInput2.TextArea = forwardRef2(function TextArea2({ maxRows = 5, style, className, ...props }, ref) {
|
|
1260
|
+
CopilotChatInput2.TextArea = forwardRef2(function TextArea2({ style, className, autoFocus, ...props }, ref) {
|
|
796
1261
|
const internalTextareaRef = useRef2(null);
|
|
797
|
-
const [maxHeight, setMaxHeight] = useState2(0);
|
|
798
1262
|
const config = useCopilotChatConfiguration();
|
|
799
1263
|
const labels = config?.labels ?? CopilotChatDefaultLabels;
|
|
800
1264
|
useImperativeHandle2(ref, () => internalTextareaRef.current);
|
|
801
|
-
const adjustHeight = () => {
|
|
802
|
-
const textarea = internalTextareaRef.current;
|
|
803
|
-
if (textarea && maxHeight > 0) {
|
|
804
|
-
textarea.style.height = "auto";
|
|
805
|
-
textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
|
|
806
|
-
}
|
|
807
|
-
};
|
|
808
1265
|
useEffect2(() => {
|
|
809
|
-
const
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
textarea.
|
|
814
|
-
|
|
815
|
-
const computedStyle = window.getComputedStyle(textarea);
|
|
816
|
-
const paddingTop = parseFloat(computedStyle.paddingTop);
|
|
817
|
-
const paddingBottom = parseFloat(computedStyle.paddingBottom);
|
|
818
|
-
const contentHeight = textarea.scrollHeight - paddingTop - paddingBottom;
|
|
819
|
-
setMaxHeight(contentHeight * maxRows + paddingTop + paddingBottom);
|
|
820
|
-
textarea.value = currentValue;
|
|
821
|
-
if (currentValue) {
|
|
822
|
-
textarea.style.height = "auto";
|
|
823
|
-
textarea.style.height = `${Math.min(textarea.scrollHeight, contentHeight * maxRows + paddingTop + paddingBottom)}px`;
|
|
824
|
-
}
|
|
825
|
-
if (props.autoFocus) {
|
|
826
|
-
textarea.focus();
|
|
827
|
-
}
|
|
828
|
-
}
|
|
1266
|
+
const textarea = internalTextareaRef.current;
|
|
1267
|
+
if (!textarea) return;
|
|
1268
|
+
const handleFocus = () => {
|
|
1269
|
+
setTimeout(() => {
|
|
1270
|
+
textarea.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
1271
|
+
}, 300);
|
|
829
1272
|
};
|
|
830
|
-
|
|
831
|
-
|
|
1273
|
+
textarea.addEventListener("focus", handleFocus);
|
|
1274
|
+
return () => textarea.removeEventListener("focus", handleFocus);
|
|
1275
|
+
}, []);
|
|
832
1276
|
useEffect2(() => {
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
const handleInput = (e) => {
|
|
836
|
-
adjustHeight();
|
|
837
|
-
if (props.onChange) {
|
|
838
|
-
props.onChange(e);
|
|
1277
|
+
if (autoFocus) {
|
|
1278
|
+
internalTextareaRef.current?.focus();
|
|
839
1279
|
}
|
|
840
|
-
};
|
|
1280
|
+
}, [autoFocus]);
|
|
841
1281
|
return /* @__PURE__ */ jsx6(
|
|
842
1282
|
"textarea",
|
|
843
1283
|
{
|
|
844
1284
|
ref: internalTextareaRef,
|
|
845
1285
|
...props,
|
|
846
|
-
onChange: handleInput,
|
|
847
1286
|
style: {
|
|
848
1287
|
overflow: "auto",
|
|
849
1288
|
resize: "none",
|
|
850
|
-
maxHeight: `${maxHeight}px`,
|
|
851
1289
|
...style
|
|
852
1290
|
},
|
|
853
1291
|
placeholder: labels.chatInputPlaceholder,
|
|
854
1292
|
className: twMerge3(
|
|
855
|
-
|
|
856
|
-
"w-full p-5 pb-0",
|
|
857
|
-
// Behavior
|
|
858
|
-
"outline-none resize-none",
|
|
859
|
-
// Background
|
|
860
|
-
"bg-transparent",
|
|
861
|
-
// Typography
|
|
862
|
-
"antialiased font-regular leading-relaxed text-[16px]",
|
|
863
|
-
// Placeholder styles
|
|
864
|
-
"placeholder:text-[#00000077] dark:placeholder:text-[#fffc]",
|
|
1293
|
+
"bg-transparent outline-none antialiased font-regular leading-relaxed text-[16px] placeholder:text-[#00000077] dark:placeholder:text-[#fffc]",
|
|
865
1294
|
className
|
|
866
1295
|
),
|
|
867
1296
|
rows: 1
|
|
@@ -876,9 +1305,7 @@ CopilotChatInput.ToolbarButton.displayName = "CopilotChatInput.ToolbarButton";
|
|
|
876
1305
|
CopilotChatInput.StartTranscribeButton.displayName = "CopilotChatInput.StartTranscribeButton";
|
|
877
1306
|
CopilotChatInput.CancelTranscribeButton.displayName = "CopilotChatInput.CancelTranscribeButton";
|
|
878
1307
|
CopilotChatInput.FinishTranscribeButton.displayName = "CopilotChatInput.FinishTranscribeButton";
|
|
879
|
-
CopilotChatInput.
|
|
880
|
-
CopilotChatInput.ToolsButton.displayName = "CopilotChatInput.ToolsButton";
|
|
881
|
-
CopilotChatInput.Toolbar.displayName = "CopilotChatInput.Toolbar";
|
|
1308
|
+
CopilotChatInput.AddMenuButton.displayName = "CopilotChatInput.AddMenuButton";
|
|
882
1309
|
var CopilotChatInput_default = CopilotChatInput;
|
|
883
1310
|
|
|
884
1311
|
// src/components/chat/CopilotChatAssistantMessage.tsx
|
|
@@ -896,14 +1323,14 @@ import "katex/dist/katex.min.css";
|
|
|
896
1323
|
import { Streamdown } from "streamdown";
|
|
897
1324
|
|
|
898
1325
|
// src/hooks/use-render-tool-call.tsx
|
|
899
|
-
import { useCallback, useEffect as useEffect5, useState as useState4, useSyncExternalStore } from "react";
|
|
1326
|
+
import { useCallback as useCallback2, useEffect as useEffect5, useState as useState4, useSyncExternalStore } from "react";
|
|
900
1327
|
import { ToolCallStatus } from "@copilotkitnext/core";
|
|
901
1328
|
|
|
902
1329
|
// src/providers/CopilotKitProvider.tsx
|
|
903
1330
|
import {
|
|
904
1331
|
createContext as createContext2,
|
|
905
1332
|
useContext as useContext2,
|
|
906
|
-
useMemo as
|
|
1333
|
+
useMemo as useMemo3,
|
|
907
1334
|
useEffect as useEffect4,
|
|
908
1335
|
useReducer,
|
|
909
1336
|
useRef as useRef4,
|
|
@@ -992,7 +1419,7 @@ var CopilotKitContext = createContext2({
|
|
|
992
1419
|
copilotkit: null
|
|
993
1420
|
});
|
|
994
1421
|
function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
|
|
995
|
-
const empty =
|
|
1422
|
+
const empty = useMemo3(() => [], []);
|
|
996
1423
|
const value = prop ?? empty;
|
|
997
1424
|
const initial = useRef4(value);
|
|
998
1425
|
useEffect4(() => {
|
|
@@ -1057,7 +1484,7 @@ var CopilotKitProvider = ({
|
|
|
1057
1484
|
humanInTheLoop,
|
|
1058
1485
|
"humanInTheLoop must be a stable array. If you want to dynamically add or remove human-in-the-loop tools, use `useHumanInTheLoop` instead."
|
|
1059
1486
|
);
|
|
1060
|
-
const processedHumanInTheLoopTools =
|
|
1487
|
+
const processedHumanInTheLoopTools = useMemo3(() => {
|
|
1061
1488
|
const processedTools = [];
|
|
1062
1489
|
const processedRenderToolCalls = [];
|
|
1063
1490
|
humanInTheLoopList.forEach((tool) => {
|
|
@@ -1086,13 +1513,13 @@ var CopilotKitProvider = ({
|
|
|
1086
1513
|
});
|
|
1087
1514
|
return { tools: processedTools, renderToolCalls: processedRenderToolCalls };
|
|
1088
1515
|
}, [humanInTheLoopList]);
|
|
1089
|
-
const allTools =
|
|
1516
|
+
const allTools = useMemo3(() => {
|
|
1090
1517
|
const tools = [];
|
|
1091
1518
|
tools.push(...frontendToolsList);
|
|
1092
1519
|
tools.push(...processedHumanInTheLoopTools.tools);
|
|
1093
1520
|
return tools;
|
|
1094
1521
|
}, [frontendToolsList, processedHumanInTheLoopTools]);
|
|
1095
|
-
const allRenderToolCalls =
|
|
1522
|
+
const allRenderToolCalls = useMemo3(() => {
|
|
1096
1523
|
const combined = [...renderToolCallsList];
|
|
1097
1524
|
frontendToolsList.forEach((tool) => {
|
|
1098
1525
|
if (tool.render) {
|
|
@@ -1109,7 +1536,7 @@ var CopilotKitProvider = ({
|
|
|
1109
1536
|
combined.push(...processedHumanInTheLoopTools.renderToolCalls);
|
|
1110
1537
|
return combined;
|
|
1111
1538
|
}, [renderToolCallsList, frontendToolsList, processedHumanInTheLoopTools]);
|
|
1112
|
-
const copilotkit =
|
|
1539
|
+
const copilotkit = useMemo3(() => {
|
|
1113
1540
|
const copilotkit2 = new CopilotKitCoreReact({
|
|
1114
1541
|
runtimeUrl,
|
|
1115
1542
|
headers,
|
|
@@ -1209,7 +1636,7 @@ function useRenderToolCall() {
|
|
|
1209
1636
|
});
|
|
1210
1637
|
return () => unsubscribe();
|
|
1211
1638
|
}, [copilotkit]);
|
|
1212
|
-
const renderToolCall =
|
|
1639
|
+
const renderToolCall = useCallback2(
|
|
1213
1640
|
({
|
|
1214
1641
|
toolCall,
|
|
1215
1642
|
toolMessage
|
|
@@ -1358,7 +1785,7 @@ function useFrontendTool(tool) {
|
|
|
1358
1785
|
}
|
|
1359
1786
|
|
|
1360
1787
|
// src/hooks/use-human-in-the-loop.tsx
|
|
1361
|
-
import { useState as useState5, useCallback as
|
|
1788
|
+
import { useState as useState5, useCallback as useCallback3, useRef as useRef5, useEffect as useEffect7 } from "react";
|
|
1362
1789
|
import React7 from "react";
|
|
1363
1790
|
function useHumanInTheLoop(tool) {
|
|
1364
1791
|
const { copilotkit } = useCopilotKit();
|
|
@@ -1368,20 +1795,20 @@ function useHumanInTheLoop(tool) {
|
|
|
1368
1795
|
const statusRef = useRef5(status);
|
|
1369
1796
|
const resolvePromiseRef = useRef5(null);
|
|
1370
1797
|
statusRef.current = status;
|
|
1371
|
-
const respond =
|
|
1798
|
+
const respond = useCallback3(async (result) => {
|
|
1372
1799
|
if (resolvePromiseRef.current) {
|
|
1373
1800
|
resolvePromiseRef.current(result);
|
|
1374
1801
|
setStatus("complete");
|
|
1375
1802
|
resolvePromiseRef.current = null;
|
|
1376
1803
|
}
|
|
1377
1804
|
}, []);
|
|
1378
|
-
const handler =
|
|
1805
|
+
const handler = useCallback3(async () => {
|
|
1379
1806
|
return new Promise((resolve) => {
|
|
1380
1807
|
setStatus("executing");
|
|
1381
1808
|
resolvePromiseRef.current = resolve;
|
|
1382
1809
|
});
|
|
1383
1810
|
}, []);
|
|
1384
|
-
const RenderComponent =
|
|
1811
|
+
const RenderComponent = useCallback3(
|
|
1385
1812
|
(props) => {
|
|
1386
1813
|
const ToolComponent = tool.render;
|
|
1387
1814
|
const currentStatus = statusRef.current;
|
|
@@ -1433,7 +1860,7 @@ function useHumanInTheLoop(tool) {
|
|
|
1433
1860
|
}
|
|
1434
1861
|
|
|
1435
1862
|
// src/hooks/use-agent.tsx
|
|
1436
|
-
import { useMemo as
|
|
1863
|
+
import { useMemo as useMemo4, useEffect as useEffect8, useReducer as useReducer2 } from "react";
|
|
1437
1864
|
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID3 } from "@copilotkitnext/shared";
|
|
1438
1865
|
var ALL_UPDATES = [
|
|
1439
1866
|
"OnMessagesChanged" /* OnMessagesChanged */,
|
|
@@ -1444,11 +1871,11 @@ function useAgent({ agentId, updates } = {}) {
|
|
|
1444
1871
|
agentId ??= DEFAULT_AGENT_ID3;
|
|
1445
1872
|
const { copilotkit } = useCopilotKit();
|
|
1446
1873
|
const [, forceUpdate] = useReducer2((x) => x + 1, 0);
|
|
1447
|
-
const updateFlags =
|
|
1874
|
+
const updateFlags = useMemo4(
|
|
1448
1875
|
() => updates ?? ALL_UPDATES,
|
|
1449
1876
|
[JSON.stringify(updates)]
|
|
1450
1877
|
);
|
|
1451
|
-
const agent =
|
|
1878
|
+
const agent = useMemo4(() => {
|
|
1452
1879
|
return copilotkit.getAgent(agentId);
|
|
1453
1880
|
}, [
|
|
1454
1881
|
agentId,
|
|
@@ -1508,12 +1935,12 @@ function useAgentContext(context) {
|
|
|
1508
1935
|
}
|
|
1509
1936
|
|
|
1510
1937
|
// src/hooks/use-suggestions.tsx
|
|
1511
|
-
import { useCallback as
|
|
1938
|
+
import { useCallback as useCallback4, useEffect as useEffect10, useMemo as useMemo5, useState as useState6 } from "react";
|
|
1512
1939
|
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID4 } from "@copilotkitnext/shared";
|
|
1513
1940
|
function useSuggestions({ agentId } = {}) {
|
|
1514
1941
|
const { copilotkit } = useCopilotKit();
|
|
1515
1942
|
const config = useCopilotChatConfiguration();
|
|
1516
|
-
const resolvedAgentId =
|
|
1943
|
+
const resolvedAgentId = useMemo5(() => agentId ?? config?.agentId ?? DEFAULT_AGENT_ID4, [agentId, config?.agentId]);
|
|
1517
1944
|
const [suggestions, setSuggestions] = useState6(() => {
|
|
1518
1945
|
const result = copilotkit.getSuggestions(resolvedAgentId);
|
|
1519
1946
|
return result.suggestions;
|
|
@@ -1557,10 +1984,10 @@ function useSuggestions({ agentId } = {}) {
|
|
|
1557
1984
|
unsubscribe();
|
|
1558
1985
|
};
|
|
1559
1986
|
}, [copilotkit, resolvedAgentId]);
|
|
1560
|
-
const reloadSuggestions =
|
|
1987
|
+
const reloadSuggestions = useCallback4(() => {
|
|
1561
1988
|
copilotkit.reloadSuggestions(resolvedAgentId);
|
|
1562
1989
|
}, [copilotkit, resolvedAgentId]);
|
|
1563
|
-
const clearSuggestions =
|
|
1990
|
+
const clearSuggestions = useCallback4(() => {
|
|
1564
1991
|
copilotkit.clearSuggestions(resolvedAgentId);
|
|
1565
1992
|
}, [copilotkit, resolvedAgentId]);
|
|
1566
1993
|
return {
|
|
@@ -1572,20 +1999,20 @@ function useSuggestions({ agentId } = {}) {
|
|
|
1572
1999
|
}
|
|
1573
2000
|
|
|
1574
2001
|
// src/hooks/use-configure-suggestions.tsx
|
|
1575
|
-
import { useCallback as
|
|
2002
|
+
import { useCallback as useCallback5, useEffect as useEffect11, useMemo as useMemo6, useRef as useRef6 } from "react";
|
|
1576
2003
|
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID5 } from "@copilotkitnext/shared";
|
|
1577
2004
|
var EMPTY_DEPS = [];
|
|
1578
2005
|
function useConfigureSuggestions(config, options) {
|
|
1579
2006
|
const { copilotkit } = useCopilotKit();
|
|
1580
2007
|
const chatConfig = useCopilotChatConfiguration();
|
|
1581
2008
|
const extraDeps = options?.deps ?? EMPTY_DEPS;
|
|
1582
|
-
const resolvedConsumerAgentId =
|
|
1583
|
-
const rawConsumerAgentId =
|
|
2009
|
+
const resolvedConsumerAgentId = useMemo6(() => chatConfig?.agentId ?? DEFAULT_AGENT_ID5, [chatConfig?.agentId]);
|
|
2010
|
+
const rawConsumerAgentId = useMemo6(() => config ? config.consumerAgentId : void 0, [config]);
|
|
1584
2011
|
const normalizationCacheRef = useRef6({
|
|
1585
2012
|
serialized: null,
|
|
1586
2013
|
config: null
|
|
1587
2014
|
});
|
|
1588
|
-
const { normalizedConfig, serializedConfig } =
|
|
2015
|
+
const { normalizedConfig, serializedConfig } = useMemo6(() => {
|
|
1589
2016
|
if (!config) {
|
|
1590
2017
|
normalizationCacheRef.current = { serialized: null, config: null };
|
|
1591
2018
|
return { normalizedConfig: null, serializedConfig: null };
|
|
@@ -1618,7 +2045,7 @@ function useConfigureSuggestions(config, options) {
|
|
|
1618
2045
|
const latestConfigRef = useRef6(null);
|
|
1619
2046
|
latestConfigRef.current = normalizedConfig;
|
|
1620
2047
|
const previousSerializedConfigRef = useRef6(null);
|
|
1621
|
-
const targetAgentId =
|
|
2048
|
+
const targetAgentId = useMemo6(() => {
|
|
1622
2049
|
if (!normalizedConfig) {
|
|
1623
2050
|
return resolvedConsumerAgentId;
|
|
1624
2051
|
}
|
|
@@ -1629,7 +2056,7 @@ function useConfigureSuggestions(config, options) {
|
|
|
1629
2056
|
return consumer;
|
|
1630
2057
|
}, [normalizedConfig, resolvedConsumerAgentId]);
|
|
1631
2058
|
const isGlobalConfig = rawConsumerAgentId === void 0 || rawConsumerAgentId === "*";
|
|
1632
|
-
const requestReload =
|
|
2059
|
+
const requestReload = useCallback5(() => {
|
|
1633
2060
|
if (!normalizedConfig) {
|
|
1634
2061
|
return;
|
|
1635
2062
|
}
|
|
@@ -2203,7 +2630,7 @@ var CopilotChatUserMessage_default = CopilotChatUserMessage;
|
|
|
2203
2630
|
import React9 from "react";
|
|
2204
2631
|
import { Loader2 } from "lucide-react";
|
|
2205
2632
|
import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2206
|
-
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";
|
|
2633
|
+
var baseClasses = "group inline-flex h-7 sm:h-8 items-center gap-1 sm:gap-1.5 rounded-full border border-border/60 bg-background px-2.5 sm:px-3 text-[11px] sm: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";
|
|
2207
2634
|
var labelClasses = "whitespace-nowrap font-medium leading-none";
|
|
2208
2635
|
var CopilotChatSuggestionPill = React9.forwardRef(function CopilotChatSuggestionPill2({ className, children, icon, isLoading, type, ...props }, ref) {
|
|
2209
2636
|
const showIcon = !isLoading && icon;
|
|
@@ -2218,7 +2645,7 @@ var CopilotChatSuggestionPill = React9.forwardRef(function CopilotChatSuggestion
|
|
|
2218
2645
|
disabled: isLoading || props.disabled,
|
|
2219
2646
|
...props,
|
|
2220
2647
|
children: [
|
|
2221
|
-
isLoading ? /* @__PURE__ */ jsx14("span", { className: "flex h-4 w-4 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx14(Loader2, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" }) }) : showIcon && /* @__PURE__ */ jsx14("span", { className: "flex h-4 w-4 items-center justify-center text-muted-foreground", children: icon }),
|
|
2648
|
+
isLoading ? /* @__PURE__ */ jsx14("span", { className: "flex h-3.5 sm:h-4 w-3.5 sm:w-4 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx14(Loader2, { className: "h-3.5 sm:h-4 w-3.5 sm:w-4 animate-spin", "aria-hidden": "true" }) }) : showIcon && /* @__PURE__ */ jsx14("span", { className: "flex h-3.5 sm:h-4 w-3.5 sm:w-4 items-center justify-center text-muted-foreground", children: icon }),
|
|
2222
2649
|
/* @__PURE__ */ jsx14("span", { className: labelClasses, children })
|
|
2223
2650
|
]
|
|
2224
2651
|
}
|
|
@@ -2236,7 +2663,7 @@ var DefaultContainer = React10.forwardRef(function DefaultContainer2({ className
|
|
|
2236
2663
|
{
|
|
2237
2664
|
ref,
|
|
2238
2665
|
className: cn(
|
|
2239
|
-
"flex flex-wrap items-center gap-2
|
|
2666
|
+
"flex flex-wrap items-center gap-1.5 sm:gap-2 pl-0 pr-4 sm:px-0 pointer-events-none",
|
|
2240
2667
|
className
|
|
2241
2668
|
),
|
|
2242
2669
|
...props
|
|
@@ -2379,10 +2806,52 @@ CopilotChatMessageView.Cursor = function Cursor({ className, ...props }) {
|
|
|
2379
2806
|
var CopilotChatMessageView_default = CopilotChatMessageView;
|
|
2380
2807
|
|
|
2381
2808
|
// src/components/chat/CopilotChatView.tsx
|
|
2382
|
-
import React11, { useRef as useRef7, useState as
|
|
2809
|
+
import React11, { useRef as useRef7, useState as useState10, useEffect as useEffect13 } from "react";
|
|
2383
2810
|
import { twMerge as twMerge7 } from "tailwind-merge";
|
|
2384
2811
|
import { StickToBottom, useStickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
|
2385
2812
|
import { ChevronDown } from "lucide-react";
|
|
2813
|
+
|
|
2814
|
+
// src/hooks/use-keyboard-height.tsx
|
|
2815
|
+
import { useState as useState9, useEffect as useEffect12 } from "react";
|
|
2816
|
+
function useKeyboardHeight() {
|
|
2817
|
+
const [keyboardState, setKeyboardState] = useState9({
|
|
2818
|
+
isKeyboardOpen: false,
|
|
2819
|
+
keyboardHeight: 0,
|
|
2820
|
+
availableHeight: typeof window !== "undefined" ? window.innerHeight : 0,
|
|
2821
|
+
viewportHeight: typeof window !== "undefined" ? window.innerHeight : 0
|
|
2822
|
+
});
|
|
2823
|
+
useEffect12(() => {
|
|
2824
|
+
if (typeof window === "undefined") {
|
|
2825
|
+
return;
|
|
2826
|
+
}
|
|
2827
|
+
const visualViewport = window.visualViewport;
|
|
2828
|
+
if (!visualViewport) {
|
|
2829
|
+
return;
|
|
2830
|
+
}
|
|
2831
|
+
const updateKeyboardState = () => {
|
|
2832
|
+
const layoutHeight = window.innerHeight;
|
|
2833
|
+
const visualHeight = visualViewport.height;
|
|
2834
|
+
const keyboardHeight = Math.max(0, layoutHeight - visualHeight);
|
|
2835
|
+
const isKeyboardOpen = keyboardHeight > 150;
|
|
2836
|
+
setKeyboardState({
|
|
2837
|
+
isKeyboardOpen,
|
|
2838
|
+
keyboardHeight,
|
|
2839
|
+
availableHeight: visualHeight,
|
|
2840
|
+
viewportHeight: layoutHeight
|
|
2841
|
+
});
|
|
2842
|
+
};
|
|
2843
|
+
updateKeyboardState();
|
|
2844
|
+
visualViewport.addEventListener("resize", updateKeyboardState);
|
|
2845
|
+
visualViewport.addEventListener("scroll", updateKeyboardState);
|
|
2846
|
+
return () => {
|
|
2847
|
+
visualViewport.removeEventListener("resize", updateKeyboardState);
|
|
2848
|
+
visualViewport.removeEventListener("scroll", updateKeyboardState);
|
|
2849
|
+
};
|
|
2850
|
+
}, []);
|
|
2851
|
+
return keyboardState;
|
|
2852
|
+
}
|
|
2853
|
+
|
|
2854
|
+
// src/components/chat/CopilotChatView.tsx
|
|
2386
2855
|
import { Fragment as Fragment6, jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2387
2856
|
function CopilotChatView({
|
|
2388
2857
|
messageView,
|
|
@@ -2405,10 +2874,11 @@ function CopilotChatView({
|
|
|
2405
2874
|
...props
|
|
2406
2875
|
}) {
|
|
2407
2876
|
const inputContainerRef = useRef7(null);
|
|
2408
|
-
const [inputContainerHeight, setInputContainerHeight] =
|
|
2409
|
-
const [isResizing, setIsResizing] =
|
|
2877
|
+
const [inputContainerHeight, setInputContainerHeight] = useState10(0);
|
|
2878
|
+
const [isResizing, setIsResizing] = useState10(false);
|
|
2410
2879
|
const resizeTimeoutRef = useRef7(null);
|
|
2411
|
-
|
|
2880
|
+
const { isKeyboardOpen, keyboardHeight, availableHeight } = useKeyboardHeight();
|
|
2881
|
+
useEffect13(() => {
|
|
2412
2882
|
const element = inputContainerRef.current;
|
|
2413
2883
|
if (!element) return;
|
|
2414
2884
|
const resizeObserver = new ResizeObserver((entries) => {
|
|
@@ -2462,15 +2932,16 @@ function CopilotChatView({
|
|
|
2462
2932
|
isResizing,
|
|
2463
2933
|
children: /* @__PURE__ */ jsx17("div", { style: { paddingBottom: `${inputContainerHeight + (hasSuggestions ? 4 : 32)}px` }, children: /* @__PURE__ */ jsxs10("div", { className: "max-w-3xl mx-auto", children: [
|
|
2464
2934
|
BoundMessageView,
|
|
2465
|
-
hasSuggestions ? /* @__PURE__ */ jsx17("div", { className: "
|
|
2935
|
+
hasSuggestions ? /* @__PURE__ */ jsx17("div", { className: "pl-0 pr-4 sm:px-0 mt-4", children: BoundSuggestionView }) : null
|
|
2466
2936
|
] }) })
|
|
2467
2937
|
});
|
|
2468
2938
|
const BoundScrollToBottomButton = renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, {});
|
|
2469
2939
|
const BoundDisclaimer = renderSlot(disclaimer, CopilotChatView.Disclaimer, {});
|
|
2470
2940
|
const BoundInputContainer = renderSlot(inputContainer, CopilotChatView.InputContainer, {
|
|
2471
2941
|
ref: inputContainerRef,
|
|
2942
|
+
keyboardHeight: isKeyboardOpen ? keyboardHeight : 0,
|
|
2472
2943
|
children: /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
2473
|
-
/* @__PURE__ */ jsx17("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 }),
|
|
2944
|
+
/* @__PURE__ */ jsx17("div", { className: "max-w-3xl mx-auto py-0 px-4 sm:px-0 [div[data-sidebar-chat]_&]:px-8 [div[data-popup-chat]_&]:px-6 pointer-events-auto", children: BoundInput }),
|
|
2474
2945
|
BoundDisclaimer
|
|
2475
2946
|
] })
|
|
2476
2947
|
});
|
|
@@ -2496,7 +2967,7 @@ function CopilotChatView({
|
|
|
2496
2967
|
const ScrollContent = ({ children, scrollToBottomButton, inputContainerHeight, isResizing }) => {
|
|
2497
2968
|
const { isAtBottom, scrollToBottom } = useStickToBottomContext();
|
|
2498
2969
|
return /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
2499
|
-
/* @__PURE__ */ jsx17(StickToBottom.Content, { className: "overflow-y-scroll overflow-x-hidden", children: /* @__PURE__ */ jsx17("div", { className: "px-4 sm:px-0 [div[data-sidebar-chat]_&]:px-8", children }) }),
|
|
2970
|
+
/* @__PURE__ */ jsx17(StickToBottom.Content, { className: "overflow-y-scroll overflow-x-hidden", children: /* @__PURE__ */ jsx17("div", { className: "px-4 sm:px-0 [div[data-sidebar-chat]_&]:px-8 [div[data-popup-chat]_&]:px-6", children }) }),
|
|
2500
2971
|
!isAtBottom && !isResizing && /* @__PURE__ */ jsx17(
|
|
2501
2972
|
"div",
|
|
2502
2973
|
{
|
|
@@ -2520,13 +2991,13 @@ function CopilotChatView({
|
|
|
2520
2991
|
className,
|
|
2521
2992
|
...props
|
|
2522
2993
|
}) => {
|
|
2523
|
-
const [hasMounted, setHasMounted] =
|
|
2994
|
+
const [hasMounted, setHasMounted] = useState10(false);
|
|
2524
2995
|
const { scrollRef, contentRef, scrollToBottom } = useStickToBottom();
|
|
2525
|
-
const [showScrollButton, setShowScrollButton] =
|
|
2526
|
-
|
|
2996
|
+
const [showScrollButton, setShowScrollButton] = useState10(false);
|
|
2997
|
+
useEffect13(() => {
|
|
2527
2998
|
setHasMounted(true);
|
|
2528
2999
|
}, []);
|
|
2529
|
-
|
|
3000
|
+
useEffect13(() => {
|
|
2530
3001
|
if (autoScroll) return;
|
|
2531
3002
|
const scrollElement = scrollRef.current;
|
|
2532
3003
|
if (!scrollElement) return;
|
|
@@ -2544,7 +3015,7 @@ function CopilotChatView({
|
|
|
2544
3015
|
};
|
|
2545
3016
|
}, [scrollRef, autoScroll]);
|
|
2546
3017
|
if (!hasMounted) {
|
|
2547
|
-
return /* @__PURE__ */ jsx17("div", { className: "h-full max-h-full flex flex-col min-h-0 overflow-y-scroll overflow-x-hidden", children: /* @__PURE__ */ jsx17("div", { className: "px-4 sm:px-0 [div[data-sidebar-chat]_&]:px-8", children }) });
|
|
3018
|
+
return /* @__PURE__ */ jsx17("div", { className: "h-full max-h-full flex flex-col min-h-0 overflow-y-scroll overflow-x-hidden", children: /* @__PURE__ */ jsx17("div", { className: "px-4 sm:px-0 [div[data-sidebar-chat]_&]:px-8 [div[data-popup-chat]_&]:px-6", children }) });
|
|
2548
3019
|
}
|
|
2549
3020
|
if (!autoScroll) {
|
|
2550
3021
|
return /* @__PURE__ */ jsxs10(
|
|
@@ -2557,7 +3028,7 @@ function CopilotChatView({
|
|
|
2557
3028
|
),
|
|
2558
3029
|
...props,
|
|
2559
3030
|
children: [
|
|
2560
|
-
/* @__PURE__ */ jsx17("div", { ref: contentRef, className: "px-4 sm:px-0 [div[data-sidebar-chat]_&]:px-8", children }),
|
|
3031
|
+
/* @__PURE__ */ jsx17("div", { ref: contentRef, className: "px-4 sm:px-0 [div[data-sidebar-chat]_&]:px-8 [div[data-popup-chat]_&]:px-6", children }),
|
|
2561
3032
|
showScrollButton && !isResizing && /* @__PURE__ */ jsx17(
|
|
2562
3033
|
"div",
|
|
2563
3034
|
{
|
|
@@ -2626,7 +3097,20 @@ function CopilotChatView({
|
|
|
2626
3097
|
...props
|
|
2627
3098
|
}
|
|
2628
3099
|
);
|
|
2629
|
-
CopilotChatView2.InputContainer = React11.forwardRef(({ children, className, ...props }, ref) => /* @__PURE__ */ jsx17(
|
|
3100
|
+
CopilotChatView2.InputContainer = React11.forwardRef(({ children, className, keyboardHeight = 0, ...props }, ref) => /* @__PURE__ */ jsx17(
|
|
3101
|
+
"div",
|
|
3102
|
+
{
|
|
3103
|
+
ref,
|
|
3104
|
+
className: cn("absolute bottom-0 left-0 right-0 z-20 pointer-events-none", className),
|
|
3105
|
+
style: {
|
|
3106
|
+
// Adjust position when keyboard is open to keep input visible
|
|
3107
|
+
transform: keyboardHeight > 0 ? `translateY(-${keyboardHeight}px)` : void 0,
|
|
3108
|
+
transition: "transform 0.2s ease-out"
|
|
3109
|
+
},
|
|
3110
|
+
...props,
|
|
3111
|
+
children
|
|
3112
|
+
}
|
|
3113
|
+
));
|
|
2630
3114
|
CopilotChatView2.InputContainer.displayName = "CopilotChatView.InputContainer";
|
|
2631
3115
|
CopilotChatView2.Disclaimer = ({ className, ...props }) => {
|
|
2632
3116
|
const config = useCopilotChatConfiguration();
|
|
@@ -2645,14 +3129,14 @@ var CopilotChatView_default = CopilotChatView;
|
|
|
2645
3129
|
|
|
2646
3130
|
// src/components/chat/CopilotChat.tsx
|
|
2647
3131
|
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID6, randomUUID as randomUUID2 } from "@copilotkitnext/shared";
|
|
2648
|
-
import { useCallback as
|
|
3132
|
+
import { useCallback as useCallback6, useEffect as useEffect14, useMemo as useMemo7 } from "react";
|
|
2649
3133
|
import { merge } from "ts-deepmerge";
|
|
2650
3134
|
import { AGUIConnectNotImplementedError } from "@ag-ui/client";
|
|
2651
3135
|
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
2652
3136
|
function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen, ...props }) {
|
|
2653
3137
|
const existingConfig = useCopilotChatConfiguration();
|
|
2654
3138
|
const resolvedAgentId = agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID6;
|
|
2655
|
-
const resolvedThreadId =
|
|
3139
|
+
const resolvedThreadId = useMemo7(
|
|
2656
3140
|
() => threadId ?? existingConfig?.threadId ?? randomUUID2(),
|
|
2657
3141
|
[threadId, existingConfig?.threadId]
|
|
2658
3142
|
);
|
|
@@ -2665,7 +3149,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
2665
3149
|
suggestionView: providedSuggestionView,
|
|
2666
3150
|
...restProps
|
|
2667
3151
|
} = props;
|
|
2668
|
-
|
|
3152
|
+
useEffect14(() => {
|
|
2669
3153
|
const connect = async (agent2) => {
|
|
2670
3154
|
try {
|
|
2671
3155
|
await copilotkit.connectAgent({ agent: agent2 });
|
|
@@ -2683,7 +3167,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
2683
3167
|
return () => {
|
|
2684
3168
|
};
|
|
2685
3169
|
}, [resolvedThreadId, agent, copilotkit, resolvedAgentId]);
|
|
2686
|
-
const onSubmitInput =
|
|
3170
|
+
const onSubmitInput = useCallback6(
|
|
2687
3171
|
async (value) => {
|
|
2688
3172
|
agent?.addMessage({
|
|
2689
3173
|
id: randomUUID2(),
|
|
@@ -2700,7 +3184,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
2700
3184
|
},
|
|
2701
3185
|
[agent, copilotkit]
|
|
2702
3186
|
);
|
|
2703
|
-
const handleSelectSuggestion =
|
|
3187
|
+
const handleSelectSuggestion = useCallback6(
|
|
2704
3188
|
async (suggestion) => {
|
|
2705
3189
|
if (!agent) {
|
|
2706
3190
|
return;
|
|
@@ -2754,7 +3238,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
2754
3238
|
})(CopilotChat || (CopilotChat = {}));
|
|
2755
3239
|
|
|
2756
3240
|
// src/components/chat/CopilotChatToggleButton.tsx
|
|
2757
|
-
import React12, { useState as
|
|
3241
|
+
import React12, { useState as useState11 } from "react";
|
|
2758
3242
|
import { MessageCircle, X as X2 } from "lucide-react";
|
|
2759
3243
|
import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2760
3244
|
var DefaultOpenIcon = ({
|
|
@@ -2785,7 +3269,7 @@ var CopilotChatToggleButton = React12.forwardRef(function CopilotChatToggleButto
|
|
|
2785
3269
|
const { onClick, type, disabled, ...restProps } = buttonProps;
|
|
2786
3270
|
const configuration = useCopilotChatConfiguration();
|
|
2787
3271
|
const labels = configuration?.labels ?? CopilotChatDefaultLabels;
|
|
2788
|
-
const [fallbackOpen, setFallbackOpen] =
|
|
3272
|
+
const [fallbackOpen, setFallbackOpen] = useState11(false);
|
|
2789
3273
|
const isOpen = configuration?.isModalOpen ?? fallbackOpen;
|
|
2790
3274
|
const setModalOpen = configuration?.setModalOpen ?? setFallbackOpen;
|
|
2791
3275
|
const handleClick = (event) => {
|
|
@@ -2871,10 +3355,10 @@ CopilotChatToggleButton.displayName = "CopilotChatToggleButton";
|
|
|
2871
3355
|
var CopilotChatToggleButton_default = CopilotChatToggleButton;
|
|
2872
3356
|
|
|
2873
3357
|
// src/components/chat/CopilotSidebarView.tsx
|
|
2874
|
-
import { useEffect as
|
|
3358
|
+
import { useEffect as useEffect15, useRef as useRef8, useState as useState12 } from "react";
|
|
2875
3359
|
|
|
2876
3360
|
// src/components/chat/CopilotModalHeader.tsx
|
|
2877
|
-
import { useCallback as
|
|
3361
|
+
import { useCallback as useCallback7 } from "react";
|
|
2878
3362
|
import { X as X3 } from "lucide-react";
|
|
2879
3363
|
import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2880
3364
|
function CopilotModalHeader({
|
|
@@ -2888,7 +3372,7 @@ function CopilotModalHeader({
|
|
|
2888
3372
|
const configuration = useCopilotChatConfiguration();
|
|
2889
3373
|
const fallbackTitle = configuration?.labels.modalHeaderTitle ?? CopilotChatDefaultLabels.modalHeaderTitle;
|
|
2890
3374
|
const resolvedTitle = title ?? fallbackTitle;
|
|
2891
|
-
const handleClose =
|
|
3375
|
+
const handleClose = useCallback7(() => {
|
|
2892
3376
|
configuration?.setModalOpen(false);
|
|
2893
3377
|
}, [configuration]);
|
|
2894
3378
|
const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {
|
|
@@ -2965,7 +3449,7 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
2965
3449
|
const configuration = useCopilotChatConfiguration();
|
|
2966
3450
|
const isSidebarOpen = configuration?.isModalOpen ?? false;
|
|
2967
3451
|
const sidebarRef = useRef8(null);
|
|
2968
|
-
const [sidebarWidth, setSidebarWidth] =
|
|
3452
|
+
const [sidebarWidth, setSidebarWidth] = useState12(width ?? DEFAULT_SIDEBAR_WIDTH);
|
|
2969
3453
|
const widthToCss = (w) => {
|
|
2970
3454
|
return typeof w === "number" ? `${w}px` : w;
|
|
2971
3455
|
};
|
|
@@ -2975,7 +3459,7 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
2975
3459
|
}
|
|
2976
3460
|
return w;
|
|
2977
3461
|
};
|
|
2978
|
-
|
|
3462
|
+
useEffect15(() => {
|
|
2979
3463
|
if (width !== void 0) {
|
|
2980
3464
|
return;
|
|
2981
3465
|
}
|
|
@@ -3007,10 +3491,13 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3007
3491
|
"style",
|
|
3008
3492
|
{
|
|
3009
3493
|
dangerouslySetInnerHTML: {
|
|
3010
|
-
__html: `
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3494
|
+
__html: `
|
|
3495
|
+
@media (min-width: 768px) {
|
|
3496
|
+
body {
|
|
3497
|
+
margin-inline-end: ${widthToMargin(sidebarWidth)};
|
|
3498
|
+
transition: margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease;
|
|
3499
|
+
}
|
|
3500
|
+
}`
|
|
3014
3501
|
}
|
|
3015
3502
|
}
|
|
3016
3503
|
),
|
|
@@ -3021,12 +3508,22 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3021
3508
|
ref: sidebarRef,
|
|
3022
3509
|
"data-copilot-sidebar": true,
|
|
3023
3510
|
className: cn(
|
|
3024
|
-
"fixed right-0 top-0 z-[1200] flex
|
|
3511
|
+
"fixed right-0 top-0 z-[1200] flex",
|
|
3512
|
+
// Height with dvh fallback and safe area support
|
|
3513
|
+
"h-[100vh] h-[100dvh] max-h-screen",
|
|
3514
|
+
// Responsive width: full on mobile, custom on desktop
|
|
3515
|
+
"w-full",
|
|
3025
3516
|
"border-l border-border bg-background text-foreground shadow-xl",
|
|
3026
3517
|
"transition-transform duration-300 ease-out",
|
|
3027
3518
|
isSidebarOpen ? "translate-x-0" : "translate-x-full pointer-events-none"
|
|
3028
3519
|
),
|
|
3029
|
-
style: {
|
|
3520
|
+
style: {
|
|
3521
|
+
// Use CSS custom property for responsive width
|
|
3522
|
+
["--sidebar-width"]: widthToCss(sidebarWidth),
|
|
3523
|
+
// Safe area insets for iOS
|
|
3524
|
+
paddingTop: "env(safe-area-inset-top)",
|
|
3525
|
+
paddingBottom: "env(safe-area-inset-bottom)"
|
|
3526
|
+
},
|
|
3030
3527
|
"aria-hidden": !isSidebarOpen,
|
|
3031
3528
|
"aria-label": "Copilot chat sidebar",
|
|
3032
3529
|
role: "complementary",
|
|
@@ -3040,14 +3537,173 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3040
3537
|
}
|
|
3041
3538
|
CopilotSidebarView.displayName = "CopilotSidebarView";
|
|
3042
3539
|
|
|
3540
|
+
// src/components/chat/CopilotPopupView.tsx
|
|
3541
|
+
import { useEffect as useEffect16, useMemo as useMemo8, useRef as useRef9, useState as useState13 } from "react";
|
|
3542
|
+
import { Fragment as Fragment8, jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3543
|
+
var DEFAULT_POPUP_WIDTH = 420;
|
|
3544
|
+
var DEFAULT_POPUP_HEIGHT = 560;
|
|
3545
|
+
var dimensionToCss = (value, fallback) => {
|
|
3546
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
3547
|
+
return `${value}px`;
|
|
3548
|
+
}
|
|
3549
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
3550
|
+
return value;
|
|
3551
|
+
}
|
|
3552
|
+
return `${fallback}px`;
|
|
3553
|
+
};
|
|
3554
|
+
function CopilotPopupView({
|
|
3555
|
+
header,
|
|
3556
|
+
width,
|
|
3557
|
+
height,
|
|
3558
|
+
clickOutsideToClose,
|
|
3559
|
+
className,
|
|
3560
|
+
...restProps
|
|
3561
|
+
}) {
|
|
3562
|
+
const configuration = useCopilotChatConfiguration();
|
|
3563
|
+
const isPopupOpen = configuration?.isModalOpen ?? false;
|
|
3564
|
+
const setModalOpen = configuration?.setModalOpen;
|
|
3565
|
+
const labels = configuration?.labels ?? CopilotChatDefaultLabels;
|
|
3566
|
+
const containerRef = useRef9(null);
|
|
3567
|
+
const [isRendered, setIsRendered] = useState13(isPopupOpen);
|
|
3568
|
+
const [isAnimatingOut, setIsAnimatingOut] = useState13(false);
|
|
3569
|
+
useEffect16(() => {
|
|
3570
|
+
if (isPopupOpen) {
|
|
3571
|
+
setIsRendered(true);
|
|
3572
|
+
setIsAnimatingOut(false);
|
|
3573
|
+
return;
|
|
3574
|
+
}
|
|
3575
|
+
if (!isRendered) {
|
|
3576
|
+
return;
|
|
3577
|
+
}
|
|
3578
|
+
setIsAnimatingOut(true);
|
|
3579
|
+
const timeout = setTimeout(() => {
|
|
3580
|
+
setIsRendered(false);
|
|
3581
|
+
setIsAnimatingOut(false);
|
|
3582
|
+
}, 200);
|
|
3583
|
+
return () => clearTimeout(timeout);
|
|
3584
|
+
}, [isPopupOpen, isRendered]);
|
|
3585
|
+
useEffect16(() => {
|
|
3586
|
+
if (!isPopupOpen) {
|
|
3587
|
+
return;
|
|
3588
|
+
}
|
|
3589
|
+
if (typeof window === "undefined") {
|
|
3590
|
+
return;
|
|
3591
|
+
}
|
|
3592
|
+
const handleKeyDown = (event) => {
|
|
3593
|
+
if (event.key === "Escape") {
|
|
3594
|
+
event.preventDefault();
|
|
3595
|
+
setModalOpen?.(false);
|
|
3596
|
+
}
|
|
3597
|
+
};
|
|
3598
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
3599
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
3600
|
+
}, [isPopupOpen, setModalOpen]);
|
|
3601
|
+
useEffect16(() => {
|
|
3602
|
+
if (!isPopupOpen) {
|
|
3603
|
+
return;
|
|
3604
|
+
}
|
|
3605
|
+
const focusTimer = setTimeout(() => {
|
|
3606
|
+
containerRef.current?.focus({ preventScroll: true });
|
|
3607
|
+
}, 200);
|
|
3608
|
+
return () => clearTimeout(focusTimer);
|
|
3609
|
+
}, [isPopupOpen]);
|
|
3610
|
+
useEffect16(() => {
|
|
3611
|
+
if (!isPopupOpen || !clickOutsideToClose) {
|
|
3612
|
+
return;
|
|
3613
|
+
}
|
|
3614
|
+
if (typeof document === "undefined") {
|
|
3615
|
+
return;
|
|
3616
|
+
}
|
|
3617
|
+
const handlePointerDown = (event) => {
|
|
3618
|
+
const target = event.target;
|
|
3619
|
+
if (!target) {
|
|
3620
|
+
return;
|
|
3621
|
+
}
|
|
3622
|
+
const container = containerRef.current;
|
|
3623
|
+
if (container?.contains(target)) {
|
|
3624
|
+
return;
|
|
3625
|
+
}
|
|
3626
|
+
const toggleButton = document.querySelector("[data-slot='chat-toggle-button']");
|
|
3627
|
+
if (toggleButton && toggleButton.contains(target)) {
|
|
3628
|
+
return;
|
|
3629
|
+
}
|
|
3630
|
+
setModalOpen?.(false);
|
|
3631
|
+
};
|
|
3632
|
+
document.addEventListener("pointerdown", handlePointerDown);
|
|
3633
|
+
return () => document.removeEventListener("pointerdown", handlePointerDown);
|
|
3634
|
+
}, [isPopupOpen, clickOutsideToClose, setModalOpen]);
|
|
3635
|
+
const headerElement = useMemo8(() => renderSlot(header, CopilotModalHeader, {}), [header]);
|
|
3636
|
+
const resolvedWidth = dimensionToCss(width, DEFAULT_POPUP_WIDTH);
|
|
3637
|
+
const resolvedHeight = dimensionToCss(height, DEFAULT_POPUP_HEIGHT);
|
|
3638
|
+
const popupStyle = useMemo8(
|
|
3639
|
+
() => ({
|
|
3640
|
+
"--copilot-popup-width": resolvedWidth,
|
|
3641
|
+
"--copilot-popup-height": resolvedHeight,
|
|
3642
|
+
"--copilot-popup-max-width": "calc(100vw - 3rem)",
|
|
3643
|
+
"--copilot-popup-max-height": "calc(100dvh - 7.5rem)",
|
|
3644
|
+
paddingTop: "env(safe-area-inset-top)",
|
|
3645
|
+
paddingBottom: "env(safe-area-inset-bottom)",
|
|
3646
|
+
paddingLeft: "env(safe-area-inset-left)",
|
|
3647
|
+
paddingRight: "env(safe-area-inset-right)"
|
|
3648
|
+
}),
|
|
3649
|
+
[resolvedHeight, resolvedWidth]
|
|
3650
|
+
);
|
|
3651
|
+
const popupAnimationClass = isPopupOpen && !isAnimatingOut ? "pointer-events-auto translate-y-0 opacity-100 md:scale-100" : "pointer-events-none translate-y-4 opacity-0 md:translate-y-5 md:scale-[0.95]";
|
|
3652
|
+
const popupContent = isRendered ? /* @__PURE__ */ jsx22(
|
|
3653
|
+
"div",
|
|
3654
|
+
{
|
|
3655
|
+
className: cn(
|
|
3656
|
+
"fixed inset-0 z-[1200] flex max-w-full flex-col items-stretch",
|
|
3657
|
+
"md:inset-auto md:bottom-24 md:right-6 md:items-end md:gap-4"
|
|
3658
|
+
),
|
|
3659
|
+
children: /* @__PURE__ */ jsxs14(
|
|
3660
|
+
"div",
|
|
3661
|
+
{
|
|
3662
|
+
ref: containerRef,
|
|
3663
|
+
tabIndex: -1,
|
|
3664
|
+
role: "dialog",
|
|
3665
|
+
"aria-label": labels.modalHeaderTitle,
|
|
3666
|
+
"data-copilot-popup": true,
|
|
3667
|
+
className: cn(
|
|
3668
|
+
"relative flex h-full w-full flex-col overflow-hidden bg-background text-foreground",
|
|
3669
|
+
"origin-bottom focus:outline-none transform-gpu transition-transform transition-opacity duration-200 ease-out",
|
|
3670
|
+
"md:transition-transform md:transition-opacity",
|
|
3671
|
+
"rounded-none border border-border/0 shadow-none ring-0",
|
|
3672
|
+
"md:h-[var(--copilot-popup-height)] md:w-[var(--copilot-popup-width)]",
|
|
3673
|
+
"md:max-h-[var(--copilot-popup-max-height)] md:max-w-[var(--copilot-popup-max-width)]",
|
|
3674
|
+
"md:origin-bottom-right md:rounded-2xl md:border-border md:shadow-xl md:ring-1 md:ring-border/40",
|
|
3675
|
+
popupAnimationClass
|
|
3676
|
+
),
|
|
3677
|
+
style: popupStyle,
|
|
3678
|
+
children: [
|
|
3679
|
+
headerElement,
|
|
3680
|
+
/* @__PURE__ */ jsx22("div", { className: "flex-1 overflow-hidden", "data-popup-chat": true, children: /* @__PURE__ */ jsx22(
|
|
3681
|
+
CopilotChatView_default,
|
|
3682
|
+
{
|
|
3683
|
+
...restProps,
|
|
3684
|
+
className: cn("h-full min-h-0", className)
|
|
3685
|
+
}
|
|
3686
|
+
) })
|
|
3687
|
+
]
|
|
3688
|
+
}
|
|
3689
|
+
)
|
|
3690
|
+
}
|
|
3691
|
+
) : null;
|
|
3692
|
+
return /* @__PURE__ */ jsxs14(Fragment8, { children: [
|
|
3693
|
+
/* @__PURE__ */ jsx22(CopilotChatToggleButton_default, {}),
|
|
3694
|
+
popupContent
|
|
3695
|
+
] });
|
|
3696
|
+
}
|
|
3697
|
+
CopilotPopupView.displayName = "CopilotPopupView";
|
|
3698
|
+
|
|
3043
3699
|
// src/components/chat/CopilotSidebar.tsx
|
|
3044
|
-
import { useMemo as
|
|
3045
|
-
import { jsx as
|
|
3700
|
+
import { useMemo as useMemo9 } from "react";
|
|
3701
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
3046
3702
|
function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
|
|
3047
|
-
const SidebarViewOverride =
|
|
3703
|
+
const SidebarViewOverride = useMemo9(() => {
|
|
3048
3704
|
const Component = (viewProps) => {
|
|
3049
3705
|
const { header: viewHeader, width: viewWidth, ...restProps } = viewProps;
|
|
3050
|
-
return /* @__PURE__ */
|
|
3706
|
+
return /* @__PURE__ */ jsx23(
|
|
3051
3707
|
CopilotSidebarView,
|
|
3052
3708
|
{
|
|
3053
3709
|
...restProps,
|
|
@@ -3058,7 +3714,7 @@ function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
|
|
|
3058
3714
|
};
|
|
3059
3715
|
return Object.assign(Component, CopilotChatView_default);
|
|
3060
3716
|
}, [header, width]);
|
|
3061
|
-
return /* @__PURE__ */
|
|
3717
|
+
return /* @__PURE__ */ jsx23(
|
|
3062
3718
|
CopilotChat,
|
|
3063
3719
|
{
|
|
3064
3720
|
...chatProps,
|
|
@@ -3069,6 +3725,50 @@ function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
|
|
|
3069
3725
|
}
|
|
3070
3726
|
CopilotSidebar.displayName = "CopilotSidebar";
|
|
3071
3727
|
|
|
3728
|
+
// src/components/chat/CopilotPopup.tsx
|
|
3729
|
+
import { useMemo as useMemo10 } from "react";
|
|
3730
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
3731
|
+
function CopilotPopup({
|
|
3732
|
+
header,
|
|
3733
|
+
defaultOpen,
|
|
3734
|
+
width,
|
|
3735
|
+
height,
|
|
3736
|
+
clickOutsideToClose,
|
|
3737
|
+
...chatProps
|
|
3738
|
+
}) {
|
|
3739
|
+
const PopupViewOverride = useMemo10(() => {
|
|
3740
|
+
const Component = (viewProps) => {
|
|
3741
|
+
const {
|
|
3742
|
+
header: viewHeader,
|
|
3743
|
+
width: viewWidth,
|
|
3744
|
+
height: viewHeight,
|
|
3745
|
+
clickOutsideToClose: viewClickOutsideToClose,
|
|
3746
|
+
...restProps
|
|
3747
|
+
} = viewProps;
|
|
3748
|
+
return /* @__PURE__ */ jsx24(
|
|
3749
|
+
CopilotPopupView,
|
|
3750
|
+
{
|
|
3751
|
+
...restProps,
|
|
3752
|
+
header: header ?? viewHeader,
|
|
3753
|
+
width: width ?? viewWidth,
|
|
3754
|
+
height: height ?? viewHeight,
|
|
3755
|
+
clickOutsideToClose: clickOutsideToClose ?? viewClickOutsideToClose
|
|
3756
|
+
}
|
|
3757
|
+
);
|
|
3758
|
+
};
|
|
3759
|
+
return Object.assign(Component, CopilotChatView_default);
|
|
3760
|
+
}, [clickOutsideToClose, header, height, width]);
|
|
3761
|
+
return /* @__PURE__ */ jsx24(
|
|
3762
|
+
CopilotChat,
|
|
3763
|
+
{
|
|
3764
|
+
...chatProps,
|
|
3765
|
+
chatView: PopupViewOverride,
|
|
3766
|
+
isModalDefaultOpen: defaultOpen
|
|
3767
|
+
}
|
|
3768
|
+
);
|
|
3769
|
+
}
|
|
3770
|
+
CopilotPopup.displayName = "CopilotPopup";
|
|
3771
|
+
|
|
3072
3772
|
// src/types/defineToolCallRenderer.ts
|
|
3073
3773
|
import { z as z2 } from "zod";
|
|
3074
3774
|
function defineToolCallRenderer(def) {
|
|
@@ -3082,25 +3782,25 @@ function defineToolCallRenderer(def) {
|
|
|
3082
3782
|
}
|
|
3083
3783
|
|
|
3084
3784
|
// src/components/WildcardToolCallRender.tsx
|
|
3085
|
-
import { useState as
|
|
3086
|
-
import { jsx as
|
|
3785
|
+
import { useState as useState14 } from "react";
|
|
3786
|
+
import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3087
3787
|
var WildcardToolCallRender = defineToolCallRenderer({
|
|
3088
3788
|
name: "*",
|
|
3089
3789
|
render: ({ args, result, name, status }) => {
|
|
3090
|
-
const [isExpanded, setIsExpanded] =
|
|
3790
|
+
const [isExpanded, setIsExpanded] = useState14(false);
|
|
3091
3791
|
const statusString = String(status);
|
|
3092
3792
|
const isActive = statusString === "inProgress" || statusString === "executing";
|
|
3093
3793
|
const isComplete = statusString === "complete";
|
|
3094
3794
|
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";
|
|
3095
|
-
return /* @__PURE__ */
|
|
3096
|
-
/* @__PURE__ */
|
|
3795
|
+
return /* @__PURE__ */ jsx25("div", { className: "mt-2 pb-2", children: /* @__PURE__ */ jsxs15("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: [
|
|
3796
|
+
/* @__PURE__ */ jsxs15(
|
|
3097
3797
|
"div",
|
|
3098
3798
|
{
|
|
3099
3799
|
className: "flex items-center justify-between gap-3 cursor-pointer",
|
|
3100
3800
|
onClick: () => setIsExpanded(!isExpanded),
|
|
3101
3801
|
children: [
|
|
3102
|
-
/* @__PURE__ */
|
|
3103
|
-
/* @__PURE__ */
|
|
3802
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
3803
|
+
/* @__PURE__ */ jsx25(
|
|
3104
3804
|
"svg",
|
|
3105
3805
|
{
|
|
3106
3806
|
className: `h-4 w-4 text-zinc-500 dark:text-zinc-400 transition-transform ${isExpanded ? "rotate-90" : ""}`,
|
|
@@ -3108,7 +3808,7 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3108
3808
|
viewBox: "0 0 24 24",
|
|
3109
3809
|
strokeWidth: 2,
|
|
3110
3810
|
stroke: "currentColor",
|
|
3111
|
-
children: /* @__PURE__ */
|
|
3811
|
+
children: /* @__PURE__ */ jsx25(
|
|
3112
3812
|
"path",
|
|
3113
3813
|
{
|
|
3114
3814
|
strokeLinecap: "round",
|
|
@@ -3118,10 +3818,10 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3118
3818
|
)
|
|
3119
3819
|
}
|
|
3120
3820
|
),
|
|
3121
|
-
/* @__PURE__ */
|
|
3122
|
-
/* @__PURE__ */
|
|
3821
|
+
/* @__PURE__ */ jsx25("span", { className: "inline-block h-2 w-2 rounded-full bg-blue-500" }),
|
|
3822
|
+
/* @__PURE__ */ jsx25("span", { className: "truncate text-sm font-medium text-zinc-900 dark:text-zinc-100", children: name })
|
|
3123
3823
|
] }),
|
|
3124
|
-
/* @__PURE__ */
|
|
3824
|
+
/* @__PURE__ */ jsx25(
|
|
3125
3825
|
"span",
|
|
3126
3826
|
{
|
|
3127
3827
|
className: `inline-flex items-center rounded-full px-2 py-1 text-xs font-medium ${statusStyles}`,
|
|
@@ -3131,14 +3831,14 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3131
3831
|
]
|
|
3132
3832
|
}
|
|
3133
3833
|
),
|
|
3134
|
-
isExpanded && /* @__PURE__ */
|
|
3135
|
-
/* @__PURE__ */
|
|
3136
|
-
/* @__PURE__ */
|
|
3137
|
-
/* @__PURE__ */
|
|
3834
|
+
isExpanded && /* @__PURE__ */ jsxs15("div", { className: "mt-3 grid gap-4", children: [
|
|
3835
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
3836
|
+
/* @__PURE__ */ jsx25("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Arguments" }),
|
|
3837
|
+
/* @__PURE__ */ jsx25("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) })
|
|
3138
3838
|
] }),
|
|
3139
|
-
result !== void 0 && /* @__PURE__ */
|
|
3140
|
-
/* @__PURE__ */
|
|
3141
|
-
/* @__PURE__ */
|
|
3839
|
+
result !== void 0 && /* @__PURE__ */ jsxs15("div", { children: [
|
|
3840
|
+
/* @__PURE__ */ jsx25("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Result" }),
|
|
3841
|
+
/* @__PURE__ */ jsx25("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) })
|
|
3142
3842
|
] })
|
|
3143
3843
|
] })
|
|
3144
3844
|
] }) });
|
|
@@ -3164,6 +3864,8 @@ export {
|
|
|
3164
3864
|
CopilotKitInspector,
|
|
3165
3865
|
CopilotKitProvider,
|
|
3166
3866
|
CopilotModalHeader,
|
|
3867
|
+
CopilotPopup,
|
|
3868
|
+
CopilotPopupView,
|
|
3167
3869
|
CopilotSidebar,
|
|
3168
3870
|
CopilotSidebarView,
|
|
3169
3871
|
WildcardToolCallRender,
|