@copilotkitnext/react 1.51.2 → 1.51.3-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +51 -12
- package/dist/index.d.ts +51 -12
- package/dist/index.js +570 -71
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +659 -158
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +7 -7
package/dist/index.mjs
CHANGED
|
@@ -5,17 +5,17 @@ export * from "@ag-ui/client";
|
|
|
5
5
|
|
|
6
6
|
// src/components/chat/CopilotChatInput.tsx
|
|
7
7
|
import {
|
|
8
|
-
useState as
|
|
8
|
+
useState as useState3,
|
|
9
9
|
useRef as useRef2,
|
|
10
10
|
useEffect as useEffect2,
|
|
11
11
|
useLayoutEffect,
|
|
12
12
|
forwardRef as forwardRef2,
|
|
13
13
|
useImperativeHandle as useImperativeHandle2,
|
|
14
|
-
useCallback,
|
|
14
|
+
useCallback as useCallback2,
|
|
15
15
|
useMemo as useMemo2
|
|
16
16
|
} from "react";
|
|
17
17
|
import { twMerge as twMerge3 } from "tailwind-merge";
|
|
18
|
-
import { Plus, Mic, ArrowUp, X, Check, Square } from "lucide-react";
|
|
18
|
+
import { Plus, Mic, ArrowUp, X, Check, Square, Loader2 } from "lucide-react";
|
|
19
19
|
|
|
20
20
|
// src/providers/CopilotChatConfigurationProvider.tsx
|
|
21
21
|
import { createContext, useContext, useMemo, useState } from "react";
|
|
@@ -40,7 +40,8 @@ var CopilotChatDefaultLabels = {
|
|
|
40
40
|
chatDisclaimerText: "AI can make mistakes. Please verify important information.",
|
|
41
41
|
chatToggleOpenLabel: "Open chat",
|
|
42
42
|
chatToggleCloseLabel: "Close chat",
|
|
43
|
-
modalHeaderTitle: "CopilotKit Chat"
|
|
43
|
+
modalHeaderTitle: "CopilotKit Chat",
|
|
44
|
+
welcomeMessageText: "How can I help you today?"
|
|
44
45
|
};
|
|
45
46
|
var CopilotChatConfiguration = createContext(null);
|
|
46
47
|
var CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, isModalDefaultOpen }) => {
|
|
@@ -381,7 +382,7 @@ function DropdownMenuSubContent({
|
|
|
381
382
|
}
|
|
382
383
|
|
|
383
384
|
// src/components/chat/CopilotChatAudioRecorder.tsx
|
|
384
|
-
import { useRef, useEffect, useImperativeHandle, forwardRef } from "react";
|
|
385
|
+
import { useRef, useEffect, useImperativeHandle, forwardRef, useCallback, useState as useState2 } from "react";
|
|
385
386
|
import { twMerge as twMerge2 } from "tailwind-merge";
|
|
386
387
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
387
388
|
var AudioRecorderError = class extends Error {
|
|
@@ -393,28 +394,126 @@ var AudioRecorderError = class extends Error {
|
|
|
393
394
|
var CopilotChatAudioRecorder = forwardRef((props, ref) => {
|
|
394
395
|
const { className, ...divProps } = props;
|
|
395
396
|
const canvasRef = useRef(null);
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
397
|
+
const [recorderState, setRecorderState] = useState2("idle");
|
|
398
|
+
const mediaRecorderRef = useRef(null);
|
|
399
|
+
const audioChunksRef = useRef([]);
|
|
400
|
+
const streamRef = useRef(null);
|
|
401
|
+
const analyserRef = useRef(null);
|
|
402
|
+
const audioContextRef = useRef(null);
|
|
403
|
+
const animationIdRef = useRef(null);
|
|
404
|
+
const amplitudeHistoryRef = useRef([]);
|
|
405
|
+
const frameCountRef = useRef(0);
|
|
406
|
+
const scrollOffsetRef = useRef(0);
|
|
407
|
+
const smoothedAmplitudeRef = useRef(0);
|
|
408
|
+
const fadeOpacityRef = useRef(0);
|
|
409
|
+
const cleanup = useCallback(() => {
|
|
410
|
+
if (animationIdRef.current) {
|
|
411
|
+
cancelAnimationFrame(animationIdRef.current);
|
|
412
|
+
animationIdRef.current = null;
|
|
413
|
+
}
|
|
414
|
+
if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
|
|
415
|
+
try {
|
|
416
|
+
mediaRecorderRef.current.stop();
|
|
417
|
+
} catch {
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
if (streamRef.current) {
|
|
421
|
+
streamRef.current.getTracks().forEach((track) => track.stop());
|
|
422
|
+
streamRef.current = null;
|
|
423
|
+
}
|
|
424
|
+
if (audioContextRef.current && audioContextRef.current.state !== "closed") {
|
|
425
|
+
audioContextRef.current.close().catch(() => {
|
|
426
|
+
});
|
|
427
|
+
audioContextRef.current = null;
|
|
428
|
+
}
|
|
429
|
+
mediaRecorderRef.current = null;
|
|
430
|
+
analyserRef.current = null;
|
|
431
|
+
audioChunksRef.current = [];
|
|
432
|
+
amplitudeHistoryRef.current = [];
|
|
433
|
+
frameCountRef.current = 0;
|
|
434
|
+
scrollOffsetRef.current = 0;
|
|
435
|
+
smoothedAmplitudeRef.current = 0;
|
|
436
|
+
fadeOpacityRef.current = 0;
|
|
437
|
+
}, []);
|
|
438
|
+
const start = useCallback(async () => {
|
|
439
|
+
if (recorderState !== "idle") {
|
|
440
|
+
throw new AudioRecorderError("Recorder is already active");
|
|
441
|
+
}
|
|
442
|
+
try {
|
|
443
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
444
|
+
streamRef.current = stream;
|
|
445
|
+
const audioContext = new AudioContext();
|
|
446
|
+
audioContextRef.current = audioContext;
|
|
447
|
+
const source = audioContext.createMediaStreamSource(stream);
|
|
448
|
+
const analyser = audioContext.createAnalyser();
|
|
449
|
+
analyser.fftSize = 2048;
|
|
450
|
+
source.connect(analyser);
|
|
451
|
+
analyserRef.current = analyser;
|
|
452
|
+
const mimeType = MediaRecorder.isTypeSupported("audio/webm;codecs=opus") ? "audio/webm;codecs=opus" : MediaRecorder.isTypeSupported("audio/webm") ? "audio/webm" : MediaRecorder.isTypeSupported("audio/mp4") ? "audio/mp4" : "";
|
|
453
|
+
const options = mimeType ? { mimeType } : {};
|
|
454
|
+
const mediaRecorder = new MediaRecorder(stream, options);
|
|
455
|
+
mediaRecorderRef.current = mediaRecorder;
|
|
456
|
+
audioChunksRef.current = [];
|
|
457
|
+
mediaRecorder.ondataavailable = (event) => {
|
|
458
|
+
if (event.data.size > 0) {
|
|
459
|
+
audioChunksRef.current.push(event.data);
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
mediaRecorder.start(100);
|
|
463
|
+
setRecorderState("recording");
|
|
464
|
+
} catch (error) {
|
|
465
|
+
cleanup();
|
|
466
|
+
if (error instanceof Error && error.name === "NotAllowedError") {
|
|
467
|
+
throw new AudioRecorderError("Microphone permission denied");
|
|
468
|
+
}
|
|
469
|
+
if (error instanceof Error && error.name === "NotFoundError") {
|
|
470
|
+
throw new AudioRecorderError("No microphone found");
|
|
471
|
+
}
|
|
472
|
+
throw new AudioRecorderError(
|
|
473
|
+
error instanceof Error ? error.message : "Failed to start recording"
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
}, [recorderState, cleanup]);
|
|
477
|
+
const stop = useCallback(() => {
|
|
478
|
+
return new Promise((resolve, reject) => {
|
|
479
|
+
const mediaRecorder = mediaRecorderRef.current;
|
|
480
|
+
if (!mediaRecorder || recorderState !== "recording") {
|
|
481
|
+
reject(new AudioRecorderError("No active recording"));
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
setRecorderState("processing");
|
|
485
|
+
mediaRecorder.onstop = () => {
|
|
486
|
+
const mimeType = mediaRecorder.mimeType || "audio/webm";
|
|
487
|
+
const audioBlob = new Blob(audioChunksRef.current, { type: mimeType });
|
|
488
|
+
cleanup();
|
|
489
|
+
setRecorderState("idle");
|
|
490
|
+
resolve(audioBlob);
|
|
491
|
+
};
|
|
492
|
+
mediaRecorder.onerror = () => {
|
|
493
|
+
cleanup();
|
|
494
|
+
setRecorderState("idle");
|
|
495
|
+
reject(new AudioRecorderError("Recording failed"));
|
|
496
|
+
};
|
|
497
|
+
mediaRecorder.stop();
|
|
498
|
+
});
|
|
499
|
+
}, [recorderState, cleanup]);
|
|
500
|
+
const calculateAmplitude = (dataArray) => {
|
|
501
|
+
let sum = 0;
|
|
502
|
+
for (let i = 0; i < dataArray.length; i++) {
|
|
503
|
+
const sample = (dataArray[i] ?? 128) / 128 - 1;
|
|
504
|
+
sum += sample * sample;
|
|
505
|
+
}
|
|
506
|
+
return Math.sqrt(sum / dataArray.length);
|
|
411
507
|
};
|
|
412
508
|
useEffect(() => {
|
|
413
509
|
const canvas = canvasRef.current;
|
|
414
510
|
if (!canvas) return;
|
|
415
511
|
const ctx = canvas.getContext("2d");
|
|
416
512
|
if (!ctx) return;
|
|
417
|
-
|
|
513
|
+
const barWidth = 2;
|
|
514
|
+
const barGap = 1;
|
|
515
|
+
const barSpacing = barWidth + barGap;
|
|
516
|
+
const scrollSpeed = 1 / 3;
|
|
418
517
|
const draw = () => {
|
|
419
518
|
const rect = canvas.getBoundingClientRect();
|
|
420
519
|
const dpr = window.devicePixelRatio || 1;
|
|
@@ -422,64 +521,87 @@ var CopilotChatAudioRecorder = forwardRef((props, ref) => {
|
|
|
422
521
|
canvas.width = rect.width * dpr;
|
|
423
522
|
canvas.height = rect.height * dpr;
|
|
424
523
|
ctx.scale(dpr, dpr);
|
|
425
|
-
ctx.imageSmoothingEnabled = false;
|
|
426
524
|
}
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
525
|
+
const maxBars = Math.floor(rect.width / barSpacing) + 2;
|
|
526
|
+
if (analyserRef.current && recorderState === "recording") {
|
|
527
|
+
if (amplitudeHistoryRef.current.length === 0) {
|
|
528
|
+
amplitudeHistoryRef.current = new Array(maxBars).fill(0);
|
|
529
|
+
}
|
|
530
|
+
if (fadeOpacityRef.current < 1) {
|
|
531
|
+
fadeOpacityRef.current = Math.min(1, fadeOpacityRef.current + 0.03);
|
|
532
|
+
}
|
|
533
|
+
scrollOffsetRef.current += scrollSpeed;
|
|
534
|
+
const bufferLength = analyserRef.current.fftSize;
|
|
535
|
+
const dataArray = new Uint8Array(bufferLength);
|
|
536
|
+
analyserRef.current.getByteTimeDomainData(dataArray);
|
|
537
|
+
const rawAmplitude = calculateAmplitude(dataArray);
|
|
538
|
+
const attackSpeed = 0.12;
|
|
539
|
+
const decaySpeed = 0.08;
|
|
540
|
+
const speed = rawAmplitude > smoothedAmplitudeRef.current ? attackSpeed : decaySpeed;
|
|
541
|
+
smoothedAmplitudeRef.current += (rawAmplitude - smoothedAmplitudeRef.current) * speed;
|
|
542
|
+
if (scrollOffsetRef.current >= barSpacing) {
|
|
543
|
+
scrollOffsetRef.current -= barSpacing;
|
|
544
|
+
amplitudeHistoryRef.current.push(smoothedAmplitudeRef.current);
|
|
545
|
+
if (amplitudeHistoryRef.current.length > maxBars) {
|
|
546
|
+
amplitudeHistoryRef.current = amplitudeHistoryRef.current.slice(-maxBars);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
433
550
|
ctx.clearRect(0, 0, rect.width, rect.height);
|
|
434
551
|
const computedStyle = getComputedStyle(canvas);
|
|
435
|
-
|
|
436
|
-
ctx.
|
|
552
|
+
ctx.fillStyle = computedStyle.color;
|
|
553
|
+
ctx.globalAlpha = fadeOpacityRef.current;
|
|
437
554
|
const centerY = rect.height / 2;
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
555
|
+
const maxAmplitude = rect.height / 2 - 2;
|
|
556
|
+
const history = amplitudeHistoryRef.current;
|
|
557
|
+
if (history.length > 0) {
|
|
558
|
+
const offset = scrollOffsetRef.current;
|
|
559
|
+
const edgeFadeWidth = 12;
|
|
560
|
+
for (let i = 0; i < history.length; i++) {
|
|
561
|
+
const amplitude = history[i] ?? 0;
|
|
562
|
+
const scaledAmplitude = Math.min(amplitude * 4, 1);
|
|
563
|
+
const barHeight = Math.max(2, scaledAmplitude * maxAmplitude * 2);
|
|
564
|
+
const x = rect.width - (history.length - i) * barSpacing - offset;
|
|
565
|
+
const y = centerY - barHeight / 2;
|
|
566
|
+
if (x + barWidth > 0 && x < rect.width) {
|
|
567
|
+
let edgeOpacity = 1;
|
|
568
|
+
if (x < edgeFadeWidth) {
|
|
569
|
+
edgeOpacity = Math.max(0, x / edgeFadeWidth);
|
|
570
|
+
} else if (x > rect.width - edgeFadeWidth) {
|
|
571
|
+
edgeOpacity = Math.max(0, (rect.width - x) / edgeFadeWidth);
|
|
572
|
+
}
|
|
573
|
+
ctx.globalAlpha = fadeOpacityRef.current * edgeOpacity;
|
|
574
|
+
ctx.fillRect(x, y, barWidth, barHeight);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
446
577
|
}
|
|
447
|
-
|
|
578
|
+
animationIdRef.current = requestAnimationFrame(draw);
|
|
448
579
|
};
|
|
449
580
|
draw();
|
|
450
581
|
return () => {
|
|
451
|
-
if (
|
|
452
|
-
cancelAnimationFrame(
|
|
582
|
+
if (animationIdRef.current) {
|
|
583
|
+
cancelAnimationFrame(animationIdRef.current);
|
|
453
584
|
}
|
|
454
585
|
};
|
|
455
|
-
}, []);
|
|
586
|
+
}, [recorderState]);
|
|
587
|
+
useEffect(() => {
|
|
588
|
+
return cleanup;
|
|
589
|
+
}, [cleanup]);
|
|
456
590
|
useImperativeHandle(
|
|
457
591
|
ref,
|
|
458
592
|
() => ({
|
|
459
593
|
get state() {
|
|
460
|
-
return
|
|
461
|
-
},
|
|
462
|
-
start: async () => {
|
|
594
|
+
return recorderState;
|
|
463
595
|
},
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
}),
|
|
468
|
-
dispose: () => {
|
|
469
|
-
}
|
|
596
|
+
start,
|
|
597
|
+
stop,
|
|
598
|
+
dispose: cleanup
|
|
470
599
|
}),
|
|
471
|
-
[]
|
|
600
|
+
[recorderState, start, stop, cleanup]
|
|
472
601
|
);
|
|
473
|
-
return /* @__PURE__ */ jsx5("div", { className: twMerge2("
|
|
474
|
-
"canvas",
|
|
475
|
-
{
|
|
476
|
-
ref: canvasRef,
|
|
477
|
-
className: "w-full h-full",
|
|
478
|
-
style: { imageRendering: "pixelated" }
|
|
479
|
-
}
|
|
480
|
-
) });
|
|
602
|
+
return /* @__PURE__ */ jsx5("div", { className: twMerge2("w-full py-3 px-5", className), ...divProps, children: /* @__PURE__ */ jsx5("canvas", { ref: canvasRef, className: "block w-full h-[26px]" }) });
|
|
481
603
|
});
|
|
482
|
-
CopilotChatAudioRecorder.displayName = "
|
|
604
|
+
CopilotChatAudioRecorder.displayName = "CopilotChatAudioRecorder";
|
|
483
605
|
|
|
484
606
|
// src/lib/slots.tsx
|
|
485
607
|
import React2 from "react";
|
|
@@ -547,6 +669,7 @@ function CopilotChatInput({
|
|
|
547
669
|
onStartTranscribe,
|
|
548
670
|
onCancelTranscribe,
|
|
549
671
|
onFinishTranscribe,
|
|
672
|
+
onFinishTranscribeWithAudio,
|
|
550
673
|
onAddFile,
|
|
551
674
|
onChange,
|
|
552
675
|
value,
|
|
@@ -564,19 +687,19 @@ function CopilotChatInput({
|
|
|
564
687
|
...props
|
|
565
688
|
}) {
|
|
566
689
|
const isControlled = value !== void 0;
|
|
567
|
-
const [internalValue, setInternalValue] =
|
|
690
|
+
const [internalValue, setInternalValue] = useState3(() => value ?? "");
|
|
568
691
|
useEffect2(() => {
|
|
569
692
|
if (!isControlled && value !== void 0) {
|
|
570
693
|
setInternalValue(value);
|
|
571
694
|
}
|
|
572
695
|
}, [isControlled, value]);
|
|
573
696
|
const resolvedValue = isControlled ? value ?? "" : internalValue;
|
|
574
|
-
const [layout, setLayout] =
|
|
697
|
+
const [layout, setLayout] = useState3("compact");
|
|
575
698
|
const ignoreResizeRef = useRef2(false);
|
|
576
699
|
const resizeEvaluationRafRef = useRef2(null);
|
|
577
700
|
const isExpanded = mode === "input" && layout === "expanded";
|
|
578
|
-
const [commandQuery, setCommandQuery] =
|
|
579
|
-
const [slashHighlightIndex, setSlashHighlightIndex] =
|
|
701
|
+
const [commandQuery, setCommandQuery] = useState3(null);
|
|
702
|
+
const [slashHighlightIndex, setSlashHighlightIndex] = useState3(0);
|
|
580
703
|
const inputRef = useRef2(null);
|
|
581
704
|
const gridRef = useRef2(null);
|
|
582
705
|
const addButtonContainerRef = useRef2(null);
|
|
@@ -699,7 +822,7 @@ function CopilotChatInput({
|
|
|
699
822
|
setCommandQuery(null);
|
|
700
823
|
}
|
|
701
824
|
}, [mode]);
|
|
702
|
-
const updateSlashState =
|
|
825
|
+
const updateSlashState = useCallback2(
|
|
703
826
|
(value2) => {
|
|
704
827
|
if (commandItems.length === 0) {
|
|
705
828
|
setCommandQuery((prev) => prev === null ? prev : null);
|
|
@@ -726,7 +849,7 @@ function CopilotChatInput({
|
|
|
726
849
|
onChange?.(nextValue);
|
|
727
850
|
updateSlashState(nextValue);
|
|
728
851
|
};
|
|
729
|
-
const clearInputValue =
|
|
852
|
+
const clearInputValue = useCallback2(() => {
|
|
730
853
|
if (!isControlled) {
|
|
731
854
|
setInternalValue("");
|
|
732
855
|
}
|
|
@@ -734,7 +857,7 @@ function CopilotChatInput({
|
|
|
734
857
|
onChange("");
|
|
735
858
|
}
|
|
736
859
|
}, [isControlled, onChange]);
|
|
737
|
-
const runCommand =
|
|
860
|
+
const runCommand = useCallback2(
|
|
738
861
|
(item) => {
|
|
739
862
|
clearInputValue();
|
|
740
863
|
item.action?.();
|
|
@@ -851,8 +974,22 @@ function CopilotChatInput({
|
|
|
851
974
|
const BoundCancelTranscribeButton = renderSlot(cancelTranscribeButton, CopilotChatInput.CancelTranscribeButton, {
|
|
852
975
|
onClick: onCancelTranscribe
|
|
853
976
|
});
|
|
977
|
+
const handleFinishTranscribe = useCallback2(async () => {
|
|
978
|
+
const recorder = audioRecorderRef.current;
|
|
979
|
+
if (recorder && recorder.state === "recording") {
|
|
980
|
+
try {
|
|
981
|
+
const audioBlob = await recorder.stop();
|
|
982
|
+
if (onFinishTranscribeWithAudio) {
|
|
983
|
+
await onFinishTranscribeWithAudio(audioBlob);
|
|
984
|
+
}
|
|
985
|
+
} catch (error) {
|
|
986
|
+
console.error("Failed to stop recording:", error);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
onFinishTranscribe?.();
|
|
990
|
+
}, [onFinishTranscribe, onFinishTranscribeWithAudio]);
|
|
854
991
|
const BoundFinishTranscribeButton = renderSlot(finishTranscribeButton, CopilotChatInput.FinishTranscribeButton, {
|
|
855
|
-
onClick:
|
|
992
|
+
onClick: handleFinishTranscribe
|
|
856
993
|
});
|
|
857
994
|
const BoundAddMenuButton = renderSlot(addMenuButton, CopilotChatInput.AddMenuButton, {
|
|
858
995
|
disabled: mode === "transcribe",
|
|
@@ -887,7 +1024,7 @@ function CopilotChatInput({
|
|
|
887
1024
|
inputRef.current.focus();
|
|
888
1025
|
}
|
|
889
1026
|
};
|
|
890
|
-
const ensureMeasurements =
|
|
1027
|
+
const ensureMeasurements = useCallback2(() => {
|
|
891
1028
|
const textarea = inputRef.current;
|
|
892
1029
|
if (!textarea) {
|
|
893
1030
|
return;
|
|
@@ -914,7 +1051,7 @@ function CopilotChatInput({
|
|
|
914
1051
|
textarea.style.height = previousHeight;
|
|
915
1052
|
textarea.style.maxHeight = `${maxHeight}px`;
|
|
916
1053
|
}, []);
|
|
917
|
-
const adjustTextareaHeight =
|
|
1054
|
+
const adjustTextareaHeight = useCallback2(() => {
|
|
918
1055
|
const textarea = inputRef.current;
|
|
919
1056
|
if (!textarea) {
|
|
920
1057
|
return 0;
|
|
@@ -935,7 +1072,7 @@ function CopilotChatInput({
|
|
|
935
1072
|
}
|
|
936
1073
|
return scrollHeight;
|
|
937
1074
|
}, [ensureMeasurements]);
|
|
938
|
-
const updateLayout =
|
|
1075
|
+
const updateLayout = useCallback2((nextLayout) => {
|
|
939
1076
|
setLayout((prev) => {
|
|
940
1077
|
if (prev === nextLayout) {
|
|
941
1078
|
return prev;
|
|
@@ -944,7 +1081,7 @@ function CopilotChatInput({
|
|
|
944
1081
|
return nextLayout;
|
|
945
1082
|
});
|
|
946
1083
|
}, []);
|
|
947
|
-
const evaluateLayout =
|
|
1084
|
+
const evaluateLayout = useCallback2(() => {
|
|
948
1085
|
if (mode !== "input") {
|
|
949
1086
|
updateLayout("compact");
|
|
950
1087
|
return;
|
|
@@ -1152,10 +1289,10 @@ function CopilotChatInput({
|
|
|
1152
1289
|
"div",
|
|
1153
1290
|
{
|
|
1154
1291
|
className: twMerge3(
|
|
1155
|
-
"relative flex min-w-0 flex-col",
|
|
1292
|
+
"relative flex min-w-0 flex-col min-h-[50px] justify-center",
|
|
1156
1293
|
isExpanded ? "col-span-3 row-start-1" : "col-start-2 row-start-1"
|
|
1157
1294
|
),
|
|
1158
|
-
children: mode === "transcribe" ? BoundAudioRecorder : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1295
|
+
children: mode === "transcribe" ? BoundAudioRecorder : mode === "processing" ? /* @__PURE__ */ jsx6("div", { className: "flex w-full items-center justify-center py-3 px-5", children: /* @__PURE__ */ jsx6(Loader2, { className: "size-[26px] animate-spin text-muted-foreground" }) }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1159
1296
|
BoundTextArea,
|
|
1160
1297
|
slashMenu
|
|
1161
1298
|
] })
|
|
@@ -1272,7 +1409,7 @@ function CopilotChatInput({
|
|
|
1272
1409
|
}
|
|
1273
1410
|
return items;
|
|
1274
1411
|
}, [onAddFile, toolsMenu, labels.chatInputToolbarAddButtonLabel]);
|
|
1275
|
-
const renderMenuItems =
|
|
1412
|
+
const renderMenuItems = useCallback2(
|
|
1276
1413
|
(items) => items.map((item, index) => {
|
|
1277
1414
|
if (item === "-") {
|
|
1278
1415
|
return /* @__PURE__ */ jsx6(DropdownMenuSeparator, {}, `separator-${index}`);
|
|
@@ -1363,7 +1500,7 @@ CopilotChatInput.AddMenuButton.displayName = "CopilotChatInput.AddMenuButton";
|
|
|
1363
1500
|
var CopilotChatInput_default = CopilotChatInput;
|
|
1364
1501
|
|
|
1365
1502
|
// src/components/chat/CopilotChatAssistantMessage.tsx
|
|
1366
|
-
import { useState as
|
|
1503
|
+
import { useState as useState8 } from "react";
|
|
1367
1504
|
import {
|
|
1368
1505
|
Copy,
|
|
1369
1506
|
Check as Check2,
|
|
@@ -1377,11 +1514,11 @@ import "katex/dist/katex.min.css";
|
|
|
1377
1514
|
import { Streamdown } from "streamdown";
|
|
1378
1515
|
|
|
1379
1516
|
// src/hooks/use-render-tool-call.tsx
|
|
1380
|
-
import React7, { useCallback as
|
|
1517
|
+
import React7, { useCallback as useCallback4, useMemo as useMemo4, useSyncExternalStore } from "react";
|
|
1381
1518
|
import { ToolCallStatus } from "@copilotkitnext/core";
|
|
1382
1519
|
|
|
1383
1520
|
// src/providers/CopilotKitProvider.tsx
|
|
1384
|
-
import { createContext as createContext2, useContext as useContext2, useMemo as useMemo3, useEffect as useEffect5, useReducer, useRef as useRef4, useState as
|
|
1521
|
+
import { createContext as createContext2, useContext as useContext2, useMemo as useMemo3, useEffect as useEffect5, useReducer, useRef as useRef4, useState as useState6 } from "react";
|
|
1385
1522
|
import { z as z2 } from "zod";
|
|
1386
1523
|
|
|
1387
1524
|
// src/lib/react-core.ts
|
|
@@ -1457,7 +1594,7 @@ var CopilotKitInspector = ({ core, ...rest }) => {
|
|
|
1457
1594
|
CopilotKitInspector.displayName = "CopilotKitInspector";
|
|
1458
1595
|
|
|
1459
1596
|
// src/components/MCPAppsActivityRenderer.tsx
|
|
1460
|
-
import { useEffect as useEffect4, useRef as useRef3, useState as
|
|
1597
|
+
import { useEffect as useEffect4, useRef as useRef3, useState as useState5, useCallback as useCallback3 } from "react";
|
|
1461
1598
|
import { z } from "zod";
|
|
1462
1599
|
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1463
1600
|
var PROTOCOL_VERSION = "2025-06-18";
|
|
@@ -1584,37 +1721,37 @@ function isNotification(msg) {
|
|
|
1584
1721
|
var MCPAppsActivityRenderer = function MCPAppsActivityRenderer2({ content, agent }) {
|
|
1585
1722
|
const containerRef = useRef3(null);
|
|
1586
1723
|
const iframeRef = useRef3(null);
|
|
1587
|
-
const [iframeReady, setIframeReady] =
|
|
1588
|
-
const [error, setError] =
|
|
1589
|
-
const [isLoading, setIsLoading] =
|
|
1590
|
-
const [iframeSize, setIframeSize] =
|
|
1591
|
-
const [fetchedResource, setFetchedResource] =
|
|
1724
|
+
const [iframeReady, setIframeReady] = useState5(false);
|
|
1725
|
+
const [error, setError] = useState5(null);
|
|
1726
|
+
const [isLoading, setIsLoading] = useState5(true);
|
|
1727
|
+
const [iframeSize, setIframeSize] = useState5({});
|
|
1728
|
+
const [fetchedResource, setFetchedResource] = useState5(null);
|
|
1592
1729
|
const contentRef = useRef3(content);
|
|
1593
1730
|
contentRef.current = content;
|
|
1594
1731
|
const agentRef = useRef3(agent);
|
|
1595
1732
|
agentRef.current = agent;
|
|
1596
1733
|
const fetchStateRef = useRef3({ inProgress: false, promise: null, resourceUri: null });
|
|
1597
|
-
const sendToIframe =
|
|
1734
|
+
const sendToIframe = useCallback3((msg) => {
|
|
1598
1735
|
if (iframeRef.current?.contentWindow) {
|
|
1599
1736
|
console.log("[MCPAppsRenderer] Sending to iframe:", msg);
|
|
1600
1737
|
iframeRef.current.contentWindow.postMessage(msg, "*");
|
|
1601
1738
|
}
|
|
1602
1739
|
}, []);
|
|
1603
|
-
const sendResponse =
|
|
1740
|
+
const sendResponse = useCallback3((id, result) => {
|
|
1604
1741
|
sendToIframe({
|
|
1605
1742
|
jsonrpc: "2.0",
|
|
1606
1743
|
id,
|
|
1607
1744
|
result
|
|
1608
1745
|
});
|
|
1609
1746
|
}, [sendToIframe]);
|
|
1610
|
-
const sendErrorResponse =
|
|
1747
|
+
const sendErrorResponse = useCallback3((id, code, message) => {
|
|
1611
1748
|
sendToIframe({
|
|
1612
1749
|
jsonrpc: "2.0",
|
|
1613
1750
|
id,
|
|
1614
1751
|
error: { code, message }
|
|
1615
1752
|
});
|
|
1616
1753
|
}, [sendToIframe]);
|
|
1617
|
-
const sendNotification =
|
|
1754
|
+
const sendNotification = useCallback3((method, params) => {
|
|
1618
1755
|
sendToIframe({
|
|
1619
1756
|
jsonrpc: "2.0",
|
|
1620
1757
|
method,
|
|
@@ -1966,6 +2103,7 @@ var CopilotKitProvider = ({
|
|
|
1966
2103
|
children,
|
|
1967
2104
|
runtimeUrl,
|
|
1968
2105
|
headers = {},
|
|
2106
|
+
credentials,
|
|
1969
2107
|
publicApiKey,
|
|
1970
2108
|
publicLicenseKey,
|
|
1971
2109
|
properties = {},
|
|
@@ -1978,7 +2116,7 @@ var CopilotKitProvider = ({
|
|
|
1978
2116
|
showDevConsole = false,
|
|
1979
2117
|
useSingleEndpoint = false
|
|
1980
2118
|
}) => {
|
|
1981
|
-
const [shouldRenderInspector, setShouldRenderInspector] =
|
|
2119
|
+
const [shouldRenderInspector, setShouldRenderInspector] = useState6(false);
|
|
1982
2120
|
useEffect5(() => {
|
|
1983
2121
|
if (typeof window === "undefined") {
|
|
1984
2122
|
return;
|
|
@@ -2111,6 +2249,7 @@ var CopilotKitProvider = ({
|
|
|
2111
2249
|
runtimeUrl: chatApiEndpoint,
|
|
2112
2250
|
runtimeTransport: useSingleEndpoint ? "single" : "rest",
|
|
2113
2251
|
headers: mergedHeaders,
|
|
2252
|
+
credentials,
|
|
2114
2253
|
properties,
|
|
2115
2254
|
agents__unsafe_dev_only: agents,
|
|
2116
2255
|
tools: allTools,
|
|
@@ -2131,7 +2270,7 @@ var CopilotKitProvider = ({
|
|
|
2131
2270
|
subscription.unsubscribe();
|
|
2132
2271
|
};
|
|
2133
2272
|
}, [copilotkit]);
|
|
2134
|
-
const [executingToolCallIds, setExecutingToolCallIds] =
|
|
2273
|
+
const [executingToolCallIds, setExecutingToolCallIds] = useState6(() => /* @__PURE__ */ new Set());
|
|
2135
2274
|
useEffect5(() => {
|
|
2136
2275
|
const subscription = copilotkit.subscribe({
|
|
2137
2276
|
onToolExecutionStart: ({ toolCallId }) => {
|
|
@@ -2159,9 +2298,10 @@ var CopilotKitProvider = ({
|
|
|
2159
2298
|
copilotkit.setRuntimeUrl(chatApiEndpoint);
|
|
2160
2299
|
copilotkit.setRuntimeTransport(useSingleEndpoint ? "single" : "rest");
|
|
2161
2300
|
copilotkit.setHeaders(mergedHeaders);
|
|
2301
|
+
copilotkit.setCredentials(credentials);
|
|
2162
2302
|
copilotkit.setProperties(properties);
|
|
2163
2303
|
copilotkit.setAgents__unsafe_dev_only(agents);
|
|
2164
|
-
}, [chatApiEndpoint, mergedHeaders, properties, agents, useSingleEndpoint]);
|
|
2304
|
+
}, [chatApiEndpoint, mergedHeaders, credentials, properties, agents, useSingleEndpoint]);
|
|
2165
2305
|
return /* @__PURE__ */ jsxs5(
|
|
2166
2306
|
CopilotKitContext.Provider,
|
|
2167
2307
|
{
|
|
@@ -2269,7 +2409,7 @@ function useRenderToolCall() {
|
|
|
2269
2409
|
() => copilotkit.renderToolCalls,
|
|
2270
2410
|
() => copilotkit.renderToolCalls
|
|
2271
2411
|
);
|
|
2272
|
-
const renderToolCall =
|
|
2412
|
+
const renderToolCall = useCallback4(
|
|
2273
2413
|
({
|
|
2274
2414
|
toolCall,
|
|
2275
2415
|
toolMessage
|
|
@@ -2359,14 +2499,14 @@ function useRenderCustomMessages() {
|
|
|
2359
2499
|
|
|
2360
2500
|
// src/hooks/use-render-activity-message.tsx
|
|
2361
2501
|
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID3 } from "@copilotkitnext/shared";
|
|
2362
|
-
import { useCallback as
|
|
2502
|
+
import { useCallback as useCallback5, useMemo as useMemo5 } from "react";
|
|
2363
2503
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
2364
2504
|
function useRenderActivityMessage() {
|
|
2365
2505
|
const { copilotkit } = useCopilotKit();
|
|
2366
2506
|
const config = useCopilotChatConfiguration();
|
|
2367
2507
|
const agentId = config?.agentId ?? DEFAULT_AGENT_ID3;
|
|
2368
2508
|
const renderers = copilotkit.renderActivityMessages;
|
|
2369
|
-
const findRenderer =
|
|
2509
|
+
const findRenderer = useCallback5(
|
|
2370
2510
|
(activityType) => {
|
|
2371
2511
|
if (!renderers.length) {
|
|
2372
2512
|
return null;
|
|
@@ -2378,7 +2518,7 @@ function useRenderActivityMessage() {
|
|
|
2378
2518
|
},
|
|
2379
2519
|
[agentId, renderers]
|
|
2380
2520
|
);
|
|
2381
|
-
const renderActivityMessage =
|
|
2521
|
+
const renderActivityMessage = useCallback5(
|
|
2382
2522
|
(message) => {
|
|
2383
2523
|
const renderer = findRenderer(message.activityType);
|
|
2384
2524
|
if (!renderer) {
|
|
@@ -2451,23 +2591,23 @@ function useFrontendTool(tool, deps) {
|
|
|
2451
2591
|
}
|
|
2452
2592
|
|
|
2453
2593
|
// src/hooks/use-human-in-the-loop.tsx
|
|
2454
|
-
import { useCallback as
|
|
2594
|
+
import { useCallback as useCallback6, useRef as useRef5, useEffect as useEffect7 } from "react";
|
|
2455
2595
|
import React8 from "react";
|
|
2456
2596
|
function useHumanInTheLoop(tool, deps) {
|
|
2457
2597
|
const { copilotkit } = useCopilotKit();
|
|
2458
2598
|
const resolvePromiseRef = useRef5(null);
|
|
2459
|
-
const respond =
|
|
2599
|
+
const respond = useCallback6(async (result) => {
|
|
2460
2600
|
if (resolvePromiseRef.current) {
|
|
2461
2601
|
resolvePromiseRef.current(result);
|
|
2462
2602
|
resolvePromiseRef.current = null;
|
|
2463
2603
|
}
|
|
2464
2604
|
}, []);
|
|
2465
|
-
const handler =
|
|
2605
|
+
const handler = useCallback6(async () => {
|
|
2466
2606
|
return new Promise((resolve) => {
|
|
2467
2607
|
resolvePromiseRef.current = resolve;
|
|
2468
2608
|
});
|
|
2469
2609
|
}, []);
|
|
2470
|
-
const RenderComponent =
|
|
2610
|
+
const RenderComponent = useCallback6(
|
|
2471
2611
|
(props) => {
|
|
2472
2612
|
const ToolComponent = tool.render;
|
|
2473
2613
|
if (props.status === "inProgress") {
|
|
@@ -2617,17 +2757,17 @@ function useAgentContext(context) {
|
|
|
2617
2757
|
}
|
|
2618
2758
|
|
|
2619
2759
|
// src/hooks/use-suggestions.tsx
|
|
2620
|
-
import { useCallback as
|
|
2760
|
+
import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo8, useState as useState7 } from "react";
|
|
2621
2761
|
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID5 } from "@copilotkitnext/shared";
|
|
2622
2762
|
function useSuggestions({ agentId } = {}) {
|
|
2623
2763
|
const { copilotkit } = useCopilotKit();
|
|
2624
2764
|
const config = useCopilotChatConfiguration();
|
|
2625
2765
|
const resolvedAgentId = useMemo8(() => agentId ?? config?.agentId ?? DEFAULT_AGENT_ID5, [agentId, config?.agentId]);
|
|
2626
|
-
const [suggestions, setSuggestions] =
|
|
2766
|
+
const [suggestions, setSuggestions] = useState7(() => {
|
|
2627
2767
|
const result = copilotkit.getSuggestions(resolvedAgentId);
|
|
2628
2768
|
return result.suggestions;
|
|
2629
2769
|
});
|
|
2630
|
-
const [isLoading, setIsLoading] =
|
|
2770
|
+
const [isLoading, setIsLoading] = useState7(() => {
|
|
2631
2771
|
const result = copilotkit.getSuggestions(resolvedAgentId);
|
|
2632
2772
|
return result.isLoading;
|
|
2633
2773
|
});
|
|
@@ -2666,10 +2806,10 @@ function useSuggestions({ agentId } = {}) {
|
|
|
2666
2806
|
subscription.unsubscribe();
|
|
2667
2807
|
};
|
|
2668
2808
|
}, [copilotkit, resolvedAgentId]);
|
|
2669
|
-
const reloadSuggestions =
|
|
2809
|
+
const reloadSuggestions = useCallback7(() => {
|
|
2670
2810
|
copilotkit.reloadSuggestions(resolvedAgentId);
|
|
2671
2811
|
}, [copilotkit, resolvedAgentId]);
|
|
2672
|
-
const clearSuggestions =
|
|
2812
|
+
const clearSuggestions = useCallback7(() => {
|
|
2673
2813
|
copilotkit.clearSuggestions(resolvedAgentId);
|
|
2674
2814
|
}, [copilotkit, resolvedAgentId]);
|
|
2675
2815
|
return {
|
|
@@ -2681,7 +2821,7 @@ function useSuggestions({ agentId } = {}) {
|
|
|
2681
2821
|
}
|
|
2682
2822
|
|
|
2683
2823
|
// src/hooks/use-configure-suggestions.tsx
|
|
2684
|
-
import { useCallback as
|
|
2824
|
+
import { useCallback as useCallback8, useEffect as useEffect11, useMemo as useMemo9, useRef as useRef6 } from "react";
|
|
2685
2825
|
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID6 } from "@copilotkitnext/shared";
|
|
2686
2826
|
function useConfigureSuggestions(config, deps) {
|
|
2687
2827
|
const { copilotkit } = useCopilotKit();
|
|
@@ -2737,7 +2877,7 @@ function useConfigureSuggestions(config, deps) {
|
|
|
2737
2877
|
return consumer;
|
|
2738
2878
|
}, [normalizedConfig, resolvedConsumerAgentId]);
|
|
2739
2879
|
const isGlobalConfig = rawConsumerAgentId === void 0 || rawConsumerAgentId === "*";
|
|
2740
|
-
const requestReload =
|
|
2880
|
+
const requestReload = useCallback8(() => {
|
|
2741
2881
|
if (!normalizedConfig) {
|
|
2742
2882
|
return;
|
|
2743
2883
|
}
|
|
@@ -2992,7 +3132,7 @@ function CopilotChatAssistantMessage({
|
|
|
2992
3132
|
CopilotChatAssistantMessage2.CopyButton = ({ className, title, onClick, ...props }) => {
|
|
2993
3133
|
const config = useCopilotChatConfiguration();
|
|
2994
3134
|
const labels = config?.labels ?? CopilotChatDefaultLabels;
|
|
2995
|
-
const [copied, setCopied] =
|
|
3135
|
+
const [copied, setCopied] = useState8(false);
|
|
2996
3136
|
const handleClick = (event) => {
|
|
2997
3137
|
setCopied(true);
|
|
2998
3138
|
setTimeout(() => setCopied(false), 2e3);
|
|
@@ -3070,7 +3210,7 @@ CopilotChatAssistantMessage.RegenerateButton.displayName = "CopilotChatAssistant
|
|
|
3070
3210
|
var CopilotChatAssistantMessage_default = CopilotChatAssistantMessage;
|
|
3071
3211
|
|
|
3072
3212
|
// src/components/chat/CopilotChatUserMessage.tsx
|
|
3073
|
-
import { useMemo as useMemo10, useState as
|
|
3213
|
+
import { useMemo as useMemo10, useState as useState9 } from "react";
|
|
3074
3214
|
import { Copy as Copy2, Check as Check3, Edit, ChevronLeft, ChevronRight } from "lucide-react";
|
|
3075
3215
|
import { twMerge as twMerge5 } from "tailwind-merge";
|
|
3076
3216
|
import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
@@ -3233,7 +3373,7 @@ function CopilotChatUserMessage({
|
|
|
3233
3373
|
CopilotChatUserMessage2.CopyButton = ({ className, title, onClick, ...props }) => {
|
|
3234
3374
|
const config = useCopilotChatConfiguration();
|
|
3235
3375
|
const labels = config?.labels ?? CopilotChatDefaultLabels;
|
|
3236
|
-
const [copied, setCopied] =
|
|
3376
|
+
const [copied, setCopied] = useState9(false);
|
|
3237
3377
|
const handleClick = (event) => {
|
|
3238
3378
|
setCopied(true);
|
|
3239
3379
|
setTimeout(() => setCopied(false), 2e3);
|
|
@@ -3328,7 +3468,7 @@ var CopilotChatUserMessage_default = CopilotChatUserMessage;
|
|
|
3328
3468
|
|
|
3329
3469
|
// src/components/chat/CopilotChatSuggestionPill.tsx
|
|
3330
3470
|
import React10 from "react";
|
|
3331
|
-
import { Loader2 } from "lucide-react";
|
|
3471
|
+
import { Loader2 as Loader22 } from "lucide-react";
|
|
3332
3472
|
import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
3333
3473
|
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";
|
|
3334
3474
|
var labelClasses = "whitespace-nowrap font-medium leading-none";
|
|
@@ -3345,7 +3485,7 @@ var CopilotChatSuggestionPill = React10.forwardRef(function CopilotChatSuggestio
|
|
|
3345
3485
|
disabled: isLoading || props.disabled,
|
|
3346
3486
|
...props,
|
|
3347
3487
|
children: [
|
|
3348
|
-
isLoading ? /* @__PURE__ */ jsx16("span", { className: "flex h-3.5 sm:h-4 w-3.5 sm:w-4 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx16(
|
|
3488
|
+
isLoading ? /* @__PURE__ */ jsx16("span", { className: "flex h-3.5 sm:h-4 w-3.5 sm:w-4 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx16(Loader22, { className: "h-3.5 sm:h-4 w-3.5 sm:w-4 animate-spin", "aria-hidden": "true" }) }) : showIcon && /* @__PURE__ */ jsx16("span", { className: "flex h-3.5 sm:h-4 w-3.5 sm:w-4 items-center justify-center text-muted-foreground", children: icon }),
|
|
3349
3489
|
/* @__PURE__ */ jsx16("span", { className: labelClasses, children })
|
|
3350
3490
|
]
|
|
3351
3491
|
}
|
|
@@ -3656,15 +3796,15 @@ CopilotChatMessageView.Cursor = function Cursor({ className, ...props }) {
|
|
|
3656
3796
|
var CopilotChatMessageView_default = CopilotChatMessageView;
|
|
3657
3797
|
|
|
3658
3798
|
// src/components/chat/CopilotChatView.tsx
|
|
3659
|
-
import React13, { useRef as useRef7, useState as
|
|
3799
|
+
import React13, { useRef as useRef7, useState as useState11, useEffect as useEffect14 } from "react";
|
|
3660
3800
|
import { twMerge as twMerge7 } from "tailwind-merge";
|
|
3661
3801
|
import { StickToBottom, useStickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
|
3662
3802
|
import { ChevronDown } from "lucide-react";
|
|
3663
3803
|
|
|
3664
3804
|
// src/hooks/use-keyboard-height.tsx
|
|
3665
|
-
import { useState as
|
|
3805
|
+
import { useState as useState10, useEffect as useEffect13 } from "react";
|
|
3666
3806
|
function useKeyboardHeight() {
|
|
3667
|
-
const [keyboardState, setKeyboardState] =
|
|
3807
|
+
const [keyboardState, setKeyboardState] = useState10({
|
|
3668
3808
|
isKeyboardOpen: false,
|
|
3669
3809
|
keyboardHeight: 0,
|
|
3670
3810
|
availableHeight: typeof window !== "undefined" ? window.innerHeight : 0,
|
|
@@ -3712,6 +3852,7 @@ function CopilotChatView({
|
|
|
3712
3852
|
inputContainer,
|
|
3713
3853
|
disclaimer,
|
|
3714
3854
|
suggestionView,
|
|
3855
|
+
welcomeScreen,
|
|
3715
3856
|
messages = [],
|
|
3716
3857
|
autoScroll = true,
|
|
3717
3858
|
inputProps,
|
|
@@ -3724,8 +3865,8 @@ function CopilotChatView({
|
|
|
3724
3865
|
...props
|
|
3725
3866
|
}) {
|
|
3726
3867
|
const inputContainerRef = useRef7(null);
|
|
3727
|
-
const [inputContainerHeight, setInputContainerHeight] =
|
|
3728
|
-
const [isResizing, setIsResizing] =
|
|
3868
|
+
const [inputContainerHeight, setInputContainerHeight] = useState11(0);
|
|
3869
|
+
const [isResizing, setIsResizing] = useState11(false);
|
|
3729
3870
|
const resizeTimeoutRef = useRef7(null);
|
|
3730
3871
|
const { isKeyboardOpen, keyboardHeight, availableHeight } = useKeyboardHeight();
|
|
3731
3872
|
useEffect14(() => {
|
|
@@ -3791,6 +3932,21 @@ function CopilotChatView({
|
|
|
3791
3932
|
BoundDisclaimer
|
|
3792
3933
|
] })
|
|
3793
3934
|
});
|
|
3935
|
+
const isEmpty = messages.length === 0;
|
|
3936
|
+
const welcomeScreenDisabled = welcomeScreen === false;
|
|
3937
|
+
const shouldShowWelcomeScreen = isEmpty && !welcomeScreenDisabled;
|
|
3938
|
+
if (shouldShowWelcomeScreen) {
|
|
3939
|
+
const welcomeScreenSlot = welcomeScreen === true ? void 0 : welcomeScreen;
|
|
3940
|
+
const BoundWelcomeScreen = renderSlot(
|
|
3941
|
+
welcomeScreenSlot,
|
|
3942
|
+
CopilotChatView.WelcomeScreen,
|
|
3943
|
+
{
|
|
3944
|
+
input: BoundInput,
|
|
3945
|
+
suggestionView: BoundSuggestionView ?? /* @__PURE__ */ jsx19(Fragment6, {})
|
|
3946
|
+
}
|
|
3947
|
+
);
|
|
3948
|
+
return /* @__PURE__ */ jsx19("div", { className: twMerge7("relative h-full", className), ...props, children: BoundWelcomeScreen });
|
|
3949
|
+
}
|
|
3794
3950
|
if (children) {
|
|
3795
3951
|
return children({
|
|
3796
3952
|
messageView: BoundMessageView,
|
|
@@ -3837,9 +3993,9 @@ function CopilotChatView({
|
|
|
3837
3993
|
className,
|
|
3838
3994
|
...props
|
|
3839
3995
|
}) => {
|
|
3840
|
-
const [hasMounted, setHasMounted] =
|
|
3996
|
+
const [hasMounted, setHasMounted] = useState11(false);
|
|
3841
3997
|
const { scrollRef, contentRef, scrollToBottom } = useStickToBottom();
|
|
3842
|
-
const [showScrollButton, setShowScrollButton] =
|
|
3998
|
+
const [showScrollButton, setShowScrollButton] = useState11(false);
|
|
3843
3999
|
useEffect14(() => {
|
|
3844
4000
|
setHasMounted(true);
|
|
3845
4001
|
}, []);
|
|
@@ -3970,15 +4126,174 @@ function CopilotChatView({
|
|
|
3970
4126
|
}
|
|
3971
4127
|
);
|
|
3972
4128
|
};
|
|
4129
|
+
CopilotChatView2.WelcomeMessage = ({
|
|
4130
|
+
className,
|
|
4131
|
+
...props
|
|
4132
|
+
}) => {
|
|
4133
|
+
const config = useCopilotChatConfiguration();
|
|
4134
|
+
const labels = config?.labels ?? CopilotChatDefaultLabels;
|
|
4135
|
+
return /* @__PURE__ */ jsx19(
|
|
4136
|
+
"h1",
|
|
4137
|
+
{
|
|
4138
|
+
className: cn(
|
|
4139
|
+
"text-xl sm:text-2xl font-medium text-foreground text-center",
|
|
4140
|
+
className
|
|
4141
|
+
),
|
|
4142
|
+
...props,
|
|
4143
|
+
children: labels.welcomeMessageText
|
|
4144
|
+
}
|
|
4145
|
+
);
|
|
4146
|
+
};
|
|
4147
|
+
CopilotChatView2.WelcomeScreen = ({
|
|
4148
|
+
welcomeMessage,
|
|
4149
|
+
input,
|
|
4150
|
+
suggestionView,
|
|
4151
|
+
className,
|
|
4152
|
+
children,
|
|
4153
|
+
...props
|
|
4154
|
+
}) => {
|
|
4155
|
+
const BoundWelcomeMessage = renderSlot(
|
|
4156
|
+
welcomeMessage,
|
|
4157
|
+
CopilotChatView2.WelcomeMessage,
|
|
4158
|
+
{}
|
|
4159
|
+
);
|
|
4160
|
+
if (children) {
|
|
4161
|
+
return /* @__PURE__ */ jsx19(Fragment6, { children: children({
|
|
4162
|
+
welcomeMessage: BoundWelcomeMessage,
|
|
4163
|
+
input,
|
|
4164
|
+
suggestionView,
|
|
4165
|
+
className,
|
|
4166
|
+
...props
|
|
4167
|
+
}) });
|
|
4168
|
+
}
|
|
4169
|
+
return /* @__PURE__ */ jsx19(
|
|
4170
|
+
"div",
|
|
4171
|
+
{
|
|
4172
|
+
className: cn(
|
|
4173
|
+
"h-full flex flex-col items-center justify-center px-4",
|
|
4174
|
+
className
|
|
4175
|
+
),
|
|
4176
|
+
...props,
|
|
4177
|
+
children: /* @__PURE__ */ jsxs11("div", { className: "w-full max-w-3xl flex flex-col items-center", children: [
|
|
4178
|
+
/* @__PURE__ */ jsx19("div", { className: "mb-6", children: BoundWelcomeMessage }),
|
|
4179
|
+
/* @__PURE__ */ jsx19("div", { className: "w-full", children: input }),
|
|
4180
|
+
/* @__PURE__ */ jsx19("div", { className: "mt-4 flex justify-center", children: suggestionView })
|
|
4181
|
+
] })
|
|
4182
|
+
}
|
|
4183
|
+
);
|
|
4184
|
+
};
|
|
3973
4185
|
})(CopilotChatView || (CopilotChatView = {}));
|
|
3974
4186
|
var CopilotChatView_default = CopilotChatView;
|
|
3975
4187
|
|
|
3976
4188
|
// src/components/chat/CopilotChat.tsx
|
|
3977
|
-
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID7, randomUUID as randomUUID2 } from "@copilotkitnext/shared";
|
|
3978
|
-
import { useCallback as
|
|
4189
|
+
import { DEFAULT_AGENT_ID as DEFAULT_AGENT_ID7, randomUUID as randomUUID2, TranscriptionErrorCode as TranscriptionErrorCode2 } from "@copilotkitnext/shared";
|
|
4190
|
+
import { useCallback as useCallback9, useEffect as useEffect15, useMemo as useMemo11, useState as useState12 } from "react";
|
|
3979
4191
|
import { merge } from "ts-deepmerge";
|
|
3980
4192
|
import { AGUIConnectNotImplementedError } from "@ag-ui/client";
|
|
3981
|
-
|
|
4193
|
+
|
|
4194
|
+
// src/lib/transcription-client.ts
|
|
4195
|
+
import {
|
|
4196
|
+
TranscriptionErrorCode
|
|
4197
|
+
} from "@copilotkitnext/shared";
|
|
4198
|
+
async function blobToBase64(blob) {
|
|
4199
|
+
return new Promise((resolve, reject) => {
|
|
4200
|
+
const reader = new FileReader();
|
|
4201
|
+
reader.onloadend = () => {
|
|
4202
|
+
const result = reader.result;
|
|
4203
|
+
const base64 = result.split(",")[1];
|
|
4204
|
+
resolve(base64 ?? "");
|
|
4205
|
+
};
|
|
4206
|
+
reader.onerror = () => reject(new Error("Failed to read audio data"));
|
|
4207
|
+
reader.readAsDataURL(blob);
|
|
4208
|
+
});
|
|
4209
|
+
}
|
|
4210
|
+
function isTranscriptionErrorResponse(data) {
|
|
4211
|
+
return typeof data === "object" && data !== null && "error" in data && "message" in data && typeof data.error === "string" && typeof data.message === "string";
|
|
4212
|
+
}
|
|
4213
|
+
function parseTranscriptionError(response) {
|
|
4214
|
+
return {
|
|
4215
|
+
code: response.error,
|
|
4216
|
+
message: response.message,
|
|
4217
|
+
retryable: response.retryable ?? false
|
|
4218
|
+
};
|
|
4219
|
+
}
|
|
4220
|
+
var TranscriptionError = class extends Error {
|
|
4221
|
+
info;
|
|
4222
|
+
constructor(info) {
|
|
4223
|
+
super(info.message);
|
|
4224
|
+
this.name = "TranscriptionError";
|
|
4225
|
+
this.info = info;
|
|
4226
|
+
}
|
|
4227
|
+
};
|
|
4228
|
+
async function transcribeAudio(core, audioBlob, filename = "recording.webm") {
|
|
4229
|
+
const runtimeUrl = core.runtimeUrl;
|
|
4230
|
+
if (!runtimeUrl) {
|
|
4231
|
+
throw new TranscriptionError({
|
|
4232
|
+
code: TranscriptionErrorCode.INVALID_REQUEST,
|
|
4233
|
+
message: "Runtime URL is not configured",
|
|
4234
|
+
retryable: false
|
|
4235
|
+
});
|
|
4236
|
+
}
|
|
4237
|
+
const headers = { ...core.headers };
|
|
4238
|
+
let response;
|
|
4239
|
+
try {
|
|
4240
|
+
if (core.runtimeTransport === "single") {
|
|
4241
|
+
const base64Audio = await blobToBase64(audioBlob);
|
|
4242
|
+
headers["Content-Type"] = "application/json";
|
|
4243
|
+
response = await fetch(runtimeUrl, {
|
|
4244
|
+
method: "POST",
|
|
4245
|
+
headers,
|
|
4246
|
+
body: JSON.stringify({
|
|
4247
|
+
method: "transcribe",
|
|
4248
|
+
body: {
|
|
4249
|
+
audio: base64Audio,
|
|
4250
|
+
mimeType: audioBlob.type || "audio/webm",
|
|
4251
|
+
filename
|
|
4252
|
+
}
|
|
4253
|
+
})
|
|
4254
|
+
});
|
|
4255
|
+
} else {
|
|
4256
|
+
delete headers["Content-Type"];
|
|
4257
|
+
const formData = new FormData();
|
|
4258
|
+
formData.append("audio", audioBlob, filename);
|
|
4259
|
+
response = await fetch(`${runtimeUrl}/transcribe`, {
|
|
4260
|
+
method: "POST",
|
|
4261
|
+
headers,
|
|
4262
|
+
body: formData
|
|
4263
|
+
});
|
|
4264
|
+
}
|
|
4265
|
+
} catch (error) {
|
|
4266
|
+
throw new TranscriptionError({
|
|
4267
|
+
code: TranscriptionErrorCode.NETWORK_ERROR,
|
|
4268
|
+
message: error instanceof Error ? error.message : "Network request failed",
|
|
4269
|
+
retryable: true
|
|
4270
|
+
});
|
|
4271
|
+
}
|
|
4272
|
+
if (!response.ok) {
|
|
4273
|
+
let errorData;
|
|
4274
|
+
try {
|
|
4275
|
+
errorData = await response.json();
|
|
4276
|
+
} catch {
|
|
4277
|
+
throw new TranscriptionError({
|
|
4278
|
+
code: TranscriptionErrorCode.PROVIDER_ERROR,
|
|
4279
|
+
message: `HTTP ${response.status}: ${response.statusText}`,
|
|
4280
|
+
retryable: response.status >= 500
|
|
4281
|
+
});
|
|
4282
|
+
}
|
|
4283
|
+
if (isTranscriptionErrorResponse(errorData)) {
|
|
4284
|
+
throw new TranscriptionError(parseTranscriptionError(errorData));
|
|
4285
|
+
}
|
|
4286
|
+
throw new TranscriptionError({
|
|
4287
|
+
code: TranscriptionErrorCode.PROVIDER_ERROR,
|
|
4288
|
+
message: typeof errorData === "object" && errorData !== null && "message" in errorData ? String(errorData.message) : "Transcription failed",
|
|
4289
|
+
retryable: response.status >= 500
|
|
4290
|
+
});
|
|
4291
|
+
}
|
|
4292
|
+
return await response.json();
|
|
4293
|
+
}
|
|
4294
|
+
|
|
4295
|
+
// src/components/chat/CopilotChat.tsx
|
|
4296
|
+
import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3982
4297
|
function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen, ...props }) {
|
|
3983
4298
|
const existingConfig = useCopilotChatConfiguration();
|
|
3984
4299
|
const resolvedAgentId = agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID7;
|
|
@@ -3989,6 +4304,12 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
3989
4304
|
const { agent } = useAgent({ agentId: resolvedAgentId });
|
|
3990
4305
|
const { copilotkit } = useCopilotKit();
|
|
3991
4306
|
const { suggestions: autoSuggestions } = useSuggestions({ agentId: resolvedAgentId });
|
|
4307
|
+
const [transcribeMode, setTranscribeMode] = useState12("input");
|
|
4308
|
+
const [inputValue, setInputValue] = useState12("");
|
|
4309
|
+
const [transcriptionError, setTranscriptionError] = useState12(null);
|
|
4310
|
+
const [isTranscribing, setIsTranscribing] = useState12(false);
|
|
4311
|
+
const isTranscriptionEnabled = copilotkit.audioFileTranscriptionEnabled;
|
|
4312
|
+
const isMediaRecorderSupported = typeof window !== "undefined" && typeof MediaRecorder !== "undefined";
|
|
3992
4313
|
const {
|
|
3993
4314
|
inputProps: providedInputProps,
|
|
3994
4315
|
messageView: providedMessageView,
|
|
@@ -4011,13 +4332,14 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
4011
4332
|
return () => {
|
|
4012
4333
|
};
|
|
4013
4334
|
}, [resolvedThreadId, agent, copilotkit, resolvedAgentId]);
|
|
4014
|
-
const onSubmitInput =
|
|
4335
|
+
const onSubmitInput = useCallback9(
|
|
4015
4336
|
async (value) => {
|
|
4016
4337
|
agent.addMessage({
|
|
4017
4338
|
id: randomUUID2(),
|
|
4018
4339
|
role: "user",
|
|
4019
4340
|
content: value
|
|
4020
4341
|
});
|
|
4342
|
+
setInputValue("");
|
|
4021
4343
|
try {
|
|
4022
4344
|
await copilotkit.runAgent({ agent });
|
|
4023
4345
|
} catch (error) {
|
|
@@ -4026,7 +4348,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
4026
4348
|
},
|
|
4027
4349
|
[agent, copilotkit]
|
|
4028
4350
|
);
|
|
4029
|
-
const handleSelectSuggestion =
|
|
4351
|
+
const handleSelectSuggestion = useCallback9(
|
|
4030
4352
|
async (suggestion) => {
|
|
4031
4353
|
agent.addMessage({
|
|
4032
4354
|
id: randomUUID2(),
|
|
@@ -4041,7 +4363,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
4041
4363
|
},
|
|
4042
4364
|
[agent, copilotkit]
|
|
4043
4365
|
);
|
|
4044
|
-
const stopCurrentRun =
|
|
4366
|
+
const stopCurrentRun = useCallback9(() => {
|
|
4045
4367
|
try {
|
|
4046
4368
|
copilotkit.stopAgent({ agent });
|
|
4047
4369
|
} catch (error) {
|
|
@@ -4053,6 +4375,75 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
4053
4375
|
}
|
|
4054
4376
|
}
|
|
4055
4377
|
}, [agent, copilotkit]);
|
|
4378
|
+
const handleStartTranscribe = useCallback9(() => {
|
|
4379
|
+
setTranscriptionError(null);
|
|
4380
|
+
setTranscribeMode("transcribe");
|
|
4381
|
+
}, []);
|
|
4382
|
+
const handleCancelTranscribe = useCallback9(() => {
|
|
4383
|
+
setTranscriptionError(null);
|
|
4384
|
+
setTranscribeMode("input");
|
|
4385
|
+
}, []);
|
|
4386
|
+
const handleFinishTranscribe = useCallback9(() => {
|
|
4387
|
+
setTranscribeMode("input");
|
|
4388
|
+
}, []);
|
|
4389
|
+
const handleFinishTranscribeWithAudio = useCallback9(async (audioBlob) => {
|
|
4390
|
+
setIsTranscribing(true);
|
|
4391
|
+
try {
|
|
4392
|
+
setTranscriptionError(null);
|
|
4393
|
+
const result = await transcribeAudio(copilotkit, audioBlob);
|
|
4394
|
+
setInputValue((prev) => {
|
|
4395
|
+
const trimmedPrev = prev.trim();
|
|
4396
|
+
if (trimmedPrev) {
|
|
4397
|
+
return `${trimmedPrev} ${result.text}`;
|
|
4398
|
+
}
|
|
4399
|
+
return result.text;
|
|
4400
|
+
});
|
|
4401
|
+
} catch (error) {
|
|
4402
|
+
console.error("CopilotChat: Transcription failed", error);
|
|
4403
|
+
if (error instanceof TranscriptionError) {
|
|
4404
|
+
const { code, retryable, message } = error.info;
|
|
4405
|
+
switch (code) {
|
|
4406
|
+
case TranscriptionErrorCode2.RATE_LIMITED:
|
|
4407
|
+
setTranscriptionError("Too many requests. Please wait a moment.");
|
|
4408
|
+
break;
|
|
4409
|
+
case TranscriptionErrorCode2.AUTH_FAILED:
|
|
4410
|
+
setTranscriptionError("Authentication error. Please check your configuration.");
|
|
4411
|
+
break;
|
|
4412
|
+
case TranscriptionErrorCode2.AUDIO_TOO_LONG:
|
|
4413
|
+
setTranscriptionError("Recording is too long. Please try a shorter recording.");
|
|
4414
|
+
break;
|
|
4415
|
+
case TranscriptionErrorCode2.AUDIO_TOO_SHORT:
|
|
4416
|
+
setTranscriptionError("Recording is too short. Please try again.");
|
|
4417
|
+
break;
|
|
4418
|
+
case TranscriptionErrorCode2.INVALID_AUDIO_FORMAT:
|
|
4419
|
+
setTranscriptionError("Audio format not supported.");
|
|
4420
|
+
break;
|
|
4421
|
+
case TranscriptionErrorCode2.SERVICE_NOT_CONFIGURED:
|
|
4422
|
+
setTranscriptionError("Transcription service is not available.");
|
|
4423
|
+
break;
|
|
4424
|
+
case TranscriptionErrorCode2.NETWORK_ERROR:
|
|
4425
|
+
setTranscriptionError("Network error. Please check your connection.");
|
|
4426
|
+
break;
|
|
4427
|
+
default:
|
|
4428
|
+
setTranscriptionError(
|
|
4429
|
+
retryable ? "Transcription failed. Please try again." : message
|
|
4430
|
+
);
|
|
4431
|
+
}
|
|
4432
|
+
} else {
|
|
4433
|
+
setTranscriptionError("Transcription failed. Please try again.");
|
|
4434
|
+
}
|
|
4435
|
+
} finally {
|
|
4436
|
+
setIsTranscribing(false);
|
|
4437
|
+
}
|
|
4438
|
+
}, [copilotkit]);
|
|
4439
|
+
useEffect15(() => {
|
|
4440
|
+
if (transcriptionError) {
|
|
4441
|
+
const timer = setTimeout(() => {
|
|
4442
|
+
setTranscriptionError(null);
|
|
4443
|
+
}, 5e3);
|
|
4444
|
+
return () => clearTimeout(timer);
|
|
4445
|
+
}
|
|
4446
|
+
}, [transcriptionError]);
|
|
4056
4447
|
const mergedProps = merge(
|
|
4057
4448
|
{
|
|
4058
4449
|
isRunning: agent.isRunning,
|
|
@@ -4069,27 +4460,56 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
4069
4460
|
const hasMessages = agent.messages.length > 0;
|
|
4070
4461
|
const shouldAllowStop = agent.isRunning && hasMessages;
|
|
4071
4462
|
const effectiveStopHandler = shouldAllowStop ? providedStopHandler ?? stopCurrentRun : providedStopHandler;
|
|
4463
|
+
const showTranscription = isTranscriptionEnabled && isMediaRecorderSupported;
|
|
4464
|
+
const effectiveMode = isTranscribing ? "processing" : transcribeMode;
|
|
4072
4465
|
const finalInputProps = {
|
|
4073
4466
|
...providedInputProps,
|
|
4074
4467
|
onSubmitMessage: onSubmitInput,
|
|
4075
4468
|
onStop: effectiveStopHandler,
|
|
4076
|
-
isRunning: agent.isRunning
|
|
4469
|
+
isRunning: agent.isRunning,
|
|
4470
|
+
mode: effectiveMode,
|
|
4471
|
+
value: inputValue,
|
|
4472
|
+
onChange: setInputValue,
|
|
4473
|
+
// Only provide transcription handlers if feature is available
|
|
4474
|
+
onStartTranscribe: showTranscription ? handleStartTranscribe : void 0,
|
|
4475
|
+
onCancelTranscribe: showTranscription ? handleCancelTranscribe : void 0,
|
|
4476
|
+
onFinishTranscribe: showTranscription ? handleFinishTranscribe : void 0,
|
|
4477
|
+
onFinishTranscribeWithAudio: showTranscription ? handleFinishTranscribeWithAudio : void 0
|
|
4077
4478
|
};
|
|
4078
|
-
finalInputProps.mode = agent.isRunning ? "processing" : finalInputProps.mode ?? "input";
|
|
4079
4479
|
const messages = useMemo11(() => [...agent.messages], [JSON.stringify(agent.messages)]);
|
|
4080
4480
|
const finalProps = merge(mergedProps, {
|
|
4081
4481
|
messages,
|
|
4082
4482
|
inputProps: finalInputProps
|
|
4083
4483
|
});
|
|
4084
4484
|
const RenderedChatView = renderSlot(chatView, CopilotChatView, finalProps);
|
|
4085
|
-
return /* @__PURE__ */
|
|
4485
|
+
return /* @__PURE__ */ jsxs12(
|
|
4086
4486
|
CopilotChatConfigurationProvider,
|
|
4087
4487
|
{
|
|
4088
4488
|
agentId: resolvedAgentId,
|
|
4089
4489
|
threadId: resolvedThreadId,
|
|
4090
4490
|
labels,
|
|
4091
4491
|
isModalDefaultOpen,
|
|
4092
|
-
children:
|
|
4492
|
+
children: [
|
|
4493
|
+
transcriptionError && /* @__PURE__ */ jsx20(
|
|
4494
|
+
"div",
|
|
4495
|
+
{
|
|
4496
|
+
style: {
|
|
4497
|
+
position: "absolute",
|
|
4498
|
+
bottom: "100px",
|
|
4499
|
+
left: "50%",
|
|
4500
|
+
transform: "translateX(-50%)",
|
|
4501
|
+
backgroundColor: "#ef4444",
|
|
4502
|
+
color: "white",
|
|
4503
|
+
padding: "8px 16px",
|
|
4504
|
+
borderRadius: "8px",
|
|
4505
|
+
fontSize: "14px",
|
|
4506
|
+
zIndex: 50
|
|
4507
|
+
},
|
|
4508
|
+
children: transcriptionError
|
|
4509
|
+
}
|
|
4510
|
+
),
|
|
4511
|
+
RenderedChatView
|
|
4512
|
+
]
|
|
4093
4513
|
}
|
|
4094
4514
|
);
|
|
4095
4515
|
}
|
|
@@ -4098,9 +4518,9 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
4098
4518
|
})(CopilotChat || (CopilotChat = {}));
|
|
4099
4519
|
|
|
4100
4520
|
// src/components/chat/CopilotChatToggleButton.tsx
|
|
4101
|
-
import React14, { useState as
|
|
4521
|
+
import React14, { useState as useState13 } from "react";
|
|
4102
4522
|
import { MessageCircle, X as X2 } from "lucide-react";
|
|
4103
|
-
import { jsx as jsx21, jsxs as
|
|
4523
|
+
import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4104
4524
|
var DefaultOpenIcon = ({
|
|
4105
4525
|
className,
|
|
4106
4526
|
...props
|
|
@@ -4129,7 +4549,7 @@ var CopilotChatToggleButton = React14.forwardRef(function CopilotChatToggleButto
|
|
|
4129
4549
|
const { onClick, type, disabled, ...restProps } = buttonProps;
|
|
4130
4550
|
const configuration = useCopilotChatConfiguration();
|
|
4131
4551
|
const labels = configuration?.labels ?? CopilotChatDefaultLabels;
|
|
4132
|
-
const [fallbackOpen, setFallbackOpen] =
|
|
4552
|
+
const [fallbackOpen, setFallbackOpen] = useState13(false);
|
|
4133
4553
|
const isOpen = configuration?.isModalOpen ?? fallbackOpen;
|
|
4134
4554
|
const setModalOpen = configuration?.setModalOpen ?? setFallbackOpen;
|
|
4135
4555
|
const handleClick = (event) => {
|
|
@@ -4191,7 +4611,7 @@ var CopilotChatToggleButton = React14.forwardRef(function CopilotChatToggleButto
|
|
|
4191
4611
|
children: renderedCloseIcon
|
|
4192
4612
|
}
|
|
4193
4613
|
);
|
|
4194
|
-
return /* @__PURE__ */
|
|
4614
|
+
return /* @__PURE__ */ jsxs13(
|
|
4195
4615
|
"button",
|
|
4196
4616
|
{
|
|
4197
4617
|
ref,
|
|
@@ -4215,12 +4635,12 @@ CopilotChatToggleButton.displayName = "CopilotChatToggleButton";
|
|
|
4215
4635
|
var CopilotChatToggleButton_default = CopilotChatToggleButton;
|
|
4216
4636
|
|
|
4217
4637
|
// src/components/chat/CopilotSidebarView.tsx
|
|
4218
|
-
import { useEffect as useEffect16, useRef as useRef8, useState as
|
|
4638
|
+
import { useEffect as useEffect16, useRef as useRef8, useState as useState14 } from "react";
|
|
4219
4639
|
|
|
4220
4640
|
// src/components/chat/CopilotModalHeader.tsx
|
|
4221
|
-
import { useCallback as
|
|
4641
|
+
import { useCallback as useCallback10 } from "react";
|
|
4222
4642
|
import { X as X3 } from "lucide-react";
|
|
4223
|
-
import { jsx as jsx22, jsxs as
|
|
4643
|
+
import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4224
4644
|
function CopilotModalHeader({
|
|
4225
4645
|
title,
|
|
4226
4646
|
titleContent,
|
|
@@ -4232,7 +4652,7 @@ function CopilotModalHeader({
|
|
|
4232
4652
|
const configuration = useCopilotChatConfiguration();
|
|
4233
4653
|
const fallbackTitle = configuration?.labels.modalHeaderTitle ?? CopilotChatDefaultLabels.modalHeaderTitle;
|
|
4234
4654
|
const resolvedTitle = title ?? fallbackTitle;
|
|
4235
|
-
const handleClose =
|
|
4655
|
+
const handleClose = useCallback10(() => {
|
|
4236
4656
|
configuration?.setModalOpen(false);
|
|
4237
4657
|
}, [configuration]);
|
|
4238
4658
|
const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {
|
|
@@ -4259,7 +4679,7 @@ function CopilotModalHeader({
|
|
|
4259
4679
|
className
|
|
4260
4680
|
),
|
|
4261
4681
|
...rest,
|
|
4262
|
-
children: /* @__PURE__ */
|
|
4682
|
+
children: /* @__PURE__ */ jsxs14("div", { className: "flex w-full items-center gap-2", children: [
|
|
4263
4683
|
/* @__PURE__ */ jsx22("div", { className: "flex-1", "aria-hidden": "true" }),
|
|
4264
4684
|
/* @__PURE__ */ jsx22("div", { className: "flex flex-1 justify-center text-center", children: BoundTitle }),
|
|
4265
4685
|
/* @__PURE__ */ jsx22("div", { className: "flex flex-1 justify-end", children: BoundCloseButton })
|
|
@@ -4302,14 +4722,14 @@ CopilotModalHeader.Title.displayName = "CopilotModalHeader.Title";
|
|
|
4302
4722
|
CopilotModalHeader.CloseButton.displayName = "CopilotModalHeader.CloseButton";
|
|
4303
4723
|
|
|
4304
4724
|
// src/components/chat/CopilotSidebarView.tsx
|
|
4305
|
-
import { Fragment as Fragment7, jsx as jsx23, jsxs as
|
|
4725
|
+
import { Fragment as Fragment7, jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4306
4726
|
var DEFAULT_SIDEBAR_WIDTH = 480;
|
|
4307
4727
|
var SIDEBAR_TRANSITION_MS = 260;
|
|
4308
4728
|
function CopilotSidebarView({ header, width, ...props }) {
|
|
4309
4729
|
const configuration = useCopilotChatConfiguration();
|
|
4310
4730
|
const isSidebarOpen = configuration?.isModalOpen ?? false;
|
|
4311
4731
|
const sidebarRef = useRef8(null);
|
|
4312
|
-
const [sidebarWidth, setSidebarWidth] =
|
|
4732
|
+
const [sidebarWidth, setSidebarWidth] = useState14(width ?? DEFAULT_SIDEBAR_WIDTH);
|
|
4313
4733
|
const widthToCss = (w) => {
|
|
4314
4734
|
return typeof w === "number" ? `${w}px` : w;
|
|
4315
4735
|
};
|
|
@@ -4346,7 +4766,7 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
4346
4766
|
return () => window.removeEventListener("resize", updateWidth);
|
|
4347
4767
|
}, [width]);
|
|
4348
4768
|
const headerElement = renderSlot(header, CopilotModalHeader, {});
|
|
4349
|
-
return /* @__PURE__ */
|
|
4769
|
+
return /* @__PURE__ */ jsxs15(Fragment7, { children: [
|
|
4350
4770
|
isSidebarOpen && /* @__PURE__ */ jsx23(
|
|
4351
4771
|
"style",
|
|
4352
4772
|
{
|
|
@@ -4387,7 +4807,7 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
4387
4807
|
"aria-hidden": !isSidebarOpen,
|
|
4388
4808
|
"aria-label": "Copilot chat sidebar",
|
|
4389
4809
|
role: "complementary",
|
|
4390
|
-
children: /* @__PURE__ */
|
|
4810
|
+
children: /* @__PURE__ */ jsxs15("div", { className: "flex h-full w-full flex-col overflow-hidden", children: [
|
|
4391
4811
|
headerElement,
|
|
4392
4812
|
/* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-hidden", "data-sidebar-chat": true, children: /* @__PURE__ */ jsx23(CopilotChatView_default, { ...props }) })
|
|
4393
4813
|
] })
|
|
@@ -4396,10 +4816,49 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
4396
4816
|
] });
|
|
4397
4817
|
}
|
|
4398
4818
|
CopilotSidebarView.displayName = "CopilotSidebarView";
|
|
4819
|
+
((CopilotSidebarView2) => {
|
|
4820
|
+
CopilotSidebarView2.WelcomeScreen = ({
|
|
4821
|
+
welcomeMessage,
|
|
4822
|
+
input,
|
|
4823
|
+
suggestionView,
|
|
4824
|
+
className,
|
|
4825
|
+
children,
|
|
4826
|
+
...props
|
|
4827
|
+
}) => {
|
|
4828
|
+
const BoundWelcomeMessage = renderSlot(
|
|
4829
|
+
welcomeMessage,
|
|
4830
|
+
CopilotChatView_default.WelcomeMessage,
|
|
4831
|
+
{}
|
|
4832
|
+
);
|
|
4833
|
+
if (children) {
|
|
4834
|
+
return /* @__PURE__ */ jsx23(Fragment7, { children: children({
|
|
4835
|
+
welcomeMessage: BoundWelcomeMessage,
|
|
4836
|
+
input,
|
|
4837
|
+
suggestionView,
|
|
4838
|
+
className,
|
|
4839
|
+
...props
|
|
4840
|
+
}) });
|
|
4841
|
+
}
|
|
4842
|
+
return /* @__PURE__ */ jsxs15(
|
|
4843
|
+
"div",
|
|
4844
|
+
{
|
|
4845
|
+
className: cn("h-full flex flex-col", className),
|
|
4846
|
+
...props,
|
|
4847
|
+
children: [
|
|
4848
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 flex flex-col items-center justify-center px-4", children: BoundWelcomeMessage }),
|
|
4849
|
+
/* @__PURE__ */ jsx23("div", { className: "px-8 pb-4", children: /* @__PURE__ */ jsxs15("div", { className: "max-w-3xl mx-auto", children: [
|
|
4850
|
+
/* @__PURE__ */ jsx23("div", { className: "mb-4 flex justify-center", children: suggestionView }),
|
|
4851
|
+
input
|
|
4852
|
+
] }) })
|
|
4853
|
+
]
|
|
4854
|
+
}
|
|
4855
|
+
);
|
|
4856
|
+
};
|
|
4857
|
+
})(CopilotSidebarView || (CopilotSidebarView = {}));
|
|
4399
4858
|
|
|
4400
4859
|
// src/components/chat/CopilotPopupView.tsx
|
|
4401
|
-
import { useEffect as useEffect17, useMemo as useMemo12, useRef as useRef9, useState as
|
|
4402
|
-
import { Fragment as Fragment8, jsx as jsx24, jsxs as
|
|
4860
|
+
import { useEffect as useEffect17, useMemo as useMemo12, useRef as useRef9, useState as useState15 } from "react";
|
|
4861
|
+
import { Fragment as Fragment8, jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4403
4862
|
var DEFAULT_POPUP_WIDTH = 420;
|
|
4404
4863
|
var DEFAULT_POPUP_HEIGHT = 560;
|
|
4405
4864
|
var dimensionToCss = (value, fallback) => {
|
|
@@ -4424,8 +4883,8 @@ function CopilotPopupView({
|
|
|
4424
4883
|
const setModalOpen = configuration?.setModalOpen;
|
|
4425
4884
|
const labels = configuration?.labels ?? CopilotChatDefaultLabels;
|
|
4426
4885
|
const containerRef = useRef9(null);
|
|
4427
|
-
const [isRendered, setIsRendered] =
|
|
4428
|
-
const [isAnimatingOut, setIsAnimatingOut] =
|
|
4886
|
+
const [isRendered, setIsRendered] = useState15(isPopupOpen);
|
|
4887
|
+
const [isAnimatingOut, setIsAnimatingOut] = useState15(false);
|
|
4429
4888
|
useEffect17(() => {
|
|
4430
4889
|
if (isPopupOpen) {
|
|
4431
4890
|
setIsRendered(true);
|
|
@@ -4516,7 +4975,7 @@ function CopilotPopupView({
|
|
|
4516
4975
|
"fixed inset-0 z-[1200] flex max-w-full flex-col items-stretch",
|
|
4517
4976
|
"md:inset-auto md:bottom-24 md:right-6 md:items-end md:gap-4"
|
|
4518
4977
|
),
|
|
4519
|
-
children: /* @__PURE__ */
|
|
4978
|
+
children: /* @__PURE__ */ jsxs16(
|
|
4520
4979
|
"div",
|
|
4521
4980
|
{
|
|
4522
4981
|
ref: containerRef,
|
|
@@ -4549,12 +5008,52 @@ function CopilotPopupView({
|
|
|
4549
5008
|
)
|
|
4550
5009
|
}
|
|
4551
5010
|
) : null;
|
|
4552
|
-
return /* @__PURE__ */
|
|
5011
|
+
return /* @__PURE__ */ jsxs16(Fragment8, { children: [
|
|
4553
5012
|
/* @__PURE__ */ jsx24(CopilotChatToggleButton_default, {}),
|
|
4554
5013
|
popupContent
|
|
4555
5014
|
] });
|
|
4556
5015
|
}
|
|
4557
5016
|
CopilotPopupView.displayName = "CopilotPopupView";
|
|
5017
|
+
((CopilotPopupView2) => {
|
|
5018
|
+
CopilotPopupView2.WelcomeScreen = ({
|
|
5019
|
+
welcomeMessage,
|
|
5020
|
+
input,
|
|
5021
|
+
suggestionView,
|
|
5022
|
+
className,
|
|
5023
|
+
children,
|
|
5024
|
+
...props
|
|
5025
|
+
}) => {
|
|
5026
|
+
const BoundWelcomeMessage = renderSlot(
|
|
5027
|
+
welcomeMessage,
|
|
5028
|
+
CopilotChatView_default.WelcomeMessage,
|
|
5029
|
+
{}
|
|
5030
|
+
);
|
|
5031
|
+
if (children) {
|
|
5032
|
+
return /* @__PURE__ */ jsx24(Fragment8, { children: children({
|
|
5033
|
+
welcomeMessage: BoundWelcomeMessage,
|
|
5034
|
+
input,
|
|
5035
|
+
suggestionView,
|
|
5036
|
+
className,
|
|
5037
|
+
...props
|
|
5038
|
+
}) });
|
|
5039
|
+
}
|
|
5040
|
+
return /* @__PURE__ */ jsxs16(
|
|
5041
|
+
"div",
|
|
5042
|
+
{
|
|
5043
|
+
className: cn("h-full flex flex-col", className),
|
|
5044
|
+
...props,
|
|
5045
|
+
children: [
|
|
5046
|
+
/* @__PURE__ */ jsx24("div", { className: "flex-1 flex flex-col items-center justify-center px-4", children: BoundWelcomeMessage }),
|
|
5047
|
+
/* @__PURE__ */ jsx24("div", { className: "px-6 pb-4", children: /* @__PURE__ */ jsxs16("div", { className: "max-w-3xl mx-auto", children: [
|
|
5048
|
+
/* @__PURE__ */ jsx24("div", { className: "mb-4 flex justify-center", children: suggestionView }),
|
|
5049
|
+
input
|
|
5050
|
+
] }) })
|
|
5051
|
+
]
|
|
5052
|
+
}
|
|
5053
|
+
);
|
|
5054
|
+
};
|
|
5055
|
+
})(CopilotPopupView || (CopilotPopupView = {}));
|
|
5056
|
+
var CopilotPopupView_default = CopilotPopupView;
|
|
4558
5057
|
|
|
4559
5058
|
// src/components/chat/CopilotSidebar.tsx
|
|
4560
5059
|
import { useMemo as useMemo13 } from "react";
|
|
@@ -4577,6 +5076,7 @@ function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
|
|
|
4577
5076
|
return /* @__PURE__ */ jsx25(
|
|
4578
5077
|
CopilotChat,
|
|
4579
5078
|
{
|
|
5079
|
+
welcomeScreen: CopilotSidebarView.WelcomeScreen,
|
|
4580
5080
|
...chatProps,
|
|
4581
5081
|
chatView: SidebarViewOverride,
|
|
4582
5082
|
isModalDefaultOpen: defaultOpen
|
|
@@ -4606,7 +5106,7 @@ function CopilotPopup({
|
|
|
4606
5106
|
...restProps
|
|
4607
5107
|
} = viewProps;
|
|
4608
5108
|
return /* @__PURE__ */ jsx26(
|
|
4609
|
-
|
|
5109
|
+
CopilotPopupView_default,
|
|
4610
5110
|
{
|
|
4611
5111
|
...restProps,
|
|
4612
5112
|
header: header ?? viewHeader,
|
|
@@ -4621,6 +5121,7 @@ function CopilotPopup({
|
|
|
4621
5121
|
return /* @__PURE__ */ jsx26(
|
|
4622
5122
|
CopilotChat,
|
|
4623
5123
|
{
|
|
5124
|
+
welcomeScreen: CopilotPopupView_default.WelcomeScreen,
|
|
4624
5125
|
...chatProps,
|
|
4625
5126
|
chatView: PopupViewOverride,
|
|
4626
5127
|
isModalDefaultOpen: defaultOpen
|
|
@@ -4642,24 +5143,24 @@ function defineToolCallRenderer(def) {
|
|
|
4642
5143
|
}
|
|
4643
5144
|
|
|
4644
5145
|
// src/components/WildcardToolCallRender.tsx
|
|
4645
|
-
import { useState as
|
|
4646
|
-
import { jsx as jsx27, jsxs as
|
|
5146
|
+
import { useState as useState16 } from "react";
|
|
5147
|
+
import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4647
5148
|
var WildcardToolCallRender = defineToolCallRenderer({
|
|
4648
5149
|
name: "*",
|
|
4649
5150
|
render: ({ args, result, name, status }) => {
|
|
4650
|
-
const [isExpanded, setIsExpanded] =
|
|
5151
|
+
const [isExpanded, setIsExpanded] = useState16(false);
|
|
4651
5152
|
const statusString = String(status);
|
|
4652
5153
|
const isActive = statusString === "inProgress" || statusString === "executing";
|
|
4653
5154
|
const isComplete = statusString === "complete";
|
|
4654
5155
|
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";
|
|
4655
|
-
return /* @__PURE__ */ jsx27("div", { className: "mt-2 pb-2", children: /* @__PURE__ */
|
|
4656
|
-
/* @__PURE__ */
|
|
5156
|
+
return /* @__PURE__ */ jsx27("div", { className: "mt-2 pb-2", children: /* @__PURE__ */ jsxs17("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: [
|
|
5157
|
+
/* @__PURE__ */ jsxs17(
|
|
4657
5158
|
"div",
|
|
4658
5159
|
{
|
|
4659
5160
|
className: "flex items-center justify-between gap-3 cursor-pointer",
|
|
4660
5161
|
onClick: () => setIsExpanded(!isExpanded),
|
|
4661
5162
|
children: [
|
|
4662
|
-
/* @__PURE__ */
|
|
5163
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
4663
5164
|
/* @__PURE__ */ jsx27(
|
|
4664
5165
|
"svg",
|
|
4665
5166
|
{
|
|
@@ -4691,12 +5192,12 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
4691
5192
|
]
|
|
4692
5193
|
}
|
|
4693
5194
|
),
|
|
4694
|
-
isExpanded && /* @__PURE__ */
|
|
4695
|
-
/* @__PURE__ */
|
|
5195
|
+
isExpanded && /* @__PURE__ */ jsxs17("div", { className: "mt-3 grid gap-4", children: [
|
|
5196
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
4696
5197
|
/* @__PURE__ */ jsx27("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Arguments" }),
|
|
4697
5198
|
/* @__PURE__ */ jsx27("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) })
|
|
4698
5199
|
] }),
|
|
4699
|
-
result !== void 0 && /* @__PURE__ */
|
|
5200
|
+
result !== void 0 && /* @__PURE__ */ jsxs17("div", { children: [
|
|
4700
5201
|
/* @__PURE__ */ jsx27("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Result" }),
|
|
4701
5202
|
/* @__PURE__ */ jsx27("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) })
|
|
4702
5203
|
] })
|