@copilotkitnext/react 0.0.14 → 0.0.16
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 +892 -196
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +922 -219
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +8 -8
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
|
}
|
|
@@ -1811,7 +2238,8 @@ function CopilotChatAssistantMessage({
|
|
|
1811
2238
|
}
|
|
1812
2239
|
);
|
|
1813
2240
|
const hasContent = !!(message.content && message.content.trim().length > 0);
|
|
1814
|
-
const
|
|
2241
|
+
const isLatestAssistantMessage = message.role === "assistant" && messages?.[messages.length - 1]?.id === message.id;
|
|
2242
|
+
const shouldShowToolbar = toolbarVisible && hasContent && !(isRunning && isLatestAssistantMessage);
|
|
1815
2243
|
if (children) {
|
|
1816
2244
|
return /* @__PURE__ */ jsx12(Fragment3, { children: children({
|
|
1817
2245
|
markdownRenderer: boundMarkdownRenderer,
|
|
@@ -2203,7 +2631,7 @@ var CopilotChatUserMessage_default = CopilotChatUserMessage;
|
|
|
2203
2631
|
import React9 from "react";
|
|
2204
2632
|
import { Loader2 } from "lucide-react";
|
|
2205
2633
|
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";
|
|
2634
|
+
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
2635
|
var labelClasses = "whitespace-nowrap font-medium leading-none";
|
|
2208
2636
|
var CopilotChatSuggestionPill = React9.forwardRef(function CopilotChatSuggestionPill2({ className, children, icon, isLoading, type, ...props }, ref) {
|
|
2209
2637
|
const showIcon = !isLoading && icon;
|
|
@@ -2218,7 +2646,7 @@ var CopilotChatSuggestionPill = React9.forwardRef(function CopilotChatSuggestion
|
|
|
2218
2646
|
disabled: isLoading || props.disabled,
|
|
2219
2647
|
...props,
|
|
2220
2648
|
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 }),
|
|
2649
|
+
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
2650
|
/* @__PURE__ */ jsx14("span", { className: labelClasses, children })
|
|
2223
2651
|
]
|
|
2224
2652
|
}
|
|
@@ -2236,7 +2664,7 @@ var DefaultContainer = React10.forwardRef(function DefaultContainer2({ className
|
|
|
2236
2664
|
{
|
|
2237
2665
|
ref,
|
|
2238
2666
|
className: cn(
|
|
2239
|
-
"flex flex-wrap items-center gap-2
|
|
2667
|
+
"flex flex-wrap items-center gap-1.5 sm:gap-2 pl-0 pr-4 sm:px-0 pointer-events-none",
|
|
2240
2668
|
className
|
|
2241
2669
|
),
|
|
2242
2670
|
...props
|
|
@@ -2379,10 +2807,52 @@ CopilotChatMessageView.Cursor = function Cursor({ className, ...props }) {
|
|
|
2379
2807
|
var CopilotChatMessageView_default = CopilotChatMessageView;
|
|
2380
2808
|
|
|
2381
2809
|
// src/components/chat/CopilotChatView.tsx
|
|
2382
|
-
import React11, { useRef as useRef7, useState as
|
|
2810
|
+
import React11, { useRef as useRef7, useState as useState10, useEffect as useEffect13 } from "react";
|
|
2383
2811
|
import { twMerge as twMerge7 } from "tailwind-merge";
|
|
2384
2812
|
import { StickToBottom, useStickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
|
2385
2813
|
import { ChevronDown } from "lucide-react";
|
|
2814
|
+
|
|
2815
|
+
// src/hooks/use-keyboard-height.tsx
|
|
2816
|
+
import { useState as useState9, useEffect as useEffect12 } from "react";
|
|
2817
|
+
function useKeyboardHeight() {
|
|
2818
|
+
const [keyboardState, setKeyboardState] = useState9({
|
|
2819
|
+
isKeyboardOpen: false,
|
|
2820
|
+
keyboardHeight: 0,
|
|
2821
|
+
availableHeight: typeof window !== "undefined" ? window.innerHeight : 0,
|
|
2822
|
+
viewportHeight: typeof window !== "undefined" ? window.innerHeight : 0
|
|
2823
|
+
});
|
|
2824
|
+
useEffect12(() => {
|
|
2825
|
+
if (typeof window === "undefined") {
|
|
2826
|
+
return;
|
|
2827
|
+
}
|
|
2828
|
+
const visualViewport = window.visualViewport;
|
|
2829
|
+
if (!visualViewport) {
|
|
2830
|
+
return;
|
|
2831
|
+
}
|
|
2832
|
+
const updateKeyboardState = () => {
|
|
2833
|
+
const layoutHeight = window.innerHeight;
|
|
2834
|
+
const visualHeight = visualViewport.height;
|
|
2835
|
+
const keyboardHeight = Math.max(0, layoutHeight - visualHeight);
|
|
2836
|
+
const isKeyboardOpen = keyboardHeight > 150;
|
|
2837
|
+
setKeyboardState({
|
|
2838
|
+
isKeyboardOpen,
|
|
2839
|
+
keyboardHeight,
|
|
2840
|
+
availableHeight: visualHeight,
|
|
2841
|
+
viewportHeight: layoutHeight
|
|
2842
|
+
});
|
|
2843
|
+
};
|
|
2844
|
+
updateKeyboardState();
|
|
2845
|
+
visualViewport.addEventListener("resize", updateKeyboardState);
|
|
2846
|
+
visualViewport.addEventListener("scroll", updateKeyboardState);
|
|
2847
|
+
return () => {
|
|
2848
|
+
visualViewport.removeEventListener("resize", updateKeyboardState);
|
|
2849
|
+
visualViewport.removeEventListener("scroll", updateKeyboardState);
|
|
2850
|
+
};
|
|
2851
|
+
}, []);
|
|
2852
|
+
return keyboardState;
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
// src/components/chat/CopilotChatView.tsx
|
|
2386
2856
|
import { Fragment as Fragment6, jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2387
2857
|
function CopilotChatView({
|
|
2388
2858
|
messageView,
|
|
@@ -2405,10 +2875,11 @@ function CopilotChatView({
|
|
|
2405
2875
|
...props
|
|
2406
2876
|
}) {
|
|
2407
2877
|
const inputContainerRef = useRef7(null);
|
|
2408
|
-
const [inputContainerHeight, setInputContainerHeight] =
|
|
2409
|
-
const [isResizing, setIsResizing] =
|
|
2878
|
+
const [inputContainerHeight, setInputContainerHeight] = useState10(0);
|
|
2879
|
+
const [isResizing, setIsResizing] = useState10(false);
|
|
2410
2880
|
const resizeTimeoutRef = useRef7(null);
|
|
2411
|
-
|
|
2881
|
+
const { isKeyboardOpen, keyboardHeight, availableHeight } = useKeyboardHeight();
|
|
2882
|
+
useEffect13(() => {
|
|
2412
2883
|
const element = inputContainerRef.current;
|
|
2413
2884
|
if (!element) return;
|
|
2414
2885
|
const resizeObserver = new ResizeObserver((entries) => {
|
|
@@ -2462,15 +2933,16 @@ function CopilotChatView({
|
|
|
2462
2933
|
isResizing,
|
|
2463
2934
|
children: /* @__PURE__ */ jsx17("div", { style: { paddingBottom: `${inputContainerHeight + (hasSuggestions ? 4 : 32)}px` }, children: /* @__PURE__ */ jsxs10("div", { className: "max-w-3xl mx-auto", children: [
|
|
2464
2935
|
BoundMessageView,
|
|
2465
|
-
hasSuggestions ? /* @__PURE__ */ jsx17("div", { className: "
|
|
2936
|
+
hasSuggestions ? /* @__PURE__ */ jsx17("div", { className: "pl-0 pr-4 sm:px-0 mt-4", children: BoundSuggestionView }) : null
|
|
2466
2937
|
] }) })
|
|
2467
2938
|
});
|
|
2468
2939
|
const BoundScrollToBottomButton = renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, {});
|
|
2469
2940
|
const BoundDisclaimer = renderSlot(disclaimer, CopilotChatView.Disclaimer, {});
|
|
2470
2941
|
const BoundInputContainer = renderSlot(inputContainer, CopilotChatView.InputContainer, {
|
|
2471
2942
|
ref: inputContainerRef,
|
|
2943
|
+
keyboardHeight: isKeyboardOpen ? keyboardHeight : 0,
|
|
2472
2944
|
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 }),
|
|
2945
|
+
/* @__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
2946
|
BoundDisclaimer
|
|
2475
2947
|
] })
|
|
2476
2948
|
});
|
|
@@ -2496,7 +2968,7 @@ function CopilotChatView({
|
|
|
2496
2968
|
const ScrollContent = ({ children, scrollToBottomButton, inputContainerHeight, isResizing }) => {
|
|
2497
2969
|
const { isAtBottom, scrollToBottom } = useStickToBottomContext();
|
|
2498
2970
|
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 }) }),
|
|
2971
|
+
/* @__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
2972
|
!isAtBottom && !isResizing && /* @__PURE__ */ jsx17(
|
|
2501
2973
|
"div",
|
|
2502
2974
|
{
|
|
@@ -2520,13 +2992,13 @@ function CopilotChatView({
|
|
|
2520
2992
|
className,
|
|
2521
2993
|
...props
|
|
2522
2994
|
}) => {
|
|
2523
|
-
const [hasMounted, setHasMounted] =
|
|
2995
|
+
const [hasMounted, setHasMounted] = useState10(false);
|
|
2524
2996
|
const { scrollRef, contentRef, scrollToBottom } = useStickToBottom();
|
|
2525
|
-
const [showScrollButton, setShowScrollButton] =
|
|
2526
|
-
|
|
2997
|
+
const [showScrollButton, setShowScrollButton] = useState10(false);
|
|
2998
|
+
useEffect13(() => {
|
|
2527
2999
|
setHasMounted(true);
|
|
2528
3000
|
}, []);
|
|
2529
|
-
|
|
3001
|
+
useEffect13(() => {
|
|
2530
3002
|
if (autoScroll) return;
|
|
2531
3003
|
const scrollElement = scrollRef.current;
|
|
2532
3004
|
if (!scrollElement) return;
|
|
@@ -2544,7 +3016,7 @@ function CopilotChatView({
|
|
|
2544
3016
|
};
|
|
2545
3017
|
}, [scrollRef, autoScroll]);
|
|
2546
3018
|
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 }) });
|
|
3019
|
+
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
3020
|
}
|
|
2549
3021
|
if (!autoScroll) {
|
|
2550
3022
|
return /* @__PURE__ */ jsxs10(
|
|
@@ -2557,7 +3029,7 @@ function CopilotChatView({
|
|
|
2557
3029
|
),
|
|
2558
3030
|
...props,
|
|
2559
3031
|
children: [
|
|
2560
|
-
/* @__PURE__ */ jsx17("div", { ref: contentRef, className: "px-4 sm:px-0 [div[data-sidebar-chat]_&]:px-8", children }),
|
|
3032
|
+
/* @__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
3033
|
showScrollButton && !isResizing && /* @__PURE__ */ jsx17(
|
|
2562
3034
|
"div",
|
|
2563
3035
|
{
|
|
@@ -2626,7 +3098,20 @@ function CopilotChatView({
|
|
|
2626
3098
|
...props
|
|
2627
3099
|
}
|
|
2628
3100
|
);
|
|
2629
|
-
CopilotChatView2.InputContainer = React11.forwardRef(({ children, className, ...props }, ref) => /* @__PURE__ */ jsx17(
|
|
3101
|
+
CopilotChatView2.InputContainer = React11.forwardRef(({ children, className, keyboardHeight = 0, ...props }, ref) => /* @__PURE__ */ jsx17(
|
|
3102
|
+
"div",
|
|
3103
|
+
{
|
|
3104
|
+
ref,
|
|
3105
|
+
className: cn("absolute bottom-0 left-0 right-0 z-20 pointer-events-none", className),
|
|
3106
|
+
style: {
|
|
3107
|
+
// Adjust position when keyboard is open to keep input visible
|
|
3108
|
+
transform: keyboardHeight > 0 ? `translateY(-${keyboardHeight}px)` : void 0,
|
|
3109
|
+
transition: "transform 0.2s ease-out"
|
|
3110
|
+
},
|
|
3111
|
+
...props,
|
|
3112
|
+
children
|
|
3113
|
+
}
|
|
3114
|
+
));
|
|
2630
3115
|
CopilotChatView2.InputContainer.displayName = "CopilotChatView.InputContainer";
|
|
2631
3116
|
CopilotChatView2.Disclaimer = ({ className, ...props }) => {
|
|
2632
3117
|
const config = useCopilotChatConfiguration();
|
|
@@ -2645,14 +3130,14 @@ var CopilotChatView_default = CopilotChatView;
|
|
|
2645
3130
|
|
|
2646
3131
|
// src/components/chat/CopilotChat.tsx
|
|
2647
3132
|
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID6, randomUUID as randomUUID2 } from "@copilotkitnext/shared";
|
|
2648
|
-
import { useCallback as
|
|
3133
|
+
import { useCallback as useCallback6, useEffect as useEffect14, useMemo as useMemo7 } from "react";
|
|
2649
3134
|
import { merge } from "ts-deepmerge";
|
|
2650
3135
|
import { AGUIConnectNotImplementedError } from "@ag-ui/client";
|
|
2651
3136
|
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
2652
3137
|
function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen, ...props }) {
|
|
2653
3138
|
const existingConfig = useCopilotChatConfiguration();
|
|
2654
3139
|
const resolvedAgentId = agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID6;
|
|
2655
|
-
const resolvedThreadId =
|
|
3140
|
+
const resolvedThreadId = useMemo7(
|
|
2656
3141
|
() => threadId ?? existingConfig?.threadId ?? randomUUID2(),
|
|
2657
3142
|
[threadId, existingConfig?.threadId]
|
|
2658
3143
|
);
|
|
@@ -2665,7 +3150,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
2665
3150
|
suggestionView: providedSuggestionView,
|
|
2666
3151
|
...restProps
|
|
2667
3152
|
} = props;
|
|
2668
|
-
|
|
3153
|
+
useEffect14(() => {
|
|
2669
3154
|
const connect = async (agent2) => {
|
|
2670
3155
|
try {
|
|
2671
3156
|
await copilotkit.connectAgent({ agent: agent2 });
|
|
@@ -2683,7 +3168,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
2683
3168
|
return () => {
|
|
2684
3169
|
};
|
|
2685
3170
|
}, [resolvedThreadId, agent, copilotkit, resolvedAgentId]);
|
|
2686
|
-
const onSubmitInput =
|
|
3171
|
+
const onSubmitInput = useCallback6(
|
|
2687
3172
|
async (value) => {
|
|
2688
3173
|
agent?.addMessage({
|
|
2689
3174
|
id: randomUUID2(),
|
|
@@ -2700,7 +3185,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
2700
3185
|
},
|
|
2701
3186
|
[agent, copilotkit]
|
|
2702
3187
|
);
|
|
2703
|
-
const handleSelectSuggestion =
|
|
3188
|
+
const handleSelectSuggestion = useCallback6(
|
|
2704
3189
|
async (suggestion) => {
|
|
2705
3190
|
if (!agent) {
|
|
2706
3191
|
return;
|
|
@@ -2754,7 +3239,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
2754
3239
|
})(CopilotChat || (CopilotChat = {}));
|
|
2755
3240
|
|
|
2756
3241
|
// src/components/chat/CopilotChatToggleButton.tsx
|
|
2757
|
-
import React12, { useState as
|
|
3242
|
+
import React12, { useState as useState11 } from "react";
|
|
2758
3243
|
import { MessageCircle, X as X2 } from "lucide-react";
|
|
2759
3244
|
import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2760
3245
|
var DefaultOpenIcon = ({
|
|
@@ -2785,7 +3270,7 @@ var CopilotChatToggleButton = React12.forwardRef(function CopilotChatToggleButto
|
|
|
2785
3270
|
const { onClick, type, disabled, ...restProps } = buttonProps;
|
|
2786
3271
|
const configuration = useCopilotChatConfiguration();
|
|
2787
3272
|
const labels = configuration?.labels ?? CopilotChatDefaultLabels;
|
|
2788
|
-
const [fallbackOpen, setFallbackOpen] =
|
|
3273
|
+
const [fallbackOpen, setFallbackOpen] = useState11(false);
|
|
2789
3274
|
const isOpen = configuration?.isModalOpen ?? fallbackOpen;
|
|
2790
3275
|
const setModalOpen = configuration?.setModalOpen ?? setFallbackOpen;
|
|
2791
3276
|
const handleClick = (event) => {
|
|
@@ -2871,10 +3356,10 @@ CopilotChatToggleButton.displayName = "CopilotChatToggleButton";
|
|
|
2871
3356
|
var CopilotChatToggleButton_default = CopilotChatToggleButton;
|
|
2872
3357
|
|
|
2873
3358
|
// src/components/chat/CopilotSidebarView.tsx
|
|
2874
|
-
import { useEffect as
|
|
3359
|
+
import { useEffect as useEffect15, useRef as useRef8, useState as useState12 } from "react";
|
|
2875
3360
|
|
|
2876
3361
|
// src/components/chat/CopilotModalHeader.tsx
|
|
2877
|
-
import { useCallback as
|
|
3362
|
+
import { useCallback as useCallback7 } from "react";
|
|
2878
3363
|
import { X as X3 } from "lucide-react";
|
|
2879
3364
|
import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2880
3365
|
function CopilotModalHeader({
|
|
@@ -2888,7 +3373,7 @@ function CopilotModalHeader({
|
|
|
2888
3373
|
const configuration = useCopilotChatConfiguration();
|
|
2889
3374
|
const fallbackTitle = configuration?.labels.modalHeaderTitle ?? CopilotChatDefaultLabels.modalHeaderTitle;
|
|
2890
3375
|
const resolvedTitle = title ?? fallbackTitle;
|
|
2891
|
-
const handleClose =
|
|
3376
|
+
const handleClose = useCallback7(() => {
|
|
2892
3377
|
configuration?.setModalOpen(false);
|
|
2893
3378
|
}, [configuration]);
|
|
2894
3379
|
const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {
|
|
@@ -2965,7 +3450,7 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
2965
3450
|
const configuration = useCopilotChatConfiguration();
|
|
2966
3451
|
const isSidebarOpen = configuration?.isModalOpen ?? false;
|
|
2967
3452
|
const sidebarRef = useRef8(null);
|
|
2968
|
-
const [sidebarWidth, setSidebarWidth] =
|
|
3453
|
+
const [sidebarWidth, setSidebarWidth] = useState12(width ?? DEFAULT_SIDEBAR_WIDTH);
|
|
2969
3454
|
const widthToCss = (w) => {
|
|
2970
3455
|
return typeof w === "number" ? `${w}px` : w;
|
|
2971
3456
|
};
|
|
@@ -2975,7 +3460,7 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
2975
3460
|
}
|
|
2976
3461
|
return w;
|
|
2977
3462
|
};
|
|
2978
|
-
|
|
3463
|
+
useEffect15(() => {
|
|
2979
3464
|
if (width !== void 0) {
|
|
2980
3465
|
return;
|
|
2981
3466
|
}
|
|
@@ -3007,10 +3492,13 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3007
3492
|
"style",
|
|
3008
3493
|
{
|
|
3009
3494
|
dangerouslySetInnerHTML: {
|
|
3010
|
-
__html: `
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3495
|
+
__html: `
|
|
3496
|
+
@media (min-width: 768px) {
|
|
3497
|
+
body {
|
|
3498
|
+
margin-inline-end: ${widthToMargin(sidebarWidth)};
|
|
3499
|
+
transition: margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease;
|
|
3500
|
+
}
|
|
3501
|
+
}`
|
|
3014
3502
|
}
|
|
3015
3503
|
}
|
|
3016
3504
|
),
|
|
@@ -3021,12 +3509,22 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3021
3509
|
ref: sidebarRef,
|
|
3022
3510
|
"data-copilot-sidebar": true,
|
|
3023
3511
|
className: cn(
|
|
3024
|
-
"fixed right-0 top-0 z-[1200] flex
|
|
3512
|
+
"fixed right-0 top-0 z-[1200] flex",
|
|
3513
|
+
// Height with dvh fallback and safe area support
|
|
3514
|
+
"h-[100vh] h-[100dvh] max-h-screen",
|
|
3515
|
+
// Responsive width: full on mobile, custom on desktop
|
|
3516
|
+
"w-full",
|
|
3025
3517
|
"border-l border-border bg-background text-foreground shadow-xl",
|
|
3026
3518
|
"transition-transform duration-300 ease-out",
|
|
3027
3519
|
isSidebarOpen ? "translate-x-0" : "translate-x-full pointer-events-none"
|
|
3028
3520
|
),
|
|
3029
|
-
style: {
|
|
3521
|
+
style: {
|
|
3522
|
+
// Use CSS custom property for responsive width
|
|
3523
|
+
["--sidebar-width"]: widthToCss(sidebarWidth),
|
|
3524
|
+
// Safe area insets for iOS
|
|
3525
|
+
paddingTop: "env(safe-area-inset-top)",
|
|
3526
|
+
paddingBottom: "env(safe-area-inset-bottom)"
|
|
3527
|
+
},
|
|
3030
3528
|
"aria-hidden": !isSidebarOpen,
|
|
3031
3529
|
"aria-label": "Copilot chat sidebar",
|
|
3032
3530
|
role: "complementary",
|
|
@@ -3040,14 +3538,173 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3040
3538
|
}
|
|
3041
3539
|
CopilotSidebarView.displayName = "CopilotSidebarView";
|
|
3042
3540
|
|
|
3541
|
+
// src/components/chat/CopilotPopupView.tsx
|
|
3542
|
+
import { useEffect as useEffect16, useMemo as useMemo8, useRef as useRef9, useState as useState13 } from "react";
|
|
3543
|
+
import { Fragment as Fragment8, jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3544
|
+
var DEFAULT_POPUP_WIDTH = 420;
|
|
3545
|
+
var DEFAULT_POPUP_HEIGHT = 560;
|
|
3546
|
+
var dimensionToCss = (value, fallback) => {
|
|
3547
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
3548
|
+
return `${value}px`;
|
|
3549
|
+
}
|
|
3550
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
3551
|
+
return value;
|
|
3552
|
+
}
|
|
3553
|
+
return `${fallback}px`;
|
|
3554
|
+
};
|
|
3555
|
+
function CopilotPopupView({
|
|
3556
|
+
header,
|
|
3557
|
+
width,
|
|
3558
|
+
height,
|
|
3559
|
+
clickOutsideToClose,
|
|
3560
|
+
className,
|
|
3561
|
+
...restProps
|
|
3562
|
+
}) {
|
|
3563
|
+
const configuration = useCopilotChatConfiguration();
|
|
3564
|
+
const isPopupOpen = configuration?.isModalOpen ?? false;
|
|
3565
|
+
const setModalOpen = configuration?.setModalOpen;
|
|
3566
|
+
const labels = configuration?.labels ?? CopilotChatDefaultLabels;
|
|
3567
|
+
const containerRef = useRef9(null);
|
|
3568
|
+
const [isRendered, setIsRendered] = useState13(isPopupOpen);
|
|
3569
|
+
const [isAnimatingOut, setIsAnimatingOut] = useState13(false);
|
|
3570
|
+
useEffect16(() => {
|
|
3571
|
+
if (isPopupOpen) {
|
|
3572
|
+
setIsRendered(true);
|
|
3573
|
+
setIsAnimatingOut(false);
|
|
3574
|
+
return;
|
|
3575
|
+
}
|
|
3576
|
+
if (!isRendered) {
|
|
3577
|
+
return;
|
|
3578
|
+
}
|
|
3579
|
+
setIsAnimatingOut(true);
|
|
3580
|
+
const timeout = setTimeout(() => {
|
|
3581
|
+
setIsRendered(false);
|
|
3582
|
+
setIsAnimatingOut(false);
|
|
3583
|
+
}, 200);
|
|
3584
|
+
return () => clearTimeout(timeout);
|
|
3585
|
+
}, [isPopupOpen, isRendered]);
|
|
3586
|
+
useEffect16(() => {
|
|
3587
|
+
if (!isPopupOpen) {
|
|
3588
|
+
return;
|
|
3589
|
+
}
|
|
3590
|
+
if (typeof window === "undefined") {
|
|
3591
|
+
return;
|
|
3592
|
+
}
|
|
3593
|
+
const handleKeyDown = (event) => {
|
|
3594
|
+
if (event.key === "Escape") {
|
|
3595
|
+
event.preventDefault();
|
|
3596
|
+
setModalOpen?.(false);
|
|
3597
|
+
}
|
|
3598
|
+
};
|
|
3599
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
3600
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
3601
|
+
}, [isPopupOpen, setModalOpen]);
|
|
3602
|
+
useEffect16(() => {
|
|
3603
|
+
if (!isPopupOpen) {
|
|
3604
|
+
return;
|
|
3605
|
+
}
|
|
3606
|
+
const focusTimer = setTimeout(() => {
|
|
3607
|
+
containerRef.current?.focus({ preventScroll: true });
|
|
3608
|
+
}, 200);
|
|
3609
|
+
return () => clearTimeout(focusTimer);
|
|
3610
|
+
}, [isPopupOpen]);
|
|
3611
|
+
useEffect16(() => {
|
|
3612
|
+
if (!isPopupOpen || !clickOutsideToClose) {
|
|
3613
|
+
return;
|
|
3614
|
+
}
|
|
3615
|
+
if (typeof document === "undefined") {
|
|
3616
|
+
return;
|
|
3617
|
+
}
|
|
3618
|
+
const handlePointerDown = (event) => {
|
|
3619
|
+
const target = event.target;
|
|
3620
|
+
if (!target) {
|
|
3621
|
+
return;
|
|
3622
|
+
}
|
|
3623
|
+
const container = containerRef.current;
|
|
3624
|
+
if (container?.contains(target)) {
|
|
3625
|
+
return;
|
|
3626
|
+
}
|
|
3627
|
+
const toggleButton = document.querySelector("[data-slot='chat-toggle-button']");
|
|
3628
|
+
if (toggleButton && toggleButton.contains(target)) {
|
|
3629
|
+
return;
|
|
3630
|
+
}
|
|
3631
|
+
setModalOpen?.(false);
|
|
3632
|
+
};
|
|
3633
|
+
document.addEventListener("pointerdown", handlePointerDown);
|
|
3634
|
+
return () => document.removeEventListener("pointerdown", handlePointerDown);
|
|
3635
|
+
}, [isPopupOpen, clickOutsideToClose, setModalOpen]);
|
|
3636
|
+
const headerElement = useMemo8(() => renderSlot(header, CopilotModalHeader, {}), [header]);
|
|
3637
|
+
const resolvedWidth = dimensionToCss(width, DEFAULT_POPUP_WIDTH);
|
|
3638
|
+
const resolvedHeight = dimensionToCss(height, DEFAULT_POPUP_HEIGHT);
|
|
3639
|
+
const popupStyle = useMemo8(
|
|
3640
|
+
() => ({
|
|
3641
|
+
"--copilot-popup-width": resolvedWidth,
|
|
3642
|
+
"--copilot-popup-height": resolvedHeight,
|
|
3643
|
+
"--copilot-popup-max-width": "calc(100vw - 3rem)",
|
|
3644
|
+
"--copilot-popup-max-height": "calc(100dvh - 7.5rem)",
|
|
3645
|
+
paddingTop: "env(safe-area-inset-top)",
|
|
3646
|
+
paddingBottom: "env(safe-area-inset-bottom)",
|
|
3647
|
+
paddingLeft: "env(safe-area-inset-left)",
|
|
3648
|
+
paddingRight: "env(safe-area-inset-right)"
|
|
3649
|
+
}),
|
|
3650
|
+
[resolvedHeight, resolvedWidth]
|
|
3651
|
+
);
|
|
3652
|
+
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]";
|
|
3653
|
+
const popupContent = isRendered ? /* @__PURE__ */ jsx22(
|
|
3654
|
+
"div",
|
|
3655
|
+
{
|
|
3656
|
+
className: cn(
|
|
3657
|
+
"fixed inset-0 z-[1200] flex max-w-full flex-col items-stretch",
|
|
3658
|
+
"md:inset-auto md:bottom-24 md:right-6 md:items-end md:gap-4"
|
|
3659
|
+
),
|
|
3660
|
+
children: /* @__PURE__ */ jsxs14(
|
|
3661
|
+
"div",
|
|
3662
|
+
{
|
|
3663
|
+
ref: containerRef,
|
|
3664
|
+
tabIndex: -1,
|
|
3665
|
+
role: "dialog",
|
|
3666
|
+
"aria-label": labels.modalHeaderTitle,
|
|
3667
|
+
"data-copilot-popup": true,
|
|
3668
|
+
className: cn(
|
|
3669
|
+
"relative flex h-full w-full flex-col overflow-hidden bg-background text-foreground",
|
|
3670
|
+
"origin-bottom focus:outline-none transform-gpu transition-transform transition-opacity duration-200 ease-out",
|
|
3671
|
+
"md:transition-transform md:transition-opacity",
|
|
3672
|
+
"rounded-none border border-border/0 shadow-none ring-0",
|
|
3673
|
+
"md:h-[var(--copilot-popup-height)] md:w-[var(--copilot-popup-width)]",
|
|
3674
|
+
"md:max-h-[var(--copilot-popup-max-height)] md:max-w-[var(--copilot-popup-max-width)]",
|
|
3675
|
+
"md:origin-bottom-right md:rounded-2xl md:border-border md:shadow-xl md:ring-1 md:ring-border/40",
|
|
3676
|
+
popupAnimationClass
|
|
3677
|
+
),
|
|
3678
|
+
style: popupStyle,
|
|
3679
|
+
children: [
|
|
3680
|
+
headerElement,
|
|
3681
|
+
/* @__PURE__ */ jsx22("div", { className: "flex-1 overflow-hidden", "data-popup-chat": true, children: /* @__PURE__ */ jsx22(
|
|
3682
|
+
CopilotChatView_default,
|
|
3683
|
+
{
|
|
3684
|
+
...restProps,
|
|
3685
|
+
className: cn("h-full min-h-0", className)
|
|
3686
|
+
}
|
|
3687
|
+
) })
|
|
3688
|
+
]
|
|
3689
|
+
}
|
|
3690
|
+
)
|
|
3691
|
+
}
|
|
3692
|
+
) : null;
|
|
3693
|
+
return /* @__PURE__ */ jsxs14(Fragment8, { children: [
|
|
3694
|
+
/* @__PURE__ */ jsx22(CopilotChatToggleButton_default, {}),
|
|
3695
|
+
popupContent
|
|
3696
|
+
] });
|
|
3697
|
+
}
|
|
3698
|
+
CopilotPopupView.displayName = "CopilotPopupView";
|
|
3699
|
+
|
|
3043
3700
|
// src/components/chat/CopilotSidebar.tsx
|
|
3044
|
-
import { useMemo as
|
|
3045
|
-
import { jsx as
|
|
3701
|
+
import { useMemo as useMemo9 } from "react";
|
|
3702
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
3046
3703
|
function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
|
|
3047
|
-
const SidebarViewOverride =
|
|
3704
|
+
const SidebarViewOverride = useMemo9(() => {
|
|
3048
3705
|
const Component = (viewProps) => {
|
|
3049
3706
|
const { header: viewHeader, width: viewWidth, ...restProps } = viewProps;
|
|
3050
|
-
return /* @__PURE__ */
|
|
3707
|
+
return /* @__PURE__ */ jsx23(
|
|
3051
3708
|
CopilotSidebarView,
|
|
3052
3709
|
{
|
|
3053
3710
|
...restProps,
|
|
@@ -3058,7 +3715,7 @@ function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
|
|
|
3058
3715
|
};
|
|
3059
3716
|
return Object.assign(Component, CopilotChatView_default);
|
|
3060
3717
|
}, [header, width]);
|
|
3061
|
-
return /* @__PURE__ */
|
|
3718
|
+
return /* @__PURE__ */ jsx23(
|
|
3062
3719
|
CopilotChat,
|
|
3063
3720
|
{
|
|
3064
3721
|
...chatProps,
|
|
@@ -3069,6 +3726,50 @@ function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
|
|
|
3069
3726
|
}
|
|
3070
3727
|
CopilotSidebar.displayName = "CopilotSidebar";
|
|
3071
3728
|
|
|
3729
|
+
// src/components/chat/CopilotPopup.tsx
|
|
3730
|
+
import { useMemo as useMemo10 } from "react";
|
|
3731
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
3732
|
+
function CopilotPopup({
|
|
3733
|
+
header,
|
|
3734
|
+
defaultOpen,
|
|
3735
|
+
width,
|
|
3736
|
+
height,
|
|
3737
|
+
clickOutsideToClose,
|
|
3738
|
+
...chatProps
|
|
3739
|
+
}) {
|
|
3740
|
+
const PopupViewOverride = useMemo10(() => {
|
|
3741
|
+
const Component = (viewProps) => {
|
|
3742
|
+
const {
|
|
3743
|
+
header: viewHeader,
|
|
3744
|
+
width: viewWidth,
|
|
3745
|
+
height: viewHeight,
|
|
3746
|
+
clickOutsideToClose: viewClickOutsideToClose,
|
|
3747
|
+
...restProps
|
|
3748
|
+
} = viewProps;
|
|
3749
|
+
return /* @__PURE__ */ jsx24(
|
|
3750
|
+
CopilotPopupView,
|
|
3751
|
+
{
|
|
3752
|
+
...restProps,
|
|
3753
|
+
header: header ?? viewHeader,
|
|
3754
|
+
width: width ?? viewWidth,
|
|
3755
|
+
height: height ?? viewHeight,
|
|
3756
|
+
clickOutsideToClose: clickOutsideToClose ?? viewClickOutsideToClose
|
|
3757
|
+
}
|
|
3758
|
+
);
|
|
3759
|
+
};
|
|
3760
|
+
return Object.assign(Component, CopilotChatView_default);
|
|
3761
|
+
}, [clickOutsideToClose, header, height, width]);
|
|
3762
|
+
return /* @__PURE__ */ jsx24(
|
|
3763
|
+
CopilotChat,
|
|
3764
|
+
{
|
|
3765
|
+
...chatProps,
|
|
3766
|
+
chatView: PopupViewOverride,
|
|
3767
|
+
isModalDefaultOpen: defaultOpen
|
|
3768
|
+
}
|
|
3769
|
+
);
|
|
3770
|
+
}
|
|
3771
|
+
CopilotPopup.displayName = "CopilotPopup";
|
|
3772
|
+
|
|
3072
3773
|
// src/types/defineToolCallRenderer.ts
|
|
3073
3774
|
import { z as z2 } from "zod";
|
|
3074
3775
|
function defineToolCallRenderer(def) {
|
|
@@ -3082,25 +3783,25 @@ function defineToolCallRenderer(def) {
|
|
|
3082
3783
|
}
|
|
3083
3784
|
|
|
3084
3785
|
// src/components/WildcardToolCallRender.tsx
|
|
3085
|
-
import { useState as
|
|
3086
|
-
import { jsx as
|
|
3786
|
+
import { useState as useState14 } from "react";
|
|
3787
|
+
import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3087
3788
|
var WildcardToolCallRender = defineToolCallRenderer({
|
|
3088
3789
|
name: "*",
|
|
3089
3790
|
render: ({ args, result, name, status }) => {
|
|
3090
|
-
const [isExpanded, setIsExpanded] =
|
|
3791
|
+
const [isExpanded, setIsExpanded] = useState14(false);
|
|
3091
3792
|
const statusString = String(status);
|
|
3092
3793
|
const isActive = statusString === "inProgress" || statusString === "executing";
|
|
3093
3794
|
const isComplete = statusString === "complete";
|
|
3094
3795
|
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__ */
|
|
3796
|
+
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: [
|
|
3797
|
+
/* @__PURE__ */ jsxs15(
|
|
3097
3798
|
"div",
|
|
3098
3799
|
{
|
|
3099
3800
|
className: "flex items-center justify-between gap-3 cursor-pointer",
|
|
3100
3801
|
onClick: () => setIsExpanded(!isExpanded),
|
|
3101
3802
|
children: [
|
|
3102
|
-
/* @__PURE__ */
|
|
3103
|
-
/* @__PURE__ */
|
|
3803
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
3804
|
+
/* @__PURE__ */ jsx25(
|
|
3104
3805
|
"svg",
|
|
3105
3806
|
{
|
|
3106
3807
|
className: `h-4 w-4 text-zinc-500 dark:text-zinc-400 transition-transform ${isExpanded ? "rotate-90" : ""}`,
|
|
@@ -3108,7 +3809,7 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3108
3809
|
viewBox: "0 0 24 24",
|
|
3109
3810
|
strokeWidth: 2,
|
|
3110
3811
|
stroke: "currentColor",
|
|
3111
|
-
children: /* @__PURE__ */
|
|
3812
|
+
children: /* @__PURE__ */ jsx25(
|
|
3112
3813
|
"path",
|
|
3113
3814
|
{
|
|
3114
3815
|
strokeLinecap: "round",
|
|
@@ -3118,10 +3819,10 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3118
3819
|
)
|
|
3119
3820
|
}
|
|
3120
3821
|
),
|
|
3121
|
-
/* @__PURE__ */
|
|
3122
|
-
/* @__PURE__ */
|
|
3822
|
+
/* @__PURE__ */ jsx25("span", { className: "inline-block h-2 w-2 rounded-full bg-blue-500" }),
|
|
3823
|
+
/* @__PURE__ */ jsx25("span", { className: "truncate text-sm font-medium text-zinc-900 dark:text-zinc-100", children: name })
|
|
3123
3824
|
] }),
|
|
3124
|
-
/* @__PURE__ */
|
|
3825
|
+
/* @__PURE__ */ jsx25(
|
|
3125
3826
|
"span",
|
|
3126
3827
|
{
|
|
3127
3828
|
className: `inline-flex items-center rounded-full px-2 py-1 text-xs font-medium ${statusStyles}`,
|
|
@@ -3131,14 +3832,14 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3131
3832
|
]
|
|
3132
3833
|
}
|
|
3133
3834
|
),
|
|
3134
|
-
isExpanded && /* @__PURE__ */
|
|
3135
|
-
/* @__PURE__ */
|
|
3136
|
-
/* @__PURE__ */
|
|
3137
|
-
/* @__PURE__ */
|
|
3835
|
+
isExpanded && /* @__PURE__ */ jsxs15("div", { className: "mt-3 grid gap-4", children: [
|
|
3836
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
3837
|
+
/* @__PURE__ */ jsx25("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Arguments" }),
|
|
3838
|
+
/* @__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
3839
|
] }),
|
|
3139
|
-
result !== void 0 && /* @__PURE__ */
|
|
3140
|
-
/* @__PURE__ */
|
|
3141
|
-
/* @__PURE__ */
|
|
3840
|
+
result !== void 0 && /* @__PURE__ */ jsxs15("div", { children: [
|
|
3841
|
+
/* @__PURE__ */ jsx25("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Result" }),
|
|
3842
|
+
/* @__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
3843
|
] })
|
|
3143
3844
|
] })
|
|
3144
3845
|
] }) });
|
|
@@ -3164,6 +3865,8 @@ export {
|
|
|
3164
3865
|
CopilotKitInspector,
|
|
3165
3866
|
CopilotKitProvider,
|
|
3166
3867
|
CopilotModalHeader,
|
|
3868
|
+
CopilotPopup,
|
|
3869
|
+
CopilotPopupView,
|
|
3167
3870
|
CopilotSidebar,
|
|
3168
3871
|
CopilotSidebarView,
|
|
3169
3872
|
WildcardToolCallRender,
|