@copilotkitnext/react 0.0.13 → 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 +47 -20
- package/dist/index.d.ts +47 -20
- package/dist/index.js +906 -308
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +935 -330
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +5 -10
- package/vitest.config.mjs +5 -0
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,17 +1305,10 @@ 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
|
|
885
|
-
import { MarkdownHooks } from "react-markdown";
|
|
886
|
-
import remarkGfm from "remark-gfm";
|
|
887
|
-
import remarkMath from "remark-math";
|
|
888
|
-
import rehypePrettyCode from "rehype-pretty-code";
|
|
889
|
-
import rehypeKatex from "rehype-katex";
|
|
890
1312
|
import { useState as useState7 } from "react";
|
|
891
1313
|
import {
|
|
892
1314
|
Copy,
|
|
@@ -898,17 +1320,17 @@ import {
|
|
|
898
1320
|
} from "lucide-react";
|
|
899
1321
|
import { twMerge as twMerge4 } from "tailwind-merge";
|
|
900
1322
|
import "katex/dist/katex.min.css";
|
|
901
|
-
import {
|
|
1323
|
+
import { Streamdown } from "streamdown";
|
|
902
1324
|
|
|
903
1325
|
// src/hooks/use-render-tool-call.tsx
|
|
904
|
-
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";
|
|
905
1327
|
import { ToolCallStatus } from "@copilotkitnext/core";
|
|
906
1328
|
|
|
907
1329
|
// src/providers/CopilotKitProvider.tsx
|
|
908
1330
|
import {
|
|
909
1331
|
createContext as createContext2,
|
|
910
1332
|
useContext as useContext2,
|
|
911
|
-
useMemo as
|
|
1333
|
+
useMemo as useMemo3,
|
|
912
1334
|
useEffect as useEffect4,
|
|
913
1335
|
useReducer,
|
|
914
1336
|
useRef as useRef4,
|
|
@@ -956,7 +1378,7 @@ var CopilotKitCoreReact = class extends CopilotKitCore {
|
|
|
956
1378
|
}
|
|
957
1379
|
};
|
|
958
1380
|
|
|
959
|
-
// src/components/
|
|
1381
|
+
// src/components/CopilotKitInspector.tsx
|
|
960
1382
|
import * as React4 from "react";
|
|
961
1383
|
import { createComponent } from "@lit-labs/react";
|
|
962
1384
|
import {
|
|
@@ -966,12 +1388,12 @@ import {
|
|
|
966
1388
|
} from "@copilotkitnext/web-inspector";
|
|
967
1389
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
968
1390
|
defineWebInspector();
|
|
969
|
-
var
|
|
1391
|
+
var CopilotKitInspectorBase = createComponent({
|
|
970
1392
|
tagName: WEB_INSPECTOR_TAG,
|
|
971
1393
|
elementClass: WebInspectorElement,
|
|
972
1394
|
react: React4
|
|
973
1395
|
});
|
|
974
|
-
var
|
|
1396
|
+
var CopilotKitInspector = React4.forwardRef(
|
|
975
1397
|
({ core, ...rest }, ref) => {
|
|
976
1398
|
const innerRef = React4.useRef(null);
|
|
977
1399
|
React4.useImperativeHandle(ref, () => innerRef.current, []);
|
|
@@ -980,10 +1402,16 @@ var WebInspector = React4.forwardRef(
|
|
|
980
1402
|
innerRef.current.core = core ?? null;
|
|
981
1403
|
}
|
|
982
1404
|
}, [core]);
|
|
983
|
-
return /* @__PURE__ */ jsx7(
|
|
1405
|
+
return /* @__PURE__ */ jsx7(
|
|
1406
|
+
CopilotKitInspectorBase,
|
|
1407
|
+
{
|
|
1408
|
+
...rest,
|
|
1409
|
+
ref: innerRef
|
|
1410
|
+
}
|
|
1411
|
+
);
|
|
984
1412
|
}
|
|
985
1413
|
);
|
|
986
|
-
|
|
1414
|
+
CopilotKitInspector.displayName = "CopilotKitInspector";
|
|
987
1415
|
|
|
988
1416
|
// src/providers/CopilotKitProvider.tsx
|
|
989
1417
|
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
@@ -991,7 +1419,7 @@ var CopilotKitContext = createContext2({
|
|
|
991
1419
|
copilotkit: null
|
|
992
1420
|
});
|
|
993
1421
|
function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
|
|
994
|
-
const empty =
|
|
1422
|
+
const empty = useMemo3(() => [], []);
|
|
995
1423
|
const value = prop ?? empty;
|
|
996
1424
|
const initial = useRef4(value);
|
|
997
1425
|
useEffect4(() => {
|
|
@@ -1056,7 +1484,7 @@ var CopilotKitProvider = ({
|
|
|
1056
1484
|
humanInTheLoop,
|
|
1057
1485
|
"humanInTheLoop must be a stable array. If you want to dynamically add or remove human-in-the-loop tools, use `useHumanInTheLoop` instead."
|
|
1058
1486
|
);
|
|
1059
|
-
const processedHumanInTheLoopTools =
|
|
1487
|
+
const processedHumanInTheLoopTools = useMemo3(() => {
|
|
1060
1488
|
const processedTools = [];
|
|
1061
1489
|
const processedRenderToolCalls = [];
|
|
1062
1490
|
humanInTheLoopList.forEach((tool) => {
|
|
@@ -1085,13 +1513,13 @@ var CopilotKitProvider = ({
|
|
|
1085
1513
|
});
|
|
1086
1514
|
return { tools: processedTools, renderToolCalls: processedRenderToolCalls };
|
|
1087
1515
|
}, [humanInTheLoopList]);
|
|
1088
|
-
const allTools =
|
|
1516
|
+
const allTools = useMemo3(() => {
|
|
1089
1517
|
const tools = [];
|
|
1090
1518
|
tools.push(...frontendToolsList);
|
|
1091
1519
|
tools.push(...processedHumanInTheLoopTools.tools);
|
|
1092
1520
|
return tools;
|
|
1093
1521
|
}, [frontendToolsList, processedHumanInTheLoopTools]);
|
|
1094
|
-
const allRenderToolCalls =
|
|
1522
|
+
const allRenderToolCalls = useMemo3(() => {
|
|
1095
1523
|
const combined = [...renderToolCallsList];
|
|
1096
1524
|
frontendToolsList.forEach((tool) => {
|
|
1097
1525
|
if (tool.render) {
|
|
@@ -1108,7 +1536,7 @@ var CopilotKitProvider = ({
|
|
|
1108
1536
|
combined.push(...processedHumanInTheLoopTools.renderToolCalls);
|
|
1109
1537
|
return combined;
|
|
1110
1538
|
}, [renderToolCallsList, frontendToolsList, processedHumanInTheLoopTools]);
|
|
1111
|
-
const copilotkit =
|
|
1539
|
+
const copilotkit = useMemo3(() => {
|
|
1112
1540
|
const copilotkit2 = new CopilotKitCoreReact({
|
|
1113
1541
|
runtimeUrl,
|
|
1114
1542
|
headers,
|
|
@@ -1145,7 +1573,7 @@ var CopilotKitProvider = ({
|
|
|
1145
1573
|
},
|
|
1146
1574
|
children: [
|
|
1147
1575
|
children,
|
|
1148
|
-
shouldRenderInspector ? /* @__PURE__ */ jsx8(
|
|
1576
|
+
shouldRenderInspector ? /* @__PURE__ */ jsx8(CopilotKitInspector, { core: copilotkit }) : null
|
|
1149
1577
|
]
|
|
1150
1578
|
}
|
|
1151
1579
|
);
|
|
@@ -1208,7 +1636,7 @@ function useRenderToolCall() {
|
|
|
1208
1636
|
});
|
|
1209
1637
|
return () => unsubscribe();
|
|
1210
1638
|
}, [copilotkit]);
|
|
1211
|
-
const renderToolCall =
|
|
1639
|
+
const renderToolCall = useCallback2(
|
|
1212
1640
|
({
|
|
1213
1641
|
toolCall,
|
|
1214
1642
|
toolMessage
|
|
@@ -1357,7 +1785,7 @@ function useFrontendTool(tool) {
|
|
|
1357
1785
|
}
|
|
1358
1786
|
|
|
1359
1787
|
// src/hooks/use-human-in-the-loop.tsx
|
|
1360
|
-
import { useState as useState5, useCallback as
|
|
1788
|
+
import { useState as useState5, useCallback as useCallback3, useRef as useRef5, useEffect as useEffect7 } from "react";
|
|
1361
1789
|
import React7 from "react";
|
|
1362
1790
|
function useHumanInTheLoop(tool) {
|
|
1363
1791
|
const { copilotkit } = useCopilotKit();
|
|
@@ -1367,20 +1795,20 @@ function useHumanInTheLoop(tool) {
|
|
|
1367
1795
|
const statusRef = useRef5(status);
|
|
1368
1796
|
const resolvePromiseRef = useRef5(null);
|
|
1369
1797
|
statusRef.current = status;
|
|
1370
|
-
const respond =
|
|
1798
|
+
const respond = useCallback3(async (result) => {
|
|
1371
1799
|
if (resolvePromiseRef.current) {
|
|
1372
1800
|
resolvePromiseRef.current(result);
|
|
1373
1801
|
setStatus("complete");
|
|
1374
1802
|
resolvePromiseRef.current = null;
|
|
1375
1803
|
}
|
|
1376
1804
|
}, []);
|
|
1377
|
-
const handler =
|
|
1805
|
+
const handler = useCallback3(async () => {
|
|
1378
1806
|
return new Promise((resolve) => {
|
|
1379
1807
|
setStatus("executing");
|
|
1380
1808
|
resolvePromiseRef.current = resolve;
|
|
1381
1809
|
});
|
|
1382
1810
|
}, []);
|
|
1383
|
-
const RenderComponent =
|
|
1811
|
+
const RenderComponent = useCallback3(
|
|
1384
1812
|
(props) => {
|
|
1385
1813
|
const ToolComponent = tool.render;
|
|
1386
1814
|
const currentStatus = statusRef.current;
|
|
@@ -1432,7 +1860,7 @@ function useHumanInTheLoop(tool) {
|
|
|
1432
1860
|
}
|
|
1433
1861
|
|
|
1434
1862
|
// src/hooks/use-agent.tsx
|
|
1435
|
-
import { useMemo as
|
|
1863
|
+
import { useMemo as useMemo4, useEffect as useEffect8, useReducer as useReducer2 } from "react";
|
|
1436
1864
|
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID3 } from "@copilotkitnext/shared";
|
|
1437
1865
|
var ALL_UPDATES = [
|
|
1438
1866
|
"OnMessagesChanged" /* OnMessagesChanged */,
|
|
@@ -1443,11 +1871,11 @@ function useAgent({ agentId, updates } = {}) {
|
|
|
1443
1871
|
agentId ??= DEFAULT_AGENT_ID3;
|
|
1444
1872
|
const { copilotkit } = useCopilotKit();
|
|
1445
1873
|
const [, forceUpdate] = useReducer2((x) => x + 1, 0);
|
|
1446
|
-
const updateFlags =
|
|
1874
|
+
const updateFlags = useMemo4(
|
|
1447
1875
|
() => updates ?? ALL_UPDATES,
|
|
1448
1876
|
[JSON.stringify(updates)]
|
|
1449
1877
|
);
|
|
1450
|
-
const agent =
|
|
1878
|
+
const agent = useMemo4(() => {
|
|
1451
1879
|
return copilotkit.getAgent(agentId);
|
|
1452
1880
|
}, [
|
|
1453
1881
|
agentId,
|
|
@@ -1507,12 +1935,12 @@ function useAgentContext(context) {
|
|
|
1507
1935
|
}
|
|
1508
1936
|
|
|
1509
1937
|
// src/hooks/use-suggestions.tsx
|
|
1510
|
-
import { useCallback as
|
|
1938
|
+
import { useCallback as useCallback4, useEffect as useEffect10, useMemo as useMemo5, useState as useState6 } from "react";
|
|
1511
1939
|
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID4 } from "@copilotkitnext/shared";
|
|
1512
1940
|
function useSuggestions({ agentId } = {}) {
|
|
1513
1941
|
const { copilotkit } = useCopilotKit();
|
|
1514
1942
|
const config = useCopilotChatConfiguration();
|
|
1515
|
-
const resolvedAgentId =
|
|
1943
|
+
const resolvedAgentId = useMemo5(() => agentId ?? config?.agentId ?? DEFAULT_AGENT_ID4, [agentId, config?.agentId]);
|
|
1516
1944
|
const [suggestions, setSuggestions] = useState6(() => {
|
|
1517
1945
|
const result = copilotkit.getSuggestions(resolvedAgentId);
|
|
1518
1946
|
return result.suggestions;
|
|
@@ -1556,10 +1984,10 @@ function useSuggestions({ agentId } = {}) {
|
|
|
1556
1984
|
unsubscribe();
|
|
1557
1985
|
};
|
|
1558
1986
|
}, [copilotkit, resolvedAgentId]);
|
|
1559
|
-
const reloadSuggestions =
|
|
1987
|
+
const reloadSuggestions = useCallback4(() => {
|
|
1560
1988
|
copilotkit.reloadSuggestions(resolvedAgentId);
|
|
1561
1989
|
}, [copilotkit, resolvedAgentId]);
|
|
1562
|
-
const clearSuggestions =
|
|
1990
|
+
const clearSuggestions = useCallback4(() => {
|
|
1563
1991
|
copilotkit.clearSuggestions(resolvedAgentId);
|
|
1564
1992
|
}, [copilotkit, resolvedAgentId]);
|
|
1565
1993
|
return {
|
|
@@ -1571,20 +1999,20 @@ function useSuggestions({ agentId } = {}) {
|
|
|
1571
1999
|
}
|
|
1572
2000
|
|
|
1573
2001
|
// src/hooks/use-configure-suggestions.tsx
|
|
1574
|
-
import { useCallback as
|
|
2002
|
+
import { useCallback as useCallback5, useEffect as useEffect11, useMemo as useMemo6, useRef as useRef6 } from "react";
|
|
1575
2003
|
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID5 } from "@copilotkitnext/shared";
|
|
1576
2004
|
var EMPTY_DEPS = [];
|
|
1577
2005
|
function useConfigureSuggestions(config, options) {
|
|
1578
2006
|
const { copilotkit } = useCopilotKit();
|
|
1579
2007
|
const chatConfig = useCopilotChatConfiguration();
|
|
1580
2008
|
const extraDeps = options?.deps ?? EMPTY_DEPS;
|
|
1581
|
-
const resolvedConsumerAgentId =
|
|
1582
|
-
const rawConsumerAgentId =
|
|
2009
|
+
const resolvedConsumerAgentId = useMemo6(() => chatConfig?.agentId ?? DEFAULT_AGENT_ID5, [chatConfig?.agentId]);
|
|
2010
|
+
const rawConsumerAgentId = useMemo6(() => config ? config.consumerAgentId : void 0, [config]);
|
|
1583
2011
|
const normalizationCacheRef = useRef6({
|
|
1584
2012
|
serialized: null,
|
|
1585
2013
|
config: null
|
|
1586
2014
|
});
|
|
1587
|
-
const { normalizedConfig, serializedConfig } =
|
|
2015
|
+
const { normalizedConfig, serializedConfig } = useMemo6(() => {
|
|
1588
2016
|
if (!config) {
|
|
1589
2017
|
normalizationCacheRef.current = { serialized: null, config: null };
|
|
1590
2018
|
return { normalizedConfig: null, serializedConfig: null };
|
|
@@ -1617,7 +2045,7 @@ function useConfigureSuggestions(config, options) {
|
|
|
1617
2045
|
const latestConfigRef = useRef6(null);
|
|
1618
2046
|
latestConfigRef.current = normalizedConfig;
|
|
1619
2047
|
const previousSerializedConfigRef = useRef6(null);
|
|
1620
|
-
const targetAgentId =
|
|
2048
|
+
const targetAgentId = useMemo6(() => {
|
|
1621
2049
|
if (!normalizedConfig) {
|
|
1622
2050
|
return resolvedConsumerAgentId;
|
|
1623
2051
|
}
|
|
@@ -1628,7 +2056,7 @@ function useConfigureSuggestions(config, options) {
|
|
|
1628
2056
|
return consumer;
|
|
1629
2057
|
}, [normalizedConfig, resolvedConsumerAgentId]);
|
|
1630
2058
|
const isGlobalConfig = rawConsumerAgentId === void 0 || rawConsumerAgentId === "*";
|
|
1631
|
-
const requestReload =
|
|
2059
|
+
const requestReload = useCallback5(() => {
|
|
1632
2060
|
if (!normalizedConfig) {
|
|
1633
2061
|
return;
|
|
1634
2062
|
}
|
|
@@ -1850,105 +2278,7 @@ function CopilotChatAssistantMessage({
|
|
|
1850
2278
|
);
|
|
1851
2279
|
}
|
|
1852
2280
|
((CopilotChatAssistantMessage2) => {
|
|
1853
|
-
|
|
1854
|
-
children,
|
|
1855
|
-
...props
|
|
1856
|
-
}) => {
|
|
1857
|
-
return /* @__PURE__ */ jsx12(
|
|
1858
|
-
"code",
|
|
1859
|
-
{
|
|
1860
|
-
className: "px-[4.8px] py-[2.5px] bg-[rgb(236,236,236)] dark:bg-gray-800 rounded text-sm font-mono font-medium! text-foreground!",
|
|
1861
|
-
...props,
|
|
1862
|
-
children
|
|
1863
|
-
}
|
|
1864
|
-
);
|
|
1865
|
-
};
|
|
1866
|
-
const CodeBlock = ({ children, className, onClick, ...props }) => {
|
|
1867
|
-
const config = useCopilotChatConfiguration();
|
|
1868
|
-
const labels = config?.labels ?? CopilotChatDefaultLabels;
|
|
1869
|
-
const [copied, setCopied] = useState7(false);
|
|
1870
|
-
const getCodeContent = (node) => {
|
|
1871
|
-
if (typeof node === "string") return node;
|
|
1872
|
-
if (Array.isArray(node)) return node.map(getCodeContent).join("");
|
|
1873
|
-
if (node?.props?.children) return getCodeContent(node.props.children);
|
|
1874
|
-
return "";
|
|
1875
|
-
};
|
|
1876
|
-
const codeContent = getCodeContent(children);
|
|
1877
|
-
const language = props["data-language"];
|
|
1878
|
-
const copyToClipboard = async () => {
|
|
1879
|
-
if (!codeContent.trim()) return;
|
|
1880
|
-
try {
|
|
1881
|
-
setCopied(true);
|
|
1882
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
1883
|
-
if (onClick) {
|
|
1884
|
-
onClick();
|
|
1885
|
-
}
|
|
1886
|
-
} catch (err) {
|
|
1887
|
-
console.error("Failed to copy code:", err);
|
|
1888
|
-
}
|
|
1889
|
-
};
|
|
1890
|
-
return /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
|
|
1891
|
-
/* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between px-4 pr-3 py-3 text-xs", children: [
|
|
1892
|
-
language && /* @__PURE__ */ jsx12("span", { className: "font-regular text-muted-foreground dark:text-white", children: language }),
|
|
1893
|
-
/* @__PURE__ */ jsxs5(
|
|
1894
|
-
"button",
|
|
1895
|
-
{
|
|
1896
|
-
className: cn(
|
|
1897
|
-
"px-2 gap-0.5 text-xs flex items-center cursor-pointer text-muted-foreground dark:text-white"
|
|
1898
|
-
),
|
|
1899
|
-
onClick: copyToClipboard,
|
|
1900
|
-
title: copied ? labels.assistantMessageToolbarCopyCodeCopiedLabel : `${labels.assistantMessageToolbarCopyCodeLabel} code`,
|
|
1901
|
-
children: [
|
|
1902
|
-
copied ? /* @__PURE__ */ jsx12(Check2, { className: "h-[10px]! w-[10px]!" }) : /* @__PURE__ */ jsx12(Copy, { className: "h-[10px]! w-[10px]!" }),
|
|
1903
|
-
/* @__PURE__ */ jsx12("span", { className: "text-[11px]", children: copied ? labels.assistantMessageToolbarCopyCodeCopiedLabel : labels.assistantMessageToolbarCopyCodeLabel })
|
|
1904
|
-
]
|
|
1905
|
-
}
|
|
1906
|
-
)
|
|
1907
|
-
] }),
|
|
1908
|
-
/* @__PURE__ */ jsx12(
|
|
1909
|
-
"pre",
|
|
1910
|
-
{
|
|
1911
|
-
className: cn(
|
|
1912
|
-
className,
|
|
1913
|
-
"rounded-2xl bg-transparent border-t-0 my-1!"
|
|
1914
|
-
),
|
|
1915
|
-
...props,
|
|
1916
|
-
children
|
|
1917
|
-
}
|
|
1918
|
-
)
|
|
1919
|
-
] });
|
|
1920
|
-
};
|
|
1921
|
-
CopilotChatAssistantMessage2.MarkdownRenderer = ({ content, className }) => /* @__PURE__ */ jsx12("div", { className, children: /* @__PURE__ */ jsx12(
|
|
1922
|
-
MarkdownHooks,
|
|
1923
|
-
{
|
|
1924
|
-
remarkPlugins: [remarkGfm, remarkMath],
|
|
1925
|
-
rehypePlugins: [
|
|
1926
|
-
[
|
|
1927
|
-
rehypePrettyCode,
|
|
1928
|
-
{
|
|
1929
|
-
keepBackground: false,
|
|
1930
|
-
theme: {
|
|
1931
|
-
dark: "one-dark-pro",
|
|
1932
|
-
light: "one-light"
|
|
1933
|
-
},
|
|
1934
|
-
bypassInlineCode: true
|
|
1935
|
-
}
|
|
1936
|
-
],
|
|
1937
|
-
rehypeKatex
|
|
1938
|
-
],
|
|
1939
|
-
components: {
|
|
1940
|
-
pre: CodeBlock,
|
|
1941
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1942
|
-
code: ({ className: className2, children, ...props }) => {
|
|
1943
|
-
if (typeof children === "string") {
|
|
1944
|
-
return /* @__PURE__ */ jsx12(InlineCode, { ...props, children });
|
|
1945
|
-
}
|
|
1946
|
-
return /* @__PURE__ */ jsx12("code", { className: className2, ...props, children });
|
|
1947
|
-
}
|
|
1948
|
-
},
|
|
1949
|
-
children: completePartialMarkdown(content || "")
|
|
1950
|
-
}
|
|
1951
|
-
) });
|
|
2281
|
+
CopilotChatAssistantMessage2.MarkdownRenderer = ({ content, className, ...props }) => /* @__PURE__ */ jsx12(Streamdown, { className, ...props, children: content ?? "" });
|
|
1952
2282
|
CopilotChatAssistantMessage2.Toolbar = ({
|
|
1953
2283
|
className,
|
|
1954
2284
|
...props
|
|
@@ -2300,7 +2630,7 @@ var CopilotChatUserMessage_default = CopilotChatUserMessage;
|
|
|
2300
2630
|
import React9 from "react";
|
|
2301
2631
|
import { Loader2 } from "lucide-react";
|
|
2302
2632
|
import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2303
|
-
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";
|
|
2304
2634
|
var labelClasses = "whitespace-nowrap font-medium leading-none";
|
|
2305
2635
|
var CopilotChatSuggestionPill = React9.forwardRef(function CopilotChatSuggestionPill2({ className, children, icon, isLoading, type, ...props }, ref) {
|
|
2306
2636
|
const showIcon = !isLoading && icon;
|
|
@@ -2315,7 +2645,7 @@ var CopilotChatSuggestionPill = React9.forwardRef(function CopilotChatSuggestion
|
|
|
2315
2645
|
disabled: isLoading || props.disabled,
|
|
2316
2646
|
...props,
|
|
2317
2647
|
children: [
|
|
2318
|
-
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 }),
|
|
2319
2649
|
/* @__PURE__ */ jsx14("span", { className: labelClasses, children })
|
|
2320
2650
|
]
|
|
2321
2651
|
}
|
|
@@ -2333,7 +2663,7 @@ var DefaultContainer = React10.forwardRef(function DefaultContainer2({ className
|
|
|
2333
2663
|
{
|
|
2334
2664
|
ref,
|
|
2335
2665
|
className: cn(
|
|
2336
|
-
"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",
|
|
2337
2667
|
className
|
|
2338
2668
|
),
|
|
2339
2669
|
...props
|
|
@@ -2476,10 +2806,52 @@ CopilotChatMessageView.Cursor = function Cursor({ className, ...props }) {
|
|
|
2476
2806
|
var CopilotChatMessageView_default = CopilotChatMessageView;
|
|
2477
2807
|
|
|
2478
2808
|
// src/components/chat/CopilotChatView.tsx
|
|
2479
|
-
import React11, { useRef as useRef7, useState as
|
|
2809
|
+
import React11, { useRef as useRef7, useState as useState10, useEffect as useEffect13 } from "react";
|
|
2480
2810
|
import { twMerge as twMerge7 } from "tailwind-merge";
|
|
2481
2811
|
import { StickToBottom, useStickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
|
2482
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
|
|
2483
2855
|
import { Fragment as Fragment6, jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2484
2856
|
function CopilotChatView({
|
|
2485
2857
|
messageView,
|
|
@@ -2502,10 +2874,11 @@ function CopilotChatView({
|
|
|
2502
2874
|
...props
|
|
2503
2875
|
}) {
|
|
2504
2876
|
const inputContainerRef = useRef7(null);
|
|
2505
|
-
const [inputContainerHeight, setInputContainerHeight] =
|
|
2506
|
-
const [isResizing, setIsResizing] =
|
|
2877
|
+
const [inputContainerHeight, setInputContainerHeight] = useState10(0);
|
|
2878
|
+
const [isResizing, setIsResizing] = useState10(false);
|
|
2507
2879
|
const resizeTimeoutRef = useRef7(null);
|
|
2508
|
-
|
|
2880
|
+
const { isKeyboardOpen, keyboardHeight, availableHeight } = useKeyboardHeight();
|
|
2881
|
+
useEffect13(() => {
|
|
2509
2882
|
const element = inputContainerRef.current;
|
|
2510
2883
|
if (!element) return;
|
|
2511
2884
|
const resizeObserver = new ResizeObserver((entries) => {
|
|
@@ -2559,15 +2932,16 @@ function CopilotChatView({
|
|
|
2559
2932
|
isResizing,
|
|
2560
2933
|
children: /* @__PURE__ */ jsx17("div", { style: { paddingBottom: `${inputContainerHeight + (hasSuggestions ? 4 : 32)}px` }, children: /* @__PURE__ */ jsxs10("div", { className: "max-w-3xl mx-auto", children: [
|
|
2561
2934
|
BoundMessageView,
|
|
2562
|
-
hasSuggestions ? /* @__PURE__ */ jsx17("div", { className: "
|
|
2935
|
+
hasSuggestions ? /* @__PURE__ */ jsx17("div", { className: "pl-0 pr-4 sm:px-0 mt-4", children: BoundSuggestionView }) : null
|
|
2563
2936
|
] }) })
|
|
2564
2937
|
});
|
|
2565
2938
|
const BoundScrollToBottomButton = renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, {});
|
|
2566
2939
|
const BoundDisclaimer = renderSlot(disclaimer, CopilotChatView.Disclaimer, {});
|
|
2567
2940
|
const BoundInputContainer = renderSlot(inputContainer, CopilotChatView.InputContainer, {
|
|
2568
2941
|
ref: inputContainerRef,
|
|
2942
|
+
keyboardHeight: isKeyboardOpen ? keyboardHeight : 0,
|
|
2569
2943
|
children: /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
2570
|
-
/* @__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 }),
|
|
2571
2945
|
BoundDisclaimer
|
|
2572
2946
|
] })
|
|
2573
2947
|
});
|
|
@@ -2593,7 +2967,7 @@ function CopilotChatView({
|
|
|
2593
2967
|
const ScrollContent = ({ children, scrollToBottomButton, inputContainerHeight, isResizing }) => {
|
|
2594
2968
|
const { isAtBottom, scrollToBottom } = useStickToBottomContext();
|
|
2595
2969
|
return /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
2596
|
-
/* @__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 }) }),
|
|
2597
2971
|
!isAtBottom && !isResizing && /* @__PURE__ */ jsx17(
|
|
2598
2972
|
"div",
|
|
2599
2973
|
{
|
|
@@ -2617,13 +2991,13 @@ function CopilotChatView({
|
|
|
2617
2991
|
className,
|
|
2618
2992
|
...props
|
|
2619
2993
|
}) => {
|
|
2620
|
-
const [hasMounted, setHasMounted] =
|
|
2994
|
+
const [hasMounted, setHasMounted] = useState10(false);
|
|
2621
2995
|
const { scrollRef, contentRef, scrollToBottom } = useStickToBottom();
|
|
2622
|
-
const [showScrollButton, setShowScrollButton] =
|
|
2623
|
-
|
|
2996
|
+
const [showScrollButton, setShowScrollButton] = useState10(false);
|
|
2997
|
+
useEffect13(() => {
|
|
2624
2998
|
setHasMounted(true);
|
|
2625
2999
|
}, []);
|
|
2626
|
-
|
|
3000
|
+
useEffect13(() => {
|
|
2627
3001
|
if (autoScroll) return;
|
|
2628
3002
|
const scrollElement = scrollRef.current;
|
|
2629
3003
|
if (!scrollElement) return;
|
|
@@ -2641,7 +3015,7 @@ function CopilotChatView({
|
|
|
2641
3015
|
};
|
|
2642
3016
|
}, [scrollRef, autoScroll]);
|
|
2643
3017
|
if (!hasMounted) {
|
|
2644
|
-
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 }) });
|
|
2645
3019
|
}
|
|
2646
3020
|
if (!autoScroll) {
|
|
2647
3021
|
return /* @__PURE__ */ jsxs10(
|
|
@@ -2654,7 +3028,7 @@ function CopilotChatView({
|
|
|
2654
3028
|
),
|
|
2655
3029
|
...props,
|
|
2656
3030
|
children: [
|
|
2657
|
-
/* @__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 }),
|
|
2658
3032
|
showScrollButton && !isResizing && /* @__PURE__ */ jsx17(
|
|
2659
3033
|
"div",
|
|
2660
3034
|
{
|
|
@@ -2723,7 +3097,20 @@ function CopilotChatView({
|
|
|
2723
3097
|
...props
|
|
2724
3098
|
}
|
|
2725
3099
|
);
|
|
2726
|
-
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
|
+
));
|
|
2727
3114
|
CopilotChatView2.InputContainer.displayName = "CopilotChatView.InputContainer";
|
|
2728
3115
|
CopilotChatView2.Disclaimer = ({ className, ...props }) => {
|
|
2729
3116
|
const config = useCopilotChatConfiguration();
|
|
@@ -2742,14 +3129,14 @@ var CopilotChatView_default = CopilotChatView;
|
|
|
2742
3129
|
|
|
2743
3130
|
// src/components/chat/CopilotChat.tsx
|
|
2744
3131
|
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID6, randomUUID as randomUUID2 } from "@copilotkitnext/shared";
|
|
2745
|
-
import { useCallback as
|
|
3132
|
+
import { useCallback as useCallback6, useEffect as useEffect14, useMemo as useMemo7 } from "react";
|
|
2746
3133
|
import { merge } from "ts-deepmerge";
|
|
2747
3134
|
import { AGUIConnectNotImplementedError } from "@ag-ui/client";
|
|
2748
3135
|
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
2749
3136
|
function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen, ...props }) {
|
|
2750
3137
|
const existingConfig = useCopilotChatConfiguration();
|
|
2751
3138
|
const resolvedAgentId = agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID6;
|
|
2752
|
-
const resolvedThreadId =
|
|
3139
|
+
const resolvedThreadId = useMemo7(
|
|
2753
3140
|
() => threadId ?? existingConfig?.threadId ?? randomUUID2(),
|
|
2754
3141
|
[threadId, existingConfig?.threadId]
|
|
2755
3142
|
);
|
|
@@ -2762,7 +3149,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
2762
3149
|
suggestionView: providedSuggestionView,
|
|
2763
3150
|
...restProps
|
|
2764
3151
|
} = props;
|
|
2765
|
-
|
|
3152
|
+
useEffect14(() => {
|
|
2766
3153
|
const connect = async (agent2) => {
|
|
2767
3154
|
try {
|
|
2768
3155
|
await copilotkit.connectAgent({ agent: agent2 });
|
|
@@ -2780,7 +3167,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
2780
3167
|
return () => {
|
|
2781
3168
|
};
|
|
2782
3169
|
}, [resolvedThreadId, agent, copilotkit, resolvedAgentId]);
|
|
2783
|
-
const onSubmitInput =
|
|
3170
|
+
const onSubmitInput = useCallback6(
|
|
2784
3171
|
async (value) => {
|
|
2785
3172
|
agent?.addMessage({
|
|
2786
3173
|
id: randomUUID2(),
|
|
@@ -2797,7 +3184,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
2797
3184
|
},
|
|
2798
3185
|
[agent, copilotkit]
|
|
2799
3186
|
);
|
|
2800
|
-
const handleSelectSuggestion =
|
|
3187
|
+
const handleSelectSuggestion = useCallback6(
|
|
2801
3188
|
async (suggestion) => {
|
|
2802
3189
|
if (!agent) {
|
|
2803
3190
|
return;
|
|
@@ -2851,7 +3238,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
2851
3238
|
})(CopilotChat || (CopilotChat = {}));
|
|
2852
3239
|
|
|
2853
3240
|
// src/components/chat/CopilotChatToggleButton.tsx
|
|
2854
|
-
import React12, { useState as
|
|
3241
|
+
import React12, { useState as useState11 } from "react";
|
|
2855
3242
|
import { MessageCircle, X as X2 } from "lucide-react";
|
|
2856
3243
|
import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2857
3244
|
var DefaultOpenIcon = ({
|
|
@@ -2882,7 +3269,7 @@ var CopilotChatToggleButton = React12.forwardRef(function CopilotChatToggleButto
|
|
|
2882
3269
|
const { onClick, type, disabled, ...restProps } = buttonProps;
|
|
2883
3270
|
const configuration = useCopilotChatConfiguration();
|
|
2884
3271
|
const labels = configuration?.labels ?? CopilotChatDefaultLabels;
|
|
2885
|
-
const [fallbackOpen, setFallbackOpen] =
|
|
3272
|
+
const [fallbackOpen, setFallbackOpen] = useState11(false);
|
|
2886
3273
|
const isOpen = configuration?.isModalOpen ?? fallbackOpen;
|
|
2887
3274
|
const setModalOpen = configuration?.setModalOpen ?? setFallbackOpen;
|
|
2888
3275
|
const handleClick = (event) => {
|
|
@@ -2968,10 +3355,10 @@ CopilotChatToggleButton.displayName = "CopilotChatToggleButton";
|
|
|
2968
3355
|
var CopilotChatToggleButton_default = CopilotChatToggleButton;
|
|
2969
3356
|
|
|
2970
3357
|
// src/components/chat/CopilotSidebarView.tsx
|
|
2971
|
-
import { useEffect as
|
|
3358
|
+
import { useEffect as useEffect15, useRef as useRef8, useState as useState12 } from "react";
|
|
2972
3359
|
|
|
2973
3360
|
// src/components/chat/CopilotModalHeader.tsx
|
|
2974
|
-
import { useCallback as
|
|
3361
|
+
import { useCallback as useCallback7 } from "react";
|
|
2975
3362
|
import { X as X3 } from "lucide-react";
|
|
2976
3363
|
import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2977
3364
|
function CopilotModalHeader({
|
|
@@ -2985,7 +3372,7 @@ function CopilotModalHeader({
|
|
|
2985
3372
|
const configuration = useCopilotChatConfiguration();
|
|
2986
3373
|
const fallbackTitle = configuration?.labels.modalHeaderTitle ?? CopilotChatDefaultLabels.modalHeaderTitle;
|
|
2987
3374
|
const resolvedTitle = title ?? fallbackTitle;
|
|
2988
|
-
const handleClose =
|
|
3375
|
+
const handleClose = useCallback7(() => {
|
|
2989
3376
|
configuration?.setModalOpen(false);
|
|
2990
3377
|
}, [configuration]);
|
|
2991
3378
|
const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {
|
|
@@ -3062,7 +3449,7 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3062
3449
|
const configuration = useCopilotChatConfiguration();
|
|
3063
3450
|
const isSidebarOpen = configuration?.isModalOpen ?? false;
|
|
3064
3451
|
const sidebarRef = useRef8(null);
|
|
3065
|
-
const [sidebarWidth, setSidebarWidth] =
|
|
3452
|
+
const [sidebarWidth, setSidebarWidth] = useState12(width ?? DEFAULT_SIDEBAR_WIDTH);
|
|
3066
3453
|
const widthToCss = (w) => {
|
|
3067
3454
|
return typeof w === "number" ? `${w}px` : w;
|
|
3068
3455
|
};
|
|
@@ -3072,7 +3459,7 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3072
3459
|
}
|
|
3073
3460
|
return w;
|
|
3074
3461
|
};
|
|
3075
|
-
|
|
3462
|
+
useEffect15(() => {
|
|
3076
3463
|
if (width !== void 0) {
|
|
3077
3464
|
return;
|
|
3078
3465
|
}
|
|
@@ -3104,10 +3491,13 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3104
3491
|
"style",
|
|
3105
3492
|
{
|
|
3106
3493
|
dangerouslySetInnerHTML: {
|
|
3107
|
-
__html: `
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
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
|
+
}`
|
|
3111
3501
|
}
|
|
3112
3502
|
}
|
|
3113
3503
|
),
|
|
@@ -3118,12 +3508,22 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3118
3508
|
ref: sidebarRef,
|
|
3119
3509
|
"data-copilot-sidebar": true,
|
|
3120
3510
|
className: cn(
|
|
3121
|
-
"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",
|
|
3122
3516
|
"border-l border-border bg-background text-foreground shadow-xl",
|
|
3123
3517
|
"transition-transform duration-300 ease-out",
|
|
3124
3518
|
isSidebarOpen ? "translate-x-0" : "translate-x-full pointer-events-none"
|
|
3125
3519
|
),
|
|
3126
|
-
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
|
+
},
|
|
3127
3527
|
"aria-hidden": !isSidebarOpen,
|
|
3128
3528
|
"aria-label": "Copilot chat sidebar",
|
|
3129
3529
|
role: "complementary",
|
|
@@ -3137,14 +3537,173 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3137
3537
|
}
|
|
3138
3538
|
CopilotSidebarView.displayName = "CopilotSidebarView";
|
|
3139
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
|
+
|
|
3140
3699
|
// src/components/chat/CopilotSidebar.tsx
|
|
3141
|
-
import { useMemo as
|
|
3142
|
-
import { jsx as
|
|
3700
|
+
import { useMemo as useMemo9 } from "react";
|
|
3701
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
3143
3702
|
function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
|
|
3144
|
-
const SidebarViewOverride =
|
|
3703
|
+
const SidebarViewOverride = useMemo9(() => {
|
|
3145
3704
|
const Component = (viewProps) => {
|
|
3146
3705
|
const { header: viewHeader, width: viewWidth, ...restProps } = viewProps;
|
|
3147
|
-
return /* @__PURE__ */
|
|
3706
|
+
return /* @__PURE__ */ jsx23(
|
|
3148
3707
|
CopilotSidebarView,
|
|
3149
3708
|
{
|
|
3150
3709
|
...restProps,
|
|
@@ -3155,7 +3714,7 @@ function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
|
|
|
3155
3714
|
};
|
|
3156
3715
|
return Object.assign(Component, CopilotChatView_default);
|
|
3157
3716
|
}, [header, width]);
|
|
3158
|
-
return /* @__PURE__ */
|
|
3717
|
+
return /* @__PURE__ */ jsx23(
|
|
3159
3718
|
CopilotChat,
|
|
3160
3719
|
{
|
|
3161
3720
|
...chatProps,
|
|
@@ -3166,6 +3725,50 @@ function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
|
|
|
3166
3725
|
}
|
|
3167
3726
|
CopilotSidebar.displayName = "CopilotSidebar";
|
|
3168
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
|
+
|
|
3169
3772
|
// src/types/defineToolCallRenderer.ts
|
|
3170
3773
|
import { z as z2 } from "zod";
|
|
3171
3774
|
function defineToolCallRenderer(def) {
|
|
@@ -3179,25 +3782,25 @@ function defineToolCallRenderer(def) {
|
|
|
3179
3782
|
}
|
|
3180
3783
|
|
|
3181
3784
|
// src/components/WildcardToolCallRender.tsx
|
|
3182
|
-
import { useState as
|
|
3183
|
-
import { jsx as
|
|
3785
|
+
import { useState as useState14 } from "react";
|
|
3786
|
+
import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3184
3787
|
var WildcardToolCallRender = defineToolCallRenderer({
|
|
3185
3788
|
name: "*",
|
|
3186
3789
|
render: ({ args, result, name, status }) => {
|
|
3187
|
-
const [isExpanded, setIsExpanded] =
|
|
3790
|
+
const [isExpanded, setIsExpanded] = useState14(false);
|
|
3188
3791
|
const statusString = String(status);
|
|
3189
3792
|
const isActive = statusString === "inProgress" || statusString === "executing";
|
|
3190
3793
|
const isComplete = statusString === "complete";
|
|
3191
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";
|
|
3192
|
-
return /* @__PURE__ */
|
|
3193
|
-
/* @__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(
|
|
3194
3797
|
"div",
|
|
3195
3798
|
{
|
|
3196
3799
|
className: "flex items-center justify-between gap-3 cursor-pointer",
|
|
3197
3800
|
onClick: () => setIsExpanded(!isExpanded),
|
|
3198
3801
|
children: [
|
|
3199
|
-
/* @__PURE__ */
|
|
3200
|
-
/* @__PURE__ */
|
|
3802
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
3803
|
+
/* @__PURE__ */ jsx25(
|
|
3201
3804
|
"svg",
|
|
3202
3805
|
{
|
|
3203
3806
|
className: `h-4 w-4 text-zinc-500 dark:text-zinc-400 transition-transform ${isExpanded ? "rotate-90" : ""}`,
|
|
@@ -3205,7 +3808,7 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3205
3808
|
viewBox: "0 0 24 24",
|
|
3206
3809
|
strokeWidth: 2,
|
|
3207
3810
|
stroke: "currentColor",
|
|
3208
|
-
children: /* @__PURE__ */
|
|
3811
|
+
children: /* @__PURE__ */ jsx25(
|
|
3209
3812
|
"path",
|
|
3210
3813
|
{
|
|
3211
3814
|
strokeLinecap: "round",
|
|
@@ -3215,10 +3818,10 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3215
3818
|
)
|
|
3216
3819
|
}
|
|
3217
3820
|
),
|
|
3218
|
-
/* @__PURE__ */
|
|
3219
|
-
/* @__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 })
|
|
3220
3823
|
] }),
|
|
3221
|
-
/* @__PURE__ */
|
|
3824
|
+
/* @__PURE__ */ jsx25(
|
|
3222
3825
|
"span",
|
|
3223
3826
|
{
|
|
3224
3827
|
className: `inline-flex items-center rounded-full px-2 py-1 text-xs font-medium ${statusStyles}`,
|
|
@@ -3228,14 +3831,14 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3228
3831
|
]
|
|
3229
3832
|
}
|
|
3230
3833
|
),
|
|
3231
|
-
isExpanded && /* @__PURE__ */
|
|
3232
|
-
/* @__PURE__ */
|
|
3233
|
-
/* @__PURE__ */
|
|
3234
|
-
/* @__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) })
|
|
3235
3838
|
] }),
|
|
3236
|
-
result !== void 0 && /* @__PURE__ */
|
|
3237
|
-
/* @__PURE__ */
|
|
3238
|
-
/* @__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) })
|
|
3239
3842
|
] })
|
|
3240
3843
|
] })
|
|
3241
3844
|
] }) });
|
|
@@ -3258,11 +3861,13 @@ export {
|
|
|
3258
3861
|
CopilotChatUserMessage_default as CopilotChatUserMessage,
|
|
3259
3862
|
CopilotChatView_default as CopilotChatView,
|
|
3260
3863
|
CopilotKitCoreReact,
|
|
3864
|
+
CopilotKitInspector,
|
|
3261
3865
|
CopilotKitProvider,
|
|
3262
3866
|
CopilotModalHeader,
|
|
3867
|
+
CopilotPopup,
|
|
3868
|
+
CopilotPopupView,
|
|
3263
3869
|
CopilotSidebar,
|
|
3264
3870
|
CopilotSidebarView,
|
|
3265
|
-
WebInspector,
|
|
3266
3871
|
WildcardToolCallRender,
|
|
3267
3872
|
defineToolCallRenderer,
|
|
3268
3873
|
useAgent,
|